From d7b024a24ee249c3ce6bf593499fdb6a79d78706 Mon Sep 17 00:00:00 2001 Message-Id: From: Lorenzo Bianconi Date: Thu, 28 Nov 2019 14:48:35 +0200 Subject: [PATCH 1/2] Add support to Default Router Preference (PRF) - RFC 4191 Introduce support for Default Router Preference (PRF) in IPv6 Router Advertisement according to RFC 4191 Signed-off-by: Lorenzo Bianconi Signed-off-by: Numan Siddique --- ovn/controller/pinctrl.c | 20 +++++++++++++++++--- ovn/lib/ovn-l7.h | 4 ++++ ovn/northd/ovn-northd.c | 8 ++++++++ ovn/ovn-nb.xml | 12 ++++++++++++ tests/ovn.at | 13 +++++++++---- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c index fa9c827c1..ea0551c21 100644 --- a/ovn/controller/pinctrl.c +++ b/ovn/controller/pinctrl.c @@ -2267,10 +2267,10 @@ ipv6_ra_update_config(const struct sbrec_port_binding *pb) goto fail; } if (!strcmp(address_mode, "dhcpv6_stateless")) { - config->mo_flags = IPV6_ND_RA_FLAG_OTHER_ADDR_CONFIG; + config->mo_flags |= IPV6_ND_RA_FLAG_OTHER_ADDR_CONFIG; config->la_flags |= IPV6_ND_RA_OPT_PREFIX_AUTONOMOUS; } else if (!strcmp(address_mode, "dhcpv6_stateful")) { - config->mo_flags = IPV6_ND_RA_FLAG_MANAGED_ADDR_CONFIG; + config->mo_flags |= IPV6_ND_RA_FLAG_MANAGED_ADDR_CONFIG; } else if (!strcmp(address_mode, "slaac")) { config->la_flags |= IPV6_ND_RA_OPT_PREFIX_AUTONOMOUS; } else { @@ -2278,6 +2278,13 @@ ipv6_ra_update_config(const struct sbrec_port_binding *pb) goto fail; } + const char *prf = smap_get(&pb->options, "ipv6_ra_prf"); + if (!strcmp(prf, "HIGH")) { + config->mo_flags |= IPV6_ND_RA_OPT_PRF_HIGH; + } else if (!strcmp(prf, "LOW")) { + config->mo_flags |= IPV6_ND_RA_OPT_PRF_LOW; + } + const char *prefixes = smap_get(&pb->options, "ipv6_ra_prefixes"); if (prefixes && !extract_ip_addresses(prefixes, &config->prefixes)) { VLOG_WARN("Invalid IPv6 prefixes: %s", prefixes); @@ -2427,10 +2434,17 @@ ipv6_ra_send(struct rconn *swconn, struct ipv6_ra_state *ra) uint64_t packet_stub[128 / 8]; struct dp_packet packet; + uint16_t router_lt = IPV6_ND_RA_LIFETIME; + + if (!router_lt) { + /* Reset PRF to MEDIUM if router lifetime is not set */ + ra->config->mo_flags &= ~IPV6_ND_RA_OPT_PRF_LOW; + } + dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub); compose_nd_ra(&packet, ra->config->eth_src, ra->config->eth_dst, &ra->config->ipv6_src, &ra->config->ipv6_dst, - 255, ra->config->mo_flags, htons(IPV6_ND_RA_LIFETIME), 0, 0, + 255, ra->config->mo_flags, htons(router_lt), 0, 0, ra->config->mtu); for (int i = 0; i < ra->config->prefixes.n_ipv6_addrs; i++) { diff --git a/ovn/lib/ovn-l7.h b/ovn/lib/ovn-l7.h index 5fc370bf5..fd898b0dc 100644 --- a/ovn/lib/ovn-l7.h +++ b/ovn/lib/ovn-l7.h @@ -287,6 +287,10 @@ nd_ra_opts_destroy(struct hmap *nd_ra_opts) #define IPV6_ND_RA_OPT_PREFIX_VALID_LIFETIME 0xffffffff #define IPV6_ND_RA_OPT_PREFIX_PREFERRED_LIFETIME 0xffffffff +#define IPV6_ND_RA_OPT_PRF_NORMAL 0x00 +#define IPV6_ND_RA_OPT_PRF_HIGH 0x08 +#define IPV6_ND_RA_OPT_PRF_LOW 0x18 + static inline void nd_ra_opts_init(struct hmap *nd_ra_opts) { diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 0e6f8f621..1bcf34369 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -6755,6 +6755,14 @@ copy_ra_to_sb(struct ovn_port *op, const char *address_mode) smap_add(&options, "ipv6_ra_src_eth", op->lrp_networks.ea_s); + const char *prf = smap_get(&op->nbrp->ipv6_ra_configs, + "router_preference"); + if (!prf || (strcmp(prf, "HIGH") && strcmp(prf, "LOW"))) { + smap_add(&options, "ipv6_ra_prf", "MEDIUM"); + } else { + smap_add(&options, "ipv6_ra_prf", prf); + } + sbrec_port_binding_set_options(op->sb, &options); smap_destroy(&options); } diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index 6f6e06777..16851dba1 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -1859,6 +1859,18 @@ + + Default Router Preference (PRF) indicates whether to prefer this + router over other default routers (RFC 4191). + Possible values are: + +
    +
  • HIGH: mapped to 0x01 in RA PRF field
  • +
  • MEDIUM: mapped to 0x00 in RA PRF field
  • +
  • LOW: mapped to 0x11 in RA PRF field
  • +
+
+ The recommended MTU for the link. Default is 0, which means no MTU Option will be included in RA packet replied by ovn-controller. diff --git a/tests/ovn.at b/tests/ovn.at index 33989e697..78524256f 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -11488,23 +11488,28 @@ ra_test 000005dc 00 0 0 c0 40 aef00000000000000000000000000000 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48' ra_test 000005dc 00 0 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 +# Test PRF for default gw +ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:router_preference="LOW" +ra_test 000005dc 18 0 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 + # Now test for RDNSS ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:rdnss='aef0::11' dns_addr=aef00000000000000000000000000011 -ra_test 000005dc 00 $dns_addr 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 +ra_test 000005dc 18 $dns_addr 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 # Now test for DNSSL ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:dnssl="aa.bb.cc" +ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:router_preference="HIGH" dnssl=02616102626202636300000000000000 -ra_test 000005dc 00 $dns_addr $dnssl c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 +ra_test 000005dc 08 $dns_addr $dnssl c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 ## Test a different address mode now ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful -ra_test 000005dc 80 $dns_addr $dnssl 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 +ra_test 000005dc 88 $dns_addr $dnssl 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 # And the other address mode ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless -ra_test 000005dc 40 $dns_addr $dnssl c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 +ra_test 000005dc 48 $dns_addr $dnssl c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000 OVN_CLEANUP([hv1],[hv2]) AT_CLEANUP -- 2.21.0