Subject: [Softwires] ietf-softwire: IPv4 + PSID primary key for lw4over6 binding

From: Andy Wingo <[email-masked]>
Date: Tue, 12 Jul 2016 12:31:51 +0200

Hello list,

I have a change request for the draft-sun-softwire-yang-05 Internet
Draft that defines a standard YANG model for lightweight 4-over-6
binding tables.

This is my first post here, so allow me to introduce myself.  Together
with some colleagues at Igalia we have made an open source
implementation of the AFTR component of a lightweight 4-over-6
deployment based on the Snabb toolkit for building software switches and
other network functions.  This lwAFTR implementation is gradually
wending its way upstream to https://github.com/snabbco/snabb.

To take a packet and look up a softwire in the binding table, the AFTR
only has to look at one thing: the combination of the IPv4 address and
port.  In the encapsulation direction you get this directly from the L3
header.  In the decapsulation direction you get it from the encapsulated
payload.  When decapsulating you also have to check that the B4 and BR
addresses match the entries in the table, but you don't have to maintain
a separate table that maps IPv6 B4 address to softwire: you just have
the one IPv4+PSID-to-softwire table, along with a little side table that
can map IPv4+port to PSID.

OK, cool.  Just one table, great.  However, draft-sun-softwire-yang-05
specifies a different hierarchy:

  module: ietf-softwire
     +--rw softwire-config
        +--...
        +--rw binding {binding}?
           +--rw br {br}?
              +--rw enable?                          boolean
              +--rw br-instances
                 +--rw br-instance* [id]
                    +--rw binding-table-versioning
                    |  +--rw binding-table-version?  uint64
                    |  +--rw binding-table-date?     yang:date-and-time
                    +--rw id                         uint32
                    +--rw name?                      string
                    +--rw softwire-num-threshold     uint32
                    +--rw tunnel-payload-mtu         uint16
                    +--rw tunnel-path-mru            uint16
                    +--rw binding-table
                       +--rw binding-entry* [binding-ipv6info]
                          +--rw binding-ipv6info     union
                          +--rw binding-ipv4-addr    inet:ipv4-address
                          +--rw port-set
                          |  +--rw psid-offset       uint8
                          |  +--rw psid-len          uint8
                          |  +--rw psid              uint16
                          +--rw br-ipv6-addr         inet:ipv6-address
                          +--rw lifetime?            uint32

This is figure 2 from section 5.2 (Lightweight 4over6 Tree Diagrams).
This YANG schema would make it necessary to map from B4 address to
softwire in some cases, which would be inefficient and not necessary
from a data-plane point of view.

Additionally, this mapping prevents one B4 from having multiple
softwires.  It seems to me that one CPE could very well have multiple
slices of IPv4 addresses.

Lightweight 4-over-6 maps a part of the IPv4 space to a set of B4s in
such a way that one IPv4+port pair will map to one B4, but the reverse
of that is not necessarily true: one B4 may map to many IPv4+port
pairs.  The natural way (to my mind) to implement a lwAFTR is to key
your table by IPv4+PSID or IPv4+port, and I think that's probably the
most natural way to manage it too -- IPv4 is after all the scarce
resource.  Allowing one CPE to have multiple softwires can allow an
operator to dynamically add capacity for a customer, on-demand.

For all these reasons IMHO the binding-table subtree should look like:

           +--rw binding-table
              +--rw binding-ipv4* [ipv4-addr]
                 +--rw ipv4-addr            inet:ipv4-address
                 +--rw psid-offset          uint8
                 +--rw psid-len             uint8
                 +--rw binding-entry* [psid]
                    +--rw psid              uint16
                    +--rw binding-ipv6info  union
                    +--rw br-ipv6-addr      inet:ipv6-address
                    +--rw lifetime?         uint32

OK, I drew it how I like it ;) This is an additional restriction where
each IPv4 address corresponds in a one-to-one way with the "offset" and
"len" PSID parameters.  If this restriction is feasible, it is certainly
a simplification from the implementation point of view.  Otherwise if
you allow each entry to have its own offset and len parameters, when you
add a binding table entry it is difficult to validate that no other
entry overlaps with that new PSID without doing a binding-table lookup
for each port covered by that PSID.

Thoughts are very welcome :)

Regards,

Andy

---

From: Linhui Sun <[email-masked]>
Date: Tue, 12 Jul 2016 19:40:18 +0800

Hi Andy,

Thanks for your comments, please see my comments inline with [LH].

Best,
Linhui

> from a data-plane point of view.
[LH]: The YANG model just defines a manner to configure and maintain the
binding table. It does not restrict how you actually perform in the data
plane. The point here is that we use the IPv6 info of lwB4 as the list key
of the binding. IMHO, if there does not exist a situation that an IPv6 info
accounts for more than one binding entry, that would be OK.

> slices of IPv4 addresses.
[LH]: It seems that you think this would be the situation that an IPv6 info
of lwB4 is corresponding to two or more binding entries. I don't know why
we need multiple IPv4 addresses for a single lwB4, but IMHO, if you do that
you can also allocate multiple IPv6 addresses to the lwB4. By doing this,
we can still have the guarantee that one IPv6 info is only mapping to an
individual binding entry.

