From patchwork Fri Aug 18 08:58:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1822763 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RRwmd5TJ5z1ygH for ; Fri, 18 Aug 2023 18:59:45 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 986C283F7C; Fri, 18 Aug 2023 08:59:43 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 986C283F7C X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YnsM0bGyUNAz; Fri, 18 Aug 2023 08:59:40 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 9DD9583F4C; Fri, 18 Aug 2023 08:59:32 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 9DD9583F4C Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5BC55C0039; Fri, 18 Aug 2023 08:59:32 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 24636C0039 for ; Fri, 18 Aug 2023 08:59:30 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id DC2F4615D5 for ; Fri, 18 Aug 2023 08:58:36 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org DC2F4615D5 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mApD5QHBIYdO for ; Fri, 18 Aug 2023 08:58:35 +0000 (UTC) Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by smtp3.osuosl.org (Postfix) with ESMTPS id EA575615D9 for ; Fri, 18 Aug 2023 08:58:34 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org EA575615D9 Received: by mail.gandi.net (Postfix) with ESMTPSA id E424D1BF206; Fri, 18 Aug 2023 08:58:31 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Fri, 18 Aug 2023 14:28:27 +0530 Message-Id: <20230818085827.1031095-1-numans@ovn.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230818085606.1030792-1-numans@ovn.org> References: <20230818085606.1030792-1-numans@ovn.org> MIME-Version: 1.0 X-GND-Sasl: numans@ovn.org Subject: [ovs-dev] [PATCH ovn v6 12/16] Reference lb related lflows for lports in a separate objdep mgr type. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Numan Siddique This will help in handling the lflows for logical switch ports or router ports incrementally. Upcoming patch will make use of this separtion. Signed-off-by: Numan Siddique --- northd/northd.c | 333 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 221 insertions(+), 112 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 8c0b732653..2ec768ab71 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -9567,7 +9567,8 @@ build_lswitch_rport_arp_req_flow(const char *ips, int addr_family, struct ovn_port *patch_op, struct ovn_datapath *od, uint32_t priority, struct lflow_data *lflows, const struct ovsdb_idl_row *stage_hint, - struct objdep_mgr *lflow_dep_mgr) + struct objdep_mgr *lflow_dep_mgr, + enum objdep_type objdep_type) { struct ds match = DS_EMPTY_INITIALIZER; struct ds actions = DS_EMPTY_INITIALIZER; @@ -9581,16 +9582,16 @@ build_lswitch_rport_arp_req_flow(const char *ips, ds_put_format(&actions, "clone {outport = %s; output; }; " "outport = \""MC_FLOOD_L2"\"; output;", patch_op->json_key); - ovn_lflow_add_with_lport_lflow_ref(lflows, od, S_SWITCH_IN_L2_LKUP, - priority, ds_cstr(&match), - ds_cstr(&actions), NULL, NULL, stage_hint, - lflow_dep_mgr, patch_op->key, patch_op->od); + ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_L2_LKUP, priority, + ds_cstr(&match), ds_cstr(&actions), stage_hint, + lflow_dep_mgr, objdep_type, patch_op->key, + patch_op->od); } else { ds_put_format(&actions, "outport = %s; output;", patch_op->json_key); - ovn_lflow_add_with_lport_lflow_ref(lflows, od, S_SWITCH_IN_L2_LKUP, - priority, ds_cstr(&match), ds_cstr(&actions), - NULL, NULL, stage_hint, lflow_dep_mgr, - patch_op->key, patch_op->od); + ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_L2_LKUP, priority, + ds_cstr(&match), ds_cstr(&actions), stage_hint, + lflow_dep_mgr, objdep_type, patch_op->key, + patch_op->od); } ds_destroy(&match); @@ -9620,39 +9621,6 @@ build_lswitch_rport_arp_req_flows(struct ovn_port *op, return; } - /* Forward ARP requests for owned IP addresses (L3, VIP, NAT) only to this - * router port. - * Priority: 80. - */ - - const char *ip_addr; - SSET_FOR_EACH (ip_addr, &op->od->lb_ips->ips_v4_reachable) { - ovs_be32 ipv4_addr; - - /* Check if the ovn port has a network configured on which we could - * expect ARP requests for the LB VIP. - */ - if (ip_parse(ip_addr, &ipv4_addr) && - lrouter_port_ipv4_reachable(op, ipv4_addr)) { - build_lswitch_rport_arp_req_flow( - ip_addr, AF_INET, sw_op, sw_od, 80, lflows, - stage_hint, lflow_dep_mgr); - } - } - SSET_FOR_EACH (ip_addr, &op->od->lb_ips->ips_v6_reachable) { - struct in6_addr ipv6_addr; - - /* Check if the ovn port has a network configured on which we could - * expect NS requests for the LB VIP. - */ - if (ipv6_parse(ip_addr, &ipv6_addr) && - lrouter_port_ipv6_reachable(op, &ipv6_addr)) { - build_lswitch_rport_arp_req_flow( - ip_addr, AF_INET6, sw_op, sw_od, 80, lflows, - stage_hint, lflow_dep_mgr); - } - } - for (size_t i = 0; i < op->od->nbr->n_nat; i++) { struct ovn_nat *nat_entry = &op->od->nat_entries[i]; const struct nbrec_nat *nat = nat_entry->nb; @@ -9672,13 +9640,13 @@ build_lswitch_rport_arp_req_flows(struct ovn_port *op, if (!sset_contains(&op->od->lb_ips->ips_v6, nat->external_ip)) { build_lswitch_rport_arp_req_flow( nat->external_ip, AF_INET6, sw_op, sw_od, 80, lflows, - stage_hint, lflow_dep_mgr); + stage_hint, lflow_dep_mgr, OBJDEP_TYPE_LPORT); } } else { if (!sset_contains(&op->od->lb_ips->ips_v4, nat->external_ip)) { build_lswitch_rport_arp_req_flow( nat->external_ip, AF_INET, sw_op, sw_od, 80, lflows, - stage_hint, lflow_dep_mgr); + stage_hint, lflow_dep_mgr, OBJDEP_TYPE_LPORT); } } } @@ -9686,12 +9654,12 @@ build_lswitch_rport_arp_req_flows(struct ovn_port *op, for (size_t i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) { build_lswitch_rport_arp_req_flow( op->lrp_networks.ipv4_addrs[i].addr_s, AF_INET, sw_op, sw_od, 80, - lflows, stage_hint, lflow_dep_mgr); + lflows, stage_hint, lflow_dep_mgr, OBJDEP_TYPE_LPORT); } for (size_t i = 0; i < op->lrp_networks.n_ipv6_addrs; i++) { build_lswitch_rport_arp_req_flow( op->lrp_networks.ipv6_addrs[i].addr_s, AF_INET6, sw_op, sw_od, 80, - lflows, stage_hint, lflow_dep_mgr); + lflows, stage_hint, lflow_dep_mgr, OBJDEP_TYPE_LPORT); } /* Self originated ARP requests/RARP/ND need to be flooded as usual. @@ -10970,6 +10938,52 @@ build_lswitch_ip_unicast_lookup(struct ovn_port *op, } } +static void +build_lswitch_ip_unicast_lookup_lb_vips(struct ovn_port *op, + struct lflow_data *lflows, + struct objdep_mgr *lflow_dep_mgr) +{ + ovs_assert(op->nbsp); + + /* For ports connected to logical routers add flows to bypass the + * broadcast flooding of ARP/ND requests in table 19. We direct the + * requests only to the router port that owns the IP address. + */ + if (!lsp_is_router(op->nbsp) || !op->peer) { + return; + } + + struct ovn_port *peer = op->peer; + const char *ip_addr; + + SSET_FOR_EACH (ip_addr, &peer->od->lb_ips->ips_v4_reachable) { + ovs_be32 ipv4_addr; + + /* Check if the ovn port has a network configured on which we could + * expect ARP requests for the LB VIP. + */ + if (ip_parse(ip_addr, &ipv4_addr) && + lrouter_port_ipv4_reachable(peer, ipv4_addr)) { + build_lswitch_rport_arp_req_flow( + ip_addr, AF_INET, op, op->od, 80, lflows, + &op->nbsp->header_, lflow_dep_mgr, OBJDEP_TYPE_LB); + } + } + SSET_FOR_EACH (ip_addr, &peer->od->lb_ips->ips_v6_reachable) { + struct in6_addr ipv6_addr; + + /* Check if the ovn port has a network configured on which we could + * expect NS requests for the LB VIP. + */ + if (ipv6_parse(ip_addr, &ipv6_addr) && + lrouter_port_ipv6_reachable(peer, &ipv6_addr)) { + build_lswitch_rport_arp_req_flow( + ip_addr, AF_INET6, op, op->od, 80, lflows, + &op->nbsp->header_, lflow_dep_mgr, OBJDEP_TYPE_LB); + } + } +} + struct bfd_entry { struct hmap_node hmap_node; @@ -13154,7 +13168,8 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op, static void build_lrouter_drop_own_dest(struct ovn_port *op, enum ovn_stage stage, uint16_t priority, bool drop_snat_ip, - struct lflow_data *lflows) + struct lflow_data *lflows, + enum objdep_type objdep_type) { struct ds match_ips = DS_EMPTY_INITIALIZER; @@ -13182,7 +13197,7 @@ build_lrouter_drop_own_dest(struct ovn_port *op, enum ovn_stage stage, match, debug_drop_action(), &op->nbrp->header_, &op->lflow_dep_mgr, - OBJDEP_TYPE_LPORT, + objdep_type, op->nbrp->name, op->od); free(match); @@ -13215,7 +13230,7 @@ build_lrouter_drop_own_dest(struct ovn_port *op, enum ovn_stage stage, match, debug_drop_action(), &op->nbrp->header_, &op->lflow_dep_mgr, - OBJDEP_TYPE_LPORT, + objdep_type, op->nbrp->name, op->od); free(match); @@ -13272,7 +13287,7 @@ build_lrouter_force_snat_flows_op(struct ovn_port *op, op->json_key, op->lrp_networks.ipv4_addrs[0].addr_s); ovn_lflow_add(lflows, op->od, S_ROUTER_IN_UNSNAT, 110, ds_cstr(match), "ct_snat;", - &op->lflow_dep_mgr, OBJDEP_TYPE_LPORT, + &op->lflow_dep_mgr, OBJDEP_TYPE_CT_LB, op->nbrp->name, op->od); ds_clear(match); @@ -13286,7 +13301,7 @@ build_lrouter_force_snat_flows_op(struct ovn_port *op, op->lrp_networks.ipv4_addrs[0].addr_s); ovn_lflow_add(lflows, op->od, S_ROUTER_OUT_SNAT, 110, ds_cstr(match), ds_cstr(actions), - &op->lflow_dep_mgr, OBJDEP_TYPE_LPORT, + &op->lflow_dep_mgr, OBJDEP_TYPE_CT_LB, op->nbrp->name, op->od); if (op->lrp_networks.n_ipv4_addrs > 1) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -13308,7 +13323,7 @@ build_lrouter_force_snat_flows_op(struct ovn_port *op, op->json_key, op->lrp_networks.ipv6_addrs[0].addr_s); ovn_lflow_add(lflows, op->od, S_ROUTER_IN_UNSNAT, 110, ds_cstr(match), "ct_snat;", - &op->lflow_dep_mgr, OBJDEP_TYPE_LPORT, + &op->lflow_dep_mgr, OBJDEP_TYPE_CT_LB, op->nbrp->name, op->od); ds_clear(match); @@ -13322,7 +13337,7 @@ build_lrouter_force_snat_flows_op(struct ovn_port *op, op->lrp_networks.ipv6_addrs[0].addr_s); ovn_lflow_add(lflows, op->od, S_ROUTER_OUT_SNAT, 110, ds_cstr(match), ds_cstr(actions), - &op->lflow_dep_mgr, OBJDEP_TYPE_LPORT, + &op->lflow_dep_mgr, OBJDEP_TYPE_CT_LB, op->nbrp->name, op->od); if (op->lrp_networks.n_ipv6_addrs > 2) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -14002,7 +14017,7 @@ build_ip_routing_flows_for_router_type_lsp(struct ovn_port *op, laddrs->ipv4_addrs[k].plen, NULL, false, 0, &peer->nbrp->header_, false, ROUTE_PRIO_OFFSET_CONNECTED, - &op->lflow_dep_mgr, OBJDEP_TYPE_LPORT, + &op->lflow_dep_mgr, OBJDEP_TYPE_CT_LB, op->nbsp->name, op->od); } } @@ -14284,7 +14299,7 @@ routable_addresses_to_lflows(struct lflow_data *lflows, ds_put_format(actions, "eth.dst = %s; next;", ra->laddrs[i].ea_s); ovn_lflow_add(lflows, peer->od, S_ROUTER_IN_ARP_RESOLVE, 100, ds_cstr(match), ds_cstr(actions), lflow_dep_mgr, - OBJDEP_TYPE_LPORT, res_name, res_od); + OBJDEP_TYPE_CT_LB, res_name, res_od); } } @@ -14393,7 +14408,7 @@ build_arp_resolve_flows_for_lrp( * Priority 2. */ build_lrouter_drop_own_dest(op, S_ROUTER_IN_ARP_RESOLVE, 2, true, - lflows); + lflows, OBJDEP_TYPE_LPORT); } /* This function adds ARP resolve flows related to a LSP. */ @@ -14550,15 +14565,63 @@ build_arp_resolve_flows_for_lsp( lflow_dep_mgr, OBJDEP_TYPE_LPORT, op->key, op->od); } + } + } +} - if (smap_get(&peer->od->nbr->options, "chassis") +static void +build_arp_resolve_flows_for_routable_addrs_throug_lsp( + struct ovn_port *op, struct lflow_data *lflows, + const struct hmap *lr_ports, + struct ds *match, struct ds *actions, + struct objdep_mgr *lflow_dep_mgr) +{ + ovs_assert(op->nbsp); + if (!lsp_is_enabled(op->nbsp)) { + return; + } + + if (!lsp_is_router(op->nbsp)) { + return; + } + + /* This is a logical switch port that connects to a router. */ + + /* The peer of this switch port is the router port for which + * we need to add logical flows such that it can resolve + * ARP entries for all the other router ports connected to + * the switch in question. */ + struct ovn_port *peer = ovn_port_get_peer(lr_ports, op); + if (!peer || !peer->nbrp) { + return; + } + + if (peer->od->nbr && + smap_get_bool(&peer->od->nbr->options, + "dynamic_neigh_routers", false)) { + return; + } + + for (size_t i = 0; i < op->od->n_router_ports; i++) { + struct ovn_port *router_port = + ovn_port_get_peer(lr_ports, op->od->router_ports[i]); + if (!router_port || !router_port->nbrp) { + continue; + } + + /* Skip the router port under consideration. */ + if (router_port == peer) { + continue; + } + + if (smap_get(&peer->od->nbr->options, "chassis") || peer->cr_port) { - routable_addresses_to_lflows(lflows, router_port, peer, - match, actions, - lflow_dep_mgr, op->key, op->od); - } + routable_addresses_to_lflows(lflows, router_port, peer, + match, actions, + lflow_dep_mgr, op->key, op->od); } } + } static void @@ -15437,43 +15500,6 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op, op->nbrp->name, op->od); } - if (sset_count(&op->od->lb_ips->ips_v4_reachable)) { - ds_clear(match); - if (is_l3dgw_port(op)) { - ds_put_format(match, "is_chassis_resident(%s)", - op->cr_port->json_key); - } - - /* Create a single ARP rule for all IPs that are used as VIPs. */ - char *lb_ips_v4_as = lr_lb_address_set_ref(op->od->tunnel_key, - AF_INET); - build_lrouter_arp_flow(op->od, op, lb_ips_v4_as, - REG_INPORT_ETH_ADDR, - match, false, 90, NULL, lflows, - &op->lflow_dep_mgr, OBJDEP_TYPE_LPORT, - op->nbrp->name, op->od); - free(lb_ips_v4_as); - } - - if (sset_count(&op->od->lb_ips->ips_v6_reachable)) { - ds_clear(match); - - if (is_l3dgw_port(op)) { - ds_put_format(match, "is_chassis_resident(%s)", - op->cr_port->json_key); - } - - /* Create a single ND rule for all IPs that are used as VIPs. */ - char *lb_ips_v6_as = lr_lb_address_set_ref(op->od->tunnel_key, - AF_INET6); - build_lrouter_nd_flow(op->od, op, "nd_na", lb_ips_v6_as, NULL, - REG_INPORT_ETH_ADDR, match, false, 90, - NULL, lflows, meter_groups, - &op->lflow_dep_mgr, OBJDEP_TYPE_LPORT, - op->nbrp->name, op->od); - free(lb_ips_v6_as); - } - if (!op->od->is_gw_router && !op->od->n_l3dgw_ports) { /* UDP/TCP/SCTP port unreachable. */ for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) { @@ -15557,19 +15583,6 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op, } } - /* Drop IP traffic destined to router owned IPs except if the IP is - * also a SNAT IP. Those are dropped later, in stage - * "lr_in_arp_resolve", if unSNAT was unsuccessful. - * - * If op->od->lb_force_snat_router_ip is true, it means the IP of the - * router port is also SNAT IP. - * - * Priority 60. - */ - if (!op->od->lb_force_snat_router_ip) { - build_lrouter_drop_own_dest(op, S_ROUTER_IN_IP_INPUT, 60, false, - lflows); - } /* ARP / ND handling for external IP addresses. * * DNAT and SNAT IP addresses are external IP addresses that need ARP @@ -15618,6 +15631,71 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op, } } +static void +build_lrouter_ipv4_ip_input_lb_related(struct ovn_port *op, + struct lflow_data *lflows, + struct ds *match, + const struct shash *meter_groups) +{ + ovs_assert(op->nbrp); + /* No ingress packets are accepted on a chassisredirect + * port, so no need to program flows for that port. */ + if (is_cr_port(op)) { + return; + } + + if (sset_count(&op->od->lb_ips->ips_v4_reachable)) { + ds_clear(match); + if (is_l3dgw_port(op)) { + ds_put_format(match, "is_chassis_resident(%s)", + op->cr_port->json_key); + } + + /* Create a single ARP rule for all IPs that are used as VIPs. */ + char *lb_ips_v4_as = lr_lb_address_set_ref(op->od->tunnel_key, + AF_INET); + build_lrouter_arp_flow(op->od, op, lb_ips_v4_as, + REG_INPORT_ETH_ADDR, + match, false, 90, NULL, lflows, + &op->lflow_dep_mgr, OBJDEP_TYPE_LB, + op->nbrp->name, op->od); + free(lb_ips_v4_as); + } + + if (sset_count(&op->od->lb_ips->ips_v6_reachable)) { + ds_clear(match); + + if (is_l3dgw_port(op)) { + ds_put_format(match, "is_chassis_resident(%s)", + op->cr_port->json_key); + } + + /* Create a single ND rule for all IPs that are used as VIPs. */ + char *lb_ips_v6_as = lr_lb_address_set_ref(op->od->tunnel_key, + AF_INET6); + build_lrouter_nd_flow(op->od, op, "nd_na", lb_ips_v6_as, NULL, + REG_INPORT_ETH_ADDR, match, false, 90, + NULL, lflows, meter_groups, + &op->lflow_dep_mgr, OBJDEP_TYPE_LB, + op->nbrp->name, op->od); + free(lb_ips_v6_as); + } + + /* Drop IP traffic destined to router owned IPs except if the IP is + * also a SNAT IP. Those are dropped later, in stage + * "lr_in_arp_resolve", if unSNAT was unsuccessful. + * + * If op->od->lb_force_snat_router_ip is true, it means the IP of the + * router port is also SNAT IP. + * + * Priority 60. + */ + if (!op->od->lb_force_snat_router_ip) { + build_lrouter_drop_own_dest(op, S_ROUTER_IN_IP_INPUT, 60, false, + lflows, OBJDEP_TYPE_LB); + } +} + static void build_lrouter_in_unsnat_match(struct ovn_datapath *od, const struct nbrec_nat *nat, struct ds *match, @@ -16898,12 +16976,27 @@ build_lswitch_and_lrouter_iterate_by_lsp(struct ovn_port *op, build_lswitch_external_port(op, lflows, &op->lflow_dep_mgr); build_lswitch_ip_unicast_lookup(op, lflows, actions, match, &op->lflow_dep_mgr); + /* Build Logical Router Flows. */ - build_ip_routing_flows_for_router_type_lsp(op, lr_ports, lflows); build_arp_resolve_flows_for_lsp(op, lflows, lr_ports, match, actions, &op->lflow_dep_mgr); } +static void +build_lb_related_iterate_by_lsp(struct ovn_port *op, + const struct hmap *lr_ports, + struct ds *match, + struct ds *actions, + struct lflow_data *lflows) +{ + ovs_assert(op->nbsp); + build_lswitch_ip_unicast_lookup_lb_vips(op, lflows, + &op->lflow_dep_mgr); + build_ip_routing_flows_for_router_type_lsp(op, lr_ports, lflows); + build_arp_resolve_flows_for_routable_addrs_throug_lsp( + op, lflows, lr_ports, match, actions, &op->lflow_dep_mgr); +} + /* Helper function to combine all lflow generation which is iterated by logical * router port. All the flows built in this function are Logical Router flows. */ @@ -16929,6 +17022,15 @@ build_lswitch_and_lrouter_iterate_by_lrp(struct ovn_port *op, lsi->meter_groups); build_lrouter_ipv4_ip_input(op, lsi->lflows, &lsi->match, &lsi->actions, lsi->meter_groups); +} + +static void +build_lb_related_iterate_by_lrp(struct ovn_port *op, + struct lswitch_flow_build_info *lsi) +{ + ovs_assert(op->nbrp); + build_lrouter_ipv4_ip_input_lb_related(op, lsi->lflows, &lsi->match, + lsi->meter_groups); build_lrouter_force_snat_flows_op(op, lsi->lflows, &lsi->match, &lsi->actions); } @@ -16993,6 +17095,9 @@ build_lflows_thread(void *arg) &lsi->match, &lsi->actions, lsi->lflows); + build_lb_related_iterate_by_lsp(op, lsi->lr_ports, + &lsi->match, &lsi->actions, + lsi->lflows); } } for (bnum = control->id; @@ -17005,6 +17110,7 @@ build_lflows_thread(void *arg) return NULL; } build_lswitch_and_lrouter_iterate_by_lrp(op, lsi); + build_lb_related_iterate_by_lrp(op, lsi); } } for (bnum = control->id; @@ -17193,9 +17299,12 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths, lsi.meter_groups, &lsi.match, &lsi.actions, lsi.lflows); + build_lb_related_iterate_by_lsp(op, lsi.lr_ports, &lsi.match, + &lsi.actions, lsi.lflows); } HMAP_FOR_EACH (op, key_node, lr_ports) { build_lswitch_and_lrouter_iterate_by_lrp(op, &lsi); + build_lb_related_iterate_by_lrp(op, &lsi); } stopwatch_stop(LFLOWS_PORTS_STOPWATCH_NAME, time_msec()); stopwatch_start(LFLOWS_LBS_STOPWATCH_NAME, time_msec());