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