The branch main has been updated by kp:

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

commit 7cef9d196ce999a61ec864961a3849c9159a96a8
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-02-10 09:44:06 +0000
Commit:     Kristof Provost <k...@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 <mi...@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);

Reply via email to