> 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.
Hi Lucas, Have you verified if you can get 'acceptable' CPU load using CoPP for ARP packets? Something like: https://github.com/ovn-org/ovn/blob/main/tests/system-ovn.at#L7866 More comments inline. Regards, Lorenzo > > 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]> > --- > AUTHORS.rst | 1 + > northd/northd.c | 46 +++++++++++++++++++++++++ > ovn-nb.xml | 13 ++++++++ > tests/ovn-northd.at | 81 +++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 141 insertions(+) > > diff --git a/AUTHORS.rst b/AUTHORS.rst > index 0aa7f796d..c1532dcae 100644 > --- a/AUTHORS.rst > +++ b/AUTHORS.rst > @@ -404,6 +404,7 @@ Thomas F. Herbert > [email protected] > Thomas Goirand [email protected] > Thomas Graf [email protected] > Thomas Lacroix [email protected] > +Tiago Matos Carvalho Reis [email protected] This should be done via a separated patch. > Tiago Pires [email protected] > Tim Rozet [email protected] > Timo Puha [email protected] > diff --git a/northd/northd.c b/northd/northd.c > index 9da995cea..7fec45f4d 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -14940,6 +14940,52 @@ 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_nd_resolve = smap_get_bool(&op->nbrp->options, > + "disable_nd_resolve", false); > + if (discard_arp_resolve || discard_nd_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)) { > + destroy_lport_addresses(&lrp_networks); you do not need to run destroy_lport_addresses() if extract_lrp_networks() fails. > + continue; > + } > + for (int j = 0; j < lrp->n_networks; j++) { > + struct in6_addr prefix; > + unsigned int plen; I guess you do not need this processing, you can use the values stored in lrp_networks. > + if (!ip46_parse_cidr(lrp->networks[j], &prefix, &plen)) { > + continue; > + } > + > + bool is_ipv4 = IN6_IS_ADDR_V4MAPPED(&prefix); > + char *ip_prefix = build_route_prefix_s(&prefix, plen); > + if ((is_ipv4 && discard_arp_resolve) || > + (!is_ipv4 && discard_nd_nd_resolve)) { > + ds_put_format(match, "(%s.dst == %s/%u) || ", > + is_ipv4 ? "ip4" : "ip6", ip_prefix, plen); > + } > + free(ip_prefix); > + } > + destroy_lport_addresses(&lrp_networks); > + } > + if (match->length > match_len) { same here. > + 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
