Skip to contentSkip to conversation

discard ARP/NDP b/mcast/null announce (poison)

PATCH Superseded Marc Suñé 2 participants 12 messages Jan 26 – Jan 29

Subsystems (4)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v2 cover discard ARP/NDP b/mcast/null announce (poison)

The current ARP and NDP implementations accept announcements with multicast (broadcast incl.) and null MAC addresses as Sender HW Address (SHA) in ARP or src/target lladdr in NDP, and updates the cache for that neighbour.

Multicast (incl. broadcast) and null MAC addresses shall never be associated with a unicast or a multicast IPv4/6 address (see RFC1812, section 3.3.2).

ARP/NDP poisioning with a broadcast and certain multicast MAC addresses, especially when poisoning a Gateway IP, have some undesired implications compared to an ARP/NDP poisioning with a regular MAC (see commit message in patch 1 for more information).

Worth mentioning that if an attacker is able to ARP/NDP poison in a L2 segment, that in itself is probably a bigger security threat (Man-in-middle etc., see Note2 in patch 1)

Since these MACs should never be announced, this patch series discards/drops these packets, which prevents broadcast and multicast ARP/NDP poisoning vectors.

This patchset only modifies the behaviour of the neighbouring subsystem when processing network packets. Static entries can still be added with mcast/bcast/null MACs.

v1: https://lore.kernel.org/netdev/[email protected]/

Changes since RFC v1
====================
- Discard announcements with multicast MAC addresses
- Check for dev->type == ARPHRD_ETHER instead of HW addrlen in ARP
- Use !is_valid_ether_addr()
- Added multicast test coverage and renamed tests accordingly
- Dropped patch 5 (scapy utils)

Comments
========

As discussed in v1, certain Load Balancers make use of Multicast MAC addresses for their VIPs:

https://support.huawei.com/enterprise/en/doc/EDOC1100213154/d8621162/dynamic-learning-of-arp-entries-with-multicast-mac-addresses
https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-network-to-support-nlb-operation-mode

But as stated in the Microsoft NLB documentation, it is expected that static entries are created for it to work:

To support this configuration, you must configure the network infrastructure to use static ARP entries and MAC address table entries. Network switches cannot learn the NLB multicast MAC address in the course of their usual operations. If you skip the manual configuration step, the network switches may flood NLB traffic to all ports or drop packets. The network may seem to function correctly at first, but problems increase over time.

Marc Suñé (4):
arp: discard invalid sha addr (b/mcast ARP poison) selftests/net: add no ARP b/mcast,null poison test
neigh: discard invalid lladdr (b/mcast poison) selftests/net: add no NDP b/mcast,null poison test

 net/ipv4/arp.c                                |   8 +
 net/ipv6/ndisc.c                              |  16 +
 tools/testing/selftests/net/.gitignore        |   2 +
 tools/testing/selftests/net/Makefile          |   3 +
 .../net/arp_ndisc_no_invalid_sha_poison.sh    | 368 ++++++++++++++++++
 tools/testing/selftests/net/arp_send.c        | 138 +++++++
 tools/testing/selftests/net/ndisc_send.c      | 198 ++++++++++
 7 files changed, 733 insertions(+)
 create mode 100755 tools/testing/selftests/net/arp_ndisc_no_invalid_sha_poison.sh
 create mode 100644 tools/testing/selftests/net/arp_send.c
 create mode 100644 tools/testing/selftests/net/ndisc_send.c
Signature · 1 line
2.47.3
#1 lore raw

PATCH v2 1/4 arp: discard invalid sha addr (b/mcast ARP poison)

Prior to this commit, the ARP implementation accepted ARP req/replies with multicast (including broadcast) and null MAC addresses as Sender HW Address (SHA), and updated the ARP cache for that neighbour. Broadcast, multicast and null MAC addresses shall never be associated with a unicast or a multicast IPv4 address (see RFC1812, section 3.3.2).

