On Mon, Mar 18, 2024 at 10:12 PM Frode Nordahl <fnord...@ubuntu.com> wrote: > > 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?
I apparently can't quite let go of this itch :) Responding to my own question, there does appear to be missing functionality in a few more areas to make IPv6 Prefix Delegation support complete: 1) We need to include the learned ipv6_prefix when building lr_in_ip_routing logical flows, something like this does it: diff --git a/lib/ovn-util.c b/lib/ovn-util.c index ee5cbcdc3..94ebf6488 100644 --- a/lib/ovn-util.c +++ b/lib/ovn-util.c @@ -344,6 +344,22 @@ extract_lrp_networks(const struct nbrec_logical_router_port *lrp, } } + for (int i = 0; i < lrp->n_ipv6_prefix; i++) { + struct in6_addr ip6; + unsigned int plen; + char *error; + + error = ipv6_parse_cidr(lrp->ipv6_prefix[i], &ip6, &plen); + if (!error) { + add_ipv6_netaddr(laddrs, ip6, plen); + } else { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_INFO_RL(&rl, "invalid syntax '%s' in ipv6_prefix", + lrp->networks[i]); + free(error); + } + } + --- I just piggy backed on extract_lrp_networks() here, but it might deserve its own extract_lrp_delegated_ipv6_prefix() or something like that for clarity? 2) Traffic is currently allowed to pass through port security, presumably due to ND/MAC learning, but we should probably let IPAM know about the learned prefixes so that dynamic addresses can be properly populated? 3) I need to manually add an external v6 default route, but as a user I would expect this to be learned through RA when IPv6 Prefix Delegation is enabled. Maybe we should make this automatic? > 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