Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Feb 2025 12:39:00 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 7cef9d196ce9 - main - pfctl: cache name/index mappings
Message-ID:  <202502131239.51DCd0jv075443@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=7cef9d196ce999a61ec864961a3849c9159a96a8

commit 7cef9d196ce999a61ec864961a3849c9159a96a8
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-02-10 09:44:06 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-02-13 12:38:43 +0000

    pfctl: cache name/index mappings
    
    Provide local implementations of if_nametoindex(3) and if_indextoname(3)
    that make use of the cache of addresses populated by the ifa_load on
    startup to save the trouble of calling expensive getaddrinfo(3) up to
    four times per rule. Performance wise this change provides a speed up
    factor of 20 with a 11k line ruleset on a machine with 150 VLANs and 250
    IP addresses (20 seconds down to 1 in this case).
    
    "wow!" henning, ok benno, florian
    
    Obtained from:  OpenBSD, mikeb <mikeb@openbsd.org>, 918dda8655
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sbin/pfctl/parse.y        |  8 ++++----
 sbin/pfctl/pfctl_parser.c | 31 +++++++++++++++++++++++++++++++
 sbin/pfctl/pfctl_parser.h |  2 ++
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index efbd7cac18e8..40d116fe1a50 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -6216,9 +6216,9 @@ expand_rule(struct pfctl_rule *r,
 		    (src_host->ifindex && dst_host->ifindex &&
 		    src_host->ifindex != dst_host->ifindex) ||
 		    (src_host->ifindex && *interface->ifname &&
-		    src_host->ifindex != if_nametoindex(interface->ifname)) ||
+		    src_host->ifindex != ifa_nametoindex(interface->ifname)) ||
 		    (dst_host->ifindex && *interface->ifname &&
-		    dst_host->ifindex != if_nametoindex(interface->ifname)))
+		    dst_host->ifindex != ifa_nametoindex(interface->ifname)))
 			continue;
 		if (!r->af && src_host->af)
 			r->af = src_host->af;
@@ -6228,9 +6228,9 @@ expand_rule(struct pfctl_rule *r,
 		if (*interface->ifname)
 			strlcpy(r->ifname, interface->ifname,
 			    sizeof(r->ifname));
-		else if (if_indextoname(src_host->ifindex, ifname))
+		else if (ifa_indextoname(src_host->ifindex, ifname))
 			strlcpy(r->ifname, ifname, sizeof(r->ifname));
-		else if (if_indextoname(dst_host->ifindex, ifname))
+		else if (ifa_indextoname(dst_host->ifindex, ifname))
 			strlcpy(r->ifname, ifname, sizeof(r->ifname));
 		else
 			memset(r->ifname, '\0', sizeof(r->ifname));
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index f567cc78dd23..d1e0b4e99940 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -38,6 +38,7 @@
 #include <sys/socket.h>
 #include <sys/param.h>
 #include <sys/proc.h>
+#include <net/if_dl.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -1518,6 +1519,8 @@ ifa_load(void)
 			    ifa->ifa_addr)->sin6_scope_id;
 		} else if (n->af == AF_LINK) {
 			ifa_add_groups_to_map(ifa->ifa_name);
+			n->ifindex = ((struct sockaddr_dl *)
+			    ifa->ifa_addr)->sdl_index;
 		}
 		if ((n->ifname = strdup(ifa->ifa_name)) == NULL)
 			err(1, "ifa_load: strdup");
@@ -1584,6 +1587,34 @@ is_a_group(char *name)
 	return (*(int *)ret_item->data);
 }
 
+unsigned int
+ifa_nametoindex(const char *ifa_name)
+{
+	struct node_host	*p;
+
+	for (p = iftab; p; p = p->next) {
+		if (p->af == AF_LINK && strcmp(p->ifname, ifa_name) == 0)
+			return (p->ifindex);
+	}
+	errno = ENXIO;
+	return (0);
+}
+
+char *
+ifa_indextoname(unsigned int ifindex, char *ifa_name)
+{
+	struct node_host	*p;
+
+	for (p = iftab; p; p = p->next) {
+		if (p->af == AF_LINK && ifindex == p->ifindex) {
+			strlcpy(ifa_name, p->ifname, IFNAMSIZ);
+			return (ifa_name);
+		}
+	}
+	errno = ENXIO;
+	return (NULL);
+}
+
 struct node_host *
 ifa_exists(char *ifa_name)
 {
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 2b0766dfd99f..e916f5e7c100 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -363,6 +363,8 @@ int			 check_netmask(struct node_host *, sa_family_t);
 int			 unmask(struct pf_addr *, sa_family_t);
 struct node_host	*gen_dynnode(struct node_host *, sa_family_t);
 void			 ifa_load(void);
+unsigned int		 ifa_nametoindex(const char *);
+char			*ifa_indextoname(unsigned int, char *);
 int			 get_query_socket(void);
 struct node_host	*ifa_exists(char *);
 struct node_host	*ifa_grouplookup(char *ifa_name, int flags);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502131239.51DCd0jv075443>