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
This commit is contained in:
parent
f52ca3dfd5
commit
86fd0bdba5
@ -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;
|
||||
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;
|
||||
}
|
||||
|
||||
if (if_try_ref(ifp))
|
||||
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;
|
||||
}
|
||||
memcpy(new_array, match_array, sz);
|
||||
free(match_array, M_TEMP);
|
||||
match_array = new_array;
|
||||
}
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
|
@ -242,6 +242,67 @@ def test_delete_iface(self):
|
||||
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},
|
||||
|
Loading…
Reference in New Issue
Block a user