The branch main has been updated by melifaro:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=055776c84a41bb88c6ccd67615ea172864f6804c

commit 055776c84a41bb88c6ccd67615ea172864f6804c
Author:     Alexander V. Chernikov <[email protected]>
AuthorDate: 2023-03-04 15:15:56 +0000
Commit:     Alexander V. Chernikov <[email protected]>
CommitDate: 2023-03-06 15:08:08 +0000

    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
---
 sys/netlink/route/iface.c | 56 ++++++++++++-----------------------------------
 1 file changed, 14 insertions(+), 42 deletions(-)

diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index 116acd863ba9..6704acd1624f 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -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)) {

Reply via email to