git: 7cef9d196ce9 - main - pfctl: cache name/index mappings
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 13 Feb 2025 12:39:00 UTC
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);