TODO: - Needs to update ovn-northd man page. - Code should be cleaned up. --- ovn/lib/ovn-util.c | 5 +++++ ovn/northd/ovn-northd.c | 39 ++++++++++++++++++++++++++++++--------- ovn/ovn-nb.xml | 6 ++++++ 3 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/ovn/lib/ovn-util.c b/ovn/lib/ovn-util.c index 7ad69ad..3e15c6b 100644 --- a/ovn/lib/ovn-util.c +++ b/ovn/lib/ovn-util.c @@ -175,6 +175,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.c b/ovn/northd/ovn-northd.c index e0e40d0..991018d 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -2086,12 +2086,17 @@ find_lrp_member_ip(const struct ovn_port *op, const char *ip_s) static void add_route(struct hmap *lflows, const struct ovn_port *op, const char *lrp_addr_s, const char *network_s, int plen, - const char *gateway) + const char *gateway, bool is_lla) { 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 (is_lla) { + /* xxx This is pretty hacky. */ + 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"); @@ -2114,10 +2119,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(&actions); - free(match); + ds_destroy(&match); } static void @@ -2227,7 +2232,8 @@ build_static_route_flow(struct hmap *lflows, struct ovn_datapath *od, goto free_prefix_s; } - add_route(lflows, out_port, lrp_addr_s, prefix_s, plen, route->nexthop); + add_route(lflows, out_port, lrp_addr_s, prefix_s, plen, + route->nexthop, false); free_prefix_s: free(prefix_s); @@ -2526,6 +2532,9 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, } if (op->lrp_networks.n_ipv6_addrs) { + /* xxx Fix this comment about broadcast */ + /* xxx We should only drop a specific lla for the interface, + * xxx since theoretically, it could conflict on a diff iface. */ /* L3 admission control: drop packets that originate from an * IPv6 address owned by the router or a broadcast address * known to the router (priority 100). */ @@ -2547,7 +2556,12 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, "ip6.dst <-> ip6.src; " "ip.ttl = 255; " "icmp6.type = 129; " +#if 0 + /* xxx Disable this to allow pinging the lla, + * xxx since this clears the inport, and our lla + * xxx route needs to scope it. */ "inport = \"\"; /* Allow sending out inport. */ " +#endif "next; "); ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 90, ds_cstr(&match), ds_cstr(&actions)); @@ -2733,13 +2747,20 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) { add_route(lflows, op, op->lrp_networks.ipv4_addrs[i].addr_s, op->lrp_networks.ipv4_addrs[i].network_s, - op->lrp_networks.ipv4_addrs[i].plen, NULL); + op->lrp_networks.ipv4_addrs[i].plen, NULL, false); } for (int i = 0; i < op->lrp_networks.n_ipv6_addrs; i++) { + /* Do not route link local addresses. */ + if (in6_is_lla(&op->lrp_networks.ipv6_addrs[i].addr)) { + add_route(lflows, op, op->lrp_networks.ipv6_addrs[i].addr_s, + "fe80::", 64, NULL, true); + continue; + } + add_route(lflows, op, op->lrp_networks.ipv6_addrs[i].addr_s, op->lrp_networks.ipv6_addrs[i].network_s, - op->lrp_networks.ipv6_addrs[i].plen, NULL); + op->lrp_networks.ipv6_addrs[i].plen, NULL, false); } } diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index e571eeb..22a3fdf 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -801,6 +801,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