diff mbox series

[ovs-dev,2/2] northd: Don't add ARP responder flows for unreachable VIPs.

Message ID 20211108171036.1005777-1-numans@ovn.org
State Accepted
Headers show
Series [ovs-dev,1/2] northd: Treat reachable and unreachable VIPs differently. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success

Commit Message

Numan Siddique Nov. 8, 2021, 5:10 p.m. UTC
From: Numan Siddique <numans@ovn.org>

If a logical router is associated with load balancer VIPs which
are unreachable from it, we don't need to add ARP responder flows
in the L2_LKUP stage of ingress pipeline of the logical switches
connected to the router.  This patch removes these flows.

Signed-off-by: Numan Siddique <numans@ovn.org>
---
 northd/northd.c         | 63 -----------------------------------------
 northd/ovn-northd.8.xml |  8 ------
 tests/ovn-northd.at     |  6 ++--
 3 files changed, 3 insertions(+), 74 deletions(-)

Comments

Dumitru Ceara Nov. 9, 2021, 12:41 p.m. UTC | #1
On 11/8/21 6:10 PM, numans@ovn.org wrote:
> From: Numan Siddique <numans@ovn.org>
> 
> If a logical router is associated with load balancer VIPs which
> are unreachable from it, we don't need to add ARP responder flows
> in the L2_LKUP stage of ingress pipeline of the logical switches
> connected to the router.  This patch removes these flows.
> 
> Signed-off-by: Numan Siddique <numans@ovn.org>
> ---

Some test numbers with a topology simulating 120 ovn-k8s nodes (120
gateway routers connected to a single join switch) with 10K load
balancers applied to all gateway router:

A. Before this patch:
- northd loop processing time: 2638ms
- SB DB size (on disk, after compaction): 94M
- number of logical flows: 55942

B. After this patch:
- northd loop processing time: 2526ms
- SB DB size (on disk, after compaction): 91M
- number of logical flows: 45942

Looks good to me, thanks!

Acked-by: Dumitru Ceara <dceara@redhat.com>
diff mbox series

Patch

diff --git a/northd/northd.c b/northd/northd.c
index 1011518a9..0638df6a2 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -7134,68 +7134,6 @@  build_lswitch_rport_arp_req_flows(struct ovn_port *op,
     }
 }
 
-static void
-build_lflows_for_unreachable_vips(struct ovn_northd_lb *lb,
-                                  struct ovn_lb_vip *lb_vip,
-                                  struct hmap *lflows,
-                                  struct ds *match)
-{
-    static const char *action = "outport = \"_MC_flood\"; output;";
-    bool ipv4 = IN6_IS_ADDR_V4MAPPED(&lb_vip->vip);
-    ovs_be32 ipv4_addr;
-
-    ds_clear(match);
-    if (ipv4) {
-        if (!ip_parse(lb_vip->vip_str, &ipv4_addr)) {
-            return;
-        }
-        ds_put_format(match, "%s && arp.op == 1 && arp.tpa == %s",
-                      FLAGBIT_NOT_VXLAN, lb_vip->vip_str);
-    } else {
-        ds_put_format(match, "%s && nd_ns && nd.target == %s",
-                      FLAGBIT_NOT_VXLAN, lb_vip->vip_str);
-    }
-
-    struct ovn_lflow *lflow_ref = NULL;
-    uint32_t hash = ovn_logical_flow_hash(
-            ovn_stage_get_table(S_SWITCH_IN_L2_LKUP),
-            ovn_stage_get_pipeline(S_SWITCH_IN_L2_LKUP), 90,
-            ds_cstr(match), action);
-
-    for (size_t i = 0; i < lb->n_nb_lr; i++) {
-        struct ovn_datapath *od = lb->nb_lr[i];
-
-        if (!od->is_gw_router && !od->n_l3dgw_ports) {
-            continue;
-        }
-
-        struct ovn_port *op;
-        LIST_FOR_EACH (op, dp_node, &od->port_list) {
-            if (!od->is_gw_router && !is_l3dgw_port(op)) {
-                continue;
-            }
-
-            struct ovn_port *peer = op->peer;
-            if (!peer || !peer->nbsp || lsp_is_external(peer->nbsp)) {
-                continue;
-            }
-
-            if ((ipv4 && lrouter_port_ipv4_reachable(op, ipv4_addr)) ||
-                (!ipv4 && lrouter_port_ipv6_reachable(op, &lb_vip->vip))) {
-                continue;
-            }
-
-            if (ovn_dp_group_add_with_reference(lflow_ref, peer->od)) {
-                continue;
-            }
-            lflow_ref = ovn_lflow_add_at_with_hash(
-                lflows, peer->od, S_SWITCH_IN_L2_LKUP, 90, ds_cstr(match),
-                action, NULL, NULL, &peer->nbsp->header_,
-                OVS_SOURCE_LOCATOR, hash);
-        }
-    }
-}
-
 static void
 build_dhcpv4_options_flows(struct ovn_port *op,
                            struct lport_addresses *lsp_addrs,
@@ -9683,7 +9621,6 @@  build_lrouter_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows,
     for (size_t i = 0; i < lb->n_vips; i++) {
         struct ovn_lb_vip *lb_vip = &lb->vips[i];
 
-        build_lflows_for_unreachable_vips(lb, lb_vip, lflows, match);
         build_lrouter_nat_flows_for_lb(lb_vip, lb, &lb->vips_nb[i],
                                        lflows, match, action,
                                        meter_groups);
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 5c6b85d70..e42c70be1 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -1582,14 +1582,6 @@  output;
         <ref column="options" table="Logical_Router"/>:mcast_relay='true'.
       </li>
 
-      <li>
-        Priority-90 flows for each VIP address of a load balancer configured
-        outside its owning router port's subnet. These flows match ARP
-        requests and ND packets for the specific IP addresses.  Matched packets
-        are forwarded to the <code>MC_FLOOD</code> multicast group which
-        contains all connected logical ports.
-      </li>
-
       <li>
         A priority-85 flow that forwards all IP multicast traffic destined to
         224.0.0.X to the <code>MC_FLOOD</code> multicast group, which
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 9499b2e45..4ccef9328 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -4718,11 +4718,11 @@  AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | sed 's/table=../table=??/' | sort],
   table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.1.100), action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_flood_l2"; output;)
   table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 30.0.0.100), action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_flood_l2"; output;)
   table=??(ls_in_l2_lkup      ), priority=80   , match=(flags[[1]] == 0 && nd_ns && nd.target == fe80::200:ff:fe00:101), action=(clone {outport = "ls1-ro1"; output; }; outport = "_MC_flood_l2"; output;)
-  table=??(ls_in_l2_lkup      ), priority=90   , match=(flags[[1]] == 0 && arp.op == 1 && arp.tpa == 192.168.4.100), action=(outport = "_MC_flood"; output;)
 ])
 
-# Make sure that there is flow for VIP 192.168.4.100 to flood as it is unreachable.
-AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | grep "192.168.4.100" | grep -v clone | grep "_MC_flood" -c], [0], [1
+
+# Make sure that there is no flow for VIP 192.168.4.100 as it is unreachable.
+AT_CHECK([grep "ls_in_l2_lkup" ls1_lflows | grep "192.168.4.100" | grep -v clone | grep "_MC_flood" -c], [1], [0
 ])
 
 AT_CLEANUP