ARP poisioning with a broadcast MAC address and certain multicast addresses, especially when poisoning a Gateway IP, have some undesired implications compared to an ARP poisioning with a regular MAC (see Note1).

Worth mentioning that if an attacker is able to ARP poison in a L2 segment, that in itself is probably a bigger security threat (Man-in-middle etc., see Note2).

However, since these MACs should never be announced as SHA, discard/drop ARPs with SHA={b/mcast, null}, which prevents the broadcast/multicast ARP poisoning vector.

Note1:

After a successful broadcast/multicast ARP poisioning attack:

1. Unicast packets and refresh ("targeted") ARPs sent to or via the poisioned IP (e.g. the default GW) are flooded by bridges/switches. That is in absence of other security controls.

Hardware swiches generally have rate-limits to prevent/mitigate broadcast storms, since ARPs are usually answered by the CPU. Legit unicast packets could be dropped (perf. degradation).

Most modern NICs implement some form of L2 MAC filtering to early discard irrelevant packets. In contrast to an ARP poisoning attack with any other MAC, both unicast and ARP ("targeted") refresh packets are passed up to the Kernel networking stack (for all hosts in the L2 segment).

2. A single forged ARP packet (e.g. for the Gateway IP) can produce up to N "targeted" (to broadcast) ARPs, where N is the number of hosts in the L2 segment that have an ARP entry for that IP (e.g. GW), and some more traffic, since the real host will answer to targeted refresh ARPs with their (real) reply.

This is a relatively low amount of traffic compared to 1).

3. An attacker could use this form of ARP poisoning to discover all hosts in a L2 segment in a very short period of time with one or few packets.

By poisoning e.g. the default GW (likely multiple times, to avoid races with real gARPs from the GW), all hosts will eventually issue refresh "targeted" ARPs for the GW IP with the broadcast MAC address as destination. These packets will be flooded in the L2 segment, revealing the presence of hosts to the attacker.

For comparison:
* Passive ARP monitoring: also stealthy, but can take a long time or not be possible at all in switches, as most refresh ARPs are targeted.
* ARP req flooding: requires swiping the entire subnet. Noisy and easy to detect.
* ICMP/L4 port scans: similar to the above.

4. In the unlikely case that hosts were to run with /proc/sys/net/ipv4/conf/*/arp_accept=1 (unsafe, and disabled by default), poisoning with the broadcast MAC could be used to create significantly more broadcast traffic (low-volume amplification attack).

An attacker could send M fake gARP with a number of IP addresses, where M is /proc/sys/net/ipv4/neigh/*/gc_thresh3 (1024 by default). This would result in M x R ARPs, where R is the number of hosts in L2 segment with arp_accept=1, and likely other (real) ARP replies coming from the attacked host. This starts to get really relevant when R > 512, which is possible in large LANs but not very common.

Note2:

However, broadcast ARP poisoning might be subtle and difficult to spot. These ARP packets appear on the surface as regular broadcast ARP requests (unless ARP hdr is inspected), traffic continues to flow uninterrupted (unless broadcast rate-limit in switches kick-in) and, the next refresh ARP reply (from the GW) or any (valid) gARP from the GW, will restore the original MAC in the ARP table, making the traffic flow normally again.

---
 net/ipv4/arp.c | 8 ++++++++
 1 file changed, 8 insertions(+)
net/ipv4/arp.c +8 -0
index c8c3e1713c0e..7dbb3fd5cc8a 100644
@@ -800,6 +800,14 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 		goto out_free_skb;
 
 /*
+ *	For Ethernet devices, Multicast/Broadcast and zero MAC addresses should
+ *	never be announced and accepted as sender HW address (RFC1812, 3.3.2).
+ *	Prevents Broadcast/Mcast ARP poisoning attack.
+ */
+	if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(sha))
+		goto out_free_skb;
+
+ /*
  *     Special case: We must set Frame Relay source Q.922 address
  */
 	if (dev_type == ARPHRD_DLCI)
