git: ba94bf2880b8 - main - pf: extend use of skip steps for Ethernet rules

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 19 Jun 2023 10:04:52 UTC
The branch main has been updated by kp:

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

commit ba94bf2880b8f33593323db50ced99c8daf8bd05
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-06-15 15:12:11 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-06-19 08:18:30 +0000

    pf: extend use of skip steps for Ethernet rules
    
    Use the already populated PFE_SKIP_DST_ADDR and extend the skip
    infrastructure to also skip on IP source/destination addresses.
    
    This should make evaluating the rules slightly faster.
    
    Reported by:    R. Christian McDonald <rcm@rcm.sh>
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D40567
---
 sys/net/pfvar.h           |  6 +++++-
 sys/netpfil/pf/pf.c       | 10 ++++------
 sys/netpfil/pf/pf_ioctl.c |  6 ++++++
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index a658573cf6f1..4176dbd3e37d 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -697,7 +697,9 @@ struct pf_keth_rule {
 #define PFE_SKIP_PROTO		2
 #define PFE_SKIP_SRC_ADDR	3
 #define PFE_SKIP_DST_ADDR	4
-#define PFE_SKIP_COUNT		5
+#define PFE_SKIP_SRC_IP_ADDR	5
+#define PFE_SKIP_DST_IP_ADDR	6
+#define PFE_SKIP_COUNT		7
 	union pf_keth_rule_ptr	 skip[PFE_SKIP_COUNT];
 
 	TAILQ_ENTRY(pf_keth_rule)	entries;
@@ -2215,6 +2217,8 @@ extern void			 pf_unlink_src_node(struct pf_ksrc_node *);
 extern u_int			 pf_free_src_nodes(struct pf_ksrc_node_list *);
 extern void			 pf_print_state(struct pf_kstate *);
 extern void			 pf_print_flags(u_int8_t);
+extern int			 pf_addr_wrap_neq(struct pf_addr_wrap *,
+				    struct pf_addr_wrap *);
 extern u_int16_t		 pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
 				    u_int8_t);
 extern u_int16_t		 pf_proto_cksum_fixup(struct mbuf *, u_int16_t,
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index ebc201e4f5b4..7b52f6f0d2aa 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -321,8 +321,6 @@ static int		 pf_check_proto_cksum(struct mbuf *, int, int,
 			    u_int8_t, sa_family_t);
 static void		 pf_print_state_parts(struct pf_kstate *,
 			    struct pf_state_key *, struct pf_state_key *);
-static int		 pf_addr_wrap_neq(struct pf_addr_wrap *,
-			    struct pf_addr_wrap *);
 static void		 pf_patch_8(struct mbuf *, u_int16_t *, u_int8_t *, u_int8_t,
 			    bool, u_int8_t);
 static struct pf_kstate	*pf_find_state(struct pfi_kkif *,
@@ -2429,7 +2427,7 @@ pf_calc_skip_steps(struct pf_krulequeue *rules)
 		PF_SET_SKIP_STEPS(i);
 }
 
-static int
+int
 pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
 {
 	if (aw1->type != aw2->type)
@@ -4014,19 +4012,19 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0)
 		else if (! pf_match_eth_addr(e->ether_dhost, &r->dst)) {
 			SDT_PROBE3(pf, eth, test_rule, mismatch, r->nr, r,
 			    "dst");
-			r = TAILQ_NEXT(r, entries);
+			r = r->skip[PFE_SKIP_DST_ADDR].ptr;
 		}
 		else if (src != NULL && PF_MISMATCHAW(&r->ipsrc.addr, src, af,
 		    r->ipsrc.neg, kif, M_GETFIB(m))) {
 			SDT_PROBE3(pf, eth, test_rule, mismatch, r->nr, r,
 			    "ip_src");
-			r = TAILQ_NEXT(r, entries);
+			r = r->skip[PFE_SKIP_SRC_IP_ADDR].ptr;
 		}
 		else if (dst != NULL && PF_MISMATCHAW(&r->ipdst.addr, dst, af,
 		    r->ipdst.neg, kif, M_GETFIB(m))) {
 			SDT_PROBE3(pf, eth, test_rule, mismatch, r->nr, r,
 			    "ip_dst");
-			r = TAILQ_NEXT(r, entries);
+			r = r->skip[PFE_SKIP_DST_IP_ADDR].ptr;
 		}
 		else if (r->match_tag && !pf_match_eth_tag(m, r, &tag,
 		    mtag ? mtag->tag : 0)) {
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index cb6d22885ef4..e76a92fb7e7f 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -843,6 +843,12 @@ pf_eth_calc_skip_steps(struct pf_keth_ruleq *rules)
 			PF_SET_SKIP_STEPS(PFE_SKIP_SRC_ADDR);
 		if (memcmp(&cur->dst, &prev->dst, sizeof(cur->dst)) != 0)
 			PF_SET_SKIP_STEPS(PFE_SKIP_DST_ADDR);
+		if (cur->ipsrc.neg != prev->ipsrc.neg ||
+		    pf_addr_wrap_neq(&cur->ipsrc.addr, &prev->ipsrc.addr))
+			PF_SET_SKIP_STEPS(PFE_SKIP_SRC_IP_ADDR);
+		if (cur->ipdst.neg != prev->ipdst.neg ||
+		    pf_addr_wrap_neq(&cur->ipdst.addr, &prev->ipdst.addr))
+			PF_SET_SKIP_STEPS(PFE_SKIP_DST_IP_ADDR);
 
 		prev = cur;
 		cur = TAILQ_NEXT(cur, entries);