Index: sys/net/pfvar.h =================================================================== --- sys/net/pfvar.h +++ 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 @@ -478,11 +463,6 @@ 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 { @@ -626,17 +606,9 @@ #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; @@ -651,8 +623,7 @@ 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 */ @@ -736,8 +707,8 @@ 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; u_int64_t packets[2]; u_int64_t bytes[2]; u_int32_t creation; @@ -1579,9 +1550,9 @@ #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; }; @@ -1693,10 +1664,10 @@ 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, @@ -1884,9 +1855,9 @@ 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 *); Index: sys/netpfil/pf/pf.h =================================================================== --- sys/netpfil/pf/pf.h +++ sys/netpfil/pf/pf.h @@ -185,6 +185,8 @@ #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 @@ 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_ */ Index: sys/netpfil/pf/pf.c =================================================================== --- sys/netpfil/pf/pf.c +++ sys/netpfil/pf/pf.c @@ -249,7 +249,7 @@ 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, @@ -292,7 +292,7 @@ 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); @@ -675,12 +675,12 @@ * 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); @@ -701,7 +701,7 @@ } 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) { @@ -755,7 +755,7 @@ } 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)]); @@ -765,9 +765,9 @@ } 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) { @@ -843,7 +843,7 @@ /* 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 @@ 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 @@ 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; @@ -3250,7 +3250,7 @@ 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; @@ -3615,13 +3615,13 @@ 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; @@ -5376,7 +5376,7 @@ 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; @@ -5539,7 +5539,7 @@ 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", Index: sys/netpfil/pf/pf_ioctl.c =================================================================== --- sys/netpfil/pf/pf_ioctl.c +++ sys/netpfil/pf/pf_ioctl.c @@ -116,6 +116,8 @@ 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 @@ */ 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 *); @@ -1146,6 +1148,42 @@ } } +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 @@ -3765,7 +3803,8 @@ 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; @@ -3791,28 +3830,12 @@ 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++; } @@ -4035,7 +4058,7 @@ } static void -pf_clear_srcnodes(struct pf_src_node *n) +pf_clear_srcnodes(struct pf_ksrc_node *n) { struct pf_state *s; int i; @@ -4075,12 +4098,12 @@ 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) Index: sys/netpfil/pf/pf_lb.c =================================================================== --- sys/netpfil/pf/pf_lb.c +++ sys/netpfil/pf/pf_lb.c @@ -64,7 +64,7 @@ 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 @@ 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; @@ -312,7 +312,7 @@ 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; @@ -522,7 +522,7 @@ 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)