Signature · 1 line
2.47.3
#2 lore raw

PATCH v2 2/4 selftests/net: add no ARP b/mcast,null poison test

In reply to Marc Suñé

Add a selftest to test that ARP bcast/mcast/null poisioning checks are never bypassed.

---
 tools/testing/selftests/net/.gitignore        |   1 +
 tools/testing/selftests/net/Makefile          |   2 +
 .../net/arp_no_invalid_sha_poision.sh         | 176 ++++++++++++++++++
 tools/testing/selftests/net/arp_send.c        | 138 ++++++++++++++
 4 files changed, 317 insertions(+)
 create mode 100755 tools/testing/selftests/net/arp_no_invalid_sha_poision.sh
 create mode 100644 tools/testing/selftests/net/arp_send.c
tools/testing/selftests/net/.gitignore +1 -0
index 6930fe926c58..fd08ceeab07c 100644
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+arp_send
 bind_bhash
 bind_timewait
 bind_wildcard
tools/testing/selftests/net/Makefile +2 -0
index 45c4ea381bc3..a765f1800752 100644
@@ -9,6 +9,7 @@ CFLAGS += -I../
 TEST_PROGS := \
 	altnames.sh \
 	amt.sh \
+	arp_no_invalid_sha_poision.sh \
 	arp_ndisc_evict_nocarrier.sh \
 	arp_ndisc_untracked_subnets.sh \
 	bareudp.sh \
@@ -164,6 +165,7 @@ TEST_GEN_FILES := \
 # end of TEST_GEN_FILES
 
 TEST_GEN_PROGS := \
+	arp_send \
 	bind_timewait \
 	bind_wildcard \
 	epoll_busy_poll \
tools/testing/selftests/net/arp_no_invalid_sha_poision.sh new file +176 -0

176 lines not on this page · raw message

tools/testing/selftests/net/arp_send.c new file +138 -0

138 lines not on this page · raw message

Signature · 1 line
2.47.3
maintainer
#3 lore raw

Re: [PATCH net v2 2/4] selftests/net: add no ARP b/mcast,null poison test

tools/testing/selftests/net/Makefile CFLAGS += -I../ · line 12

Quoted 12 lines · On Tue, 27 Jan 2026 00:53:03 +0100 Marc Suñé wrote:

Add a selftest to test that ARP bcast/mcast/null poisioning checks are never bypassed.

tools/testing/selftests/net/Makefile +1 -0
index 45c4ea381bc3..a765f1800752 100644
@@ -9,6 +9,7 @@ CFLAGS += -I../
 TEST_PROGS := \
 	altnames.sh \
 	amt.sh \
+	arp_no_invalid_sha_poision.sh \

alphabetical sort pls

tools/testing/selftests/net/Makefile CFLAGS += -I../

Quoted 13 lines
tools/testing/selftests/net/Makefile +9 -0
 	arp_ndisc_evict_nocarrier.sh \
 	arp_ndisc_untracked_subnets.sh \
 	bareudp.sh \
 
+readonly V4_ADDR0="10.0.10.1"
+readonly V4_ADDR1="10.0.10.2"
+readonly BCAST_MAC="ff:ff:ff:ff:ff:ff"
+readonly MCAST_MAC="01:00:5e:00:00:00"
+readonly NULL_MAC="00:00:00:00:00:00"
+readonly VALID_MAC="02:01:02:03:04:05"
+readonly ARP_REQ=1
+readonly ARP_REPLY=2
+nsid=100

unused? (please run shellcheck)

tools/testing/selftests/net/arp_send.c

Quoted 6 lines
tools/testing/selftests/net/Makefile +3 -0
+ret=0
+veth0_ifindex=0
+veth1_mac=
tools/testing/selftests/net/arp_send.c new file +0 -0
new file mode 100644