> _______________________________________________
> Softwires mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/softwires
>

---

From: <[email-masked]>
Date: Tue, 12 Jul 2016 11:46:16 +0000

Dear Andy,

Please see inline.

Cheers,
Med

> -----Message d'origine-----
> De : Softwires [mailto:[email-masked]] De la part de Andy
> Wingo
> Envoyé : mardi 12 juillet 2016 12:32
> À : [email-masked]
> Objet : [Softwires] ietf-softwire: IPv4 + PSID primary key for lw4over6
> binding
> 
> Hello list,
> 

[Med] Actually, the data model allows to map a B4 to one or multiple softwires. 

The rationale for using binding-ipv6info as an index is to ease enforcing per-subscriber policies (e.g., limit the number of softwires per B4).

> softwires.

[Med] The data model in -05 allows for multiple softwires per B4 (distinct IPv6 addresses). This can even be controlled using softwire-num-threshold     

This design is relaxing the following restriction from RFC7596:

   Although it would be possible to extend lw4o6 to have more than one
   active lw4o6 tunnel configured simultaneously, this document is only
   concerned with the use of a single tunnel.

  It seems to me that one CPE could very well have multiple
> slices of IPv4 addresses.

[Med] That's possible with the current data model: distinct binding entries that belong to the same B4 may have distinct IPv4 addresses. Whether the same or distinct IPv4 addresses are bound to the same B4 is deployment-specific. IMHO, this should be considered with caution as it may lead to some applications failures e.g., RTP using IPv4@1 while companion RTCP flows are bound to another IPv4@2.

> operator to dynamically add capacity for a customer, on-demand.

[Med] As mentioned above, this doable with the current model. Policies are per-subscriber, not based on the IPv4+port set.

---

From: Andy Wingo <[email-masked]>
Date: Tue, 12 Jul 2016 14:28:30 +0200

Hi Lunhui,

Thank you for your feedback.  I am still developing my YANG instincts
currently.

On Tue 12 Jul 2016 13:40, Linhui Sun <[email-masked]> writes:

> [LH]: It seems that you think this would be the situation that an IPv6
> info of lwB4 is corresponding to two or more binding entries. I don't
> know why we need multiple IPv4 addresses for a single lwB4, but IMHO, if
> you do that you can also allocate multiple IPv6 addresses to the lwB4.
> By doing this, we can still have the guarantee that one IPv6 info is
> only mapping to an individual binding entry.

I believe that the use case goes more like this: you have a subscriber
who is allocated a small port set, and this is causing them probems;
they call to complain.  You could move them to an IPv4 address with more
ports per customer (and cause them to renew their lease, etc), or you
could just give them an additional potentially port-restricted
softwire.  This second case would make it useful to associate one B4
with multiple softwires.

I am not an operator however so I don't know how important this would
be.  Perhaps simply causing them to renew their lease is sufficient.

Andy

---

From: Andy Wingo <[email-masked]>
Date: Tue, 12 Jul 2016 14:48:49 +0200

Hi Mohamed,

Thank you for your response.

On Tue 12 Jul 2016 13:46, <[email-masked]> writes:

> The rationale for using binding-ipv6info as an index is to ease
> enforcing per-subscriber policies (e.g., limit the number of softwires
> per B4).

I am new to YANG; apologies in advance for making all of the beginner
mistakes.  My understanding of the specification

              list binding-entry {
                key "binding-ipv6info";
                description "binding entry";
                uses binding-entry;
              }

was that "binding-ipv6info" uniquely identifies the B4 (because it's a
key within the binding-entry list).  Is that not the case?  If it is the
case, how is it possible for one B4 to have multiple softwires?

>> It seems to me that one CPE could very well have multiple slices of
>> IPv4 addresses.
>
> [Med] That's possible with the current data model: distinct binding
> entries that belong to the same B4 may have distinct IPv4
> addresses. Whether the same or distinct IPv4 addresses are bound to the
> same B4 is deployment-specific. IMHO, this should be considered with
> caution as it may lead to some applications failures e.g., RTP using
> IPv4@1 while companion RTCP flows are bound to another IPv4@2.

Indeed.  Happily for me though this complexity is on the B4 side of
things ;-)  By the time it gets to the AFTR I don't have any sort of
policy decisions to make there.  It is a very pleasant standard in that
regard :)

Regards,

Andy

---

From: Ian Farrer <[email-masked]>
Date: Tue, 12 Jul 2016 15:00:05 +0200

Hi Andy,

Please see inline.

Cheers,
Ian

> On 12 Jul 2016, at 14:48, Andy Wingo <[email-masked]> wrote:
> 
> Hi Mohamed,
> 

[if - It depends what defines multiple softwires here. The B4 can have multiple softwires if the source v6 and the v4/PSID tuple are unique. The routing choice for the B4 of which softwire to use for which traffic is local to the implementation and not specified.

From the lwAFTR’s perspective, they are two separate binding table entries. The fact that they are going to the same B4 is invisible.]

