Consider the following scenario:
(192.168.10.10/24) VM1 -> LS -> LR -> TS -> LR -> LS -> VM2 (192.168.20.20/24)

Also, LSPs from LS have the addresses configured, it's not used unknown 
addresses
in this case.

Ping from VM1 to VM2 works correctly, it's ok. But, if VM1 try to flood,
for example the IP 192.168.20.30 (an innexistent LSP), we'll see a high CPU 
load in
ovn-controller from the network destination due to the get_arp function.
For this case, ovn-controller have ovn-is-interconn = true.

In the connection LR -> TS -> LR all addresses are known, so arp resolve
could be disable. For this case, add the option disable_arp_resolve=true
to logical_router_port drop the packets for unknown addresses. If the
communication is IPv6, configure the option disable_nd_resolve=true.


Co-authored-by: Tiago Matos Carvalho Reis <[email protected]>
Signed-off-by: Tiago Matos Carvalho Reis <[email protected]>
Signed-off-by: Lucas Vargas Dias <[email protected]>
---
 northd/northd.c     | 54 ++++++++++++++++++++++++++++++
 ovn-nb.xml          | 13 ++++++++
 tests/ovn-northd.at | 81 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+)

diff --git a/northd/northd.c b/northd/northd.c
index 9da995cea..356dbaa94 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -14940,6 +14940,60 @@ build_arp_resolve_flows_for_lrp(struct ovn_port *op,
                                     &op->nbrp->header_,
                                     lflow_ref);
         }
+
+        bool discard_arp_resolve = smap_get_bool(&op->nbrp->options,
+            "disable_arp_resolve", false);
+        bool discard_nd_resolve = smap_get_bool(&op->nbrp->options,
+            "disable_nd_resolve", false);
+        if (discard_arp_resolve || discard_nd_resolve) {
+            ds_clear(match);
+
+            ds_put_format(match, "inport == %s && is_chassis_resident(%s) && "
+                "(", op->json_key, op->cr_port->json_key);
+
+            size_t match_len = match->length;
+            for (size_t i = 0; i < op->od->nbr->n_ports; i++) {
+                struct nbrec_logical_router_port *lrp = op->od->nbr->ports[i];
+                struct lport_addresses lrp_networks;
+                if (!extract_lrp_networks(lrp, &lrp_networks)) {
+                    continue;
+                }
+
+                for (int j = 0; j < lrp_networks.n_ipv4_addrs; j++) {
+                    if (!discard_arp_resolve) {
+                        break;
+                    }
+                    struct ipv4_netaddr ipv4 = lrp_networks.ipv4_addrs[j];
+                    struct in6_addr ip = in6_addr_mapped_ipv4(ipv4.addr);
+                    if (prefix_is_link_local(&ip, ipv4.plen)) {
+                        continue;
+                    }
+                    ds_put_format(match, "(ip4.dst == %s/%u) || ",
+                        ipv4.network_s, ipv4.plen);
+                }
+                for (int j = 0; j < lrp_networks.n_ipv6_addrs; j++) {
+                    if (!discard_nd_resolve) {
+                        break;
+                    }
+                    struct ipv6_netaddr ipv6 = lrp_networks.ipv6_addrs[j];
+                    if (prefix_is_link_local(&ipv6.addr, ipv6.plen)) {
+                        continue;
+                    }
+                    ds_put_format(match, "(ip6.dst == %s/%u) || ",
+                        ipv6.network_s, ipv6.plen);
+                }
+                destroy_lport_addresses(&lrp_networks);
+            }
+
+            if (match->length > match_len) {
+                ds_truncate(match, match->length - 4);
+                ds_put_format(match, ")");
+                ovn_lflow_add_drop_with_desc(lflows, op->od,
+                    S_ROUTER_IN_ARP_RESOLVE, 50,
+                    ds_cstr(match), "No L2 unknown",
+                    lflow_ref);
+            }
+        }
     }
 }
 
diff --git a/ovn-nb.xml b/ovn-nb.xml
index 73b5f213f..872741a2f 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -4499,6 +4499,19 @@ or
           routes in <code>ovn-ic</code> daemon.
         </p>
       </column>
+
+      <column name="options" key="disable_arp_resolve">
+        <p>
+          If set to <code>true</code>, disable get_arp for
+          known networks.
+        </p>
+      </column>
+      <column name="options" key="disable_nd_resolve">
+        <p>
+          If set to <code>true</code>, disable get_nd for
+          known networks.
+        </p>
+      </column>
     </group>
 
     <group title="Attachment">
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 5c9cc5cca..7c8237acd 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -10111,6 +10111,87 @@ AT_CHECK([grep -e "ls_in_arp_rsp" S1flows | 
ovn_strip_lflows], [0], [dnl
 AT_CLEANUP
 ])
 
