git: 86fd0bdba540 - main - netlink: fix interface dump.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 16 Feb 2023 13:39:58 UTC
The branch main has been updated by melifaro:
URL: https://cgit.FreeBSD.org/src/commit/?id=86fd0bdba540132ae298457e160b651f61d1db6b
commit 86fd0bdba540132ae298457e160b651f61d1db6b
Author: Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-02-16 13:17:58 +0000
Commit: Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-02-16 13:20:45 +0000
netlink: fix interface dump.
The current code missed interface addition when reallocating
temporary buffer.
Tweak the code to perform the reallocation first and add
interface afterwards unconditionally.
Reported by: Marek Zarychta <zarychtam@plan-b.pwste.edu.pl>
MFC after: 3 days
---
sys/netlink/route/iface.c | 33 ++++++++++---------
tests/sys/netlink/test_rtnl_iface.py | 61 ++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 17 deletions(-)
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index 9cd7e6e80f3c..0eafacff4775 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -449,24 +449,23 @@ rtnl_handle_getlink(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *n
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
wa.count++;
if (match_iface(&attrs, ifp)) {
- if (offset < base_count) {
- if (!if_try_ref(ifp))
- continue;
- match_array[offset++] = ifp;
- continue;
- }
- /* Too many matches, need to reallocate */
- struct ifnet **new_array;
- int sz = base_count * sizeof(void *);
- base_count *= 2;
- new_array = malloc(sz * 2, M_TEMP, M_NOWAIT);
- if (new_array == NULL) {
- error = ENOMEM;
- break;
+ if (offset >= base_count) {
+ /* Too many matches, need to reallocate */
+ struct ifnet **new_array;
+ int sz = base_count * sizeof(void *);
+ base_count *= 2;
+ new_array = malloc(sz * 2, M_TEMP, M_NOWAIT);
+ if (new_array == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ memcpy(new_array, match_array, sz);
+ free(match_array, M_TEMP);
+ match_array = new_array;
}
- memcpy(new_array, match_array, sz);
- free(match_array, M_TEMP);
- match_array = new_array;
+
+ if (if_try_ref(ifp))
+ match_array[offset++] = ifp;
}
}
NET_EPOCH_EXIT(et);
diff --git a/tests/sys/netlink/test_rtnl_iface.py b/tests/sys/netlink/test_rtnl_iface.py
index ecc932c6213e..cbe5aed8b8ae 100644
--- a/tests/sys/netlink/test_rtnl_iface.py
+++ b/tests/sys/netlink/test_rtnl_iface.py
@@ -242,6 +242,67 @@ class TestRtNlIface(NetlinkTestTemplate, SingleVnetTestTemplate):
assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
assert rx_msg.error_code == errno.ENODEV
+ @pytest.mark.require_user("root")
+ def test_dump_ifaces_many(self):
+ """Tests if interface dummp is not missing interfaces"""
+
+ ifmap = {}
+ for ifname in (self.vnet.iface_alias_map["if1"].name, "lo0"):
+ ifindex = socket.if_nametoindex(ifname)
+ ifmap[ifindex] = ifname
+
+ for i in range(40):
+ ifname = "lo{}".format(i + 1)
+ flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
+ msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
+ msg.nl_hdr.nlmsg_flags = (
+ flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
+ )
+ msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, ifname))
+ msg.add_nla(
+ NlAttrNested(
+ IflattrType.IFLA_LINKINFO,
+ [
+ NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
+ ],
+ )
+ )
+
+ rx_msg = self.get_reply(msg)
+ assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
+ nla_list, _ = rx_msg.parse_attrs(bytes(rx_msg.cookie)[4:], rtnl_ifla_attrs)
+ nla_map = {n.nla_type: n for n in nla_list}
+ assert nla_map[IflattrType.IFLA_IFNAME.value].text == ifname
+ ifindex = nla_map[IflattrType.IFLA_NEW_IFINDEX.value].u32
+ assert ifindex > 0
+ assert ifindex not in ifmap
+ ifmap[ifindex] = ifname
+
+ # Dump all interfaces and check if the output matches ifmap
+ kernel_ifmap = {}
+ msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_GETLINK.value)
+ msg.nl_hdr.nlmsg_flags = (
+ NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
+ )
+ self.write_message(msg)
+ while True:
+ rx_msg = self.read_message()
+ if msg.nl_hdr.nlmsg_seq != rx_msg.nl_hdr.nlmsg_seq:
+ raise ValueError(
+ "unexpected seq {}".format(rx_msg.nl_hdr.nlmsg_seq)
+ )
+ if rx_msg.is_type(NlMsgType.NLMSG_ERROR):
+ raise ValueError("unexpected message {}".format(rx_msg))
+ if rx_msg.is_type(NlMsgType.NLMSG_DONE):
+ break
+ if not rx_msg.is_type(NlRtMsgType.RTM_NEWLINK):
+ raise ValueError("unexpected message {}".format(rx_msg))
+
+ ifindex = rx_msg.base_hdr.ifi_index
+ assert ifindex == rx_msg.base_hdr.ifi_index
+ kernel_ifmap[ifindex] = rx_msg.get_nla(IflattrType.IFLA_IFNAME).text
+ assert kernel_ifmap == ifmap
+
#
# *
# * {len=76, type=RTM_NEWLINK, flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE, seq=1662892737, pid=0},