Repository navigation
vrrp: don't subscribe the gratuitous ARP/NDISC packet sockets to receive traffic - #2750
Conversation
…ffic The gratuitous ARP socket is send-only, but it is created with ETH_P_ARP, which registers a kernel receive hook: every incoming ARP packet is handed to packet_rcv() for this socket before the BPF filter drops it. With many keepalived instances in separate namespaces (e.g. OpenStack Neutron L3 HA routers), this saturates a CPU. Use protocol 0 so no hook is registered. Sending is unchanged, as the kernel uses sll_protocol, which keepalived already sets. Fixes acassen#2749 Signed-off-by: Axel Jacquet <axel.jacquet@infomaniak.com>
|
@axelJacquet Many thanks for the detailed explanation and the patch. Based on the information you have provided, I think there are several changes that are missing:
I suspect the calls to |
…lters The unsolicited NA socket has the same issue as the gratuitous ARP socket: it is created with ETH_P_IPV6, so every incoming IPv6 packet is handed to packet_rcv() before the BPF filter drops it. Create it with protocol 0 as well. With protocol 0 no receive hook is registered, so the "receive nothing" BPF filter is no longer needed on either socket. Signed-off-by: Axel Jacquet <axel.jacquet@infomaniak.com>
|
Thanks for the review! I've pushed a second commit: the NDISC socket is now also created with protocol 0, and I don't think the change can be applied to I built three variants of current master (e922f97) and ran two keepalived instances (priority 150 and 100, same VRID) in two namespaces connected by a veth pair, Linux 6.12:
So I've kept The |
|
@axelJacquet Many thanks for identifying this issue and providing the resolution. |
Fixes #2749
The
PF_PACKETsocket used to send gratuitous ARPs is send-only, but is created withhtons(ETH_P_ARP), which registers a kernel receive hook: every incoming ARP packet of the host is handed topacket_rcv()for this socket, then dropped by the "receive nothing" BPF filter. With many keepalived instances in separate namespaces (OpenStack Neutron L3 HA routers), this becomes quadratic and saturates a CPU.This creates the socket with protocol
0("If protocol is set to zero, no packets are received",packet(7)). Sending is unchanged: with a destination address, the kernel uses
sll_protocol, which keepalived already sets.Details, history and measurements are in #2749.
Tested on 2.2.7 (Debian 12, Linux 6.12):
/proc/net/packet: protocol0000,R 0);