From: Anton Ivanov <anton.iva...@cambridgegreys.com> Signed-off-by: Anton Ivanov <anton.iva...@cambridgegreys.com> --- northd/ovn-northd.c | 141 ++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 64 deletions(-)
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 71d90159d..4dfb9badd 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -8658,6 +8658,16 @@ build_lrouter_flows_gateway_redirect_od( struct ovn_datapath *od, struct hmap *lflows, struct ds *match, struct ds *actions); +/* Local router ingress table ARP_REQUEST: ARP request. + * + * In the common case where the Ethernet destination has been resolved, + * this table outputs the packet (priority 0). Otherwise, it composes + * and sends an ARP/IPv6 NA request (priority 100). */ +static void +build_lrouter_flows_arp_request_od( + struct ovn_datapath *od, struct hmap *lflows, + struct ds *match, struct ds *actions); + /* * Do not remove this comment - it is here on purpose * It serves as a marker so that pulling operations out @@ -8773,71 +8783,9 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, od, lflows, &match, &actions); } - /* Local router ingress table ARP_REQUEST: ARP request. - * - * In the common case where the Ethernet destination has been resolved, - * this table outputs the packet (priority 0). Otherwise, it composes - * and sends an ARP/IPv6 NA request (priority 100). */ HMAP_FOR_EACH (od, key_node, datapaths) { - if (!od->nbr) { - 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 && " REG_NEXT_HOP_IPV6 " == %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_with_hint(lflows, od, S_ROUTER_IN_ARP_REQUEST, 200, - ds_cstr(&match), ds_cstr(&actions), - &route->header_); - } - - ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100, - "eth.dst == 00:00:00:00:00:00 && ip4", - "arp { " - "eth.dst = ff:ff:ff:ff:ff:ff; " - "arp.spa = " REG_SRC_IPV4 "; " - "arp.tpa = " REG_NEXT_HOP_IPV4 "; " - "arp.op = 1; " /* ARP request */ - "output; " - "};"); - ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100, - "eth.dst == 00:00:00:00:00:00 && ip6", - "nd_ns { " - "nd.target = " REG_NEXT_HOP_IPV6 "; " - "output; " - "};"); - ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 0, "1", "output;"); + build_lrouter_flows_arp_request_od( + od, lflows, &match, &actions); } /* Logical router egress table DELIVERY: Delivery (priority 100-110). @@ -11205,6 +11153,71 @@ build_lrouter_flows_gateway_redirect_od( } } +static void +build_lrouter_flows_arp_request_od( + struct ovn_datapath *od, struct hmap *lflows, + struct ds *match, struct ds *actions) +{ + if (od->nbr) { + + 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 && " REG_NEXT_HOP_IPV6 " == %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_with_hint(lflows, od, S_ROUTER_IN_ARP_REQUEST, 200, + ds_cstr(match), ds_cstr(actions), + &route->header_); + } + + ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100, + "eth.dst == 00:00:00:00:00:00 && ip4", + "arp { " + "eth.dst = ff:ff:ff:ff:ff:ff; " + "arp.spa = " REG_SRC_IPV4 "; " + "arp.tpa = " REG_NEXT_HOP_IPV4 "; " + "arp.op = 1; " /* ARP request */ + "output; " + "};"); + ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100, + "eth.dst == 00:00:00:00:00:00 && ip6", + "nd_ns { " + "nd.target = " REG_NEXT_HOP_IPV6 "; " + "output; " + "};"); + ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 0, "1", "output;"); + } +} + /* Updates the Logical_Flow and Multicast_Group tables in the OVN_SB database, * constructing their contents based on the OVN_NB database. */ static void -- 2.20.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev