netlink: use newly-added if_foreach_sleep() to iterate over the interface list.
Summary: MFC after: 2 weeks Subscribers: imp, glebius Differential Revision: https://reviews.freebsd.org/D38907
This commit is contained in:
+14
-42
@@ -360,8 +360,10 @@ static const struct nlattr_parser nla_p_if[] = {
|
||||
NL_DECLARE_STRICT_PARSER(ifmsg_parser, struct ifinfomsg, check_ifmsg, nlf_p_if, nla_p_if);
|
||||
|
||||
static bool
|
||||
match_iface(struct nl_parsed_link *attrs, struct ifnet *ifp)
|
||||
match_iface(struct ifnet *ifp, void *_arg)
|
||||
{
|
||||
struct nl_parsed_link *attrs = (struct nl_parsed_link *)_arg;
|
||||
|
||||
if (attrs->ifi_index != 0 && attrs->ifi_index != ifp->if_index)
|
||||
return (false);
|
||||
if (attrs->ifi_type != 0 && attrs->ifi_index != ifp->if_type)
|
||||
@@ -373,6 +375,15 @@ match_iface(struct nl_parsed_link *attrs, struct ifnet *ifp)
|
||||
return (true);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_cb(struct ifnet *ifp, void *_arg)
|
||||
{
|
||||
struct netlink_walkargs *wa = (struct netlink_walkargs *)_arg;
|
||||
if (!dump_iface(wa->nw, ifp, &wa->hdr, 0))
|
||||
return (ENOMEM);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* {nlmsg_len=52, nlmsg_type=RTM_GETLINK, nlmsg_flags=NLM_F_REQUEST, nlmsg_seq=1662842818, nlmsg_pid=0},
|
||||
* {ifi_family=AF_PACKET, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0},
|
||||
@@ -417,7 +428,7 @@ rtnl_handle_getlink(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *n
|
||||
}
|
||||
|
||||
if (ifp != NULL) {
|
||||
if (match_iface(&attrs, ifp)) {
|
||||
if (match_iface(ifp, &attrs)) {
|
||||
if (!dump_iface(wa.nw, ifp, &wa.hdr, 0))
|
||||
error = ENOMEM;
|
||||
} else
|
||||
@@ -438,46 +449,7 @@ rtnl_handle_getlink(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *n
|
||||
*/
|
||||
|
||||
NL_LOG(LOG_DEBUG2, "Start dump");
|
||||
|
||||
struct ifnet **match_array = NULL;
|
||||
int offset = 0, base_count = 0;
|
||||
|
||||
NLP_LOG(LOG_DEBUG3, nlp, "MATCHING: index=%u type=%d name=%s",
|
||||
attrs.ifi_index, attrs.ifi_type, attrs.ifla_ifname);
|
||||
NET_EPOCH_ENTER(et);
|
||||
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
|
||||
wa.count++;
|
||||
if (match_iface(&attrs, ifp)) {
|
||||
if (offset >= base_count) {
|
||||
/* Too many matches, need to reallocate */
|
||||
struct ifnet **new_array;
|
||||
/* Start with 128 bytes, do 2x increase on each realloc */
|
||||
base_count = (base_count != 0) ? base_count * 2 : 16;
|
||||
new_array = malloc(base_count * sizeof(void *), M_TEMP, M_NOWAIT);
|
||||
if (new_array == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
memcpy(new_array, match_array, offset * sizeof(void *));
|
||||
free(match_array, M_TEMP);
|
||||
match_array = new_array;
|
||||
}
|
||||
|
||||
if (if_try_ref(ifp))
|
||||
match_array[offset++] = ifp;
|
||||
}
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
|
||||
NL_LOG(LOG_DEBUG2, "Matched %d interface(s), dumping", offset);
|
||||
for (int i = 0; error == 0 && i < offset; i++) {
|
||||
if (!dump_iface(wa.nw, match_array[i], &wa.hdr, 0))
|
||||
error = ENOMEM;
|
||||
}
|
||||
for (int i = 0; i < offset; i++)
|
||||
if_rele(match_array[i]);
|
||||
free(match_array, M_TEMP);
|
||||
|
||||
if_foreach_sleep(match_iface, &attrs, dump_cb, &wa);
|
||||
NL_LOG(LOG_DEBUG2, "End dump, iterated %d dumped %d", wa.count, wa.dumped);
|
||||
|
||||
if (!nlmsg_end_dump(wa.nw, error, &wa.hdr)) {
|
||||
|
||||
Reference in New Issue
Block a user