Could you check if mausezahn from netsniff-ng can send these packets already? We already depend on mausezahn for other tests.

Similar comments on patch 4, I'm not gonna repeat.

author
#4 lore raw

Re: [PATCH net v2 2/4] selftests/net: add no ARP b/mcast,null poison test

Missatge de Jakub Kicinski <[email protected]> del dia dj., 29 de gen. 2026 a les 5:27:

Quoted 21 lines · On Tue, 27 Jan 2026 00:53:03 +0100 Marc Suñé wrote:

tools/testing/selftests/net/Makefile CFLAGS += -I../ · line 12

Quoted 12 lines

Add a selftest to test that ARP bcast/mcast/null poisioning checks are never bypassed.

tools/testing/selftests/net/Makefile +1 -0
index 45c4ea381bc3..a765f1800752 100644
@@ -9,6 +9,7 @@ CFLAGS += -I../
 TEST_PROGS := \
      altnames.sh \
      amt.sh \
+     arp_no_invalid_sha_poision.sh \

alphabetical sort pls

Quoted 3 lines
tools/testing/selftests/net/Makefile +0 -0
      arp_ndisc_evict_nocarrier.sh \
      arp_ndisc_untracked_subnets.sh \
      bareudp.sh \
Quoted 11 lines

tools/testing/selftests/net/Makefile

Quoted 9 lines
tools/testing/selftests/net/Makefile +9 -0
+readonly V4_ADDR0="10.0.10.1"
+readonly V4_ADDR1="10.0.10.2"
+readonly BCAST_MAC="ff:ff:ff:ff:ff:ff"
+readonly MCAST_MAC="01:00:5e:00:00:00"
+readonly NULL_MAC="00:00:00:00:00:00"
+readonly VALID_MAC="02:01:02:03:04:05"
+readonly ARP_REQ=1
+readonly ARP_REPLY=2
+nsid=100

unused? (please run shellcheck)

Errors fixed in v3.

Quoted 5 lines
Quoted 4 lines
tools/testing/selftests/net/Makefile +3 -0
+ret=0
+veth0_ifindex=0
+veth1_mac=
Quoted 7 lines

tools/testing/selftests/net/arp_send.c

Quoted 2 lines
tools/testing/selftests/net/arp_send.c new file +0 -0
new file mode 100644

Could you check if mausezahn from netsniff-ng can send these packets already? We already depend on mausezahn for other tests.

Similar comments on patch 4, I'm not gonna repeat.

I can do that for ARP, but not for NDP apparently. Only basic ICMPv6 echo req/reply is supported. For NDP (ICMPv6), it needs to be specified using -P (hex). Kind of ugly...

In RFC v1 I proposed to use a scapy
(https://lore.kernel.org/netdev/3cfd28edb2c2b055e74b975623a3d38ade0237f1.1766349632.git.marcdevel@gmail.com/),
which is substantially smaller than arp_send/ndisc_send.c. I dropped it based on the v1 review I got. I see scapy is used in bpf/ and tc-testing/ self-tests.

What's your preference?

a) use mausezahn only for ARP, use ndisc_send.c for NDP
b) use only .c progs for consistency
c) recover the scapy patch and squash it in patches 2/4

Thanks

maintainer
#5 lore raw

Re: [PATCH net v2 2/4] selftests/net: add no ARP b/mcast,null poison test

Quoted 18 lines · On Thu, 29 Jan 2026 19:28:22 +0100 Marc Sune wrote:
Quoted 7 lines

tools/testing/selftests/net/arp_send.c

Quoted 2 lines
tools/testing/selftests/net/arp_send.c new file +0 -0
new file mode 100644  

Could you check if mausezahn from netsniff-ng can send these packets already? We already depend on mausezahn for other tests.

Similar comments on patch 4, I'm not gonna repeat.

