git: ef0a241c0ba4 - stable/12 - pf: Split pf_src_node into a kernel and userspace struct

Kristof Provost kp at FreeBSD.org
Wed Jan 20 14:44:54 UTC 2021


The branch stable/12 has been updated by kp:

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

commit ef0a241c0ba4c594512fa5e1a243a9eb4c61b0f6
Author:     Kristof Provost <kp at FreeBSD.org>
AuthorDate: 2020-12-23 13:51:52 +0000
Commit:     Kristof Provost <kp at FreeBSD.org>
CommitDate: 2021-01-20 14:16:04 +0000

    pf: Split pf_src_node into a kernel and userspace struct
    
    Introduce a kernel version of struct pf_src_node (pf_ksrc_node).
    
    This will allow us to improve the in-kernel data structure without
    breaking userspace compatibility.
    
    Reviewed by:    philip
    MFC after:      2 weeks
    Sponsored by:   Orange Business Services
    Differential Revision:  https://reviews.freebsd.org/D27707
    
    (cherry picked from commit 17ad7334ca6225e0dc5caca12d1eb5886115f7af)
---
 sys/net/pfvar.h           | 57 +++++++++-------------------------------
 sys/netpfil/pf/pf.c       | 34 ++++++++++++------------
 sys/netpfil/pf/pf.h       | 50 +++++++++++++++++++++++++++++++++++
 sys/netpfil/pf/pf_ioctl.c | 67 +++++++++++++++++++++++++++++++----------------
 sys/netpfil/pf/pf_lb.c    |  8 +++---
 5 files changed, 129 insertions(+), 87 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 24faee5d45c6..5ff47c99b457 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -54,21 +54,6 @@
 #include <netpfil/pf/pf_altq.h>
 #include <netpfil/pf/pf_mtag.h>
 
-struct pf_addr {
-	union {
-		struct in_addr		v4;
-		struct in6_addr		v6;
-		u_int8_t		addr8[16];
-		u_int16_t		addr16[8];
-		u_int32_t		addr32[4];
-	} pfa;		    /* 128-bit address */
-#define v4	pfa.v4
-#define v6	pfa.v6
-#define addr8	pfa.addr8
-#define addr16	pfa.addr16
-#define addr32	pfa.addr32
-};
-
 #define PFI_AFLAG_NETWORK	0x01
 #define PFI_AFLAG_BROADCAST	0x02
 #define PFI_AFLAG_PEER		0x04
@@ -481,12 +466,6 @@ struct pf_osfp_ioctl {
 	int			fp_getnum;	/* DIOCOSFPGET number */
 };
 
