git: 2eeb808361e4 - main - IfAPI: Add iterator to loop over all interfaces

From: Justin Hibbits <jhibbits_at_FreeBSD.org>
Date: Fri, 03 Feb 2023 14:45:17 UTC
The branch main has been updated by jhibbits:

URL: https://cgit.FreeBSD.org/src/commit/?id=2eeb808361e421f9a054820fa358e899383742de

commit 2eeb808361e421f9a054820fa358e899383742de
Author:     Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2023-02-01 21:28:11 +0000
Commit:     Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2023-02-03 14:38:02 +0000

    IfAPI: Add iterator to loop over all interfaces
    
    Summary:
    Sometimes it's useful to iterate over all interfaces in the current
    VNET, as the linuxulator does in several places.
    
    Unlike other iterators in the IfAPI this propagates any error received
    up to the caller, instead of returning a count.
    
    Sponsored by:   Juniper Networks, Inc.
    Reviewed by:    glebius, melifaro
    Differential Revision: https://reviews.freebsd.org/D38348
---
 sys/net/if.c     | 19 +++++++++++++++++++
 sys/net/if_var.h |  3 +++
 2 files changed, 22 insertions(+)

diff --git a/sys/net/if.c b/sys/net/if.c
index 951349b97ffb..8bb5ed0043e5 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -4466,6 +4466,25 @@ if_lladdr_count(if_t ifp)
 	return (count);
 }
 
+int
+if_foreach(if_foreach_cb_t cb, void *cb_arg)
+{
+	if_t ifp;
+	int error;
+
+	NET_EPOCH_ASSERT();
+	MPASS(cb);
+
+	error = 0;
+	CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+		error = cb(ifp, cb_arg);
+		if (error != 0)
+			break;
+	}
+
+	return (error);
+}
+
 u_int
 if_foreach_lladdr(if_t ifp, iflladdr_cb_t cb, void *cb_arg)
 {
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 4c3d4138f7ec..b4cdcf27253f 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -665,6 +665,9 @@ struct ifaddr * if_getifaddr(const if_t ifp);
 typedef u_int if_addr_cb_t(void *, struct ifaddr *, u_int);
 u_int if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg);
 
+typedef int (*if_foreach_cb_t)(if_t, void *);
+int	if_foreach(if_foreach_cb_t, void *);
+
 /* Functions */
 void if_setinitfn(if_t ifp, if_init_fn_t);
 void if_setinputfn(if_t ifp, if_input_fn_t);