summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Michelson <mmichels@redhat.com>2019-03-25 17:29:55 -0400
committerBen Pfaff <blp@ovn.org>2019-03-25 14:53:38 -0700
commit1bf58bc3a2e479c6e87640aa8e25cbf8ea57d20f (patch)
tree7ee36e019ffdb6ae3ecff2569aadf388e6256443
parentdc2d6552cd2370a342ff00ba02894a332c4f19cf (diff)
downloadopenvswitch-1bf58bc3a2e479c6e87640aa8e25cbf8ea57d20f.tar.gz
OVN: Always send prefix option in RAs
OVN's behavior when sending router advertisements has been to include IP prefix information only if the address mode is set to "slaac" or "dhcp_stateless". In these modes, sending the prefix to the client is necessary so that it may automatically provision its IP address. We do not send the prefix option when the address mode is set to "dhcp_stateful" since there is no need for the client to automatically provision an IP address. This logic is flawed, however. When using dhcp_stateful, we provide a managed IPv6 address for a client. However, because we do not provide prefix information in our RAs, the client does not know the prefix length for the address it has been allocated. With dhclient, we have seen it assume either /64 or /128, depending on which version is being used. This may not accurately reflect the prefix length being used by the DHCP server though. The fix here is to always send prefix information in our RAs, regardless of address mode. The key difference lies in how we set the A (autonomous addressing) flag. For slaac and dhcp_stateless address modes, we will set this flag, indicating the client should provision its own address based on the prefix we have sent. For dhcp_stateful, we will not set this flag. This way, it is clear the prefix is informational, and the client should not try to provision its own IPv6 address. Signed-off-by: Mark Michelson <mmichels@redhat.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
-rw-r--r--ovn/lib/actions.c12
-rw-r--r--ovn/lib/ovn-l7.h3
-rw-r--r--ovn/northd/ovn-northd.c11
-rw-r--r--tests/ovn.at8
4 files changed, 16 insertions, 18 deletions
diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c
index 56e1ab2ae..eb7e5badd 100644
--- a/ovn/lib/actions.c
+++ b/ovn/lib/actions.c
@@ -1954,12 +1954,6 @@ parse_put_nd_ra_opts(struct action_context *ctx, const struct expr_field *dst,
return;
}
- if (addr_mode_stateful && prefix_set) {
- lexer_error(ctx->lexer, "prefix option can't be"
- " set when address mode is dhcpv6_stateful.");
- return;
- }
-
if (!addr_mode_stateful && !prefix_set) {
lexer_error(ctx->lexer, "prefix option needs "
"to be set when address mode is slaac/dhcpv6_stateless.");
@@ -2020,10 +2014,14 @@ encode_put_nd_ra_option(const struct ovnact_gen_option *o,
struct ovs_nd_prefix_opt *prefix_opt =
ofpbuf_put_uninit(ofpacts, sizeof *prefix_opt);
uint8_t prefix_len = ipv6_count_cidr_bits(&c->mask.ipv6);
+ struct ovs_ra_msg *ra = ofpbuf_at(ofpacts, ra_offset, sizeof *ra);
prefix_opt->type = ND_OPT_PREFIX_INFORMATION;
prefix_opt->len = 4;
prefix_opt->prefix_len = prefix_len;
- prefix_opt->la_flags = IPV6_ND_RA_OPT_PREFIX_FLAGS;
+ prefix_opt->la_flags = IPV6_ND_RA_OPT_PREFIX_ON_LINK;
+ if (!(ra->mo_flags & IPV6_ND_RA_FLAG_MANAGED_ADDR_CONFIG)) {
+ prefix_opt->la_flags |= IPV6_ND_RA_OPT_PREFIX_AUTONOMOUS;
+ }
put_16aligned_be32(&prefix_opt->valid_lifetime,
htonl(IPV6_ND_RA_OPT_PREFIX_VALID_LIFETIME));
put_16aligned_be32(&prefix_opt->preferred_lifetime,
diff --git a/ovn/lib/ovn-l7.h b/ovn/lib/ovn-l7.h
index 08c3da54a..12d7b2267 100644
--- a/ovn/lib/ovn-l7.h
+++ b/ovn/lib/ovn-l7.h
@@ -245,7 +245,8 @@ nd_ra_opts_destroy(struct hmap *nd_ra_opts)
#define IPV6_ND_RA_REACHABLE_TIME 0
#define IPV6_ND_RA_RETRANSMIT_TIMER 0
-#define IPV6_ND_RA_OPT_PREFIX_FLAGS 0xc0
+#define IPV6_ND_RA_OPT_PREFIX_ON_LINK 0x80
+#define IPV6_ND_RA_OPT_PREFIX_AUTONOMOUS 0x40
#define IPV6_ND_RA_OPT_PREFIX_VALID_LIFETIME 0xffffffff
#define IPV6_ND_RA_OPT_PREFIX_PREFERRED_LIFETIME 0xffffffff
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 81fc32ada..03fc003d2 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -6207,13 +6207,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
continue;
}
- /* Add the prefix option if the address mode is slaac or
- * dhcpv6_stateless. */
- if (strcmp(address_mode, "dhcpv6_stateful")) {
- ds_put_format(&actions, ", prefix = %s/%u",
- op->lrp_networks.ipv6_addrs[i].network_s,
- op->lrp_networks.ipv6_addrs[i].plen);
- }
+ ds_put_format(&actions, ", prefix = %s/%u",
+ op->lrp_networks.ipv6_addrs[i].network_s,
+ op->lrp_networks.ipv6_addrs[i].plen);
+
add_rs_response_flow = true;
}
diff --git a/tests/ovn.at b/tests/ovn.at
index f7f1ab5a8..2d55e4fe1 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1262,9 +1262,11 @@ reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:0
reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
slla option not present
reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
- prefix option can't be set when address mode is dhcpv6_stateful.
+ encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
+ has prereqs ip6
reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
- prefix option can't be set when address mode is dhcpv6_stateful.
+ encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
+ has prereqs ip6
reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
@@ -8758,7 +8760,7 @@ ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dh
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"`])
addr_mode=80
-default_prefix_option_config=""
+default_prefix_option_config=03044080ffffffffffffffff00000000
src_mac=fa163e000004
src_lla=fe80000000000000f8163efffe000004
mtu=000005dc