On Mon, Oct 27, 2025 at 9:21 PM Lucas Vargas Dias via dev < [email protected]> wrote:
> 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]> > --- > Hi Lucas, sorry for the late response, but I have to agree with Lorenzo and Alexander on this. Both of them mentioned CoPP as a solution which makes sense considering the problem seems to be high ovn-controller CPU usage in pinctrl. And it makes me wonder if there is any reason why couldn't CoPP be used? It was built exactly for this to limit the traffic towards userspace, to protect the control plane. There might be another solution, that is ACLs. Would that be feasible in any capacity for you to create ACLs that would block this traffic? As you said in your case those IPs are known I think it should be possible to create ACL drop flow based on those IPs. While there isn't technically anything wrong with the option, it's the fact that we would be adding another option. I would love to avoid that if possible, especially if any of the solutions above would work. My bet would be on the CoPP, because as I said, it's specifically made for those scenarios. Please let me know what you think. Thanks, Ales > 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 > > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
