[ovs-dev] [PATCH v2 ovn 1/2] Add support to Default Router Preference (PRF) - RFC 4191
Lorenzo Bianconi
lorenzo.bianconi at redhat.com
Thu Nov 28 12:48:35 UTC 2019
Introduce support for Default Router Preference (PRF) in IPv6 Router
Advertisement according to RFC 4191
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
---
controller/pinctrl.c | 20 +++++++++++++++++---
lib/ovn-l7.h | 4 ++++
northd/ovn-northd.c | 8 ++++++++
ovn-nb.xml | 12 ++++++++++++
tests/ovn.at | 13 +++++++++----
5 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 8fc31d38a..48a2baee7 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -2297,10 +2297,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 {
@@ -2308,6 +2308,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);
@@ -2457,10 +2464,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/lib/ovn-l7.h b/lib/ovn-l7.h
index 5fc370bf5..fd898b0dc 100644
--- a/lib/ovn-l7.h
+++ b/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/northd/ovn-northd.c b/northd/ovn-northd.c
index d58a59ffd..28628a574 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -7135,6 +7135,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-nb.xml b/ovn-nb.xml
index 4a93d2f4a..a297728bc 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -1927,6 +1927,18 @@
</ul>
</column>
+ <column name="ipv6_ra_configs" key="router_preference">
+ Default Router Preference (PRF) indicates whether to prefer this
+ router over other default routers (RFC 4191).
+ Possible values are:
+
+ <ul>
+ <li>HIGH: mapped to 0x01 in RA PRF field</li>
+ <li>MEDIUM: mapped to 0x00 in RA PRF field</li>
+ <li>LOW: mapped to 0x11 in RA PRF field</li>
+ </ul>
+ </column>
+
<column name="ipv6_ra_configs" key="mtu">
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 f54823b5d..d36a7a699 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -11470,23 +11470,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
More information about the dev
mailing list