-
-union pf_rule_ptr {
-	struct pf_rule		*ptr;
-	u_int32_t		 nr;
-};
-
 #define	PF_ANCHOR_NAME_SIZE	 64
 
 struct pf_rule {
@@ -630,18 +609,9 @@ struct pf_rule {
 #define PFSTATE_ADAPT_START	60000	/* default adaptive timeout start */
 #define PFSTATE_ADAPT_END	120000	/* default adaptive timeout end */
 
-
-struct pf_threshold {
-	u_int32_t	limit;
-#define	PF_THRESHOLD_MULT	1000
-#define PF_THRESHOLD_MAX	0xffffffff / PF_THRESHOLD_MULT
-	u_int32_t	seconds;
-	u_int32_t	count;
-	u_int32_t	last;
-};
-
-struct pf_src_node {
-	LIST_ENTRY(pf_src_node) entry;
+#ifdef _KERNEL
+struct pf_ksrc_node {
+	LIST_ENTRY(pf_ksrc_node) entry;
 	struct pf_addr	 addr;
 	struct pf_addr	 raddr;
 	union pf_rule_ptr rule;
@@ -656,8 +626,7 @@ struct pf_src_node {
 	sa_family_t	 af;
 	u_int8_t	 ruletype;
 };
-
-#define PFSNODE_HIWAT		10000	/* default source node table size */
+#endif
 
 struct pf_state_scrub {
 	struct timeval	pfss_last;	/* time received last packet	*/
@@ -741,8 +710,8 @@ struct pf_state {
 	struct pf_state_key	*key[2];	/* addresses stack and wire  */
 	struct pfi_kif		*kif;
 	struct pfi_kif		*rt_kif;
-	struct pf_src_node	*src_node;
-	struct pf_src_node	*nat_src_node;
+	struct pf_ksrc_node	*src_node;
+	struct pf_ksrc_node	*nat_src_node;
 	counter_u64_t		 packets[2];
 	counter_u64_t		 bytes[2];
 	u_int32_t		 creation;
@@ -1572,9 +1541,9 @@ struct pf_ifspeed_v1 {
 #endif /* _KERNEL */
 
 #ifdef _KERNEL
-LIST_HEAD(pf_src_node_list, pf_src_node);
+LIST_HEAD(pf_ksrc_node_list, pf_ksrc_node);
 struct pf_srchash {
-	struct pf_src_node_list		nodes;
+	struct pf_ksrc_node_list		nodes;
 	struct mtx			lock;
 };
 
@@ -1686,10 +1655,10 @@ pf_release_state(struct pf_state *s)
 extern struct pf_state		*pf_find_state_byid(uint64_t, uint32_t);
 extern struct pf_state		*pf_find_state_all(struct pf_state_key_cmp *,
 				    u_int, int *);
-extern struct pf_src_node	*pf_find_src_node(struct pf_addr *,
+extern struct pf_ksrc_node	*pf_find_src_node(struct pf_addr *,
 				    struct pf_rule *, sa_family_t, int);
-extern void			 pf_unlink_src_node(struct pf_src_node *);
-extern u_int			 pf_free_src_nodes(struct pf_src_node_list *);
+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_state *);
 extern void			 pf_print_flags(u_int8_t);
 extern u_int16_t		 pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
@@ -1881,9 +1850,9 @@ int			 pf_step_out_of_anchor(struct pf_anchor_stackframe *, int *,
 
 int			 pf_map_addr(u_int8_t, struct pf_rule *,
 			    struct pf_addr *, struct pf_addr *,
-			    struct pf_addr *, struct pf_src_node **);
+			    struct pf_addr *, struct pf_ksrc_node **);
 struct pf_rule		*pf_get_translation(struct pf_pdesc *, struct mbuf *,
-			    int, int, struct pfi_kif *, struct pf_src_node **,
+			    int, int, struct pfi_kif *, struct pf_ksrc_node **,
 			    struct pf_state_key **, struct pf_state_key **,
 			    struct pf_addr *, struct pf_addr *,
 			    uint16_t, uint16_t, struct pf_anchor_stackframe *);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 84133039eb45..7b2128da7985 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -250,7 +250,7 @@ static int		 pf_test_rule(struct pf_rule **, struct pf_state **,
 			    struct pf_ruleset **, struct inpcb *);
 static int		 pf_create_state(struct pf_rule *, struct pf_rule *,
 			    struct pf_rule *, struct pf_pdesc *,
-			    struct pf_src_node *, struct pf_state_key *,
+			    struct pf_ksrc_node *, struct pf_state_key *,
 			    struct pf_state_key *, struct mbuf *, int,
 			    u_int16_t, u_int16_t, int *, struct pfi_kif *,
 			    struct pf_state **, int, u_int16_t, u_int16_t,
@@ -295,7 +295,7 @@ static struct pf_state	*pf_find_state(struct pfi_kif *,
 			    struct pf_state_key_cmp *, u_int);
 static int		 pf_src_connlimit(struct pf_state **);
 static void		 pf_overload_task(void *v, int pending);
-static int		 pf_insert_src_node(struct pf_src_node **,
+static int		 pf_insert_src_node(struct pf_ksrc_node **,
 			    struct pf_rule *, struct pf_addr *, sa_family_t);
 static u_int		 pf_purge_expired_states(u_int, int);
 static void		 pf_purge_unlinked_rules(void);
@@ -677,12 +677,12 @@ pf_overload_task(void *v, int pending)
  * Can return locked on failure, so that we can consistently
  * allocate and insert a new one.
  */
-struct pf_src_node *
+struct pf_ksrc_node *
 pf_find_src_node(struct pf_addr *src, struct pf_rule *rule, sa_family_t af,
 	int returnlocked)
 {
 	struct pf_srchash *sh;
-	struct pf_src_node *n;
+	struct pf_ksrc_node *n;
 
 	counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_SEARCH], 1);
 
@@ -703,7 +703,7 @@ pf_find_src_node(struct pf_addr *src, struct pf_rule *rule, sa_family_t af,
 }
 
 static int
-pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
+pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_rule *rule,
     struct pf_addr *src, sa_family_t af)
 {
 
@@ -757,7 +757,7 @@ pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
 }
 
 void
-pf_unlink_src_node(struct pf_src_node *src)
+pf_unlink_src_node(struct pf_ksrc_node *src)
 {
 
 	PF_HASHROW_ASSERT(&V_pf_srchash[pf_hashsrc(&src->addr, src->af)]);
@@ -767,9 +767,9 @@ pf_unlink_src_node(struct pf_src_node *src)
 }
 
 u_int
-pf_free_src_nodes(struct pf_src_node_list *head)
+pf_free_src_nodes(struct pf_ksrc_node_list *head)
 {
-	struct pf_src_node *sn, *tmp;
+	struct pf_ksrc_node *sn, *tmp;
 	u_int count = 0;
 
 	LIST_FOREACH_SAFE(sn, head, entry, tmp) {
@@ -845,7 +845,7 @@ pf_initialize()
 
 	/* Source nodes. */
 	V_pf_sources_z = uma_zcreate("pf source nodes",
-	    sizeof(struct pf_src_node), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
+	    sizeof(struct pf_ksrc_node), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
 	    0);
 	V_pf_limits[PF_LIMIT_SRC_NODES].zone = V_pf_sources_z;
 	uma_zone_set_max(V_pf_sources_z, PFSNODE_HIWAT);
@@ -1594,9 +1594,9 @@ pf_state_expires(const struct pf_state *state)
 void
 pf_purge_expired_src_nodes()
 {
-	struct pf_src_node_list	 freelist;
+	struct pf_ksrc_node_list	 freelist;
 	struct pf_srchash	*sh;
-	struct pf_src_node	*cur, *next;
+	struct pf_ksrc_node	*cur, *next;
 	int i;
 
 	LIST_INIT(&freelist);
@@ -1619,7 +1619,7 @@ pf_purge_expired_src_nodes()
 static void
 pf_src_tree_remove_state(struct pf_state *s)
 {
-	struct pf_src_node *sn;
+	struct pf_ksrc_node *sn;
 	struct pf_srchash *sh;
 	uint32_t timeout;
 
@@ -3311,7 +3311,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
 	sa_family_t		 af = pd->af;
 	struct pf_rule		*r, *a = NULL;
 	struct pf_ruleset	*ruleset = NULL;
-	struct pf_src_node	*nsn = NULL;
+	struct pf_ksrc_node	*nsn = NULL;
 	struct tcphdr		*th = pd->hdr.tcp;
 	struct pf_state_key	*sk = NULL, *nk = NULL;
 	u_short			 reason;
@@ -3676,13 +3676,13 @@ cleanup:
 
 static int
 pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
-    struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *nk,
+    struct pf_pdesc *pd, struct pf_ksrc_node *nsn, struct pf_state_key *nk,
     struct pf_state_key *sk, struct mbuf *m, int off, u_int16_t sport,
     u_int16_t dport, int *rewrite, struct pfi_kif *kif, struct pf_state **sm,
     int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen)
 {
 	struct pf_state		*s = NULL;
-	struct pf_src_node	*sn = NULL;
+	struct pf_ksrc_node	*sn = NULL;
 	struct tcphdr		*th = pd->hdr.tcp;
 	u_int16_t		 mss = V_tcp_mssdflt;
 	u_short			 reason;
@@ -5576,7 +5576,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
 	struct ip		*ip;
 	struct ifnet		*ifp = NULL;
 	struct pf_addr		 naddr;
-	struct pf_src_node	*sn = NULL;
+	struct pf_ksrc_node	*sn = NULL;
 	int			 error = 0;
 	uint16_t		 ip_len, ip_off;
 
@@ -5739,7 +5739,7 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
 	struct ip6_hdr		*ip6;
 	struct ifnet		*ifp = NULL;
 	struct pf_addr		 naddr;
-	struct pf_src_node	*sn = NULL;
+	struct pf_ksrc_node	*sn = NULL;
 
 	KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
 	KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
index 253e88049b7c..7add0877224e 100644
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -185,6 +185,8 @@ enum	{ PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
 #define	PF_TABLE_NAME_SIZE	32
 #define	PF_QNAME_SIZE		64
 
+struct pf_rule;
+
 struct pf_status {
 	uint64_t	counters[PFRES_MAX];
 	uint64_t	lcounters[LCNT_MAX];
@@ -202,4 +204,52 @@ struct pf_status {
 	uint8_t		pf_chksum[PF_MD5_DIGEST_LENGTH];
 };
 
+struct pf_addr {
+	union {
+		struct in_addr		v4;
+		struct in6_addr		v6;
+		u_int8_t		addr8[16];
+		u_int16_t		addr16[8];
+		u_int32_t		addr32[4];
+	} pfa;		    /* 128-bit address */
+#define v4	pfa.v4
+#define v6	pfa.v6
+#define addr8	pfa.addr8
+#define addr16	pfa.addr16
+#define addr32	pfa.addr32
+};
+
+union pf_rule_ptr {
+	struct pf_rule		*ptr;
+	u_int32_t		 nr;
+};
+
+struct pf_threshold {
+	u_int32_t	limit;
+#define	PF_THRESHOLD_MULT	1000
+#define PF_THRESHOLD_MAX	0xffffffff / PF_THRESHOLD_MULT
+	u_int32_t	seconds;
+	u_int32_t	count;
+	u_int32_t	last;
+};
+
+struct pf_src_node {
+	LIST_ENTRY(pf_src_node) entry;
+	struct pf_addr	 addr;
+	struct pf_addr	 raddr;
+	union pf_rule_ptr rule;
+	struct pfi_kif	*kif;
+	u_int64_t	 bytes[2];
+	u_int64_t	 packets[2];
+	u_int32_t	 states;
+	u_int32_t	 conn;
+	struct pf_threshold	conn_rate;
+	u_int32_t	 creation;
+	u_int32_t	 expire;
+	sa_family_t	 af;
+	u_int8_t	 ruletype;
+};
+
+#define PFSNODE_HIWAT		10000	/* default source node table size */
+
 #endif	/* _NET_PF_H_ */
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 65f71ad8399e..cb503f7f3e1e 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -116,6 +116,8 @@ static int		 pf_commit_rules(u_int32_t, int, char *);
 static int		 pf_addr_setup(struct pf_ruleset *,
 			    struct pf_addr_wrap *, sa_family_t);
 static void		 pf_addr_copyout(struct pf_addr_wrap *);
+static void		 pf_src_node_copy(const struct pf_ksrc_node *,
+			    struct pf_src_node *);
 #ifdef ALTQ
 static int		 pf_export_kaltq(struct pf_altq *,
 			    struct pfioc_altq_v1 *, size_t);
@@ -191,7 +193,7 @@ struct cdev *pf_dev;
  */
 static void		 pf_clear_states(void);
 static int		 pf_clear_tables(void);
-static void		 pf_clear_srcnodes(struct pf_src_node *);
+static void		 pf_clear_srcnodes(struct pf_ksrc_node *);
 static void		 pf_kill_srcnodes(struct pfioc_src_node_kill *);
 static void		 pf_tbladdr_copyout(struct pf_addr_wrap *);
 
@@ -1148,6 +1150,42 @@ pf_addr_copyout(struct pf_addr_wrap *addr)
 	}
 }
 
+static void
+pf_src_node_copy(const struct pf_ksrc_node *in, struct pf_src_node *out)
+{
+	int	secs = time_uptime, diff;
+
+	bzero(out, sizeof(struct pf_src_node));
+
+	bcopy(&in->addr, &out->addr, sizeof(struct pf_addr));
+	bcopy(&in->raddr, &out->raddr, sizeof(struct pf_addr));
+
+	if (in->rule.ptr != NULL)
+		out->rule.nr = in->rule.ptr->nr;
+
+	bcopy(&in->bytes, &out->bytes, sizeof(u_int64_t) * 2);
+	bcopy(&in->packets, &out->packets, sizeof(u_int64_t) * 2);
+	out->states = in->states;
+	out->conn = in->conn;
+	out->af = in->af;
+	out->ruletype = in->ruletype;
+
+	out->creation = secs - in->creation;
+	if (out->expire > secs)
+		out->expire -= secs;
+	else
+		out->expire = 0;
+
+	/* Adjust the connection rate estimate. */
+	diff = secs - in->conn_rate.last;
+	if (diff >= in->conn_rate.seconds)
+		out->conn_rate.count = 0;
+	else
+		out->conn_rate.count -=
+		    in->conn_rate.count * diff /
+		    in->conn_rate.seconds;
+}
+
 #ifdef ALTQ
 /*
  * Handle export of struct pf_kaltq to user binaries that may be using any
@@ -3771,7 +3809,8 @@ DIOCCHANGEADDR_error:
 	case DIOCGETSRCNODES: {
 		struct pfioc_src_nodes	*psn = (struct pfioc_src_nodes *)addr;
 		struct pf_srchash	*sh;
-		struct pf_src_node	*n, *p, *pstore;
+		struct pf_ksrc_node	*n;
+		struct pf_src_node	*p, *pstore;
 		uint32_t		 i, nr = 0;
 
 		for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask;
@@ -3797,28 +3836,12 @@ DIOCCHANGEADDR_error:
 		    i++, sh++) {
 		    PF_HASHROW_LOCK(sh);
 		    LIST_FOREACH(n, &sh->nodes, entry) {
-			int	secs = time_uptime, diff;
 
 			if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
 				break;
 
-			bcopy(n, p, sizeof(struct pf_src_node));
-			if (n->rule.ptr != NULL)
-				p->rule.nr = n->rule.ptr->nr;
-			p->creation = secs - p->creation;
-			if (p->expire > secs)
-				p->expire -= secs;
-			else
-				p->expire = 0;
+			pf_src_node_copy(n, p);
 
-			/* Adjust the connection rate estimate. */
-			diff = secs - n->conn_rate.last;
-			if (diff >= n->conn_rate.seconds)
-				p->conn_rate.count = 0;
-			else
-				p->conn_rate.count -=
-				    n->conn_rate.count * diff /
-				    n->conn_rate.seconds;
 			p++;
 			nr++;
 		    }
@@ -4044,7 +4067,7 @@ pf_clear_tables(void)
 }
 
 static void
-pf_clear_srcnodes(struct pf_src_node *n)
+pf_clear_srcnodes(struct pf_ksrc_node *n)
 {
 	struct pf_state *s;
 	int i;
@@ -4084,12 +4107,12 @@ pf_clear_srcnodes(struct pf_src_node *n)
 static void
 pf_kill_srcnodes(struct pfioc_src_node_kill *psnk)
 {
-	struct pf_src_node_list	 kill;
+	struct pf_ksrc_node_list	 kill;
 
 	LIST_INIT(&kill);
 	for (int i = 0; i <= pf_srchashmask; i++) {
 		struct pf_srchash *sh = &V_pf_srchash[i];
-		struct pf_src_node *sn, *tmp;
+		struct pf_ksrc_node *sn, *tmp;
 
 		PF_HASHROW_LOCK(sh);
 		LIST_FOREACH_SAFE(sn, &sh->nodes, entry, tmp)
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index 46f91f8ff3ef..294e1c9be4b9 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -64,7 +64,7 @@ static struct pf_rule	*pf_match_translation(struct pf_pdesc *, struct mbuf *,
 			    uint16_t, int, struct pf_anchor_stackframe *);
 static int pf_get_sport(sa_family_t, uint8_t, struct pf_rule *,
     struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *,
-    uint16_t *, uint16_t, uint16_t, struct pf_src_node **);
+    uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **);
 
 #define mix(a,b,c) \
 	do {					\
@@ -215,7 +215,7 @@ static int
 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
     struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr,
     uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low,
-    uint16_t high, struct pf_src_node **sn)
+    uint16_t high, struct pf_ksrc_node **sn)
 {
 	struct pf_state_key_cmp	key;
 	struct pf_addr		init_addr;
@@ -308,7 +308,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
 
 int
 pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
-    struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
+    struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_ksrc_node **sn)
 {
 	struct pf_pool		*rpool = &r->rpool;
 	struct pf_addr		*raddr = NULL, *rmask = NULL;
@@ -518,7 +518,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
 
 struct pf_rule *
 pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
-    struct pfi_kif *kif, struct pf_src_node **sn,
+    struct pfi_kif *kif, struct pf_ksrc_node **sn,
     struct pf_state_key **skp, struct pf_state_key **nkp,
     struct pf_addr *saddr, struct pf_addr *daddr,
     uint16_t sport, uint16_t dport, struct pf_anchor_stackframe *anchor_stack)


More information about the dev-commits-src-all mailing list