I can do that for ARP, but not for NDP apparently. Only basic ICMPv6 echo req/reply is supported. For NDP (ICMPv6), it needs to be specified using -P (hex). Kind of ugly...

In RFC v1 I proposed to use a scapy
(https://lore.kernel.org/netdev/3cfd28edb2c2b055e74b975623a3d38ade0237f1.1766349632.git.marcdevel@gmail.com/),
which is substantially smaller than arp_send/ndisc_send.c. I dropped it based on the v1 review I got. I see scapy is used in bpf/ and tc-testing/ self-tests.

Quoted 5 lines

What's your preference?

a) use mausezahn only for ARP, use ndisc_send.c for NDP
b) use only .c progs for consistency
c) recover the scapy patch and squash it in patches 2/4

Hm, I think there's another tool we use for ndisc - ndisc6 Could you try if that works? if not maybe grep around if any other tool is already used by the tests, we have a bunch of ndisc and igmp tests, maybe one of those will do.

If not, my first choice would be to update ndisc6 or mausezahn to teach them. Second choice a local C code just ndisc_send.c scapy as the last choice.

#6 lore raw

PATCH v2 3/4 neigh: discard invalid lladdr (b/mcast poison)

In reply to Marc Suñé

Prior to this commit, the NDP implementation accepted NDP NS/NA with the broadcast, multicast and null addresses as src/dst lladdr, and updated the neighbour cache for that host.

Broadcast, multicast and null MAC addresses shall never be associated with a unicast or a multicast IPv6 address (see RFC1812, section 3.3.2).

NDP poisioning with a broadcast MAC and certain multicast MAC addresses, especially when poisoning a Gateway IP, have some undesired implications compared to an NDP poisioning with a regular MAC (see ARP bcast poison commit for more details).

Since these MACs should never be announced, discard/drop NDP with lladdr={bcast, null}, which prevents the broadcast/multicast NDP poisoning vector.

---
 net/ipv6/ndisc.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
net/ipv6/ndisc.c +16 -0
index f6a5d8c73af9..34202a816a4f 100644
@@ -830,6 +830,14 @@ static enum skb_drop_reason ndisc_recv_ns(struct sk_buff *skb)
 			return reason;
 		}
 
+		/*
+		 * Broadcast/Multicast and zero MAC addresses should
+		 * never be announced and accepted as llsrc address (prevent
+		 * NDP B/MCAST MAC poisoning attack).
+		 */
+		if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(lladdr))
+			return reason;
+
 		/* RFC2461 7.1.1:
 		 *	If the IP source address is the unspecified address,
 		 *	there MUST NOT be source link-layer address option
@@ -1033,6 +1041,14 @@ static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb)
 			net_dbg_ratelimited("NA: invalid link-layer address length\n");
 			return reason;
 		}
+
+		/*
+		 * Broadcast/Multicast and zero MAC addresses should
+		 * never be announced and accepted as llsrc address (prevent
+		 * NDP B/MCAST MAC poisoning attack).
+		 */
+		if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(lladdr))
+			return reason;
 	}
 	ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
 	if (ifp) {
Signature · 1 line
2.47.3
maintainer
#7 lore raw

Re: [net,v2,3/4] neigh: discard invalid lladdr (b/mcast poison)

This is an AI-generated review of your patch. The human sending this email has considered the AI review valid, or at least plausible.

For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
neigh: discard invalid lladdr (b/mcast poison)

This commit adds validation to reject NDP Neighbor Solicitation and Neighbor Advertisement messages that contain broadcast, multicast, or null MAC addresses in the link-layer address options.

Quoted 4 lines
net/ipv6/ndisc.c +0 -0
index f6a5d8c73af9..34202a816a4f 100644

[ ... ]

net/ipv6/ndisc.c static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb) · line 1047

