The prefix we obtain is used to fill the ``ipv6_ra_prefixes``
option for configuration of instances through SLAAC.

As discussed in RFC 7421 the interface identifier is 64 bits long,
and client implementations refrain from performing SLAAC with any
other prefix length.

TODO: I'm pretty sure the origin of this behavior is tied to an
      older RFC, attempt to track it down.

The DHCPv6 server is at liberty to offer whichever prefix length it
wants, so make sure new requests are for a prefix length of 64 so
that it is suitable.

TODO: We may need to make the default prefix-length to request
      configurable?  Setting this to 64 fixes an issue I see in my
      network where the server will delegate a /62 by default,
      which does not work well for SLAAC.

A future improvement might be to adjust the requested prefix length
to the number of downstream LRPs we have and then allocate to the
downstream LRPs from that larger delegated prefix.

TODO: We are free to request whatever prefix-length we want, and
      the server is equally free to ignore our request and give us
      something else.  So we need some generic handling of
      allocations where prefix-length < 64.  Perhaps just split
      the prefix up in /64 chunks and add them all to
      ``ipv6_ra_prefixes`` ?

TODO: tests

QUESTION: From cursory view there appears to be an issue with
          routing inside OVN after successful IPv6 Prefix
          Delegation, it may be an issue with my setup, but
          thought I might as well ask.  Is the prefix delegation
          code supposed to automatically handle internal routing?

Signed-off-by: Frode Nordahl <fnord...@ubuntu.com>
---
 controller/pinctrl.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 721a737de..8c4425a2e 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -1120,9 +1120,7 @@ compose_prefixd_packet(struct dp_packet *b, struct 
ipv6_prefixd_state *pfd)
     if (pfd->uuid.len) {
         payload += pfd->uuid.len + sizeof(struct dhcpv6_opt_header);
     }
-    if (ipv6_addr_is_set(&pfd->prefix)) {
-        payload += sizeof(struct dhcpv6_opt_ia_prefix);
-    }
+    payload += sizeof(struct dhcpv6_opt_ia_prefix);
 
     eth_compose(b, (struct eth_addr) ETH_ADDR_C(33,33,00,01,00,02), pfd->ea,
                 ETH_TYPE_IPV6, IPV6_HEADER_LEN);
@@ -1174,23 +1172,38 @@ compose_prefixd_packet(struct dp_packet *b, struct 
ipv6_prefixd_state *pfd)
     ia_pd->opt.code = htons(DHCPV6_OPT_IA_PD);
     int opt_len = sizeof(struct dhcpv6_opt_ia_na) -
                   sizeof(struct dhcpv6_opt_header);
-    if (ipv6_addr_is_set(&pfd->prefix)) {
-        opt_len += sizeof(struct dhcpv6_opt_ia_prefix);
-    }
+    opt_len += sizeof(struct dhcpv6_opt_ia_prefix);
     ia_pd->opt.len = htons(opt_len);
     ia_pd->iaid = htonl(pfd->aid);
     ia_pd->t1 = OVS_BE32_MAX;
     ia_pd->t2 = OVS_BE32_MAX;
+    struct dhcpv6_opt_ia_prefix *ia_prefix =
+        (struct dhcpv6_opt_ia_prefix *)(ia_pd + 1);
+    ia_prefix->opt.code = htons(DHCPV6_OPT_IA_PREFIX);
+    ia_prefix->opt.len = htons(sizeof(struct dhcpv6_opt_ia_prefix) -
+                               sizeof(struct dhcpv6_opt_header));
     if (ipv6_addr_is_set(&pfd->prefix)) {
-        struct dhcpv6_opt_ia_prefix *ia_prefix =
-            (struct dhcpv6_opt_ia_prefix *)(ia_pd + 1);
-        ia_prefix->opt.code = htons(DHCPV6_OPT_IA_PREFIX);
-        ia_prefix->opt.len = htons(sizeof(struct dhcpv6_opt_ia_prefix) -
-                                   sizeof(struct dhcpv6_opt_header));
         ia_prefix->plife_time = OVS_BE32_MAX;
         ia_prefix->vlife_time = OVS_BE32_MAX;
         ia_prefix->plen = pfd->plen;
         ia_prefix->ipv6 = pfd->prefix;
+    } else {
+        /* The prefix we obtain is used to fill the ``ipv6_ra_prefixes``
+         * option for configuration of instances through SLAAC.
+         *
+         * As discussed in RFC 7421 the interface identifier is 64 bits long,
+         * and client implementations refrain from performing SLAAC with any
+         * other prefix length.
+         *
+         * The DHCPv6 server is at liberty to offer whichever prefix length it
+         * wants, so make sure new requests are for a prefix length of 64 so
+         * that it is suitable.
+         *
+         * A future improvement might be to adjust the requested prefix length
+         * to the number of downstream LRPs we have and then allocate to the
+         * downstream LRPs from that larger delegated prefix. */
+        ia_prefix->ipv6 = in6addr_any;
+        ia_prefix->plen = 64;
     }
 
     uint32_t csum = packet_csum_pseudoheader6(dp_packet_l3(b));
-- 
2.43.0

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to