We have same problem (too many calls of pinctrl results in CPU high 
load) but this can be solved with use copp + meter arp-resolve

On 9/30/25 5:11 PM, Lucas Vargas Dias via dev 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.
> To fix it, the idea could be the following logical flow in LR:
>    table=22(lr_in_arp_resolve  ), priority=50   , match=(ip4.dst == 
> 192.168.20.0/24 && reg0 != 192.168.20.1), action=(drop;)
>
> Signed-off-by: Lucas Vargas Dias <[email protected]>
> ---
>   northd/northd.c | 62 +++++++++++++++++++++++++++++++++++--------------
>   1 file changed, 45 insertions(+), 17 deletions(-)
>
> diff --git a/northd/northd.c b/northd/northd.c
> index fe5199a86..710ac6b6d 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -1572,6 +1572,7 @@ join_logical_ports_lsp(struct hmap *ports,
>       if (op->has_unknown) {
>           od->has_unknown = true;
>       }
> +
>       hmap_insert(&od->ports, &op->dp_node,
>                   hmap_node_hash(&op->key_node));
>   
> @@ -1808,6 +1809,7 @@ join_logical_ports(const struct 
> sbrec_port_binding_table *sbrec_pb_table,
>               vector_push(&peer->od->ls_peers, &op->od);
>               peer->peer = op;
>               op->peer = peer;
> +            peer->od->has_unknown = op->od->has_unknown;
>   
>               /* Fill op->lsp_addrs for op->nbsp->addresses[] with
>                * contents "router", which was skipped in the loop above. */
> @@ -14358,6 +14360,7 @@ build_arp_resolve_flows_for_lrouter(
>           struct lflow_ref *lflow_ref)
>   {
>       ovs_assert(od->nbr);
> +
>       /* Multicast packets already have the outport set so just advance to
>        * next table (priority 500). */
>       ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_RESOLVE, 500,
> @@ -14376,6 +14379,48 @@ build_arp_resolve_flows_for_lrouter(
>   
>       ovn_lflow_add_default_drop(lflows, od, S_ROUTER_IN_ARP_RESOLVE,
>                                  lflow_ref);
> +
> +    if (!od->has_unknown) {
> +        struct ds match = DS_EMPTY_INITIALIZER;
> +        for (int i = 0; i < od->nbr->n_ports; i++) {
> +            const struct nbrec_logical_router_port *lrp = od->nbr->ports[i];
> +            struct lport_addresses lrp_networks;
> +            if (!extract_lrp_networks(lrp, &lrp_networks)) {
> +                destroy_lport_addresses(&lrp_networks);
> +                continue;
> +            }
> +
> +            for (int j = 0; j < lrp->n_networks; j++) {
> +                struct in6_addr prefix;
> +                unsigned int plen;
> +                if (!ip46_parse_cidr(lrp->networks[j], &prefix, &plen)) {
> +                    continue;
> +                }
> +
> +                bool is_ipv4 = IN6_IS_ADDR_V4MAPPED(&prefix);
> +                ds_clear(&match);
> +                char *ip_prefix = build_route_prefix_s(&prefix, plen);
> +                ds_put_format(&match, "%s.dst == %s/%u && %s != ",
> +                    is_ipv4 ? "ip4" : "ip6", ip_prefix, plen,
> +                    is_ipv4 ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6);
> +                if (is_ipv4) {
> +                    ds_put_format(&match, "%s",
> +                        lrp_networks.ipv4_addrs->addr_s);
> +                } else {
> +                    ds_put_format(&match, "%s",
> +                        lrp_networks.ipv6_addrs->addr_s);
> +                }
> +
> +                ovn_lflow_add_drop_with_desc(lflows, od,
> +                    S_ROUTER_IN_ARP_RESOLVE, 50,
> +                    ds_cstr(&match), "No L2 unknown",
> +                    lflow_ref);
> +                free(ip_prefix);
> +            }
> +            destroy_lport_addresses(&lrp_networks);
> +        }
> +        ds_destroy(&match);
> +    }
>   }
>   
>   /* Local router ingress table ARP_RESOLVE: ARP Resolution.
> @@ -14825,23 +14870,6 @@ build_arp_resolve_flows_for_lsp(
>                                           &op->nbsp->header_,
>                                           op->lflow_ref);
>               }
> -
> -            if (router_port->lrp_networks.n_ipv6_addrs) {
> -                ds_clear(match);
> -                ds_put_format(match, "outport == %s && "
> -                              REG_NEXT_HOP_IPV6 " == ",
> -                              peer->json_key);
> -                op_put_v6_networks(match, router_port);
> -
> -                ds_clear(actions);
> -                ds_put_format(actions, "eth.dst = %s; next;",
> -                              router_port->lrp_networks.ea_s);
> -                ovn_lflow_add_with_hint(lflows, peer->od,
> -                                        S_ROUTER_IN_ARP_RESOLVE, 100,
> -                                        ds_cstr(match), ds_cstr(actions),
> -                                        &op->nbsp->header_,
> -                                        op->lflow_ref);
> -            }
>           }
>       }
>   }


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

Reply via email to