Every IPv6-enabled interface is supposed to have a link-local address available to it. This commit adds a link local interface to each router port and scopes link-local routes to the ingress port that received the packet.
Signed-off-by: Justin Pettit <jpet...@ovn.org> --- ovn/lib/ovn-util.c | 11 +++++++++-- ovn/northd/ovn-northd.8.xml | 5 +++++ ovn/northd/ovn-northd.c | 15 ++++++++++----- ovn/ovn-nb.xml | 6 ++++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/ovn/lib/ovn-util.c b/ovn/lib/ovn-util.c index 51e3026..f90670e 100644 --- a/ovn/lib/ovn-util.c +++ b/ovn/lib/ovn-util.c @@ -122,9 +122,11 @@ extract_lsp_addresses(char *address, struct lport_addresses *laddrs) /* Extracts the mac, IPv4 and IPv6 addresses from the * "nbrec_logical_router_port" parameter 'lrp'. Stores the IPv4 and * IPv6 addresses in the 'ipv4_addrs' and 'ipv6_addrs' fields of - * 'laddrs', respectively. + * 'laddrs', respectively. In addition, a link local IPv6 address + * based on the 'mac' member of 'lrp' is added to the 'ipv6_addrs' + * field. * - * Return true if at least 'MAC' is found in 'lrp', false otherwise. + * Return true if a valid 'mac' address is found in 'lrp', false otherwise. * * The caller must call destroy_lport_addresses(). */ bool @@ -175,6 +177,11 @@ extract_lrp_networks(const struct nbrec_logical_router_port *lrp, } } + /* Always add the IPv6 link local address. */ + struct in6_addr lla; + in6_generate_lla(laddrs->ea, &lla); + add_ipv6_netaddr(laddrs, lla, 64); + return true; } diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml index 790ca7e..bfcaeb5 100644 --- a/ovn/northd/ovn-northd.8.xml +++ b/ovn/northd/ovn-northd.8.xml @@ -1131,6 +1131,11 @@ next; Instead, if the route is from a configured static route, <var>G</var> is the next hop IP address. Else it is <code>ip6.dst</code>. </p> + + <p> + If the address <var>A</var> is in the link-local scope, the + route will be limited to sending on the ingress port. + </p> </li> <!-- ICMP errors are not yet supported. diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 4e0e072..f0f72f0 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -2778,8 +2778,13 @@ add_route(struct hmap *lflows, const struct ovn_port *op, { bool is_ipv4 = strchr(network_s, '.') ? true : false; - char *match = xasprintf("ip%s.dst == %s/%d", is_ipv4 ? "4" : "6", - network_s, plen); + struct ds match = DS_EMPTY_INITIALIZER; + if (!strcmp("fe80::", network_s) && plen == 64) { + /* Scope IPv6 link-local addresses to the local router port. */ + ds_put_format(&match, "inport == %s && ", op->json_key); + } + ds_put_format(&match, "ip%s.dst == %s/%d", is_ipv4 ? "4" : "6", + network_s, plen); struct ds actions = DS_EMPTY_INITIALIZER; ds_put_format(&actions, "ip.ttl--; %sreg0 = ", is_ipv4 ? "" : "xx"); @@ -2802,10 +2807,10 @@ add_route(struct hmap *lflows, const struct ovn_port *op, /* The priority here is calculated to implement longest-prefix-match * routing. */ - ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_ROUTING, plen, match, - ds_cstr(&actions)); + ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_ROUTING, plen, + ds_cstr(&match), ds_cstr(&actions)); + ds_destroy(&match); ds_destroy(&actions); - free(match); } static void diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index 85aa2d3..4ce295a 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -885,6 +885,12 @@ address is 192.168.0.1 and that packets destined to 192.168.0.<var>x</var> should be routed to this port. </p> + + <p> + A logical router port always adds a link-local IPv6 address + (fe80::/64) automatically generated from the interface's MAC + address using the modified EUI-64 format. + </p> </column> <column name="mac"> -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev