From owner-dev-commits-src-branches@freebsd.org Wed Jan 20 14:44:54 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2B8544F875C; Wed, 20 Jan 2021 14:44:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DLSwk0kj3z4qnP; Wed, 20 Jan 2021 14:44:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0BFDF1B306; Wed, 20 Jan 2021 14:44:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10KEisYP019316; Wed, 20 Jan 2021 14:44:54 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10KEisCK019315; Wed, 20 Jan 2021 14:44:54 GMT (envelope-from git) Date: Wed, 20 Jan 2021 14:44:54 GMT Message-Id: <202101201444.10KEisCK019315@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: ef0a241c0ba4 - stable/12 - pf: Split pf_src_node into a kernel and userspace struct MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: ef0a241c0ba4c594512fa5e1a243a9eb4c61b0f6 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Jan 2021 14:44:54 -0000 The branch stable/12 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=ef0a241c0ba4c594512fa5e1a243a9eb4c61b0f6 commit ef0a241c0ba4c594512fa5e1a243a9eb4c61b0f6 Author: Kristof Provost AuthorDate: 2020-12-23 13:51:52 +0000 Commit: Kristof Provost 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 #include -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)