Date: Wed, 20 Jan 2021 14:44:57 GMT From: Kristof Provost <kp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 3e4a92026657 - stable/12 - pf: Split pf_rule into kernel and user space versions Message-ID: <202101201444.10KEivcd019387@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=3e4a9202665701d858e6049fe645a2e3d0ff093e commit 3e4a9202665701d858e6049fe645a2e3d0ff093e Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2020-12-05 13:32:54 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2021-01-20 14:16:04 +0000 pf: Split pf_rule into kernel and user space versions No functional change intended. MFC after: 2 weeks Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D27758 (cherry picked from commit e86bddea9fe62d5093a1942cf21950b3c5ca62e5) --- sys/net/pfvar.h | 234 +++++++++++++++++++++--------- sys/netpfil/pf/if_pflog.c | 4 +- sys/netpfil/pf/if_pfsync.c | 2 +- sys/netpfil/pf/pf.c | 124 ++++++++-------- sys/netpfil/pf/pf.h | 48 +++++++ sys/netpfil/pf/pf_if.c | 6 +- sys/netpfil/pf/pf_ioctl.c | 337 ++++++++++++++++++++++++++++++++++---------- sys/netpfil/pf/pf_lb.c | 24 ++-- sys/netpfil/pf/pf_norm.c | 10 +- sys/netpfil/pf/pf_ruleset.c | 303 +++++++++++++++++++++++++++++++++++---- sys/netpfil/pf/pf_table.c | 36 ++--- 11 files changed, 857 insertions(+), 271 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 440110e77298..4dd2db1a34b9 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -293,11 +293,115 @@ extern struct sx pf_end_lock; #define PF_ALGNMNT(off) (((off) % 2) == 0) #ifdef _KERNEL + +union pf_krule_ptr { + struct pf_krule *ptr; + u_int32_t nr; +}; + +struct pf_krule { + struct pf_rule_addr src; + struct pf_rule_addr dst; + union pf_krule_ptr skip[PF_SKIP_COUNT]; + char label[PF_RULE_LABEL_SIZE]; + char ifname[IFNAMSIZ]; + char qname[PF_QNAME_SIZE]; + char pqname[PF_QNAME_SIZE]; + char tagname[PF_TAG_NAME_SIZE]; + char match_tagname[PF_TAG_NAME_SIZE]; + + char overload_tblname[PF_TABLE_NAME_SIZE]; + + TAILQ_ENTRY(pf_krule) entries; + struct pf_pool rpool; + + u_int64_t evaluations; + u_int64_t packets[2]; + u_int64_t bytes[2]; + + struct pfi_kif *kif; + struct pf_kanchor *anchor; + struct pfr_ktable *overload_tbl; + + pf_osfp_t os_fingerprint; + + int rtableid; + u_int32_t timeout[PFTM_MAX]; + u_int32_t max_states; + u_int32_t max_src_nodes; + u_int32_t max_src_states; + u_int32_t max_src_conn; + struct { + u_int32_t limit; + u_int32_t seconds; + } max_src_conn_rate; + u_int32_t qid; + u_int32_t pqid; + u_int32_t rt_listid; + u_int32_t nr; + u_int32_t prob; + uid_t cuid; + pid_t cpid; + + counter_u64_t states_cur; + counter_u64_t states_tot; + counter_u64_t src_nodes; + + u_int16_t return_icmp; + u_int16_t return_icmp6; + u_int16_t max_mss; + u_int16_t tag; + u_int16_t match_tag; + u_int16_t scrub_flags; + + struct pf_rule_uid uid; + struct pf_rule_gid gid; + + u_int32_t rule_flag; + u_int8_t action; + u_int8_t direction; + u_int8_t log; + u_int8_t logif; + u_int8_t quick; + u_int8_t ifnot; + u_int8_t match_tag_not; + u_int8_t natpass; + + u_int8_t keep_state; + sa_family_t af; + u_int8_t proto; + u_int8_t type; + u_int8_t code; + u_int8_t flags; + u_int8_t flagset; + u_int8_t min_ttl; + u_int8_t allow_opts; + u_int8_t rt; + u_int8_t return_ttl; + u_int8_t tos; + u_int8_t set_tos; + u_int8_t anchor_relative; + u_int8_t anchor_wildcard; + + u_int8_t flush; + u_int8_t prio; + u_int8_t set_prio[2]; + + struct { + struct pf_addr addr; + u_int16_t port; + } divert; + + uint64_t u_states_cur; + uint64_t u_states_tot; + uint64_t u_src_nodes; +}; + struct pf_ksrc_node { LIST_ENTRY(pf_ksrc_node) entry; struct pf_addr addr; struct pf_addr raddr; - union pf_rule_ptr rule; + union pf_krule_ptr rule; struct pfi_kif *kif; counter_u64_t bytes[2]; counter_u64_t packets[2]; @@ -374,6 +478,15 @@ struct pf_state_cmp { u_int8_t pad[3]; }; +#define PFSTATE_ALLOWOPTS 0x01 +#define PFSTATE_SLOPPY 0x02 +/* was PFSTATE_PFLOW 0x04 */ +#define PFSTATE_NOSYNC 0x08 +#define PFSTATE_ACK 0x10 +#define PFSTATE_SETPRIO 0x0200 +#define PFSTATE_SETMASK (PFSTATE_SETPRIO) + +#ifdef _KERNEL struct pf_state { u_int64_t id; u_int32_t creatorid; @@ -386,9 +499,9 @@ struct pf_state { LIST_ENTRY(pf_state) entry; struct pf_state_peer src; struct pf_state_peer dst; - union pf_rule_ptr rule; - union pf_rule_ptr anchor; - union pf_rule_ptr nat_rule; + union pf_krule_ptr rule; + union pf_krule_ptr anchor; + union pf_krule_ptr nat_rule; struct pf_addr rt_addr; struct pf_state_key *key[2]; /* addresses stack and wire */ struct pfi_kif *kif; @@ -403,13 +516,6 @@ struct pf_state { u_int16_t tag; u_int8_t log; u_int8_t state_flags; -#define PFSTATE_ALLOWOPTS 0x01 -#define PFSTATE_SLOPPY 0x02 -/* was PFSTATE_PFLOW 0x04 */ -#define PFSTATE_NOSYNC 0x08 -#define PFSTATE_ACK 0x10 -#define PFSTATE_SETPRIO 0x0200 -#define PFSTATE_SETMASK (PFSTATE_SETPRIO) u_int8_t timeout; u_int8_t sync_state; /* PFSYNC_S_x */ @@ -417,6 +523,7 @@ struct pf_state { u_int8_t sync_updates; u_int8_t _tail[3]; }; +#endif /* * Unified state structures for pulling states out of the kernel @@ -501,11 +608,11 @@ void pfsync_state_export(struct pfsync_state *, struct pf_state *); /* pflog */ -struct pf_ruleset; +struct pf_kruleset; struct pf_pdesc; typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t, - u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *, - struct pf_ruleset *, struct pf_pdesc *, int); + u_int8_t, u_int8_t, struct pf_krule *, struct pf_krule *, + struct pf_kruleset *, struct pf_pdesc *, int); extern pflog_packet_t *pflog_packet_ptr; #endif /* _KERNEL */ @@ -563,42 +670,42 @@ extern pflog_packet_t *pflog_packet_ptr; d += ntohl(s[1]); \ } while (0) -TAILQ_HEAD(pf_rulequeue, pf_rule); +TAILQ_HEAD(pf_krulequeue, pf_krule); -struct pf_anchor; +struct pf_kanchor; -struct pf_ruleset { +struct pf_kruleset { struct { - struct pf_rulequeue queues[2]; + struct pf_krulequeue queues[2]; struct { - struct pf_rulequeue *ptr; - struct pf_rule **ptr_array; + struct pf_krulequeue *ptr; + struct pf_krule **ptr_array; u_int32_t rcount; u_int32_t ticket; int open; } active, inactive; } rules[PF_RULESET_MAX]; - struct pf_anchor *anchor; + struct pf_kanchor *anchor; u_int32_t tticket; int tables; int topen; }; -RB_HEAD(pf_anchor_global, pf_anchor); -RB_HEAD(pf_anchor_node, pf_anchor); -struct pf_anchor { - RB_ENTRY(pf_anchor) entry_global; - RB_ENTRY(pf_anchor) entry_node; - struct pf_anchor *parent; - struct pf_anchor_node children; +RB_HEAD(pf_kanchor_global, pf_kanchor); +RB_HEAD(pf_kanchor_node, pf_kanchor); +struct pf_kanchor { + RB_ENTRY(pf_kanchor) entry_global; + RB_ENTRY(pf_kanchor) entry_node; + struct pf_kanchor *parent; + struct pf_kanchor_node children; char name[PF_ANCHOR_NAME_SIZE]; char path[MAXPATHLEN]; - struct pf_ruleset ruleset; + struct pf_kruleset ruleset; int refcnt; /* anchor rules */ int match; /* XXX: used for pfctl black magic */ }; -RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare); -RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare); +RB_PROTOTYPE(pf_kanchor_global, pf_kanchor, entry_global, pf_anchor_compare); +RB_PROTOTYPE(pf_kanchor_node, pf_kanchor, entry_node, pf_kanchor_compare); #define PF_RESERVED_ANCHOR "_pf" @@ -625,7 +732,7 @@ RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare); PFR_TFLAG_REFDANCHOR | \ PFR_TFLAG_COUNTERS) -struct pf_anchor_stackframe; +struct pf_kanchor_stackframe; struct pfr_table { char pfrt_anchor[MAXPATHLEN]; @@ -707,6 +814,7 @@ struct pfr_kcounters { ((kc)->pfrkc_counters + \ (dir) * PFR_OP_ADDR_MAX * PFR_TYPE_MAX + (op) * PFR_TYPE_MAX + (t)) +#ifdef _KERNEL SLIST_HEAD(pfr_kentryworkq, pfr_kentry); struct pfr_kentry { struct radix_node pfrke_node[2]; @@ -729,7 +837,7 @@ struct pfr_ktable { struct radix_node_head *pfrkt_ip6; struct pfr_ktable *pfrkt_shadow; struct pfr_ktable *pfrkt_root; - struct pf_ruleset *pfrkt_rs; + struct pf_kruleset *pfrkt_rs; long pfrkt_larg; int pfrkt_nflags; }; @@ -745,6 +853,7 @@ struct pfr_ktable { #define pfrkt_match pfrkt_kts.pfrkts_match #define pfrkt_nomatch pfrkt_kts.pfrkts_nomatch #define pfrkt_tzero pfrkt_kts.pfrkts_tzero +#endif /* keep synced with pfi_kif, used in RB_FIND */ struct pfi_kif_cmp { @@ -789,7 +898,7 @@ struct pf_pdesc { void *any; } hdr; - struct pf_rule *nat_rule; /* nat/rdr rule applied to packet */ + struct pf_krule *nat_rule; /* nat/rdr rule applied to packet */ struct pf_addr *src; /* src address */ struct pf_addr *dst; /* dst address */ u_int16_t *sport; @@ -1282,7 +1391,7 @@ VNET_DECLARE(struct pf_altqqueue *, pf_altqs_inactive); VNET_DECLARE(struct pf_altqqueue *, pf_altq_ifs_inactive); #define V_pf_altq_ifs_inactive VNET(pf_altq_ifs_inactive) -VNET_DECLARE(struct pf_rulequeue, pf_unlinked_rules); +VNET_DECLARE(struct pf_krulequeue, pf_unlinked_rules); #define V_pf_unlinked_rules VNET(pf_unlinked_rules) void pf_initialize(void); @@ -1292,7 +1401,7 @@ void pf_cleanup(void); struct pf_mtag *pf_get_mtag(struct mbuf *); -extern void pf_calc_skip_steps(struct pf_rulequeue *); +extern void pf_calc_skip_steps(struct pf_krulequeue *); #ifdef ALTQ extern void pf_altq_ifnet_event(struct ifnet *, int); #endif @@ -1339,7 +1448,7 @@ 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_ksrc_node *pf_find_src_node(struct pf_addr *, - struct pf_rule *, sa_family_t, int); + struct pf_krule *, sa_family_t, int); 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 *); @@ -1351,11 +1460,11 @@ extern u_int16_t pf_proto_cksum_fixup(struct mbuf *, u_int16_t, VNET_DECLARE(struct ifnet *, sync_ifp); #define V_sync_ifp VNET(sync_ifp); -VNET_DECLARE(struct pf_rule, pf_default_rule); +VNET_DECLARE(struct pf_krule, pf_default_rule); #define V_pf_default_rule VNET(pf_default_rule) extern void pf_addrcpy(struct pf_addr *, struct pf_addr *, u_int8_t); -void pf_free_rule(struct pf_rule *); +void pf_free_rule(struct pf_krule *); #ifdef INET int pf_test(int, int, struct ifnet *, struct mbuf **, struct inpcb *); @@ -1417,7 +1526,7 @@ void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t, int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *, sa_family_t); void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *); struct pfr_ktable * - pfr_attach_table(struct pf_ruleset *, char *); + pfr_attach_table(struct pf_kruleset *, char *); void pfr_detach_table(struct pfr_ktable *); int pfr_clr_tables(struct pfr_table *, int *, int); int pfr_add_tables(struct pfr_table *, int, int *, int); @@ -1471,7 +1580,7 @@ void pfi_get_ifaces(const char *, struct pfi_kif *, int *); int pfi_set_flags(const char *, int); int pfi_clear_flags(const char *, int); -int pf_match_tag(struct mbuf *, struct pf_rule *, int *, int); +int pf_match_tag(struct mbuf *, struct pf_krule *, int *, int); int pf_tag_packet(struct mbuf *, struct pf_pdesc *, int); int pf_addr_cmp(struct pf_addr *, struct pf_addr *, sa_family_t); @@ -1490,25 +1599,24 @@ VNET_DECLARE(struct pf_limit, pf_limits[PF_LIMIT_MAX]); #endif /* _KERNEL */ #ifdef _KERNEL -VNET_DECLARE(struct pf_anchor_global, pf_anchors); +VNET_DECLARE(struct pf_kanchor_global, pf_anchors); #define V_pf_anchors VNET(pf_anchors) -VNET_DECLARE(struct pf_anchor, pf_main_anchor); +VNET_DECLARE(struct pf_kanchor, pf_main_anchor); #define V_pf_main_anchor VNET(pf_main_anchor) #define pf_main_ruleset V_pf_main_anchor.ruleset -#endif -/* these ruleset functions can be linked into userland programs (pfctl) */ int pf_get_ruleset_number(u_int8_t); -void pf_init_ruleset(struct pf_ruleset *); -int pf_anchor_setup(struct pf_rule *, - const struct pf_ruleset *, const char *); -int pf_anchor_copyout(const struct pf_ruleset *, - const struct pf_rule *, struct pfioc_rule *); -void pf_anchor_remove(struct pf_rule *); -void pf_remove_if_empty_ruleset(struct pf_ruleset *); -struct pf_ruleset *pf_find_ruleset(const char *); -struct pf_ruleset *pf_find_or_create_ruleset(const char *); +void pf_init_kruleset(struct pf_kruleset *); +int pf_kanchor_setup(struct pf_krule *, + const struct pf_kruleset *, const char *); +int pf_kanchor_copyout(const struct pf_kruleset *, + const struct pf_krule *, struct pfioc_rule *); +void pf_kanchor_remove(struct pf_krule *); +void pf_remove_if_empty_kruleset(struct pf_kruleset *); +struct pf_kruleset *pf_find_kruleset(const char *); +struct pf_kruleset *pf_find_or_create_kruleset(const char *); void pf_rs_initialize(void); +#endif /* The fingerprint functions can be linked into userland programs (tcpdump) */ int pf_osfp_add(struct pf_osfp_ioctl *); @@ -1524,21 +1632,21 @@ int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t); #ifdef _KERNEL void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); -void pf_step_into_anchor(struct pf_anchor_stackframe *, int *, - struct pf_ruleset **, int, struct pf_rule **, - struct pf_rule **, int *); -int pf_step_out_of_anchor(struct pf_anchor_stackframe *, int *, - struct pf_ruleset **, int, struct pf_rule **, - struct pf_rule **, int *); +void pf_step_into_anchor(struct pf_kanchor_stackframe *, int *, + struct pf_kruleset **, int, struct pf_krule **, + struct pf_krule **, int *); +int pf_step_out_of_anchor(struct pf_kanchor_stackframe *, int *, + struct pf_kruleset **, int, struct pf_krule **, + struct pf_krule **, int *); -int pf_map_addr(u_int8_t, struct pf_rule *, +int pf_map_addr(u_int8_t, struct pf_krule *, struct pf_addr *, struct pf_addr *, struct pf_addr *, struct pf_ksrc_node **); -struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, +struct pf_krule *pf_get_translation(struct pf_pdesc *, struct mbuf *, 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 *); + uint16_t, uint16_t, struct pf_kanchor_stackframe *); struct pf_state_key *pf_state_key_setup(struct pf_pdesc *, struct pf_addr *, struct pf_addr *, u_int16_t, u_int16_t); diff --git a/sys/netpfil/pf/if_pflog.c b/sys/netpfil/pf/if_pflog.c index 87e674f46942..030f75c2507e 100644 --- a/sys/netpfil/pf/if_pflog.c +++ b/sys/netpfil/pf/if_pflog.c @@ -202,8 +202,8 @@ pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data) static int pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir, - u_int8_t reason, struct pf_rule *rm, struct pf_rule *am, - struct pf_ruleset *ruleset, struct pf_pdesc *pd, int lookupsafe) + u_int8_t reason, struct pf_krule *rm, struct pf_krule *am, + struct pf_kruleset *ruleset, struct pf_pdesc *pd, int lookupsafe) { struct ifnet *ifn; struct pfloghdr hdr; diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index a6967d2297a6..0d0e62cf1b8b 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -464,7 +464,7 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) struct pfsync_state_key *kw, *ks; struct pf_state *st = NULL; struct pf_state_key *skw = NULL, *sks = NULL; - struct pf_rule *r = NULL; + struct pf_krule *r = NULL; struct pfi_kif *kif; int error; diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 89236817e3e9..85a6b27d7139 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -182,7 +182,7 @@ struct pf_overload_entry { struct pf_addr addr; sa_family_t af; uint8_t dir; - struct pf_rule *rule; + struct pf_krule *rule; }; SLIST_HEAD(pf_overload_head, pf_overload_entry); @@ -197,7 +197,7 @@ MTX_SYSINIT(pf_overloadqueue_mtx, &pf_overloadqueue_mtx, #define PF_OVERLOADQ_LOCK() mtx_lock(&pf_overloadqueue_mtx) #define PF_OVERLOADQ_UNLOCK() mtx_unlock(&pf_overloadqueue_mtx) -VNET_DEFINE(struct pf_rulequeue, pf_unlinked_rules); +VNET_DEFINE(struct pf_krulequeue, pf_unlinked_rules); struct mtx pf_unlnkdrules_mtx; MTX_SYSINIT(pf_unlnkdrules_mtx, &pf_unlnkdrules_mtx, "pf unlinked rules", MTX_DEF); @@ -231,34 +231,34 @@ static void pf_change_icmp(struct pf_addr *, u_int16_t *, u_int16_t *, u_int16_t *, u_int16_t *, u_int16_t *, u_int8_t, sa_family_t); static void pf_send_tcp(struct mbuf *, - const struct pf_rule *, sa_family_t, + const struct pf_krule *, sa_family_t, const struct pf_addr *, const struct pf_addr *, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, u_int16_t, struct ifnet *); static void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, - sa_family_t, struct pf_rule *); + sa_family_t, struct pf_krule *); static void pf_detach_state(struct pf_state *); static int pf_state_key_attach(struct pf_state_key *, struct pf_state_key *, struct pf_state *); static void pf_state_key_detach(struct pf_state *, int); static int pf_state_key_ctor(void *, int, void *, int); static u_int32_t pf_tcp_iss(struct pf_pdesc *); -static int pf_test_rule(struct pf_rule **, struct pf_state **, +static int pf_test_rule(struct pf_krule **, struct pf_state **, int, struct pfi_kif *, struct mbuf *, int, - struct pf_pdesc *, struct pf_rule **, - struct pf_ruleset **, struct inpcb *); -static int pf_create_state(struct pf_rule *, struct pf_rule *, - struct pf_rule *, struct pf_pdesc *, + struct pf_pdesc *, struct pf_krule **, + struct pf_kruleset **, struct inpcb *); +static int pf_create_state(struct pf_krule *, struct pf_krule *, + struct pf_krule *, struct pf_pdesc *, 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, int); -static int pf_test_fragment(struct pf_rule **, int, +static int pf_test_fragment(struct pf_krule **, int, struct pfi_kif *, struct mbuf *, void *, - struct pf_pdesc *, struct pf_rule **, - struct pf_ruleset **); + struct pf_pdesc *, struct pf_krule **, + struct pf_kruleset **); static int pf_tcp_track_full(struct pf_state_peer *, struct pf_state_peer *, struct pf_state **, struct pfi_kif *, struct mbuf *, int, @@ -296,20 +296,20 @@ static struct pf_state *pf_find_state(struct pfi_kif *, 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_ksrc_node **, - struct pf_rule *, struct pf_addr *, sa_family_t); + struct pf_krule *, struct pf_addr *, sa_family_t); static u_int pf_purge_expired_states(u_int, int); static void pf_purge_unlinked_rules(void); static int pf_mtag_uminit(void *, int, int); static void pf_mtag_free(struct m_tag *); #ifdef INET -static void pf_route(struct mbuf **, struct pf_rule *, int, +static void pf_route(struct mbuf **, struct pf_krule *, int, struct ifnet *, struct pf_state *, struct pf_pdesc *, struct inpcb *); #endif /* INET */ #ifdef INET6 static void pf_change_a6(struct pf_addr *, u_int16_t *, struct pf_addr *, u_int8_t); -static void pf_route6(struct mbuf **, struct pf_rule *, int, +static void pf_route6(struct mbuf **, struct pf_krule *, int, struct ifnet *, struct pf_state *, struct pf_pdesc *, struct inpcb *); #endif /* INET6 */ @@ -678,7 +678,7 @@ pf_overload_task(void *v, int pending) * allocate and insert a new one. */ struct pf_ksrc_node * -pf_find_src_node(struct pf_addr *src, struct pf_rule *rule, sa_family_t af, +pf_find_src_node(struct pf_addr *src, struct pf_krule *rule, sa_family_t af, int returnlocked) { struct pf_srchash *sh; @@ -716,7 +716,7 @@ pf_free_src_node(struct pf_ksrc_node *sn) } static int -pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_rule *rule, +pf_insert_src_node(struct pf_ksrc_node **sn, struct pf_krule *rule, struct pf_addr *src, sa_family_t af) { @@ -1805,8 +1805,8 @@ relock: static void pf_purge_unlinked_rules() { - struct pf_rulequeue tmpq; - struct pf_rule *r, *r1; + struct pf_krulequeue tmpq; + struct pf_krule *r, *r1; /* * If we have overloading task pending, then we'd @@ -2031,9 +2031,9 @@ pf_print_flags(u_int8_t f) } while (0) void -pf_calc_skip_steps(struct pf_rulequeue *rules) +pf_calc_skip_steps(struct pf_krulequeue *rules) { - struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT]; + struct pf_krule *cur, *prev, *head[PF_SKIP_COUNT]; int i; cur = TAILQ_FIRST(rules); @@ -2441,7 +2441,7 @@ pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd, } static void -pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, +pf_send_tcp(struct mbuf *replyto, const struct pf_krule *r, sa_family_t af, const struct pf_addr *saddr, const struct pf_addr *daddr, u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, @@ -2601,7 +2601,7 @@ pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, } static void -pf_return(struct pf_rule *r, struct pf_rule *nr, struct pf_pdesc *pd, +pf_return(struct pf_krule *r, struct pf_krule *nr, struct pf_pdesc *pd, struct pf_state_key *sk, int off, struct mbuf *m, struct tcphdr *th, struct pfi_kif *kif, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen, u_short *reason) @@ -2716,7 +2716,7 @@ pf_match_ieee8021q_pcp(u_int8_t prio, struct mbuf *m) static void pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, - struct pf_rule *r) + struct pf_krule *r) { struct pf_send_entry *pfse; struct mbuf *m0; @@ -2904,7 +2904,7 @@ pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) } int -pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag, int mtag) +pf_match_tag(struct mbuf *m, struct pf_krule *r, int *tag, int mtag) { if (*tag == -1) *tag = mtag; @@ -2928,10 +2928,10 @@ pf_tag_packet(struct mbuf *m, struct pf_pdesc *pd, int tag) } #define PF_ANCHOR_STACKSIZE 32 -struct pf_anchor_stackframe { - struct pf_ruleset *rs; - struct pf_rule *r; /* XXX: + match bit */ - struct pf_anchor *child; +struct pf_kanchor_stackframe { + struct pf_kruleset *rs; + struct pf_krule *r; /* XXX: + match bit */ + struct pf_kanchor *child; }; /* @@ -2941,18 +2941,18 @@ struct pf_anchor_stackframe { #define PF_ANCHORSTACK_MASK (PF_ANCHORSTACK_MATCH) #define PF_ANCHOR_MATCH(f) ((uintptr_t)(f)->r & PF_ANCHORSTACK_MATCH) -#define PF_ANCHOR_RULE(f) (struct pf_rule *) \ +#define PF_ANCHOR_RULE(f) (struct pf_krule *) \ ((uintptr_t)(f)->r & ~PF_ANCHORSTACK_MASK) #define PF_ANCHOR_SET_MATCH(f) do { (f)->r = (void *) \ ((uintptr_t)(f)->r | PF_ANCHORSTACK_MATCH); \ } while (0) void -pf_step_into_anchor(struct pf_anchor_stackframe *stack, int *depth, - struct pf_ruleset **rs, int n, struct pf_rule **r, struct pf_rule **a, +pf_step_into_anchor(struct pf_kanchor_stackframe *stack, int *depth, + struct pf_kruleset **rs, int n, struct pf_krule **r, struct pf_krule **a, int *match) { - struct pf_anchor_stackframe *f; + struct pf_kanchor_stackframe *f; PF_RULES_RASSERT(); @@ -2969,9 +2969,9 @@ pf_step_into_anchor(struct pf_anchor_stackframe *stack, int *depth, f->rs = *rs; f->r = *r; if ((*r)->anchor_wildcard) { - struct pf_anchor_node *parent = &(*r)->anchor->children; + struct pf_kanchor_node *parent = &(*r)->anchor->children; - if ((f->child = RB_MIN(pf_anchor_node, parent)) == NULL) { + if ((f->child = RB_MIN(pf_kanchor_node, parent)) == NULL) { *r = NULL; return; } @@ -2984,12 +2984,12 @@ pf_step_into_anchor(struct pf_anchor_stackframe *stack, int *depth, } int -pf_step_out_of_anchor(struct pf_anchor_stackframe *stack, int *depth, - struct pf_ruleset **rs, int n, struct pf_rule **r, struct pf_rule **a, +pf_step_out_of_anchor(struct pf_kanchor_stackframe *stack, int *depth, + struct pf_kruleset **rs, int n, struct pf_krule **r, struct pf_krule **a, int *match) { - struct pf_anchor_stackframe *f; - struct pf_rule *fr; + struct pf_kanchor_stackframe *f; + struct pf_krule *fr; int quick = 0; PF_RULES_RASSERT(); @@ -3000,7 +3000,7 @@ pf_step_out_of_anchor(struct pf_anchor_stackframe *stack, int *depth, f = stack + *depth - 1; fr = PF_ANCHOR_RULE(f); if (f->child != NULL) { - struct pf_anchor_node *parent; + struct pf_kanchor_node *parent; /* * This block traverses through @@ -3016,7 +3016,7 @@ pf_step_out_of_anchor(struct pf_anchor_stackframe *stack, int *depth, PF_ANCHOR_SET_MATCH(f); *match = 0; } - f->child = RB_NEXT(pf_anchor_node, parent, f->child); + f->child = RB_NEXT(pf_kanchor_node, parent, f->child); if (f->child != NULL) { *rs = &f->child->ruleset; *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); @@ -3325,16 +3325,16 @@ pf_tcp_iss(struct pf_pdesc *pd) } static int -pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, +pf_test_rule(struct pf_krule **rm, struct pf_state **sm, int direction, struct pfi_kif *kif, struct mbuf *m, int off, struct pf_pdesc *pd, - struct pf_rule **am, struct pf_ruleset **rsm, struct inpcb *inp) + struct pf_krule **am, struct pf_kruleset **rsm, struct inpcb *inp) { - struct pf_rule *nr = NULL; + struct pf_krule *nr = NULL; struct pf_addr * const saddr = pd->src; struct pf_addr * const daddr = pd->dst; sa_family_t af = pd->af; - struct pf_rule *r, *a = NULL; - struct pf_ruleset *ruleset = NULL; + struct pf_krule *r, *a = NULL; + struct pf_kruleset *ruleset = NULL; struct pf_ksrc_node *nsn = NULL; struct tcphdr *th = pd->hdr.tcp; struct pf_state_key *sk = NULL, *nk = NULL; @@ -3347,7 +3347,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, u_int16_t sport = 0, dport = 0; u_int16_t bproto_sum = 0, bip_sum = 0; u_int8_t icmptype = 0, icmpcode = 0; - struct pf_anchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; + struct pf_kanchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; PF_RULES_RASSERT(); @@ -3699,7 +3699,7 @@ cleanup: } static int -pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, +pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, 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, @@ -3960,18 +3960,18 @@ csfailed: } static int -pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, - struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, - struct pf_ruleset **rsm) +pf_test_fragment(struct pf_krule **rm, int direction, struct pfi_kif *kif, + struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_krule **am, + struct pf_kruleset **rsm) { - struct pf_rule *r, *a = NULL; - struct pf_ruleset *ruleset = NULL; + struct pf_krule *r, *a = NULL; + struct pf_kruleset *ruleset = NULL; sa_family_t af = pd->af; u_short reason; int tag = -1; int asd = 0; int match = 0; - struct pf_anchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; + struct pf_kanchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; PF_RULES_RASSERT(); @@ -5592,7 +5592,7 @@ pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif, #ifdef INET static void -pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, +pf_route(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp, struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp) { struct mbuf *m0, *m1; @@ -5755,7 +5755,7 @@ bad: #ifdef INET6 static void -pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, +pf_route6(struct mbuf **m, struct pf_krule *r, int dir, struct ifnet *oifp, struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp) { struct mbuf *m0; @@ -6023,9 +6023,9 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb * struct mbuf *m = *m0; struct ip *h = NULL; struct m_tag *ipfwtag; - struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; + struct pf_krule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; struct pf_state *s = NULL; - struct pf_ruleset *ruleset = NULL; + struct pf_kruleset *ruleset = NULL; struct pf_pdesc pd; int off, dirndx, pqid = 0; @@ -6318,7 +6318,7 @@ done: } if (log) { - struct pf_rule *lr; + struct pf_krule *lr; if (s != NULL && s->nat_rule.ptr != NULL && s->nat_rule.ptr->log & PF_LOG_ALL) @@ -6416,9 +6416,9 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb struct mbuf *m = *m0, *n = NULL; struct m_tag *mtag; struct ip6_hdr *h = NULL; - struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; + struct pf_krule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; struct pf_state *s = NULL; - struct pf_ruleset *ruleset = NULL; + struct pf_kruleset *ruleset = NULL; struct pf_pdesc pd; int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0; @@ -6721,7 +6721,7 @@ done: printf("pf: divert(9) is not supported for IPv6\n"); if (log) { - struct pf_rule *lr; + struct pf_krule *lr; if (s != NULL && s->nat_rule.ptr != NULL && s->nat_rule.ptr->log & PF_LOG_ALL) diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h index aa6409bcbaa9..4e73d815aece 100644 --- a/sys/netpfil/pf/pf.h +++ b/sys/netpfil/pf/pf.h @@ -35,6 +35,8 @@ #ifndef _NET_PF_H_ #define _NET_PF_H_ +#include <sys/tree.h> + #define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0) #define PF_TCPS_PROXY_DST ((TCP_NSTATES)+1) @@ -569,4 +571,50 @@ struct pf_src_node { #define PFSNODE_HIWAT 10000 /* default source node table size */ +TAILQ_HEAD(pf_rulequeue, pf_rule); + +struct pf_anchor; + +struct pf_ruleset { + struct { + struct pf_rulequeue queues[2]; + struct { + struct pf_rulequeue *ptr; + struct pf_rule **ptr_array; + u_int32_t rcount; + u_int32_t ticket; + int open; + } active, inactive; + } rules[PF_RULESET_MAX]; + struct pf_anchor *anchor; + u_int32_t tticket; + int tables; + int topen; +}; + +RB_HEAD(pf_anchor_global, pf_anchor); +RB_HEAD(pf_anchor_node, pf_anchor); +struct pf_anchor { + RB_ENTRY(pf_anchor) entry_global; + RB_ENTRY(pf_anchor) entry_node; + struct pf_anchor *parent; + struct pf_anchor_node children; + char name[PF_ANCHOR_NAME_SIZE]; + char path[MAXPATHLEN]; + struct pf_ruleset ruleset; + int refcnt; /* anchor rules */ + int match; /* XXX: used for pfctl black magic */ +}; +RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare); +RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare); + +/* these ruleset functions can be linked into userland programs (pfctl) */ +int pf_get_ruleset_number(u_int8_t); +void pf_init_ruleset(struct pf_ruleset *); +int pf_anchor_setup(struct pf_rule *, + const struct pf_ruleset *, const char *); +void pf_remove_if_empty_ruleset(struct pf_ruleset *); +struct pf_ruleset *pf_find_ruleset(const char *); +struct pf_ruleset *pf_find_or_create_ruleset(const char *); + #endif /* _NET_PF_H_ */ diff --git a/sys/netpfil/pf/pf_if.c b/sys/netpfil/pf/pf_if.c index 9d761790c764..fa43ca292ae1 100644 --- a/sys/netpfil/pf/pf_if.c +++ b/sys/netpfil/pf/pf_if.c @@ -391,7 +391,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af) { struct pfi_dynaddr *dyn; char tblname[PF_TABLE_NAME_SIZE]; - struct pf_ruleset *ruleset = NULL; + struct pf_kruleset *ruleset = NULL; struct pfi_kif *kif; int rv = 0; @@ -429,7 +429,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af) if (dyn->pfid_net != 128) snprintf(tblname + strlen(tblname), sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net); - if ((ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR)) == NULL) { + if ((ruleset = pf_find_or_create_kruleset(PF_RESERVED_ANCHOR)) == NULL) { rv = ENOMEM; goto _bad; } @@ -453,7 +453,7 @@ _bad: if (dyn->pfid_kt != NULL) pfr_detach_table(dyn->pfid_kt); if (ruleset != NULL) - pf_remove_if_empty_ruleset(ruleset); + pf_remove_if_empty_kruleset(ruleset); if (dyn->pfid_kif != NULL) pfi_kif_unref(dyn->pfid_kif); free(dyn, PFI_MTYPE); diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 4767cfd48afd..e928c65734a7 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -109,11 +109,11 @@ static void pf_qid_unref(u_int32_t); #endif /* ALTQ */ static int pf_begin_rules(u_int32_t *, int, const char *); static int pf_rollback_rules(u_int32_t, int, char *); -static int pf_setup_pfsync_matching(struct pf_ruleset *); -static void pf_hash_rule(MD5_CTX *, struct pf_rule *); +static int pf_setup_pfsync_matching(struct pf_kruleset *); +static void pf_hash_rule(MD5_CTX *, struct pf_krule *); static void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *); static int pf_commit_rules(u_int32_t, int, char *); -static int pf_addr_setup(struct pf_ruleset *, +static int pf_addr_setup(struct pf_kruleset *, 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 *, @@ -125,7 +125,7 @@ static int pf_import_kaltq(struct pfioc_altq_v1 *, struct pf_altq *, size_t); #endif /* ALTQ */ -VNET_DEFINE(struct pf_rule, pf_default_rule); +VNET_DEFINE(struct pf_krule, pf_default_rule); #ifdef ALTQ VNET_DEFINE_STATIC(int, pf_altq_running); @@ -271,7 +271,7 @@ pfattach_vnet(void) V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT; RB_INIT(&V_pf_anchors); - pf_init_ruleset(&pf_main_ruleset); + pf_init_kruleset(&pf_main_ruleset); *** 1387 LINES SKIPPED ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101201444.10KEivcd019387>