On Fri, Feb 11, 2022 at 5:41 PM Lorenzo Bianconi <[email protected]> wrote: > > > On Tue, Feb 8, 2022 at 1:27 PM Mark Michelson <[email protected]> wrote: > > > > > > Thanks Lorenzo. > > > > > > Acked-by: Mark Michelson <[email protected]> > > > > Thanks. I applied to the main branch. > > Thanks Numan. I guess this patch can be considered a bug-fix, so can you > please > backport it? Thanks.
I've backported to branch-21.12. Do let me know if it needs backporting further down. Numan > > Regards, > Lorenzo > > > > > Numan > > > > > > > > On 2/4/22 19:19, Lorenzo Bianconi wrote: > > > > Send non-periodic Router Advertisement with rdnss, dnssl and route_info > > > > options if configured by the user. > > > > > > > > Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1851788 > > > > Signed-off-by: Lorenzo Bianconi <[email protected]> > > > > --- > > > > Changes since v1: > > > > - copy input string before running strtok_r() in encode_ra_dnssl_opt() > > > > and > > > > encode_ra_route_info_opt(). > > > > - cap max len value in encode_ra_dnssl_opt(). > > > > --- > > > > controller/pinctrl.c | 35 ++-------- > > > > include/ovn/actions.h | 1 + > > > > lib/actions.c | 153 ++++++++++++++++++++++++++++++++++++++++++ > > > > lib/ovn-l7.h | 3 + > > > > northd/northd.c | 16 +++++ > > > > tests/ovn.at | 30 +++++++-- > > > > 6 files changed, 204 insertions(+), 34 deletions(-) > > > > > > > > diff --git a/controller/pinctrl.c b/controller/pinctrl.c > > > > index 293aecea2..ac6ec26e0 100644 > > > > --- a/controller/pinctrl.c > > > > +++ b/controller/pinctrl.c > > > > @@ -3712,37 +3712,14 @@ static void > > > > packet_put_ra_dnssl_opt(struct dp_packet *b, ovs_be32 lifetime, > > > > char *dnssl_data) > > > > { > > > > - char *dnssl_list, *t0, *r0 = NULL, dnssl[255] = {}; > > > > size_t prev_l4_size = dp_packet_l4_size(b); > > > > - size_t size = sizeof(struct ovs_nd_dnssl); > > > > - int i = 0; > > > > + char dnssl[255] = {}; > > > > + int size; > > > > > > > > - dnssl_list = xstrdup(dnssl_data); > > > > - > > > > - /* Multiple DNS Search List must be 'comma' separated > > > > - * (e.g. "a.b.c, d.e.f"). Domain names must be encoded > > > > - * as described in Section 3.1 of RFC1035. > > > > - * (e.g if dns list is a.b.c,www.ovn.org, it will be encoded as: > > > > - * 01 61 01 62 01 63 00 03 77 77 77 03 6f 76 63 03 6f 72 67 00 > > > > - */ > > > > - for (t0 = strtok_r(dnssl_list, ",", &r0); t0; > > > > - t0 = strtok_r(NULL, ",", &r0)) { > > > > - char *t1, *r1 = NULL; > > > > - > > > > - size += strlen(t0) + 2; > > > > - if (size > sizeof(dnssl)) { > > > > - goto out; > > > > - } > > > > - > > > > - for (t1 = strtok_r(t0, ".", &r1); t1; > > > > - t1 = strtok_r(NULL, ".", &r1)) { > > > > - dnssl[i++] = strlen(t1); > > > > - memcpy(&dnssl[i], t1, strlen(t1)); > > > > - i += strlen(t1); > > > > - } > > > > - dnssl[i++] = 0; > > > > + size = encode_ra_dnssl_opt(dnssl_data, dnssl, sizeof(dnssl)); > > > > + if (size < 0) { > > > > + return; > > > > } > > > > - size = ROUND_UP(size, 8); > > > > > > > > struct ip6_hdr *nh = dp_packet_l3(b); > > > > nh->ip6_plen = htons(prev_l4_size + size); > > > > @@ -3760,8 +3737,6 @@ packet_put_ra_dnssl_opt(struct dp_packet *b, > > > > ovs_be32 lifetime, > > > > uint32_t icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b)); > > > > ra->icmph.icmp6_cksum = csum_finish(csum_continue(icmp_csum, ra, > > > > prev_l4_size + > > > > size)); > > > > -out: > > > > - free(dnssl_list); > > > > } > > > > > > > > static void > > > > diff --git a/include/ovn/actions.h b/include/ovn/actions.h > > > > index cdef5fb03..0641b927e 100644 > > > > --- a/include/ovn/actions.h > > > > +++ b/include/ovn/actions.h > > > > @@ -807,5 +807,6 @@ void ovnacts_encode(const struct ovnact[], size_t > > > > ovnacts_len, > > > > > > > > void ovnacts_free(struct ovnact[], size_t ovnacts_len); > > > > char *ovnact_op_to_string(uint32_t); > > > > +int encode_ra_dnssl_opt(char *data, char *buf, int buf_len); > > > > > > > > #endif /* ovn/actions.h */ > > > > diff --git a/lib/actions.c b/lib/actions.c > > > > index d5d8391bb..5d3caaf2b 100644 > > > > --- a/lib/actions.c > > > > +++ b/lib/actions.c > > > > @@ -40,6 +40,7 @@ > > > > #include "simap.h" > > > > #include "uuid.h" > > > > #include "socket-util.h" > > > > +#include "lib/ovn-util.h" > > > > > > > > VLOG_DEFINE_THIS_MODULE(actions); > > > > > > > > @@ -2992,6 +2993,15 @@ parse_put_nd_ra_opts(struct action_context *ctx, > > > > const struct expr_field *dst, > > > > case ND_OPT_MTU: > > > > ok = c->format == LEX_F_DECIMAL; > > > > break; > > > > + > > > > + case ND_OPT_RDNSS: > > > > + ok = c->format == LEX_F_IPV6; > > > > + break; > > > > + > > > > + case ND_OPT_ROUTE_INFO_TYPE: > > > > + case ND_OPT_DNSSL: > > > > + ok = !!c->string; > > > > + break; > > > > } > > > > > > > > if (!ok) { > > > > @@ -3022,6 +3032,109 @@ format_PUT_ND_RA_OPTS(const struct > > > > ovnact_put_opts *po, > > > > format_put_opts("put_nd_ra_opts", po, s); > > > > } > > > > > > > > +int encode_ra_dnssl_opt(char *data, char *buf, int buf_len) > > > > +{ > > > > + size_t size = sizeof(struct ovs_nd_dnssl); > > > > + char *dnssl = xstrdup(data); > > > > + char *t0, *r0 = NULL; > > > > + int i = 0; > > > > + > > > > + /* Multiple DNS Search List must be 'comma' separated > > > > + * (e.g. "a.b.c, d.e.f"). Domain names must be encoded > > > > + * as described in Section 3.1 of RFC1035. > > > > + * (e.g if dns list is a.b.c,www.ovn.org, it will be encoded as: > > > > + * 01 61 01 62 01 63 00 03 77 77 77 03 6f 76 63 03 6f 72 67 00 > > > > + */ > > > > + for (t0 = strtok_r(dnssl, ",", &r0); t0; > > > > + t0 = strtok_r(NULL, ",", &r0)) { > > > > + char *t1, *r1 = NULL; > > > > + > > > > + size += strlen(t0) + 2; > > > > + if (size > buf_len) { > > > > + free(dnssl); > > > > + return -EINVAL; > > > > + } > > > > + > > > > + for (t1 = strtok_r(t0, ".", &r1); t1; > > > > + t1 = strtok_r(NULL, ".", &r1)) { > > > > + int len = strlen(t1); > > > > + if (len > UINT8_MAX) { > > > > + len = UINT8_MAX; > > > > + } > > > > + > > > > + buf[i++] = len; > > > > + memcpy(&buf[i], t1, len); > > > > + i += len; > > > > + } > > > > + buf[i++] = 0; > > > > + } > > > > + free(dnssl); > > > > + > > > > + return ROUND_UP(size, 8); > > > > +} > > > > + > > > > +static void > > > > +encode_ra_route_info_opt(struct ofpbuf *ofpacts, char *route_data) > > > > +{ > > > > + char *route_list = xstrdup(route_data); > > > > + char *t0, *r0 = NULL; > > > > + > > > > + for (t0 = strtok_r(route_list, ",", &r0); t0; > > > > + t0 = strtok_r(NULL, ",", &r0)) { > > > > + struct ovs_nd_route_info nd_rinfo; > > > > + char *t1, *r1 = NULL; > > > > + int index; > > > > + > > > > + for (t1 = strtok_r(t0, "-", &r1), index = 0; t1; > > > > + t1 = strtok_r(NULL, "-", &r1), index++) { > > > > + > > > > + nd_rinfo.type = ND_OPT_ROUTE_INFO_TYPE; > > > > + nd_rinfo.route_lifetime = htonl(0xffffffff); > > > > + > > > > + switch (index) { > > > > + case 0: > > > > + if (!strcmp(t1, "HIGH")) { > > > > + nd_rinfo.flags = IPV6_ND_RA_OPT_PRF_HIGH; > > > > + } else if (!strcmp(t1, "LOW")) { > > > > + nd_rinfo.flags = IPV6_ND_RA_OPT_PRF_LOW; > > > > + } else { > > > > + nd_rinfo.flags = IPV6_ND_RA_OPT_PRF_NORMAL; > > > > + } > > > > + break; > > > > + case 1: { > > > > + struct lport_addresses route; > > > > + uint8_t plen; > > > > + > > > > + if (!extract_ip_addresses(t1, &route)) { > > > > + goto out; > > > > + } > > > > + if (!route.n_ipv6_addrs) { > > > > + destroy_lport_addresses(&route); > > > > + goto out; > > > > + } > > > > + > > > > + nd_rinfo.prefix_len = route.ipv6_addrs->plen; > > > > + plen = DIV_ROUND_UP(nd_rinfo.prefix_len, 64); > > > > + nd_rinfo.len = 1 + plen; > > > > + struct ovs_nd_route_info *rinfo_opt = > > > > + ofpbuf_put_uninit(ofpacts, sizeof *rinfo_opt); > > > > + memcpy(rinfo_opt, &nd_rinfo, sizeof *rinfo_opt); > > > > + void *data = ofpbuf_put_uninit(ofpacts, plen * 8); > > > > + memcpy(data, &route.ipv6_addrs->network, plen * 8); > > > > + > > > > + destroy_lport_addresses(&route); > > > > + index = 0; > > > > + break; > > > > + } > > > > + default: > > > > + break; > > > > + } > > > > + } > > > > + } > > > > +out: > > > > + free(route_list); > > > > +} > > > > + > > > > static void > > > > encode_put_nd_ra_option(const struct ovnact_gen_option *o, > > > > struct ofpbuf *ofpacts, ptrdiff_t ra_offset) > > > > @@ -3096,6 +3209,46 @@ encode_put_nd_ra_option(const struct > > > > ovnact_gen_option *o, > > > > sizeof(ovs_be32[4])); > > > > break; > > > > } > > > > + > > > > + case ND_OPT_RDNSS: > > > > + { > > > > + struct nd_rdnss_opt *rdnss_opt = > > > > + ofpbuf_put_uninit(ofpacts, sizeof *rdnss_opt); > > > > + rdnss_opt->type = ND_OPT_RDNSS; > > > > + rdnss_opt->len = 3; > > > > + rdnss_opt->reserved = htons(0); > > > > + put_16aligned_be32(&rdnss_opt->lifetime, htonl(0xffffffff)); > > > > + void *dns = ofpbuf_put_uninit(ofpacts, sizeof(ovs_be32[4])); > > > > + memcpy(dns, &c->value.be128[7].be32, sizeof(ovs_be32[4])); > > > > + break; > > > > + } > > > > + > > > > + case ND_OPT_DNSSL: > > > > + { > > > > + char dnssl[255] = {}; > > > > + int size; > > > > + > > > > + size = encode_ra_dnssl_opt(c->string, dnssl, sizeof(dnssl)); > > > > + if (size < 0) { > > > > + break; > > > > + } > > > > + > > > > + struct ovs_nd_dnssl *nd_dnssl = > > > > + ofpbuf_put_uninit(ofpacts, sizeof *nd_dnssl); > > > > + nd_dnssl->type = ND_OPT_DNSSL; > > > > + nd_dnssl->len = size / 8; > > > > + nd_dnssl->reserved = 0; > > > > + put_16aligned_be32(&nd_dnssl->lifetime, htonl(0xffffffff)); > > > > + void *p = ofpbuf_put_uninit(ofpacts, size - sizeof *nd_dnssl); > > > > + memcpy(p, dnssl, size - sizeof *nd_dnssl); > > > > + break; > > > > + } > > > > + > > > > + case ND_OPT_ROUTE_INFO_TYPE: > > > > + { > > > > + encode_ra_route_info_opt(ofpacts, c->string); > > > > + break; > > > > + } > > > > } > > > > } > > > > > > > > diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h > > > > index 256e963d9..49ecea81f 100644 > > > > --- a/lib/ovn-l7.h > > > > +++ b/lib/ovn-l7.h > > > > @@ -409,6 +409,9 @@ nd_ra_opts_init(struct hmap *nd_ra_opts) > > > > nd_ra_opt_add(nd_ra_opts, "slla", ND_OPT_SOURCE_LINKADDR, "mac"); > > > > nd_ra_opt_add(nd_ra_opts, "prefix", ND_OPT_PREFIX_INFORMATION, > > > > "ipv6"); > > > > nd_ra_opt_add(nd_ra_opts, "mtu", ND_OPT_MTU, "uint32"); > > > > + nd_ra_opt_add(nd_ra_opts, "rdnss", ND_OPT_RDNSS, "ipv6"); > > > > + nd_ra_opt_add(nd_ra_opts, "dnssl", ND_OPT_DNSSL, "str"); > > > > + nd_ra_opt_add(nd_ra_opts, "route_info", ND_OPT_ROUTE_INFO_TYPE, > > > > "str"); > > > > } > > > > > > > > #define EMPTY_LB_VIP 1 > > > > diff --git a/northd/northd.c b/northd/northd.c > > > > index fc7a64f99..861812259 100644 > > > > --- a/northd/northd.c > > > > +++ b/northd/northd.c > > > > @@ -10855,6 +10855,22 @@ build_ND_RA_flows_for_lrouter_port( > > > > ds_put_format(actions, ", router_preference = \"%s\"", prf); > > > > } > > > > > > > > + const char *ra_rdnss = smap_get(&op->nbrp->ipv6_ra_configs, > > > > "rdnss"); > > > > + if (ra_rdnss) { > > > > + ds_put_format(actions, ", rdnss = %s", ra_rdnss); > > > > + } > > > > + > > > > + const char *ra_dnssl = smap_get(&op->nbrp->ipv6_ra_configs, > > > > "dnssl"); > > > > + if (ra_dnssl) { > > > > + ds_put_format(actions, ", dnssl = \"%s\"", ra_dnssl); > > > > + } > > > > + > > > > + const char *route_info = smap_get(&op->nbrp->ipv6_ra_configs, > > > > + "route_info"); > > > > + if (route_info) { > > > > + ds_put_format(actions, ", route_info = \"%s\"", route_info); > > > > + } > > > > + > > > > bool add_rs_response_flow = false; > > > > > > > > for (size_t i = 0; i < op->lrp_networks.n_ipv6_addrs; i++) { > > > > diff --git a/tests/ovn.at b/tests/ovn.at > > > > index 957eb7850..33685109f 100644 > > > > --- a/tests/ovn.at > > > > +++ b/tests/ovn.at > > > > @@ -11902,9 +11902,10 @@ options:rxq_pcap=${pcap_file}-rx.pcap > > > > OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep > > > > -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`]) > > > > > > > > # This shell function sends a Router Solicitation packet. > > > > -# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT > > > > +# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT > > > > RDNSS DNSSL ROUTE_INFO > > > > test_ipv6_ra() { > > > > local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 > > > > prefix_opt=$6 > > > > + local rdnss=$7 dnssl=$8 route_info=$9 > > > > local > > > > request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac} > > > > > > > > local len=24 > > > > @@ -11914,6 +11915,18 @@ test_ipv6_ra() { > > > > mtu_opt=05010000${mtu} > > > > fi > > > > > > > > + if test ${#rdnss} != 0; then > > > > + len=`expr $len + ${#rdnss} / 2` > > > > + fi > > > > + > > > > + if test ${#dnssl} != 0; then > > > > + len=`expr $len + ${#dnssl} / 2` > > > > + fi > > > > + > > > > + if test ${#route_info} != 0; then > > > > + len=`expr $len + ${#route_info} / 2` > > > > + fi > > > > + > > > > if test ${#prefix_opt} != 0; then > > > > prefix_opt=${prefix_opt}fdad1234567800000000000000000000 > > > > len=`expr $len + ${#prefix_opt} / 2` > > > > @@ -11922,7 +11935,7 @@ test_ipv6_ra() { > > > > len=$(printf "%x" $len) > > > > local lrp_mac=fa163e000001 > > > > local lrp_lla=fe80000000000000f8163efffe000001 > > > > - local > > > > reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt} > > > > + local > > > > reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${rdnss}${dnssl}${route_info}${prefix_opt} > > > > echo $reply >> $inport.expected > > > > > > > > as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request > > > > @@ -11960,6 +11973,9 @@ reset_pcap_file hv1-vif3 hv1/vif3 > > > > ovn-nbctl --wait=hv set Logical_Router_Port lrp0 > > > > ipv6_ra_configs:mtu=1500 > > > > ovn-nbctl --wait=hv set Logical_Router_Port lrp0 > > > > ipv6_ra_configs:send_periodic="false" > > > > ovn-nbctl --wait=hv set Logical_Router_Port lrp0 > > > > ipv6_ra_configs:router_preference="LOW" > > > > +ovn-nbctl --wait=hv set Logical_Router_port lrp0 > > > > ipv6_ra_configs:rdnss=1000::11 > > > > +ovn-nbctl --wait=hv set Logical_Router_port lrp0 > > > > ipv6_ra_configs:dnssl=aa.bb.cc > > > > +ovn-nbctl --wait=hv set Logical_Router_port lrp0 > > > > ipv6_ra_configs:route_info=HIGH-1001::11/48,LOW-1002::11/96 > > > > > > > > # Make sure that ovn-controller has installed the corresponding OF > > > > Flow. > > > > OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep > > > > -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`]) > > > > @@ -11970,8 +11986,11 @@ > > > > default_prefix_option_config=030440c0ffffffffffffffff00000000 > > > > src_mac=fa163e000003 > > > > src_lla=fe80000000000000f8163efffe000003 > > > > mtu=000005dc > > > > +rdnss=19030000ffffffff10000000000000000000000000000011 > > > > +dnssl=1f030000ffffffff02616102626202636300000000000000 > > > > +route_info=18023008ffffffff100100000000000018036018ffffffff10020000000000000000000000000000 > > > > > > > > -test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu > > > > $default_prefix_option_config > > > > +test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu > > > > $default_prefix_option_config $rdnss $dnssl $route_info > > > > > > > > # NXT_RESUME should be 2. > > > > OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c > > > > NXT_RESUME`]) > > > > @@ -11993,6 +12012,8 @@ reset_pcap_file hv1-vif3 hv1/vif3 > > > > # Set the address mode to dhcpv6_stateful, router_preference to HIGH > > > > ovn-nbctl --wait=hv set Logical_Router_Port lrp0 > > > > ipv6_ra_configs:address_mode=dhcpv6_stateful > > > > ovn-nbctl --wait=hv set Logical_Router_Port lrp0 > > > > ipv6_ra_configs:router_preference="HIGH" > > > > +ovn-nbctl --wait=hv remove Logical_Router_Port lrp0 ipv6_ra_configs > > > > rdnss > > > > +ovn-nbctl --wait=hv remove Logical_Router_Port lrp0 ipv6_ra_configs > > > > route_info > > > > # Make sure that ovn-controller has installed the corresponding OF > > > > Flow. > > > > OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep > > > > -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`]) > > > > > > > > @@ -12003,7 +12024,7 @@ src_mac=fa163e000004 > > > > src_lla=fe80000000000000f8163efffe000004 > > > > mtu=000005dc > > > > > > > > -test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu > > > > $default_prefix_option_config > > > > +test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu > > > > $default_prefix_option_config "" $dnssl > > > > > > > > # NXT_RESUME should be 3. > > > > OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c > > > > NXT_RESUME`]) > > > > @@ -12025,6 +12046,7 @@ reset_pcap_file hv1-vif3 hv1/vif3 > > > > # Set the address mode to dhcpv6_stateless, reset router preference > > > > to default > > > > ovn-nbctl --wait=hv set Logical_Router_Port lrp0 > > > > ipv6_ra_configs:address_mode=dhcpv6_stateless > > > > ovn-nbctl --wait=hv set Logical_Router_Port lrp0 > > > > ipv6_ra_configs:router_preference="MEDIUM" > > > > +ovn-nbctl --wait=hv remove Logical_Router_Port lrp0 ipv6_ra_configs > > > > dnssl > > > > # Make sure that ovn-controller has installed the corresponding OF > > > > Flow. > > > > OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep > > > > -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`]) > > > > > > > > > > > > > > _______________________________________________ > > > dev mailing list > > > [email protected] > > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > > > > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
