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