Quoted 8 lines
net/ipv6/ndisc.c +4 -0
@@ -1033,6 +1041,14 @@ static enum skb_drop_reason ndisc_recv_na(struct sk_buff *skb)
 			net_dbg_ratelimited("NA: invalid link-layer address length\n");
 			return reason;
 		}
+
+		/*
+		 * Broadcast/Multicast and zero MAC addresses should
+		 * never be announced and accepted as llsrc address (prevent
                                                  ^^^^^

In ndisc_recv_na(), should this comment say "lltgt" (target link-layer address) instead of "llsrc"?

Looking at the code above this block, the lladdr variable is assigned from ndopts.nd_opts_tgt_lladdr (Target Link-Layer Address option per RFC 4861), not nd_opts_src_lladdr (Source Link-Layer Address option). The comment appears to have been copy-pasted from the NS handler without updating the terminology.

Quoted 5 lines
net/ipv6/ndisc.c +4 -0
+		 * NDP B/MCAST MAC poisoning attack).
+		 */
+		if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(lladdr))
+			return reason;
 	}
Signature · 1 line
pw-bot: cr
#8 lore raw

PATCH v2 4/4 selftests/net: add no NDP b/mcast,null poison test

In reply to Marc Suñé

Add a selftest to test that NDP bcast/mcast/null poisioning checks are never bypassed.

---
 tools/testing/selftests/net/.gitignore        |   1 +
 tools/testing/selftests/net/Makefile          |   3 +-
 .../net/arp_ndisc_no_invalid_sha_poison.sh    | 368 ++++++++++++++++++
 .../net/arp_no_invalid_sha_poision.sh         | 176 ---------
 tools/testing/selftests/net/ndisc_send.c      | 198 ++++++++++
 5 files changed, 569 insertions(+), 177 deletions(-)
 create mode 100755 tools/testing/selftests/net/arp_ndisc_no_invalid_sha_poison.sh
 delete mode 100755 tools/testing/selftests/net/arp_no_invalid_sha_poision.sh
 create mode 100644 tools/testing/selftests/net/ndisc_send.c
tools/testing/selftests/net/.gitignore +1 -0
index fd08ceeab07c..5a82300a22a9 100644
@@ -18,6 +18,7 @@ ipv6_flowlabel_mgr
 ipv6_fragmentation
 log.txt
 msg_zerocopy
+ndisc_send
 netlink-dumps
 nettest
 proc_net_pktgen
tools/testing/selftests/net/Makefile +2 -1
index a765f1800752..afc24d419135 100644
@@ -9,7 +9,7 @@ CFLAGS += -I../
 TEST_PROGS := \
 	altnames.sh \
 	amt.sh \
-	arp_no_invalid_sha_poision.sh \
+	arp_ndisc_no_invalid_sha_poison.sh \
 	arp_ndisc_evict_nocarrier.sh \
 	arp_ndisc_untracked_subnets.sh \
 	bareudp.sh \
@@ -170,6 +170,7 @@ TEST_GEN_PROGS := \
 	bind_wildcard \
 	epoll_busy_poll \
 	ipv6_fragmentation \
+	ndisc_send \
 	proc_net_pktgen \
 	reuseaddr_conflict \
 	reuseport_bpf \
tools/testing/selftests/net/arp_ndisc_no_invalid_sha_poison.sh new file +368 -0

368 lines not on this page · raw message

tools/testing/selftests/net/arp_no_invalid_sha_poision.sh deleted +0 -176

176 lines not on this page · raw message

tools/testing/selftests/net/ndisc_send.c new file +198 -0

198 lines not on this page · raw message

Signature · 1 line
2.47.3
maintainer
#9 lore raw
In reply to Marc Suñé
Quoted 18 lines · On Tue, 27 Jan 2026 00:53:01 +0100 Marc Suñé wrote:

The current ARP and NDP implementations accept announcements with multicast (broadcast incl.) and null MAC addresses as Sender HW Address (SHA) in ARP or src/target lladdr in NDP, and updates the cache for that neighbour.

