Re: [Roll] Benjamin Kaduk's Discuss on draft-ietf-roll-aodv-rpl-10: (with DISCUSS and COMMENT)

Charlie Perkins <charles.perkins@earthlink.net> Wed, 18 August 2021 20:46 UTC

Return-Path: <charles.perkins@earthlink.net>
X-Original-To: roll@ietfa.amsl.com
Delivered-To: roll@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 273FA3A1D15; Wed, 18 Aug 2021 13:46:27 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.1
X-Spam-Level:
X-Spam-Status: No, score=-2.1 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, NICE_REPLY_A=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=earthlink.net
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gqueg9U3rw-w; Wed, 18 Aug 2021 13:46:21 -0700 (PDT)
Received: from mta-202a.oxsus-vadesecure.net (mta-202a.oxsus-vadesecure.net [51.81.232.240]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id A3ED13A1D0C; Wed, 18 Aug 2021 13:46:21 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; bh=VnJRI69UzpFOttoOFCnPbVvTQ7jaTxB0Ydn8F8 a6WrI=; c=relaxed/relaxed; d=earthlink.net; h=from:reply-to:subject: date:to:cc:resent-date:resent-from:resent-to:resent-cc:in-reply-to: references:list-id:list-help:list-unsubscribe:list-subscribe:list-post: list-owner:list-archive; q=dns/txt; s=dk12062016; t=1629319580; x=1629924380; b=XYlxTAgTituA0f+qJpBamQU7i6xBvJg1Fb/Mvsx8GaWBrskIFmwoZAQ eJNISHTEGX6X+ZkdrYV+x5GDvRZl1F5XjPliqqNUUjmeszHWoK2dgRxv9qkUuQBlSWZEfjn WLtU+D3t5257W1os2iyXZNAVSc8b2Rv84fGVC1/BCW4H3ajBmrmbUDUNoImz0GRnYUGVRcA Sa7YoKYdCfE2xJ8T6ZIQFimgD/uzlgs3+DK7ICfvnPdjHpwUxrjs6o+3e10ymEIl21rWnjC WWNyRq9wq7QPgR404lwX64I2I4jecsTmfY32iJR9NlJ6KwtER07bC8Xy8SOl3WRphHFUB8g whg==
Received: from [192.168.1.72] ([99.51.72.196]) by smtp.oxsus-vadesecure.net ESMTP oxsus2nmtao02p with ngmta id 99f79d5f-169c8186661baf04; Wed, 18 Aug 2021 20:46:19 +0000
To: Benjamin Kaduk <kaduk@mit.edu>, The IESG <iesg@ietf.org>
Cc: draft-ietf-roll-aodv-rpl@ietf.org, roll-chairs@ietf.org, roll@ietf.org, Ines Robles <mariainesrobles@googlemail.com>, aretana.ietf@gmail.com
References: <161913172006.16574.8625402788675096789@ietfa.amsl.com>
From: Charlie Perkins <charles.perkins@earthlink.net>
Message-ID: <54ab3f3d-3220-6fbb-a01f-8effc87a5f10@earthlink.net>
Date: Wed, 18 Aug 2021 13:46:17 -0700
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0
MIME-Version: 1.0
In-Reply-To: <161913172006.16574.8625402788675096789@ietfa.amsl.com>
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Content-Language: en-US
Archived-At: <https://mailarchive.ietf.org/arch/msg/roll/fayTN8CMJMPN0r2c8KrchGwmDyw>
Subject: Re: [Roll] Benjamin Kaduk's Discuss on draft-ietf-roll-aodv-rpl-10: (with DISCUSS and COMMENT)
X-BeenThere: roll@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Routing Over Low power and Lossy networks <roll.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/roll>, <mailto:roll-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/roll/>
List-Post: <mailto:roll@ietf.org>
List-Help: <mailto:roll-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/roll>, <mailto:roll-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 18 Aug 2021 20:46:28 -0000

Hello Benjamin,

Please excuse the unusually long delay it has taken for us to respond to 
your comments.

Regarding the following:


 >  Benjamin Kaduk Discuss
 > Discuss (2021-04-22)

 > Specifically, there are several places in the document (most notably
 > Section 6.4) that provide steps for processing a RREP-DIO that refer to
 > the value of the "S bit".  There is no S bit in the RREP option as
 > defined in Section 4.2; indeed, there has never been an S bit in the
 > RREP option since it was introduced in the -03.  The -02 was proposing
 > changes directly in the DIO base object, which included an S bit, so in
 > that version of the document referring to an "S bit" in the reply
 > processing could have made sense.

Thank you very much for pointing out this inconsistency.  Once we 
decided that
the 'S' bit was not explicitly needed in the RREP option, we should have
changed this wording, but we just missed it.  Instead of referring to 
the 'S'
bit of the RREP, the text has to instead refer to a status bit in the 
internal
data structure for the RREQ-Instance, which we also called the 'S' bit.


<===== Text added after the last para of Step 1 of 6.2.1 =======>

       Step 1:

       If the S bit in the received RREQ-DIO is set to 1, the router MUST
       determine whether each direction of the link (by which the RREQ-
       DIO is received) satisfies the Objective Function.  In case that
       the downward (i.e., towards the TargNode) direction of the link
       does not satisfy the Objective Function, the link can't be used
       symmetrically, thus the S bit of the RREQ-DIO to be sent out MUST
       be set as 0.  If the S bit in the received RREQ-DIO is set to 0,
       the router MUST determine into the upward direction (towards the
       OrigNode) of the link.

       If the upward direction of the link can satisfy the Objective
       Function, and the router's Rank would not exceed the MaxUseRank
       limit, the router joins the DODAG of the RREQ-Instance.  The
       router that transmitted the received RREQ-DIO is selected as the
       preferred parent.  Otherwise, if the Objective Function is not
       satisfied or the MaxUseRank limit is exceeded, the router MUST
       discard the received RREQ-DIO and MUST NOT join the DODAG.

       When a router joins the RREQ-Instance, it also associates within
       its data structure for the RREQ-Instance the information about
       whether or not the RREQ has the S-bit set to 1. This information
       associated to RREQ-Instance is known as the S-bit of the
       RREQ-Instance. It will be used later during the RREP-DIO message
       processing (Section 6.4) for RPLInstance pairing as described
       in Section 6.3.3.

...
<=== Text added to Step 1 of 6.4.===>

6.4.  Receiving and Forwarding Route Reply

    Upon receiving a RREP-DIO, a router which does not belong to the
    RREP-Instance goes through the following steps:

    Step 1:

       If the S-bit of the RREQ-Instance is set to 1, the router MUST
       proceed to step 2.

       If the S-bit of the RREQ-Instance is set to 0, the router MUST
       determine whether the downward direction of the link (towards the
       TargNode) over which the RREP-DIO is received satisfies the
       Objective Function, and the router's Rank would not exceed the
       MaxRank limit.  If so, the router joins the DODAG of the RREP-
       Instance.  The router that transmitted the received RREP-DIO is
       selected as the preferred parent.  Afterwards, other RREP-DIO
       messages can be received.


 > There are also a few places that refer to using RREP (reply) processing
 > to relate to membership in or joining of the RREQ (request) DODAG.  I
 > assume that these are, in effect, typographical errors that should refer
 > to the RREP DODAG, but the one character has extreme significance to
 > protocol operations.

We are reviewing every instance of this wording, and have made the suggested
correction where appropriate.


 > I also think that there is too much ambiguity relating to the processing
 > of RREPs in the symmetric vs asymmetric case (which returns to the
 > question of whether there is or should be an S bit in the RREP option).
 > In particular, the semantics of the Address Vector field (for the
 > source-routing case only, of course) vary.  In the symmetric case this
 > field is set by TargNode and propagated unchanged in the RREPs, but for
 > the asymmetric case each intermediate node needs to add its address in
 > the Address Vector.  We do cover these different behaviors in Sections
 > 6.3.1 and 6.3.2, but leave it very unclear as to how an intermediate
 > node tells whether a received RREP is for the symmetric or asymmetric
 > case.

This is intended to be resolved by maintaining the 'S' bit status in the
RREQ-Instance.


 >            An explicit S bit would make this easy, of course, though it
 > seems like it *might* be possible to use whether the RREP was received
 > over a unicast or multicast address/interface as a stand in.
 >
 > However,
 > that technique would be complicated by the presence of gratuitous RREPs,
 > which are unicast in cases that do not quite align up with symmetric vs
 > asymmetric.  (Whether the processing behavior should reflect the "append
 > to address vector" or "propagate address vector unchanged" for the
 > gratuitous case is also not entirely clear to me.)

Given the maintenance of the 'S' bit status in the RREQ-Instance, it should
not be necessary to make the determination based on whether or not the 
message
was received as a multicast.


 > On a more minor note, I don't think the description of rollover in
 > Section 6.3.3 is correct.  More in the COMMENT, but in essence, even
 > though the shift is capped at 63, the instance ID can go up to 255 and
 > wrapping should occur at the instance ID boundary, not the shift
 > boundary.

The point of the shift parameter is to be able to "modify" the value of the
RPLInstanceID so that a unique association can be made between RREQ-Instance
and RREP-Instance. We are confident that having 64 values to choose from 
will
enable the node to make the unique association.


 > Comment (2021-04-22)

 > The Abstract and Introduction do not paint a very clear picture of what
 > is going to happen.  Section 3 helps a fair bit, but I would have
 > expected the introduction to mention that RREQ/RREP go in separate
 > (paired) RPL instances, and that instances are created (and destroyed?)
 > for each route being discovered.  (This would also be a great place to
 > clarify how AODV-RPL interacts with regular RPL, as was requested by
 > other ADs already.)

We will use your wording when adding additional text to the Introduction.
AODV-RPL can be used alongside RPL and add routes to the existing
RPL-discovered routes.  However, there does not seem to be much value in
maintaining two routing protocols even if they are compatible.


 > I would like to see a clearer picture of the relationship between the
 > lifetime of routes discovered using AODV-RPL and the lifetime of the
 > DODAGs used to build them.  The (non-infinite) DODAG lifetime options
 > are fairly short, and I would (perhaps naively) expect routes to have a
 > longer lifetime than that in many cases.  But it seems that the
 > information stored with a route includes the RPL InstanceID, and if the
 > route is to outlast the DODAG, then that information would become stale,
 > and I don't know what value there would be in keeping it around in that
 > case and risking collisions.  Is it expected that when routes are to be
 > long-lived, the L value of 0 is to be used?

Routes are intended to last long enough to support the applications 
running on
the OrigNode and TargNode that required the route.  The same considerations
apply to RPL, and so we expected that AODV-RPL would use the same mechanism
for route longevity that is used by RPL.

Your explanation for route lifetime is fine to me.  In addition, DODAG
lifetime cannot be lower than the route lifetime since that could lead to
stale information as observed.


 > Section 1

 >>    (DAO) message of RPL.  AODV-RPL specifies a new MOP (Mode of
 >>    Operation) running in a separate instance dedicated to discover P2P
 >>    routes, which may differ from the point-to-multipoint routes
 >>    discoverable by native RPL.  AODV-RPL can be operated whether or not

 > I don't really understand why we find it useful to make a comparison
 > between P2P routes and P2MP routes.

Agreed.  It isn't useful. "P2P routes discoverable by native RPL" is better.


 > Section 2

 >>    RREP-DIO message
 >>       An AODV-RPL MOP DIO message containing the RREP option.  The
 >>       RPLInstanceID in RREP-DIO is typically paired to the one in the
 >
 > Typically, or actually (noting that §6.3.3 allows for the pairing
 > process to include a "Shift" count for cases where the value cannot
 > match exactly)?  Is this an attempt to reflect the symmetric case where
 > a DODAG is not built for symmetric routes?  If so, it's not clear that
 > we accurately portray what would be the "typical" case...but even in
 > that symmetric case we still have to populate the RPLInstance field in
 > the unicast RREP-DIO, and that still has the pairing logic.  So I'm back
 > to wondering when these would not be paired.

It is intended to allow for the shift parameter.  §6.3.3 clearly states
"the RREQ-Instance and the RREP-Instance in the same route discovery MUST
be paired using the RPLInstanceID." Accordingly, we modify the text as 
follows.

    "The RPLInstanceID in RREP-DIO MUST be paired to the one in the 
associated
     RREQ-DIO message as described in §6.3.3."


 > Section 3

 >>    The routes discovered by AODV-RPL are not constrained to traverse a
 >>    common ancestor.  AODV-RPL can enable asymmetric communication paths
 >>    in networks with bidirectional asymmetric links.  For this purpose,

 > Can AODV-RPL function in networks with unidirectional links?

Yes, as long as the node receiving an RREQ or RREP message can valuate 
whether
or not the link bearing an incoming message satisfies the OF.


 >>    to TargNode, and another from TargNode to OrigNode. When possible,
 >>    AODV-RPL also enables symmetric route discovery along Paired DODAGs
 >>    (see Section 5).

 > In what circumstances is it not possible to do so?

It is possible when the links are symmetric.

 > Section 4.1

 >>    OrigNode sets its IPv6 address in the DODAGID field of the RREQ-DIO
 >>    message.  A RREQ-DIO message MUST carry exactly one RREQ option,
 >>    otherwise it MUST be dropped.  (Similarly for RREP in §4.2.)

 > I suggest clarifying that other options are allowed (required, even).

Yes, other options are allowed. We will clarify this point by
referring to Section 4.3 which says, "A RREQ-DIO message MUST carry at
least one ART Option.  A RREP-DIO message MUST carry exactly one ART 
Option.
Otherwise, the message MUST be dropped."

 > Who sets the S bit, and can it change as the DODAG is being constructed?
 > ("See Section 5" would be fine.)

Only the OrigNode sets the 'S' bit.


 >>    L
 >>       2-bit unsigned integer determining the duration that a node is
 >>       able to belong to the temporary DAG in RREQ-Instance, including
 >>       the OrigNode and the TargNode.  Once the time is reached, a node
 >>       MUST leave the DAG and stop sending or receiving any more DIOs for
 >>       the temporary DODAG.

 > How do we account for time skew as the DIO propagates?  Each node just
 > leaves on their own timer?

Yes, the measure time duration depends on each node's ability to keep
track of the time.


 >>    Address Vector
 >>       A vector of IPv6 addresses representing the route that the RREQ-
 >>       DIO has passed.  It is only present when the H bit is set to 0.
 >>       The prefix of each address is elided according to the Compr field.

 >>    TargNode can join the RREQ instance at a Rank whose integer portion
 >>    is equal to the MaxRank.  Other nodes MUST NOT join a RREQ instance
 >>    if its own Rank would be equal to or higher than MaxRank.  A router
 >>    MUST discard a received RREQ if the integer part of the advertised
 >>    Rank equals or exceeds the MaxRank limit.

 > Both of these descriptions might benefit from a bit more detail.  E.g.,
 > the latter paragraph doesn't say that TargNode can join if the rank is
 > less than MaxRank, only if it's equal.

Good point!  Yes, the TargNode can join if the rank is less than or
equal to MaxRank.


 > Section 4.2

 >>    H
 >>       Requests either source routing (H=0) or hop-by-hop (H=1) for the
 >>       downstream route.  It MUST be set to be the same as the H bit in
 >>       RREQ option.

 > (editorial) I'd suggest putting the "MUST be the same" requirement as
 > the first sentence, and then the other sentence could be "determines
 > whether source routing (H=0) or hop-by-hop (H=1) is used for the
 > downstream route"

O.K.


 >>    L
 >>       2-bit unsigned integer defined as in RREQ option.

 > Does L need to have the same value as in the triggering RREQ option?  If
 > not, when might TargNode choose a different value?

Both the DODAGs are part of the same route discovery, and RPLInstanceID
requires that both DODAGs be alive.  There can however be a route with
asymmetric data traffic profile between OrigNode and TargNode.  In this
case, it is possible that the data occupancy times of the two DODAGs are
different.  The OrigNode should consider this factor while fixing the
duration.  The L-value for the RREQ-Instance has to be larger than the
L value for the RREP-Instance.


 >>    Address Vector
 >>       Only present when the H bit is set to 0.  For an asymmetric route,
 >>       the Address Vector represents the IPv6 addresses of the route that
 >>       the RREP-DIO has passed.  For a symmetric route, it is the Address
 >>       Vector when the RREQ-DIO arrives at the TargNode, unchanged during
 >>       the transmission to the OrigNode.

 > [ed. this was written before I made a discuss point about it, but I'm
 > leaving the text for the extra detail.  It's okay to just respond to the
 > discuss point and not here.]
 > If I understand correctly, the S bit indicating symmetric vs asymmetric
 > route is present only in the RREQ-DIO, and is not included in-band in
 > the RREP-DIO.  Does this require all nodes on the path to remember
 > whether a symmetric route is being constructed on the RREQ-DIO instance,
 > use the Shift in the RREP-DIO to correlate to the corresponding RREQ-DIO
 > and 'S' bit status, as part of the processing (to determine whether or
 > not to append to the Address Vector)?

Yes, that is the requirement.



 > Section 4.3

 >>    Dest SeqNo

 >>       In RREQ-DIO, if nonzero, it is the last known Sequence Number for
 >>       TargNode for which a route is desired.  In RREP-DIO, it is the
 >>       destination sequence number associated to the route.

 > The destination sequence number for the downstream route or the upstream
 > route?

The RREQ carries the destination sequence number for the last OF-compliant
route that OrigNode stored to the TargNode - i.e., the downstream route.


 > Also, should we say that zero is used if there is no known 
information about
 > the sequence number of TargNode (and not otherwise)?

Agreed.


 >>    r
 >>       A one-bit reserved field.  This field MUST be initialized to zero
 >>       by the sender and MUST be ignored by the receiver.

 > The secdir reviewer noted the mismatch between 'X' in the figure and 'r'
 > here; please fix.

Agreed.


 >>    Prefix Length
 >>       7-bit unsigned integer.  Number of valid leading bits in the IPv6
 >>       Prefix.  If Prefix Length is 0, then the value in the Target
 >>       Prefix / Address field represents an IPv6 address, not a prefix.
 >>
 >>    Target Prefix / Address
 >>       (variable-length field) An IPv6 destination address or prefix.
 >>       The Prefix Length field contains the number of valid leading bits
 >>       in the prefix.  The length of the field is the least number of
 >>       octets that can contain all of the bits of the Prefix, in other
 >>       words Floor((7+(Prefix Length))/8) octets.  The remaining bits in
 >>       the Target Prefix / Address field after the prefix length (if any)
 >>       MUST be set to zero on transmission and MUST be ignored on
 >>       receipt.

 > Please specify how long the Address field is when Prefix Length is zero
 > (indicating that the last field is the Address variant).

Address field is 128 bits for IPv6 addresses.


 > Section 5

 >>    Links are considered symmetric until additional information is
 >>    collected.  [...]
 >
 > What kinds of problems will arise if we start taking actions based on
 > this assumption before the "additional information" is available?
 > (That is to say, perhaps this is not a useful phrasing, since what we
 > actually do is get updates about the presence of asymmetric links as we
 > construct the route.)

How about, "indication to the contrary is received"?


 >>    bit set to 1, then all the one-hop links on the route from the
 >>    OrigNode O to this router meet the requirements of route discovery,
 >
 > Re "the route", this would presumably be the one recorded in the Address
 > Vector of the RREQ in question?  (Multiple RREQs for the same route
 > computation can arrive at a given node with different address vectors,
 > right?

Yes, both of your statements are correct.  We will try to devise more exact
wording, or if you have a suggestion that would be appreciated.


 >
 > Also, the way this is written implies that it does not say anything
 > about "non-one-hop links" on the route, but I don't really know what a
 > link that's not a one-hop link would be.  Can we just say "all the hops"
 > or "all the links"?

Good idea.


 >>    and the route can be used symmetrically.

 > But does that matter for any routers other than TargNode (for any of the
 > AODV-RPL Target Options)?

Yes, because in the symmetric case unicast RREP is specified.


 >>    doesn't satisfy the Objective Function.  Based on the S bit received
 >>    in RREQ-DIO, TargNode T determines whether or not the route is
 >>    symmetric before transmitting the RREP-DIO message upstream towards
 >>    the OrigNode O.

 > Does that determination affect the construction of the RREP-DIO in any
 > way?  (E.g., if there was an S bit.)

Section 6.3.1 says:

    "For a symmetric route, the RREP-DIO message is unicast to the next hop
     according to the accumulated address vector (H=0) or the route 
entry (H=1)."


 >>             Figure 5: AODV-RPL with Asymmetric Paired Instances

 > Some discussion of how the third(? second?) intermediate router detects
 > the asymmetry and clears the S bit might be appropriate.

We will describe Figure 5 by with the help of link asymmetry detection
methods discussion given in the same section, Section 5. The proposed text:

    As shown in the Figure 5, an intermediate router determines the 'S' bit
    value RREQ-DIO should carry with the help of link asymmetry detection
    methods discussed in Section 5. It is expected that the intermediate
    router has already made the link asymmetry decision by the time RREQ-DIO
    arrives.

 > Section 6.1
 >
 >>    link-local multicast.  The DIO MUST contain at least one ART Option
 >>    (see Section 4.3).  The S bit in RREQ-DIO sent out by the OrigNode is
 >>    set to 1.
 >
 > I'd suggest saying that the required ART Option indicates the TargNode.

O.K.


 >>    OrigNode can maintain different RPLInstances to discover routes with
 >>    different requirements to the same targets.  Using the RPLInstanceID
 >>    pairing mechanism (see Section 6.3.3), route replies (RREP-DIOs) for
 >>    different RPLInstances can be distinguished.
 >
 > When using different RPLInstances for this purpose, what constitutes
 > "initiates a route discovery process" across those instances -- is it
 > permissible to only increment the sequence number once when initiating
 > multiple discovery processes on different instances?

It is also needed to put in the correct OF and other values specific to 
the desired route.  If those are all the same, just incrementing the 
sequence number is fine.


 > Section 6.2.1
 >
 >>    Step 1:
 >
 >>       If the S bit in the received RREQ-DIO is set to 1, the router MUST
 >>       determine whether each direction of the link (by which the RREQ-
 >>       DIO is received) satisfies the Objective Function. In case that
 >>       the downward (i.e. towards the TargNode) direction of the link
 >>       does not satisfy the Objective Function, the link can't be used
 >>       symmetrically, thus the S bit of the RREQ-DIO to be sent out MUST
 >>       be set as 0.  If the S bit in the received RREQ-DIO is set to 0,
 >>       the router MUST determine into the upward direction (towards the
 >>       OrigNode) of the link.
 >
 >>       If the upward direction of the link can satisfy the Objective
 >>       Function, and the router's Rank would not exceed the MaxUseRank
 >>       limit, the router joins the DODAG of the RREQ-Instance.  The
 >>       router that transmitted the received RREQ-DIO is selected as the
 >>       preferred parent.  Otherwise, if the Objective Function is not
 >>       satisfied or the MaxUseRank limit is exceeded, the router MUST
 >>       discard the received RREQ-DIO and MUST NOT join the DODAG.
 >
 > The way this is written is confusing to me.  It seems to say that (1)
 > you only check the upward direction is the S bit in the received
 > RREQ-DIO is set to zero, and (2) the only time you join the DODAG is if
 > you're checking the upward direction.  So, when the received S-bit is 1,
 > do you just never join the DODAG?  I assume this is not the intent, but
 > that is how I interpret the words that are on the page.

It is supposed to mean that the node always checks the upstream link, and
joins if the OF is satisfied.  If the OF is not satisfied,

 >>       Sequence Number.  The Destination Address and the RPLInstanceID
 >>       respectively can be learned from the DODAGID and the RPLInstanceID
 >>       of the RREQ-DIO, and the Source Address is the address used by the
 >>       local router to send data to the OrigNode.  The Next Hop is the

 > "Source Address is the address used by the local router to send data to
 > the OrigNode" seems like the definition of the source address in a route
 > table entry, not a procedure for how to set it.  Should this be the
 > address used by the local router to send data to the preferred parent?

Yes, we will use that terminology.


 > Section 6.3.1

 >>    implementation-specific and out of scope.  If the implementation
 >>    selects the symmetric route, and the L bit is not 0, the TargNode MAY
 >>    delay transmitting the RREP-DIO for duration RREP_WAIT_TIME to await
 >>    a symmetric route with a lower Rank.  The value of RREP_WAIT_TIME is
 >>    set by default to 1/4 of the time duration determined by the L bit.

 > There is no L *bit* in the RREQ option or the RFC 6550 DIO. There is a
 > two-bit L field in the RREQ option, but even if I replace 'bit' with
 > 'field', it's still not clear why having a DODAG with no lifetime limit
 > implies that delaying the RREP-DIO is not allowed.

I don't see what is wrong about using L=0 to disallow the delay.


 > Section 6.3.2

 >>    When a RREQ-DIO arrives at a TargNode with the S bit set to 0, the
 >>    TargNode MUST build a DODAG in the RREP-Instance rooted at itself in

 > I don't understand how the definite article is appropriate for "the
 > RREP-Instance rooted at itself" -- I thought there were multiple
 > (paired) instances corresponding to the various RREQ DODAGs that
 > requested routes to TargNode.

That is a good point.  It has to be the RREP-Instance corresponding to the
RREQ-DIO.



 >>    RREP_WAIT_TIME to await a route with a lower Rank.  The value of
 >>    RREP_WAIT_TIME is set by default to 1/4 of the time duration
 >>    determined by the L bit.

 > ("L bit" again, and no indication of what to do for L==0.)

The behavior should be the same.


 >>    The settings of the fields in RREP option and ART option are the same
 >>    as for the symmetric route, except for the S bit.

 > There is no S bit in the RREP.  What is this intending to say?

It should have said, "except for the value of the 'S' bit associated
with the RREP-instance".


 > Section 6.3.3

 >>    When preparing the RREP-DIO, a TargNode could find the RPLInstanceID
 >>    to be used for the RREP-Instance is already occupied by another RPL
 >>    Instance from an earlier route discovery operation which is still
 >>    active.  In other words, it might happen that two distinct OrigNodes
 >>    need routes to the same TargNode, and they happen to use the same
 >>    RPLInstanceID for RREQ-Instance.  In this case, the occupied
 >>    RPLInstanceID MUST NOT be used again.  [...]

 > A reminder might be helpful that the RPLInstanceID is a property of a
 > DODAG, and a DODAG is identified by the DODAGID, which in this case is
 > the address of the TargNode.  So that is why we need to avoid reusing
 > RPLInstanceID in the context of the RREP-DIO, whereas there is no
 > problem with collisions in RPLInstanceID across RREQ-DIOs (where the
 > DODAGID is the OrigNode address, that suffices to disambiguate).


When preparing the RREP-DIO, a TargNode could find the RPLInstanceID 
candidate
for the RREP-Instance is already occupied by another RPL Instance from an
earlier route discovery operation which is still active.   This unlikely 
case
might happen if two distinct OrigNodes need routes to the same TargNode, and
they happen to use the same RPLInstanceID for RREQ-Instance. In this 
case, the
occupied RPLInstanceID which denotes Objective Function of the DODAG, 
MUST NOT
be used again.  Reusing the same RPLInstanceID for two distinct
DODAGs originated with the same DODAGID (TargNode address) would prevent
intermediate routers to distinguish between these DODAGs (and their 
associated
Objective Functions).  RPLInstanceID collisions do not occur across 
RREQ-DIOs;
the DODAGID equals the OrigNode address and is sufficient to
disambiguate between DODAGs.



 >>    shift to be applied to original RPLInstanceID.  When the new
 >>    RPLInstanceID after shifting exceeds 63, it rolls over starting at 0.

 > I thought RPLInstanceID was a full 8-bit field (even though Shift is
 > only six bits); wouldn't rollover happen after 255?

You are correct.  It should say 255 instead of 63.


 >>    For example, the original RPLInstanceID is 60, and shifted by 6, the
 >>    new RPLInstanceID will be 2.  Related operations can be found in
 >>    Section 6.4.

 > (So this example wouldn't actually show rollover.)

Correct again.


 > Section 6.4

 >>    Upon receiving a RREP-DIO, a router which does not belong to the
 >>    RREQ-Instance goes through the following steps:

 > Do we care about RREQ-Instance membership or RREP-Instance membership,
 > for processing the RREP-DIO?


Right, it should have been RREP-Instance, not RREQ-Instance as shown.
But in fact, we do not need this conditional check at all. Processing
the newly arriving RREP-DIO even if the router has already joined
RREP-Instance can result in better downward route to TargNode.


 >    Step 1:

 >>       If the S bit is set to 1, the router MUST proceed to step 2.

 > There is no S bit in the RREP option!

Correct again.  This should refer to the S-bit of the associated Instance.


 >>       and the destination address is learned from the DODAGID.  The
 >>       lifetime is set according to DODAG configuration (i.e., not the L
 >>       bit) and can be extended when the route is actually used.  The

 > ("L bit" again)

Check.


 >>    Upon receiving a RREP-DIO, a router which already belongs to the
 >>    RREQ-Instance SHOULD drop the RREP-DIO.

 > (RREQ-Instance vs RREP-Instance, again.)

Check.



 > Section 10

 > It seems like a malicious node that forges a gratuitous RREP could do
 > significant damage as well, so that might be worth mentioning.

Yes.

 >>    routing loop.  The TargNode MUST NOT generate a RREP if one of its
 >>    addresses is present in the Address Vector.  An Intermediate Router
 >>    MUST NOT forward a RREP if one of its addresses is present in the
 >>    Address Vector.

 > These requirements seem important enough that I'd prefer to seem them
 > imposed in the main body text that covers RREP handling, and the
 > security considerations mentioned here and referring to those handling
 > requirements.

Agreed.  These requirements belong better in the main body text.

Regards,
Charlie P.

On 4/22/2021 3:48 PM, Benjamin Kaduk via Datatracker wrote:
> Benjamin Kaduk has entered the following ballot position for
> draft-ietf-roll-aodv-rpl-10: Discuss
>
> When responding, please keep the subject line intact and reply to all
> email addresses included in the To and CC lines. (Feel free to cut this
> introductory paragraph, however.)
>
>
> Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
> for more information about DISCUSS and COMMENT positions.
>
>
> The document, along with other ballot positions, can be found here:
> https://datatracker.ietf.org/doc/draft-ietf-roll-aodv-rpl/
>
>
>
> ----------------------------------------------------------------------
> DISCUSS:
> ----------------------------------------------------------------------
>
> My apologies for coming in with a late review, but I think there are
> some serious internal inconsistencies in this document that leave me
> unsure whether the document is in a reviewable form.  It might be
> prudent to have the document return to the WG to fix the identified
> issues and get additional review.
>
> Specifically, there are several places in the document (most notably
> Section 6.4) that provide steps for processing a RREP-DIO that refer to
> the value of the "S bit".  There is no S bit in the RREP option as
> defined in Section 4.2; indeed, there has never been an S bit in the
> RREP option since it was introduced in the -03.  The -02 was proposing
> changes directly in the DIO base object, which included an S bit, so in
> that version of the document referring to an "S bit" in the reply
> processing could have made sense.
>
> There are also a few places that refer to using RREP (reply) processing
> to relate to membership in or joining of the RREQ (request) DODAG.  I
> assume that these are, in effect, typographical errors that should refer
> to the RREP DODAG, but the one character has extreme significance to
> protocol operations.
>
> I also think that there is too much ambiguity relating to the processing
> of RREPs in the symmetric vs asymmetric case (which returns to the
> question of whether there is or should be an S bit in the RREP option).
> In particular, the semantics of the Address Vector field (for the
> source-routing case only, of course) vary.  In the symmetric case this
> field is set by TargNode and propagated unchanged in the RREPs, but for
> the asymmetric case each intermediate node needs to add its address in
> the Address Vector.  We do cover these different behaviors in Sections
> 6.3.1 and 6.3.2, but leave it very unclear as to how an intermediate
> node tells whether a received RREP is for the symmetric or asymmetric
> case.  An explicit S bit would make this easy, of course, though it
> seems like it *might* be possible to use whether the RREP was received
> over a unicast or multicast address/interface as a stand in.  However,
> that technique would be complicated by the presence of gratuitous RREPs,
> which are unicast in cases that do not quite align up with symmetric vs
> asymmetric.  (Whether the processing behavior should reflect the "append
> to address vector" or "propagate address vector unchanged" for the
> gratuitous case is also not entirely clear to me.)
>
> On a more minor note, I don't think the description of rollover in
> Section 6.3.3 is correct.  More in the COMMENT, but in essence, even
> though the shift is capped at 63, the instance ID can go up to 255 and
> wrapping should occur at the instance ID boundary, not the shift
> boundary.
>
>
> ----------------------------------------------------------------------
> COMMENT:
> ----------------------------------------------------------------------
>
> The Abstract and Introduction do not paint a very clear picture of what
> is going to happen.  Section 3 helps a fair bit, but I would have
> expected the introduction to mention that RREQ/RREP go in separate
> (paired) RPL instances, and that instances are created (and destroyed?)
> for each route being discovered.  (This would also be a great place to
> clarify how AODV-RPL interacts with regular RPL, as was requested by
> other ADs already.)
>
> I would like to see a clearer picture of the relationship between the
> lifetime of routes discovered using AODV-RPL and the lifetime of the
> DODAGs used to build them.  The (non-infinite) DODAG lifetime options
> are fairly short, and I would (perhaps naively) expect routes to have a
> longer lifetime than that in many cases.  But it seems that the
> information stored with a route includes the RPL InstanceID, and if the
> route is to outlast the DODAG, then that information would become stale,
> and I don't know what value there would be in keeping it around in that
> case and risking collisions.  Is it expected that when routes are to be
> long-lived, the L value of 0 is to be used?
>
> Section 1
>
>     (DAO) message of RPL.  AODV-RPL specifies a new MOP (Mode of
>     Operation) running in a separate instance dedicated to discover P2P
>     routes, which may differ from the point-to-multipoint routes
>     discoverable by native RPL.  AODV-RPL can be operated whether or not
>
> I don't really understand why we find it useful to make a comparison
> between P2P routes and P2MP routes.
>
> Section 2
>
>     RREP-DIO message
>        An AODV-RPL MOP DIO message containing the RREP option.  The
>        RPLInstanceID in RREP-DIO is typically paired to the one in the
>
> Typically, or actually (noting that §6.3.3 allows for the pairing
> process to include a "Shift" count for cases where the value cannot
> match exactly)?  Is this an attempt to reflect the symmetric case where
> a DODAG is not built for symmetric routes?  If so, it's not clear that
> we accurately portray what would be the "typical" case...but even in
> that symmetric case we still have to populate the RPLInstance field in
> the unicast RREP-DIO, and that still has the pairing logic.  So I'm back
> to wondering when these would not be paired.
>
> Section 3
>
>     The routes discovered by AODV-RPL are not constrained to traverse a
>     common ancestor.  AODV-RPL can enable asymmetric communication paths
>     in networks with bidirectional asymmetric links.  For this purpose,
>
> Can AODV-RPL function in networks with unidirectional links?
>
>     to TargNode, and another from TargNode to OrigNode.  When possible,
>     AODV-RPL also enables symmetric route discovery along Paired DODAGs
>     (see Section 5).
>
> In what circumstances is it not possible to do so?
>
> Section 4.1
>
>     OrigNode sets its IPv6 address in the DODAGID field of the RREQ-DIO
>     message.  A RREQ-DIO message MUST carry exactly one RREQ option,
>     otherwise it MUST be dropped.  (Similarly for RREP in §4.2.)
>
> I suggest clarifying that other options are allowed (required, even).
>
> Who sets the S bit, and can it change as the DODAG is being constructed?
> ("See Section 5" would be fine.)
>
>     L
>        2-bit unsigned integer determining the duration that a node is
>        able to belong to the temporary DAG in RREQ-Instance, including
>        the OrigNode and the TargNode.  Once the time is reached, a node
>        MUST leave the DAG and stop sending or receiving any more DIOs for
>        the temporary DODAG.
>
> How do we account for time skew as the DIO propagates?  Each node just
> leaves on their own timer?
>
>     Address Vector
>        A vector of IPv6 addresses representing the route that the RREQ-
>        DIO has passed.  It is only present when the H bit is set to 0.
>        The prefix of each address is elided according to the Compr field.
>
>     TargNode can join the RREQ instance at a Rank whose integer portion
>     is equal to the MaxRank.  Other nodes MUST NOT join a RREQ instance
>     if its own Rank would be equal to or higher than MaxRank.  A router
>     MUST discard a received RREQ if the integer part of the advertised
>     Rank equals or exceeds the MaxRank limit.
>
> Both of these descriptions might benefit from a bit more detail.  E.g.,
> the latter paragraph doesn't say that TargNode can join if the rank is
> less than MaxRank, only if it's equal.
>
> Section 4.2
>
>     H
>        Requests either source routing (H=0) or hop-by-hop (H=1) for the
>        downstream route.  It MUST be set to be the same as the H bit in
>        RREQ option.
>
> (editorial) I'd suggest putting the "MUST be the same" requirement as
> the first sentence, and then the other sentence could be "determines
> whether source routing (H=0) or hop-by-hop (H=1) is used for the
> downstream route"
>
>     L
>        2-bit unsigned integer defined as in RREQ option.
>
> Does L need to have the same value as in the triggering RREQ option?  If
> not, when might TargNode choose a different value?
>
>     Address Vector
>        Only present when the H bit is set to 0.  For an asymmetric route,
>        the Address Vector represents the IPv6 addresses of the route that
>        the RREP-DIO has passed.  For a symmetric route, it is the Address
>        Vector when the RREQ-DIO arrives at the TargNode, unchanged during
>        the transmission to the OrigNode.
>
> [ed. this was written before I made a discuss point about it, but I'm
> leaving the text for the extra detail.  It's okay to just respond to the
> discuss point and not here.]
> If I understand correctly, the S bit indicating symmetric vs asymmetric
> route is present only in the RREQ-DIO, and is not included in-band in
> the RREP-DIO.  Does this require all nodes on the path to remember
> whether a symmetric route is being constructed on the RREQ-DIO instance,
> use the Shift in the RREP-DIO to correlate to the corresponding RREQ-DIO
> and 'S' bit status, as part of the processing (to determine whether or
> not to append to the Address Vector)?
>
> Section 4.3
>
>     Dest SeqNo
>
>        In RREQ-DIO, if nonzero, it is the last known Sequence Number for
>        TargNode for which a route is desired.  In RREP-DIO, it is the
>        destination sequence number associated to the route.
>
> The destination sequence number for the downstream route or the upstream
> route?
>
> Also, should we say that zero is used if there is no known information about
> the sequence number of TargNode (and not otherwise)?
>
>     r
>        A one-bit reserved field.  This field MUST be initialized to zero
>        by the sender and MUST be ignored by the receiver.
>
> The secdir reviewer noted the mismatch between 'X' in the figure and 'r'
> here; please fix.
>
>     Prefix Length
>        7-bit unsigned integer.  Number of valid leading bits in the IPv6
>        Prefix.  If Prefix Length is 0, then the value in the Target
>        Prefix / Address field represents an IPv6 address, not a prefix.
>
>     Target Prefix / Address
>        (variable-length field) An IPv6 destination address or prefix.
>        The Prefix Length field contains the number of valid leading bits
>        in the prefix.  The length of the field is the least number of
>        octets that can contain all of the bits of the Prefix, in other
>        words Floor((7+(Prefix Length))/8) octets.  The remaining bits in
>        the Target Prefix / Address field after the prefix length (if any)
>        MUST be set to zero on transmission and MUST be ignored on
>        receipt.
>
> Please specify how long the Address field is when Prefix Length is zero
> (indicating that the last field is the Address variant).
>
> Section 5
>
>     Links are considered symmetric until additional information is
>     collected.  [...]
>
> What kinds of problems will arise if we start taking actions based on
> this assumption before the "additional information" is available?
> (That is to say, perhaps this is not a useful phrasing, since what we
> actually do is get updates about the presence of asymmetric links as we
> construct the route.)
>
>     bit set to 1, then all the one-hop links on the route from the
>     OrigNode O to this router meet the requirements of route discovery,
>
> Re "the route", this would presumably be the one recorded in the Address
> Vector of the RREQ in question?  (Multiple RREQs for the same route
> computation can arrive at a given node with different address vectors,
> right?
>
> Also, the way this is written implies that it does not say anything
> about "non-one-hop links" on the route, but I don't really know what a
> link that's not a one-hop link would be.  Can we just say "all the hops"
> or "all the links"?
>
>     and the route can be used symmetrically.
>
> But does that matter for any routers other than TargNode (for any of the
> AODV-RPL Target Options)?
>
>     doesn't satisfy the Objective Function.  Based on the S bit received
>     in RREQ-DIO, TargNode T determines whether or not the route is
>     symmetric before transmitting the RREP-DIO message upstream towards
>     the OrigNode O.
>
> Does that determination affect the construction of the RREP-DIO in any
> way?  (E.g., if there was an S bit.)
>
>              Figure 5: AODV-RPL with Asymmetric Paired Instances
>
> Some discussion of how the third(? second?) intermediate router detects
> the asymmetry and clears the S bit might be appropriate.
>
> Section 6.1
>
>     link-local multicast.  The DIO MUST contain at least one ART Option
>     (see Section 4.3).  The S bit in RREQ-DIO sent out by the OrigNode is
>     set to 1.
>
> I'd suggest saying that the required ART Option indicates the TargNode.
>
>     OrigNode can maintain different RPLInstances to discover routes with
>     different requirements to the same targets.  Using the RPLInstanceID
>     pairing mechanism (see Section 6.3.3), route replies (RREP-DIOs) for
>     different RPLInstances can be distinguished.
>
> When using different RPLInstances for this purpose, what constitutes
> "initiates a route discovery process" across those instances -- is it
> permissible to only increment the sequence number once when initiating
> multiple discovery processes on different instances?
>
> Section 6.2.1
>
>     Step 1:
>
>        If the S bit in the received RREQ-DIO is set to 1, the router MUST
>        determine whether each direction of the link (by which the RREQ-
>        DIO is received) satisfies the Objective Function.  In case that
>        the downward (i.e. towards the TargNode) direction of the link
>        does not satisfy the Objective Function, the link can't be used
>        symmetrically, thus the S bit of the RREQ-DIO to be sent out MUST
>        be set as 0.  If the S bit in the received RREQ-DIO is set to 0,
>        the router MUST determine into the upward direction (towards the
>        OrigNode) of the link.
>
>        If the upward direction of the link can satisfy the Objective
>        Function, and the router's Rank would not exceed the MaxUseRank
>        limit, the router joins the DODAG of the RREQ-Instance.  The
>        router that transmitted the received RREQ-DIO is selected as the
>        preferred parent.  Otherwise, if the Objective Function is not
>        satisfied or the MaxUseRank limit is exceeded, the router MUST
>        discard the received RREQ-DIO and MUST NOT join the DODAG.
>
> The way this is written is confusing to me.  It seems to say that (1)
> you only check the upward direction is the S bit in the received
> RREQ-DIO is set to zero, and (2) the only time you join the DODAG is if
> you're checking the upward direction.  So, when the received S-bit is 1,
> do you just never join the DODAG?  I assume this is not the intent, but
> that is how I interpret the words that are on the page.
>
>        Sequence Number.  The Destination Address and the RPLInstanceID
>        respectively can be learned from the DODAGID and the RPLInstanceID
>        of the RREQ-DIO, and the Source Address is the address used by the
>        local router to send data to the OrigNode.  The Next Hop is the
>
> "Source Address is the address used by the local router to send data to
> the OrigNode" seems like the definition of the source address in a route
> table entry, not a procedure for how to set it.  Should this be the
> address used by the local router to send data to the preferred parent?
>
> Section 6.3.1
>
>     implementation-specific and out of scope.  If the implementation
>     selects the symmetric route, and the L bit is not 0, the TargNode MAY
>     delay transmitting the RREP-DIO for duration RREP_WAIT_TIME to await
>     a symmetric route with a lower Rank.  The value of RREP_WAIT_TIME is
>     set by default to 1/4 of the time duration determined by the L bit.
>
> There is no L *bit* in the RREQ option or the RFC 6550 DIO.  There is a
> two-bit L field in the RREQ option, but even if I replace 'bit' with
> 'field', it's still not clear why having a DODAG with no lifetime limit
> implies that delaying the RREP-DIO is not allowed.
>
> Section 6.3.2
>
>     When a RREQ-DIO arrives at a TargNode with the S bit set to 0, the
>     TargNode MUST build a DODAG in the RREP-Instance rooted at itself in
>
> I don't understand how the definite article is appropriate for "the
> RREP-Instance rooted at itself" -- I thought there were multiple
> (paired) instances corresponding to the various RREQ DODAGs that
> requested routes to TargNode.
>
>     RREP_WAIT_TIME to await a route with a lower Rank.  The value of
>     RREP_WAIT_TIME is set by default to 1/4 of the time duration
>     determined by the L bit.
>
> ("L bit" again, and no indication of what to do for L==0.)
>
>     The settings of the fields in RREP option and ART option are the same
>     as for the symmetric route, except for the S bit.
>
> There is no S bit in the RREP.  What is this intending to say?
>
> Section 6.3.3
>
>     When preparing the RREP-DIO, a TargNode could find the RPLInstanceID
>     to be used for the RREP-Instance is already occupied by another RPL
>     Instance from an earlier route discovery operation which is still
>     active.  In other words, it might happen that two distinct OrigNodes
>     need routes to the same TargNode, and they happen to use the same
>     RPLInstanceID for RREQ-Instance.  In this case, the occupied
>     RPLInstanceID MUST NOT be used again.  [...]
>
> A reminder might be helpful that the RPLInstanceID is a property of a
> DODAG, and a DODAG is identified by the DODAGID, which in this case is
> the address of the TargNode.  So that is why we need to avoid reusing
> RPLInstanceID in the context of the RREP-DIO, whereas there is no
> problem with collisions in RPLInstanceID across RREQ-DIOs (where the
> DODAGID is the OrigNode address, that suffices to disambiguate).
>
>     shift to be applied to original RPLInstanceID.  When the new
>     RPLInstanceID after shifting exceeds 63, it rolls over starting at 0.
>
> I thought RPLInstanceID was a full 8-bit field (even though Shift is
> only six bits); wouldn't rollover happen after 255?
>
>     For example, the original RPLInstanceID is 60, and shifted by 6, the
>     new RPLInstanceID will be 2.  Related operations can be found in
>     Section 6.4.
>
> (So this example wouldn't actually show rollover.)
>
> Section 6.4
>
>     Upon receiving a RREP-DIO, a router which does not belong to the
>     RREQ-Instance goes through the following steps:
>
> Do we care about RREQ-Instance membership or RREP-Instance membership,
> for processing the RREP-DIO?
>
>     Step 1:
>
>        If the S bit is set to 1, the router MUST proceed to step 2.
>
> There is no S bit in the RREP option!
>
>        and the destination address is learned from the DODAGID.  The
>        lifetime is set according to DODAG configuration (i.e., not the L
>        bit) and can be extended when the route is actually used.  The
>
> ("L bit" again)
>
>     Upon receiving a RREP-DIO, a router which already belongs to the
>     RREQ-Instance SHOULD drop the RREP-DIO.
>
> (RREQ-Instance vs RREP-Instance, again.)
>
> Section 10
>
> It seems like a malicious node that forges a gratuitous RREP could do
> significant damage as well, so that might be worth mentioning.
>
>     routing loop.  The TargNode MUST NOT generate a RREP if one of its
>     addresses is present in the Address Vector.  An Intermediate Router
>     MUST NOT forward a RREP if one of its addresses is present in the
>     Address Vector.
>
> These requirements seem important enough that I'd prefer to seem them
> imposed in the main body text that covers RREP handling, and the
> security considerations mentioned here and referring to those handling
> requirements.
>
>
>