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) {
|
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
|
||||||
wa.count++;
|
wa.count++;
|
||||||
if (match_iface(&attrs, ifp)) {
|
if (match_iface(&attrs, ifp)) {
|
||||||
if (offset < base_count) {
|
if (offset >= base_count) {
|
||||||
if (!if_try_ref(ifp))
|
/* Too many matches, need to reallocate */
|
||||||
continue;
|
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;
|
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);
|
NET_EPOCH_EXIT(et);
|
||||||
|
@ -242,6 +242,67 @@ def test_delete_iface(self):
|
|||||||
assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
|
assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
|
||||||
assert rx_msg.error_code == errno.ENODEV
|
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},
|
# * {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