mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
Merge branch 'netlink-fixes-for-cross-namespace-nsid-reporting'
Ilya Maximets says: ==================== netlink: fixes for cross-namespace nsid reporting While working on some new features for OVS and OVN we discovered that self-referential NSIDs get unintentionally allocated in the system as well as unexpectedly reported for local events on all-nsid listeners. More details in the patches. They change user-visible behavior, but the current behavior is arguably a bug, as it makes it hard to use all-nsid sockets without a decent amount of extra unrelated work of tracking when new NSIDs are allocated for your local namespace. Tests are added to check the expected behavior and YNL is extended to support all-nsid sockets in the tests. ==================== Link: https://patch.msgid.link/20260520172317.175168-1-i.maximets@ovn.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
f54ea9ba95
|
|
@ -1482,9 +1482,14 @@ static void do_one_broadcast(struct sock *sk,
|
|||
p->skb2 = NULL;
|
||||
goto out;
|
||||
}
|
||||
NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
|
||||
if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
|
||||
NETLINK_CB(p->skb2).nsid_is_set = true;
|
||||
|
||||
NETLINK_CB(p->skb2).nsid_is_set = false;
|
||||
if (!net_eq(sock_net(sk), p->net)) {
|
||||
NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
|
||||
if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
|
||||
NETLINK_CB(p->skb2).nsid_is_set = true;
|
||||
}
|
||||
|
||||
val = netlink_broadcast_deliver(sk, p->skb2);
|
||||
if (val < 0) {
|
||||
netlink_overrun(sk);
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@
|
|||
|
||||
import time
|
||||
|
||||
from lib.py import ksft_run, ksft_exit, ksft_true
|
||||
from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_true
|
||||
from lib.py import ip
|
||||
from lib.py import NetNS, NetNSEnter
|
||||
from lib.py import RtnlFamily
|
||||
|
||||
|
||||
LINK_NETNSID = 100
|
||||
LINK_NETNSID2 = 200
|
||||
|
||||
|
||||
def test_event() -> None:
|
||||
|
|
@ -32,6 +33,57 @@ def test_event() -> None:
|
|||
"Received unexpected link notification")
|
||||
|
||||
|
||||
def test_event_all_nsid() -> None:
|
||||
"""NETLINK_LISTEN_ALL_NSID notifications: local events must not
|
||||
carry nsid even with a self-referential mapping. Remote events
|
||||
must carry the correct nsid."""
|
||||
|
||||
with NetNS() as ns1, NetNS() as ns2:
|
||||
net1, net2 = str(ns1), str(ns2)
|
||||
|
||||
with NetNSEnter(net1):
|
||||
rtnl = RtnlFamily()
|
||||
rtnl.ntf_listen_all_nsid()
|
||||
rtnl.ntf_subscribe("rtnlgrp-link")
|
||||
|
||||
# Case 1: no nsid assigned, local event, no nsid expected.
|
||||
ip("link add dummy-lo type dummy", ns=net1)
|
||||
|
||||
# Case 2: self-referential nsid, local event, still no nsid.
|
||||
ip(f"netns set {net1} {LINK_NETNSID}", ns=net1)
|
||||
ip("link add dummy-sr type dummy", ns=net1)
|
||||
|
||||
# Case 3: remote event, nsid present.
|
||||
ip(f"netns set {net2} {LINK_NETNSID2}", ns=net1)
|
||||
ip("link add dummy-re type dummy", ns=net2)
|
||||
|
||||
# Collect the three newlink events, ignoring unrelated noise.
|
||||
events = {}
|
||||
for msg in rtnl.poll_ntf(duration=1):
|
||||
if msg['name'] == 'getlink':
|
||||
ifname = msg['msg'].get('ifname')
|
||||
if ifname in ('dummy-lo', 'dummy-sr', 'dummy-re'):
|
||||
events[ifname] = msg
|
||||
if len(events) == 3:
|
||||
break
|
||||
|
||||
ksft_true('dummy-lo' in events, "missing local event")
|
||||
ksft_true(events['dummy-lo'].get('nsid') is None,
|
||||
"local event without nsid should not carry nsid")
|
||||
|
||||
ksft_true('dummy-sr' in events, "missing self-ref event")
|
||||
ksft_true(events['dummy-sr'].get('nsid') is None,
|
||||
"local event with self-ref nsid should not carry nsid")
|
||||
|
||||
ksft_true('dummy-re' in events, "missing remote event")
|
||||
ksft_eq(events['dummy-re'].get('nsid'), LINK_NETNSID2,
|
||||
"remote event should carry nsid")
|
||||
|
||||
ip("link del dummy-lo", ns=net1)
|
||||
ip("link del dummy-sr", ns=net1)
|
||||
ip("link del dummy-re", ns=net2)
|
||||
|
||||
|
||||
def validate_link_netns(netns, ifname, link_netnsid) -> bool:
|
||||
link_info = ip(f"-d link show dev {ifname}", ns=netns, json=True)
|
||||
if not link_info:
|
||||
|
|
@ -133,7 +185,12 @@ def test_peer_net() -> None:
|
|||
|
||||
|
||||
def main() -> None:
|
||||
ksft_run([test_event, test_link_net, test_peer_net])
|
||||
ksft_run([
|
||||
test_event,
|
||||
test_event_all_nsid,
|
||||
test_link_net,
|
||||
test_peer_net,
|
||||
])
|
||||
ksft_exit()
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user