Multicast (incl. broadcast) and null MAC addresses shall never be associated with a unicast or a multicast IPv4/6 address (see RFC1812, section 3.3.2).

ARP/NDP poisioning with a broadcast and certain multicast MAC addresses, especially when poisoning a Gateway IP, have some undesired implications compared to an ARP/NDP poisioning with a regular MAC (see commit message in patch 1 for more information).

Worth mentioning that if an attacker is able to ARP/NDP poison in a L2 segment, that in itself is probably a bigger security threat (Man-in-middle etc., see Note2 in patch 1)

Quoted 7 lines

Since these MACs should never be announced, this patch series discards/drops these packets, which prevents broadcast and multicast ARP/NDP poisoning vectors.

This patchset only modifies the behaviour of the neighbouring subsystem when processing network packets. Static entries can still be added with mcast/bcast/null MACs.

Not a very strong opinion but my intuition would be to target this to net-next. I read it as an improvement to RFC compliance more than a solution.

author
#10 lore raw

Missatge de Jakub Kicinski <[email protected]> del dia dj., 29 de gen. 2026 a les 5:24:

Quoted 24 lines · On Tue, 27 Jan 2026 00:53:01 +0100 Marc Suñé wrote:
Quoted 22 lines

The current ARP and NDP implementations accept announcements with multicast (broadcast incl.) and null MAC addresses as Sender HW Address (SHA) in ARP or src/target lladdr in NDP, and updates the cache for that neighbour.

Multicast (incl. broadcast) and null MAC addresses shall never be associated with a unicast or a multicast IPv4/6 address (see RFC1812, section 3.3.2).

ARP/NDP poisioning with a broadcast and certain multicast MAC addresses, especially when poisoning a Gateway IP, have some undesired implications compared to an ARP/NDP poisioning with a regular MAC (see commit message in patch 1 for more information).

Worth mentioning that if an attacker is able to ARP/NDP poison in a L2 segment, that in itself is probably a bigger security threat (Man-in-middle etc., see Note2 in patch 1)

Since these MACs should never be announced, this patch series discards/drops these packets, which prevents broadcast and multicast ARP/NDP poisoning vectors.

Quoted 7 lines
Quoted 3 lines

This patchset only modifies the behaviour of the neighbouring subsystem when processing network packets. Static entries can still be added with mcast/bcast/null MACs.

Not a very strong opinion but my intuition would be to target this to net-next. I read it as an improvement to RFC compliance more than a solution.

The main driver for this patchset is to remove the attack vectors described in Note 1 and Note 2 of Patch 1/4 (in the cover letter of RFC v1), not so much being RFC compliant. They are arguably low risk, but I would think there is value in having them on all stable versions. I originally targeted net and didn't add Fixes as I think these sanity checks have never been there.

Let me know if you prefer v3 to target net-next instead.

maintainer
#11 lore raw
Quoted 8 lines · On Thu, 29 Jan 2026 19:39:59 +0100 Marc Sune wrote:
Quoted 7 lines
Quoted 3 lines

This patchset only modifies the behaviour of the neighbouring subsystem when processing network packets. Static entries can still be added with mcast/bcast/null MACs.

Not a very strong opinion but my intuition would be to target this to net-next. I read it as an improvement to RFC compliance more than a solution.

Quoted 8 lines

The main driver for this patchset is to remove the attack vectors described in Note 1 and Note 2 of Patch 1/4 (in the cover letter of RFC v1), not so much being RFC compliant. They are arguably low risk, but I would think there is value in having them on all stable versions. I originally targeted net and didn't add Fixes as I think these sanity checks have never been there.

Let me know if you prefer v3 to target net-next instead.

Nobody else chiming in to disagree with me so if it's your word against mine I do prefer net-next :)

No matter what we do an unsecured L2 is not defensible by making tweaks at the endpoint in the IP protocol stack.