+
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([check options:disable_arp_resolve and options:disable_nd_resolve for 
LRP])
+ovn_start NORTHD_TYPE
+check ovn-nbctl lr-add S1
+check ovn-nbctl --wait=sb lrp-add S1 S1-vm1  50:54:00:00:00:010 
192.168.0.10/24 fd00::2/64
+check ovn-nbctl --wait=sb lrp-set-gateway-chassis S1-vm1 chassis-1
+
+ovn-sbctl dump-flows S1 > S1flows
+AT_CAPTURE_FILE([S1flows])
+
+ovn-sbctl dump-flows S1 > S1flows
+AT_CAPTURE_FILE([S1flows])
+
+AT_CHECK([grep -e "lr_in_arp_resolve" S1flows | ovn_strip_lflows], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=0    , match=(1), action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 0), 
action=(get_nd(outport, xxreg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 1), 
action=(get_arp(outport, reg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=500  , match=(ip4.mcast || 
ip6.mcast), action=(next;)
+])
+
+
+# Set the disable_arp_resolve option and verify the flow
+check ovn-nbctl --wait=sb set logical_router_port S1-vm1 
options:disable_arp_resolve=true
+
+ovn-sbctl dump-flows S1 > S1flows
+AT_CAPTURE_FILE([S1flows])
+
+AT_CHECK([grep -e "lr_in_arp_resolve" S1flows | ovn_strip_lflows], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=0    , match=(1), action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 0), 
action=(get_nd(outport, xxreg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 1), 
action=(get_arp(outport, reg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=50   , match=(inport == "S1-vm1" && 
is_chassis_resident("cr-S1-vm1") && ((ip4.dst == 192.168.0.0/24))), 
action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=500  , match=(ip4.mcast || 
ip6.mcast), action=(next;)
+])
+
+check ovn-nbctl --wait=sb set logical_router_port S1-vm1 
options:disable_nd_resolve=true
+
+ovn-sbctl dump-flows S1 > S1flows
+AT_CAPTURE_FILE([S1flows])
+
+AT_CHECK([grep -e "lr_in_arp_resolve" S1flows | ovn_strip_lflows], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=0    , match=(1), action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 0), 
action=(get_nd(outport, xxreg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 1), 
action=(get_arp(outport, reg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=50   , match=(inport == "S1-vm1" && 
is_chassis_resident("cr-S1-vm1") && ((ip4.dst == 192.168.0.0/24) || (ip6.dst == 
fd00::/64))), action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=500  , match=(ip4.mcast || 
ip6.mcast), action=(next;)
+])
+
+# Remove lrp from chassis
+check ovn-nbctl --wait=sb lrp-del-gateway-chassis S1-vm1 chassis-1
+
+ovn-sbctl dump-flows S1 > S1flows
+AT_CAPTURE_FILE([S1flows])
+
+AT_CHECK([grep -e "lr_in_arp_resolve" S1flows | ovn_strip_lflows], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=0    , match=(1), action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 0), 
action=(get_nd(outport, xxreg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 1), 
action=(get_arp(outport, reg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=500  , match=(ip4.mcast || 
ip6.mcast), action=(next;)
+])
+
+check ovn-nbctl --wait=sb set logical_router_port S1-vm1 
options:disable_arp_resolve=false
+check ovn-nbctl --wait=sb lrp-set-gateway-chassis S1-vm1 chassis-1
+
+ovn-sbctl dump-flows S1 > S1flows
+AT_CAPTURE_FILE([S1flows])
+
+AT_CHECK([grep -e "lr_in_arp_resolve" S1flows | ovn_strip_lflows], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=0    , match=(1), action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 0), 
action=(get_nd(outport, xxreg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=1    , match=(reg9[[9]] == 1), 
action=(get_arp(outport, reg0); next;)
+  table=??(lr_in_arp_resolve  ), priority=50   , match=(inport == "S1-vm1" && 
is_chassis_resident("cr-S1-vm1") && ((ip6.dst == fd00::/64))), action=(drop;)
+  table=??(lr_in_arp_resolve  ), priority=500  , match=(ip4.mcast || 
ip6.mcast), action=(next;)
+])
+
+
+AT_CLEANUP
+])
+
+
 OVN_FOR_EACH_NORTHD_NO_HV([
 AT_SETUP([Address set incremental processing])
 ovn_start
-- 
2.43.0


-- 




_'Esta mensagem é direcionada apenas para os endereços constantes no 
cabeçalho inicial. Se você não está listado nos endereços constantes no 
cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa 
mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão 
imediatamente anuladas e proibidas'._


* **'Apesar do Magazine Luiza tomar 
todas as precauções razoáveis para assegurar que nenhum vírus esteja 
presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por 
quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.*



_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to