---

From: <[email-masked]>
Date: Tue, 12 Jul 2016 13:07:43 +0000

Re-,

Please see inline.

Cheers,
Med

> De : Andy Wingo [mailto:[email-masked]]
> Envoyé : mardi 12 juillet 2016 14:49
> À : BOUCADAIR Mohamed IMT/OLN
> Cc : [email-masked]
> Objet : Re: [Softwires] ietf-softwire: IPv4 + PSID primary key for
> lw4over6 binding
> 
> Hi Mohamed,
> 
> key within the binding-entry list).  Is that not the case?

[Med] "binding-ipv6info" uniquely identifies an entry, ** not ** a B4. The B4 is identified by applying, for example, a subscriber-mask (https://tools.ietf.org/html/rfc7785#section-3). That is, a filter on all "binding-ipv6info" that belong, e.g., to the same /56. 

  If it is the
> policy decisions to make there.  It is a very pleasant standard in that

[Med] Glad to hear that it is pleasant.

---

From: Andy Wingo <[email-masked]>
Date: Tue, 12 Jul 2016 15:24:46 +0200

Hi Ian,

Thanks for being so patient with a newcomer.  A doubt inline:

On Tue 12 Jul 2016 15:00, Ian Farrer <[email-masked]> writes:

> [if - It depends what defines multiple softwires here. The B4 can have
> multiple softwires if the source v6 and the v4/PSID tuple are
> unique. The routing choice for the B4 of which softwire to use for which
> traffic is local to the implementation and not specified.
>
> From the lwAFTR’s perspective, they are two separate binding table
> entries. The fact that they are going to the same B4 is invisible.]

I'm definitely on-board with the possibility of there being more than
one softwire per B4.  At least from the perspective of the AFTR that is
entirely compatible with RFC 7596.

However it still seems to me that the YANG module prohibits this from
being the case.  The only key in the "binding-entry" list is the
binding-ipv6info, which of course is just an IPv6 address or a prefix
identifying the B4.  Because the key must be unique within the list,
unless you have multiple distinct binding-ipv6info values for a B4 you
can't have multiple softwires per B4.

But, I could be reading the draft YANG module and/or RFC 6020 entirely
wrong.  I look forward to being less ignorant :)

Andy

---

From: Andy Wingo <[email-masked]>
Date: Wed, 13 Jul 2016 16:49:25 +0200

Hi Monhamed,

On Tue 12 Jul 2016 15:07, <[email-masked]> writes:

> [Med] "binding-ipv6info" uniquely identifies an entry, ** not ** a
> B4. The B4 is identified by applying, for example, a subscriber-mask
> (https://tools.ietf.org/html/rfc7785#section-3). That is, a filter on
> all "binding-ipv6info" that belong, e.g., to the same /56.

I see, thank you.  If I understand you correctly, you are saying that to
have multiple softwires that a B4 should terminate those softwires with
distinct IPv6 addresses.  From the AFTR perspective this restriction is
not neccessary but if you find it useful, sure.

Andy

---

From: Andy Wingo <[email-masked]>
Date: Wed, 13 Jul 2016 17:17:51 +0200

Hello list,

I reply to my own message since I have been spending time specifying an
implementation of this module recently on the AFTR side and I just can't
shake the thought that the YANG module organization is wrong.

_From the AFTR perspective_, identifying binding table entries by the B4
IPv6 address is the wrong thing.  It is not sufficient, it is not
necessary, and it is not appropriate.

Not sufficient: in the data plane, when encapsulating, you don't know
the B4 IPv6 address.  You identify the softwire by the IPv4+port.  You
can use this same strategy to identify the softwire in the decapsulation
direction.

Not necessary: Because you can identify the softwire by IPv4+PSID, and
because the binding table can be quite big (millions of entries), if you
can avoid duplicating this table just to allow binding table entries to
be looked up by IPv6, that would be good.  ietf-softwire seems to
require this reverse mapping; when a configuration agent gets a request
to set

   /softwire-config/binding/br/br-instances/0/binding-table/127:10:20:30:40:50:60:128/port-set/psid

to 1, you would need a table keyed by IPv6 address.

Not appropriate: consider, say we get this "set the PSID of the softwire
127:10:20:30:40:50:60:128 to 1" request, and we actually do manage to
locate the binding entry for this softwire.  To validate that the change
is consistent, we only need to do one thing: check that this
IPv4/PSID/psid-offset/psid-length doesn't overlap with any other
softwire.  We don't need to validate anything about the IPv6 address of
the softwire.  This again hints that it's the IPv4+PSID that should be
the key, and probably that within each IPv4 address, all softwires have
the same psid-offset/psid-length.  The natural way to identify and
manage softwires from an AFTR perspective is by IPv4 and PSID.

If the YANG module remains how it is, that's fine -- it just means that
we're going to have to serialize all changes through one part of the
configuration agent so that we can keep our IPv6->softwire mapping in
precise sync with the IPv4,port->softwire map used by the data plane.

Andy