git: 901a242269b2 - main - ifconfig: Add netlink support for reading ifgroup

From: Pouria Mousavizadeh Tehrani <pouria_at_FreeBSD.org>
Date: Thu, 27 Aug 2026 13:27:40 UTC
The branch main has been updated by pouria:

URL: https://cgit.FreeBSD.org/src/commit/?id=901a242269b208613a3e4fc02f78c52b7eeed828

commit 901a242269b208613a3e4fc02f78c52b7eeed828
Author:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
AuthorDate: 2026-08-27 13:01:11 +0000
Commit:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
CommitDate: 2026-08-27 13:04:55 +0000

    ifconfig: Add netlink support for reading ifgroup
    
    Read interface groups from IFLAF_GROUP netlink attribute.
    
    Reviewed by:    glebius
    Differential Revision:  https://reviews.freebsd.org/D58644
---
 sbin/ifconfig/ifconfig_netlink.c | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c
index c37108737379..38e3edb3e597 100644
--- a/sbin/ifconfig/ifconfig_netlink.c
+++ b/sbin/ifconfig/ifconfig_netlink.c
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdbool.h>
+#include <fnmatch.h>
 #include <err.h>
 #include <errno.h>
 #include <netdb.h>
@@ -252,6 +253,41 @@ prepare_ifaddrs(struct snl_state *ss, struct ifmap *ifmap)
 	}
 }
 
+/*
+ * Returns true if an interface should be listed because any its groups
+ * matches shell pattern "match" and none of groups matches pattern "nomatch".
+ * If any pattern is NULL, corresponding condition is skipped.
+ */
+static bool
+group_member_nl(if_link_t *link, const char *match, const char *nomatch)
+{
+	bool	matched, nomatched;
+
+	/* Sanity checks. */
+	if (match == NULL && nomatch == NULL)
+		return (true);
+	if (link == NULL)
+		return (false);
+
+	/* Perform matching. */
+	matched = false;
+	nomatched = true;
+	for (uint32_t i = 0; i < link->iflaf_groups.count; i++) {
+		char *ifgroup = link->iflaf_groups.items[i];
+
+		if (match && !matched)
+			matched = !fnmatch(match, ifgroup, 0);
+		if (nomatch && nomatched)
+			nomatched = fnmatch(nomatch, ifgroup, 0);
+	}
+
+	if (match && !nomatch)
+		return (matched);
+	if (!match && nomatch)
+		return (nomatched);
+	return (matched && nomatched);
+}
+
 static bool
 match_iface(struct ifconfig_args *args, struct iface *iface)
 {
@@ -263,7 +299,7 @@ match_iface(struct ifconfig_args *args, struct iface *iface)
 	if (!match_if_flags(args, link->ifi_flags))
 		return (false);
 
-	if (!group_member(link->ifla_ifname, args->matchgroup, args->nogroup))
+	if (!group_member_nl(link, args->matchgroup, args->nogroup))
 		return (false);
 
 	if (args->afp == NULL)