diff options
author | Numan Siddique <nusiddiq@redhat.com> | 2018-12-17 21:49:44 +0530 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2018-12-17 16:12:14 -0800 |
commit | 250ed43465c7beeff171b6deb3e33a10d73be94a (patch) | |
tree | 58d462126d5d01ea033b6ebe5e11d19bf258bfde /ovn/northd/ovn-northd.c | |
parent | 5a77cf961e346cb949a231e282d70ebac00358c8 (diff) | |
download | openvswitch-250ed43465c7beeff171b6deb3e33a10d73be94a.tar.gz |
ovn: Fix the invalid eth.dst and ip6.dst set by nd_ns action for certain cases.
When an IPv6 packet enters a router pipeline and it needs to be routed via
the nexthop IP address set in the static route, OVN generates an IPv6
Neigh Solicitation request if the nexthop IP is not resolved yet. But
right now, the generated IPv6 Neigh Solicitation packet doesn't set
the eth.dst to the mutlicast address derived from the nexthop and
ip6.dst to the solicited-node multicast address corresponding to the
nexthop address. Instead it generates these values from the actual
ip6.dst of the original packet.
This patch fixes this issue.
Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ovn/northd/ovn-northd.c')
-rw-r--r-- | ovn/northd/ovn-northd.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index e1fbf60f3..6850d4f72 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -6624,6 +6624,42 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, continue; } + for (int i = 0; i < od->nbr->n_static_routes; i++) { + const struct nbrec_logical_router_static_route *route; + + route = od->nbr->static_routes[i]; + struct in6_addr gw_ip6; + unsigned int plen; + char *error = ipv6_parse_cidr(route->nexthop, &gw_ip6, &plen); + if (error || plen != 128) { + free(error); + continue; + } + + ds_clear(&match); + ds_put_format(&match, "eth.dst == 00:00:00:00:00:00 && " + "ip6 && xxreg0 == %s", route->nexthop); + struct in6_addr sn_addr; + struct eth_addr eth_dst; + in6_addr_solicited_node(&sn_addr, &gw_ip6); + ipv6_multicast_to_ethernet(ð_dst, &sn_addr); + + char sn_addr_s[INET6_ADDRSTRLEN + 1]; + ipv6_string_mapped(sn_addr_s, &sn_addr); + + ds_clear(&actions); + ds_put_format(&actions, + "nd_ns { " + "eth.dst = "ETH_ADDR_FMT"; " + "ip6.dst = %s; " + "nd.target = %s; " + "output; " + "};", ETH_ADDR_ARGS(eth_dst), sn_addr_s, + route->nexthop); + ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 200, + ds_cstr(&match), ds_cstr(&actions)); + } + ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100, "eth.dst == 00:00:00:00:00:00", "arp { " |