]> git.proxmox.com Git - mirror_ovs.git/commitdiff
OVN: Always send prefix option in RAs
authorMark Michelson <mmichels@redhat.com>
Mon, 25 Mar 2019 21:29:55 +0000 (17:29 -0400)
committerBen Pfaff <blp@ovn.org>
Mon, 25 Mar 2019 21:46:12 +0000 (14:46 -0700)
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>
ovn/lib/actions.c
ovn/lib/ovn-l7.h
ovn/northd/ovn-northd.c
tests/ovn.at

index 56e1ab2ae65583c52680d9f157d38b0d095f1fe1..eb7e5badda33a3a2cdc0da4d7835702b36c01dbf 100644 (file)
@@ -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,
index fe3104e1fe0c5051af1a97bc11ebf1e95fe7c619..c24201ef0cff4c55867e8149f29a062a97c1d5f5 100644 (file)
@@ -258,7 +258,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
 
index 2843969f44346db6a8cd7a6b2e8505fe0cb6e64f..05b8aad4f008d8e1e78e90f3e76c698b5d0804a4 100644 (file)
@@ -6312,13 +6312,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;
         }
 
index f2f2bc405af350e518b8280039c1f95f84052495..069d3bb30bb21c9ed31b7cf807cf49305ee75574 100644 (file)
@@ -1260,9 +1260,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);
@@ -9376,7 +9378,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