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
This commit is contained in:
parent
dc865dae89
commit
e86bddea9f
234
sys/net/pfvar.h
234
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;
|
||||
@ -1294,7 +1403,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);
|
||||
@ -1304,7 +1413,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
|
||||
@ -1351,7 +1460,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 *);
|
||||
@ -1363,11 +1472,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 *);
|
||||
@ -1429,7 +1538,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);
|
||||
@ -1483,7 +1592,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);
|
||||
@ -1502,25 +1611,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 *);
|
||||
@ -1536,21 +1644,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);
|
||||
|
@ -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;
|
||||
|
@ -463,7 +463,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;
|
||||
|
||||
|
@ -181,7 +181,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);
|
||||
@ -196,7 +196,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);
|
||||
@ -230,34 +230,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,
|
||||
@ -295,20 +295,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)
|
||||
{
|
||||
|
||||
@ -1806,8 +1806,8 @@ pf_purge_expired_states(u_int i, int maxcheck)
|
||||
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
|
||||
@ -2032,9 +2032,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);
|
||||
@ -2440,7 +2440,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,
|
||||
@ -2600,7 +2600,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)
|
||||
@ -2714,7 +2714,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;
|
||||
@ -2902,7 +2902,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;
|
||||
@ -2926,10 +2926,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;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2939,18 +2939,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();
|
||||
|
||||
@ -2967,9 +2967,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;
|
||||
}
|
||||
@ -2982,12 +2982,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();
|
||||
@ -2998,7 +2998,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
|
||||
@ -3014,7 +3014,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);
|
||||
@ -3324,16 +3324,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;
|
||||
@ -3346,7 +3346,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();
|
||||
|
||||
@ -3698,7 +3698,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
|
||||
}
|
||||
|
||||
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 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@ -5463,7 +5463,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;
|
||||
@ -5626,7 +5626,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
|
||||
|
||||
#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;
|
||||
@ -5893,9 +5893,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;
|
||||
|
||||
@ -6185,7 +6185,7 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
|
||||
}
|
||||
|
||||
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)
|
||||
@ -6283,9 +6283,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;
|
||||
|
||||
@ -6585,7 +6585,7 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
|
||||
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)
|
||||
|
@ -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_ */
|
||||
|
@ -403,7 +403,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
|
||||
struct epoch_tracker et;
|
||||
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;
|
||||
|
||||
@ -441,7 +441,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;
|
||||
}
|
||||
@ -467,7 +467,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
|
||||
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);
|
||||
|
@ -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);
|
||||
|
||||
/* default rule should never be garbage collected */
|
||||
V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
|
||||
@ -337,11 +337,11 @@ pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
|
||||
u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
|
||||
u_int8_t check_ticket)
|
||||
{
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_rule *rule;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_krule *rule;
|
||||
int rs_num;
|
||||
|
||||
ruleset = pf_find_ruleset(anchor);
|
||||
ruleset = pf_find_kruleset(anchor);
|
||||
if (ruleset == NULL)
|
||||
return (NULL);
|
||||
rs_num = pf_get_ruleset_number(rule_action);
|
||||
@ -353,7 +353,7 @@ pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
|
||||
return (NULL);
|
||||
if (r_last)
|
||||
rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
|
||||
pf_rulequeue);
|
||||
pf_krulequeue);
|
||||
else
|
||||
rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
|
||||
} else {
|
||||
@ -362,7 +362,7 @@ pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
|
||||
return (NULL);
|
||||
if (r_last)
|
||||
rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
|
||||
pf_rulequeue);
|
||||
pf_krulequeue);
|
||||
else
|
||||
rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
|
||||
}
|
||||
@ -411,7 +411,7 @@ pf_empty_pool(struct pf_palist *poola)
|
||||
}
|
||||
|
||||
static void
|
||||
pf_unlink_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
|
||||
pf_unlink_rule(struct pf_krulequeue *rulequeue, struct pf_krule *rule)
|
||||
{
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
@ -425,7 +425,7 @@ pf_unlink_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
|
||||
}
|
||||
|
||||
void
|
||||
pf_free_rule(struct pf_rule *rule)
|
||||
pf_free_rule(struct pf_krule *rule)
|
||||
{
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
@ -459,7 +459,7 @@ pf_free_rule(struct pf_rule *rule)
|
||||
pfr_detach_table(rule->overload_tbl);
|
||||
if (rule->kif)
|
||||
pfi_kif_unref(rule->kif);
|
||||
pf_anchor_remove(rule);
|
||||
pf_kanchor_remove(rule);
|
||||
pf_empty_pool(&rule->rpool.list);
|
||||
counter_u64_free(rule->states_cur);
|
||||
counter_u64_free(rule->states_tot);
|
||||
@ -896,14 +896,14 @@ pf_altq_ifnet_event(struct ifnet *ifp, int remove)
|
||||
static int
|
||||
pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
|
||||
{
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_rule *rule;
|
||||
struct pf_kruleset *rs;
|
||||
struct pf_krule *rule;
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
|
||||
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
|
||||
return (EINVAL);
|
||||
rs = pf_find_or_create_ruleset(anchor);
|
||||
rs = pf_find_or_create_kruleset(anchor);
|
||||
if (rs == NULL)
|
||||
return (EINVAL);
|
||||
while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
|
||||
@ -918,14 +918,14 @@ pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
|
||||
static int
|
||||
pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
|
||||
{
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_rule *rule;
|
||||
struct pf_kruleset *rs;
|
||||
struct pf_krule *rule;
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
|
||||
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
|
||||
return (EINVAL);
|
||||
rs = pf_find_ruleset(anchor);
|
||||
rs = pf_find_kruleset(anchor);
|
||||
if (rs == NULL || !rs->rules[rs_num].inactive.open ||
|
||||
rs->rules[rs_num].inactive.ticket != ticket)
|
||||
return (0);
|
||||
@ -979,7 +979,7 @@ pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
|
||||
}
|
||||
|
||||
static void
|
||||
pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule)
|
||||
pf_hash_rule(MD5_CTX *ctx, struct pf_krule *rule)
|
||||
{
|
||||
u_int16_t x;
|
||||
u_int32_t y;
|
||||
@ -1020,9 +1020,9 @@ pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule)
|
||||
static int
|
||||
pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
|
||||
{
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_rule *rule, **old_array;
|
||||
struct pf_rulequeue *old_rules;
|
||||
struct pf_kruleset *rs;
|
||||
struct pf_krule *rule, **old_array;
|
||||
struct pf_krulequeue *old_rules;
|
||||
int error;
|
||||
u_int32_t old_rcount;
|
||||
|
||||
@ -1030,7 +1030,7 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
|
||||
|
||||
if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
|
||||
return (EINVAL);
|
||||
rs = pf_find_ruleset(anchor);
|
||||
rs = pf_find_kruleset(anchor);
|
||||
if (rs == NULL || !rs->rules[rs_num].inactive.open ||
|
||||
ticket != rs->rules[rs_num].inactive.ticket)
|
||||
return (EBUSY);
|
||||
@ -1069,16 +1069,16 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
|
||||
rs->rules[rs_num].inactive.ptr_array = NULL;
|
||||
rs->rules[rs_num].inactive.rcount = 0;
|
||||
rs->rules[rs_num].inactive.open = 0;
|
||||
pf_remove_if_empty_ruleset(rs);
|
||||
pf_remove_if_empty_kruleset(rs);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pf_setup_pfsync_matching(struct pf_ruleset *rs)
|
||||
pf_setup_pfsync_matching(struct pf_kruleset *rs)
|
||||
{
|
||||
MD5_CTX ctx;
|
||||
struct pf_rule *rule;
|
||||
struct pf_krule *rule;
|
||||
int rs_cnt;
|
||||
u_int8_t digest[PF_MD5_DIGEST_LENGTH];
|
||||
|
||||
@ -1115,7 +1115,7 @@ pf_setup_pfsync_matching(struct pf_ruleset *rs)
|
||||
}
|
||||
|
||||
static int
|
||||
pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr,
|
||||
pf_addr_setup(struct pf_kruleset *ruleset, struct pf_addr_wrap *addr,
|
||||
sa_family_t af)
|
||||
{
|
||||
int error = 0;
|
||||
@ -1425,6 +1425,194 @@ pf_altq_get_nth_active(u_int32_t n)
|
||||
}
|
||||
#endif /* ALTQ */
|
||||
|
||||
static void
|
||||
pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule)
|
||||
{
|
||||
|
||||
bzero(rule, sizeof(*rule));
|
||||
|
||||
bcopy(&krule->src, &rule->src, sizeof(rule->src));
|
||||
bcopy(&krule->dst, &rule->dst, sizeof(rule->dst));
|
||||
|
||||
for (int i = 0; i < PF_SKIP_COUNT; ++i) {
|
||||
if (rule->skip[i].ptr == NULL)
|
||||
rule->skip[i].nr = -1;
|
||||
else
|
||||
rule->skip[i].nr = krule->skip[i].ptr->nr;
|
||||
}
|
||||
|
||||
strlcpy(rule->label, krule->label, sizeof(rule->label));
|
||||
strlcpy(rule->ifname, krule->ifname, sizeof(rule->ifname));
|
||||
strlcpy(rule->qname, krule->qname, sizeof(rule->qname));
|
||||
strlcpy(rule->pqname, krule->pqname, sizeof(rule->pqname));
|
||||
strlcpy(rule->tagname, krule->tagname, sizeof(rule->tagname));
|
||||
strlcpy(rule->match_tagname, krule->match_tagname,
|
||||
sizeof(rule->match_tagname));
|
||||
strlcpy(rule->overload_tblname, krule->overload_tblname,
|
||||
sizeof(rule->overload_tblname));
|
||||
|
||||
bcopy(&krule->rpool, &rule->rpool, sizeof(krule->rpool));
|
||||
|
||||
rule->evaluations = krule->evaluations;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
rule->packets[i] = krule->packets[i];
|
||||
rule->bytes[i] = krule->bytes[i];
|
||||
}
|
||||
|
||||
/* kif, anchor, overload_tbl are not copied over. */
|
||||
|
||||
rule->os_fingerprint = krule->os_fingerprint;
|
||||
|
||||
rule->rtableid = krule->rtableid;
|
||||
bcopy(krule->timeout, rule->timeout, sizeof(krule->timeout));
|
||||
rule->max_states = krule->max_states;
|
||||
rule->max_src_nodes = krule->max_src_nodes;
|
||||
rule->max_src_states = krule->max_src_states;
|
||||
rule->max_src_conn = krule->max_src_conn;
|
||||
rule->max_src_conn_rate.limit = krule->max_src_conn_rate.limit;
|
||||
rule->max_src_conn_rate.seconds = krule->max_src_conn_rate.seconds;
|
||||
rule->qid = krule->qid;
|
||||
rule->pqid = krule->pqid;
|
||||
rule->rt_listid = krule->rt_listid;
|
||||
rule->nr = krule->nr;
|
||||
rule->prob = krule->prob;
|
||||
rule->cuid = krule->cuid;
|
||||
rule->cpid = krule->cpid;
|
||||
|
||||
rule->return_icmp = krule->return_icmp;
|
||||
rule->return_icmp6 = krule->return_icmp6;
|
||||
rule->max_mss = krule->max_mss;
|
||||
rule->tag = krule->tag;
|
||||
rule->match_tag = krule->match_tag;
|
||||
rule->scrub_flags = krule->scrub_flags;
|
||||
|
||||
bcopy(&krule->uid, &rule->uid, sizeof(krule->uid));
|
||||
bcopy(&krule->gid, &rule->gid, sizeof(krule->gid));
|
||||
|
||||
rule->rule_flag = krule->rule_flag;
|
||||
rule->action = krule->action;
|
||||
rule->direction = krule->direction;
|
||||
rule->log = krule->log;
|
||||
rule->logif = krule->logif;
|
||||
rule->quick = krule->quick;
|
||||
rule->ifnot = krule->ifnot;
|
||||
rule->match_tag_not = krule->match_tag_not;
|
||||
rule->natpass = krule->natpass;
|
||||
|
||||
rule->keep_state = krule->keep_state;
|
||||
rule->af = krule->af;
|
||||
rule->proto = krule->proto;
|
||||
rule->type = krule->type;
|
||||
rule->code = krule->code;
|
||||
rule->flags = krule->flags;
|
||||
rule->flagset = krule->flagset;
|
||||
rule->min_ttl = krule->min_ttl;
|
||||
rule->allow_opts = krule->allow_opts;
|
||||
rule->rt = krule->rt;
|
||||
rule->return_ttl = krule->return_ttl;
|
||||
rule->tos = krule->tos;
|
||||
rule->set_tos = krule->set_tos;
|
||||
rule->anchor_relative = krule->anchor_relative;
|
||||
rule->anchor_wildcard = krule->anchor_wildcard;
|
||||
|
||||
rule->flush = krule->flush;
|
||||
rule->prio = krule->prio;
|
||||
rule->set_prio[0] = krule->set_prio[0];
|
||||
rule->set_prio[1] = krule->set_prio[1];
|
||||
|
||||
bcopy(&krule->divert, &rule->divert, sizeof(krule->divert));
|
||||
|
||||
rule->u_states_cur = counter_u64_fetch(krule->states_cur);
|
||||
rule->u_states_tot = counter_u64_fetch(krule->states_tot);
|
||||
rule->u_src_nodes = counter_u64_fetch(krule->src_nodes);
|
||||
}
|
||||
|
||||
static void
|
||||
pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
|
||||
{
|
||||
|
||||
bzero(krule, sizeof(*krule));
|
||||
|
||||
bcopy(&rule->src, &krule->src, sizeof(rule->src));
|
||||
bcopy(&rule->dst, &krule->dst, sizeof(rule->dst));
|
||||
|
||||
strlcpy(krule->label, rule->label, sizeof(rule->label));
|
||||
strlcpy(krule->ifname, rule->ifname, sizeof(rule->ifname));
|
||||
strlcpy(krule->qname, rule->qname, sizeof(rule->qname));
|
||||
strlcpy(krule->pqname, rule->pqname, sizeof(rule->pqname));
|
||||
strlcpy(krule->tagname, rule->tagname, sizeof(rule->tagname));
|
||||
strlcpy(krule->match_tagname, rule->match_tagname,
|
||||
sizeof(rule->match_tagname));
|
||||
strlcpy(krule->overload_tblname, rule->overload_tblname,
|
||||
sizeof(rule->overload_tblname));
|
||||
|
||||
bcopy(&rule->rpool, &krule->rpool, sizeof(krule->rpool));
|
||||
|
||||
/* Don't allow userspace to set evaulations, packets or bytes. */
|
||||
/* kif, anchor, overload_tbl are not copied over. */
|
||||
|
||||
krule->os_fingerprint = krule->os_fingerprint;
|
||||
|
||||
krule->rtableid = rule->rtableid;
|
||||
bcopy(rule->timeout, krule->timeout, sizeof(krule->timeout));
|
||||
krule->max_states = rule->max_states;
|
||||
krule->max_src_nodes = rule->max_src_nodes;
|
||||
krule->max_src_states = rule->max_src_states;
|
||||
krule->max_src_conn = rule->max_src_conn;
|
||||
krule->max_src_conn_rate.limit = rule->max_src_conn_rate.limit;
|
||||
krule->max_src_conn_rate.seconds = rule->max_src_conn_rate.seconds;
|
||||
krule->qid = rule->qid;
|
||||
krule->pqid = rule->pqid;
|
||||
krule->rt_listid = rule->rt_listid;
|
||||
krule->nr = rule->nr;
|
||||
krule->prob = rule->prob;
|
||||
krule->cuid = rule->cuid;
|
||||
krule->cpid = rule->cpid;
|
||||
|
||||
krule->return_icmp = rule->return_icmp;
|
||||
krule->return_icmp6 = rule->return_icmp6;
|
||||
krule->max_mss = rule->max_mss;
|
||||
krule->tag = rule->tag;
|
||||
krule->match_tag = rule->match_tag;
|
||||
krule->scrub_flags = rule->scrub_flags;
|
||||
|
||||
bcopy(&rule->uid, &krule->uid, sizeof(krule->uid));
|
||||
bcopy(&rule->gid, &krule->gid, sizeof(krule->gid));
|
||||
|
||||
krule->rule_flag = rule->rule_flag;
|
||||
krule->action = rule->action;
|
||||
krule->direction = rule->direction;
|
||||
krule->log = rule->log;
|
||||
krule->logif = rule->logif;
|
||||
krule->quick = rule->quick;
|
||||
krule->ifnot = rule->ifnot;
|
||||
krule->match_tag_not = rule->match_tag_not;
|
||||
krule->natpass = rule->natpass;
|
||||
|
||||
krule->keep_state = rule->keep_state;
|
||||
krule->af = rule->af;
|
||||
krule->proto = rule->proto;
|
||||
krule->type = rule->type;
|
||||
krule->code = rule->code;
|
||||
krule->flags = rule->flags;
|
||||
krule->flagset = rule->flagset;
|
||||
krule->min_ttl = rule->min_ttl;
|
||||
krule->allow_opts = rule->allow_opts;
|
||||
krule->rt = rule->rt;
|
||||
krule->return_ttl = rule->return_ttl;
|
||||
krule->tos = rule->tos;
|
||||
krule->set_tos = rule->set_tos;
|
||||
krule->anchor_relative = rule->anchor_relative;
|
||||
krule->anchor_wildcard = rule->anchor_wildcard;
|
||||
|
||||
krule->flush = rule->flush;
|
||||
krule->prio = rule->prio;
|
||||
krule->set_prio[0] = rule->set_prio[0];
|
||||
krule->set_prio[1] = rule->set_prio[1];
|
||||
|
||||
bcopy(&rule->divert, &krule->divert, sizeof(krule->divert));
|
||||
}
|
||||
|
||||
static int
|
||||
pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
|
||||
{
|
||||
@ -1587,8 +1775,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
case DIOCADDRULE: {
|
||||
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_rule *rule, *tail;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_krule *rule, *tail;
|
||||
struct pf_pooladdr *pa;
|
||||
struct pfi_kif *kif = NULL;
|
||||
int rs_num;
|
||||
@ -1616,7 +1804,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
#endif /* INET6 */
|
||||
|
||||
rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
|
||||
bcopy(&pr->rule, rule, sizeof(struct pf_rule));
|
||||
pf_rule_to_krule(&pr->rule, rule);
|
||||
|
||||
if (rule->ifname[0])
|
||||
kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK);
|
||||
rule->states_cur = counter_u64_alloc(M_WAITOK);
|
||||
@ -1629,7 +1818,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
PF_RULES_WLOCK();
|
||||
pr->anchor[sizeof(pr->anchor) - 1] = 0;
|
||||
ruleset = pf_find_ruleset(pr->anchor);
|
||||
ruleset = pf_find_kruleset(pr->anchor);
|
||||
if (ruleset == NULL)
|
||||
ERROUT(EINVAL);
|
||||
rs_num = pf_get_ruleset_number(pr->rule.action);
|
||||
@ -1649,7 +1838,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
}
|
||||
|
||||
tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
|
||||
pf_rulequeue);
|
||||
pf_krulequeue);
|
||||
if (tail)
|
||||
rule->nr = tail->nr + 1;
|
||||
else
|
||||
@ -1693,7 +1882,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
error = ENOMEM;
|
||||
if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
|
||||
error = ENOMEM;
|
||||
if (pf_anchor_setup(rule, ruleset, pr->anchor_call))
|
||||
if (pf_kanchor_setup(rule, ruleset, pr->anchor_call))
|
||||
error = EINVAL;
|
||||
if (rule->scrub_flags & PFSTATE_SETPRIO &&
|
||||
(rule->set_prio[0] > PF_PRIO_MAX ||
|
||||
@ -1753,13 +1942,13 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
case DIOCGETRULES: {
|
||||
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_rule *tail;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_krule *tail;
|
||||
int rs_num;
|
||||
|
||||
PF_RULES_WLOCK();
|
||||
pr->anchor[sizeof(pr->anchor) - 1] = 0;
|
||||
ruleset = pf_find_ruleset(pr->anchor);
|
||||
ruleset = pf_find_kruleset(pr->anchor);
|
||||
if (ruleset == NULL) {
|
||||
PF_RULES_WUNLOCK();
|
||||
error = EINVAL;
|
||||
@ -1772,7 +1961,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
break;
|
||||
}
|
||||
tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
|
||||
pf_rulequeue);
|
||||
pf_krulequeue);
|
||||
if (tail)
|
||||
pr->nr = tail->nr + 1;
|
||||
else
|
||||
@ -1784,13 +1973,13 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
case DIOCGETRULE: {
|
||||
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_rule *rule;
|
||||
int rs_num, i;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_krule *rule;
|
||||
int rs_num;
|
||||
|
||||
PF_RULES_WLOCK();
|
||||
pr->anchor[sizeof(pr->anchor) - 1] = 0;
|
||||
ruleset = pf_find_ruleset(pr->anchor);
|
||||
ruleset = pf_find_kruleset(pr->anchor);
|
||||
if (ruleset == NULL) {
|
||||
PF_RULES_WUNLOCK();
|
||||
error = EINVAL;
|
||||
@ -1815,23 +2004,16 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
bcopy(rule, &pr->rule, sizeof(struct pf_rule));
|
||||
pr->rule.u_states_cur = counter_u64_fetch(rule->states_cur);
|
||||
pr->rule.u_states_tot = counter_u64_fetch(rule->states_tot);
|
||||
pr->rule.u_src_nodes = counter_u64_fetch(rule->src_nodes);
|
||||
if (pf_anchor_copyout(ruleset, rule, pr)) {
|
||||
|
||||
pf_krule_to_rule(rule, &pr->rule);
|
||||
|
||||
if (pf_kanchor_copyout(ruleset, rule, pr)) {
|
||||
PF_RULES_WUNLOCK();
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
pf_addr_copyout(&pr->rule.src.addr);
|
||||
pf_addr_copyout(&pr->rule.dst.addr);
|
||||
for (i = 0; i < PF_SKIP_COUNT; ++i)
|
||||
if (rule->skip[i].ptr == NULL)
|
||||
pr->rule.skip[i].nr = -1;
|
||||
else
|
||||
pr->rule.skip[i].nr =
|
||||
rule->skip[i].ptr->nr;
|
||||
|
||||
if (pr->action == PF_GET_CLR_CNTR) {
|
||||
rule->evaluations = 0;
|
||||
@ -1845,8 +2027,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
case DIOCCHANGERULE: {
|
||||
struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_rule *oldrule = NULL, *newrule = NULL;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_krule *oldrule = NULL, *newrule = NULL;
|
||||
struct pfi_kif *kif = NULL;
|
||||
struct pf_pooladdr *pa;
|
||||
u_int32_t nr = 0;
|
||||
@ -1876,7 +2058,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
}
|
||||
#endif /* INET6 */
|
||||
newrule = malloc(sizeof(*newrule), M_PFRULE, M_WAITOK);
|
||||
bcopy(&pcr->rule, newrule, sizeof(struct pf_rule));
|
||||
pf_rule_to_krule(&pcr->rule, newrule);
|
||||
|
||||
if (newrule->ifname[0])
|
||||
kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK);
|
||||
newrule->states_cur = counter_u64_alloc(M_WAITOK);
|
||||
@ -1894,7 +2077,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
pcr->pool_ticket != V_ticket_pabuf)
|
||||
ERROUT(EBUSY);
|
||||
|
||||
ruleset = pf_find_ruleset(pcr->anchor);
|
||||
ruleset = pf_find_kruleset(pcr->anchor);
|
||||
if (ruleset == NULL)
|
||||
ERROUT(EINVAL);
|
||||
|
||||
@ -1953,7 +2136,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
error = ENOMEM;
|
||||
if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
|
||||
error = ENOMEM;
|
||||
if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
|
||||
if (pf_kanchor_setup(newrule, ruleset, pcr->anchor_call))
|
||||
error = EINVAL;
|
||||
TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
|
||||
if (pa->addr.type == PF_ADDR_TABLE) {
|
||||
@ -2002,7 +2185,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
ruleset->rules[rs_num].active.ptr);
|
||||
else if (pcr->action == PF_CHANGE_ADD_TAIL)
|
||||
oldrule = TAILQ_LAST(
|
||||
ruleset->rules[rs_num].active.ptr, pf_rulequeue);
|
||||
ruleset->rules[rs_num].active.ptr, pf_krulequeue);
|
||||
else {
|
||||
oldrule = TAILQ_FIRST(
|
||||
ruleset->rules[rs_num].active.ptr);
|
||||
@ -2044,7 +2227,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
ruleset->rules[rs_num].active.ticket++;
|
||||
|
||||
pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
|
||||
pf_remove_if_empty_ruleset(ruleset);
|
||||
pf_remove_if_empty_kruleset(ruleset);
|
||||
|
||||
PF_RULES_WUNLOCK();
|
||||
break;
|
||||
@ -2432,8 +2615,8 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
case DIOCCLRRULECTRS: {
|
||||
/* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
|
||||
struct pf_ruleset *ruleset = &pf_main_ruleset;
|
||||
struct pf_rule *rule;
|
||||
struct pf_kruleset *ruleset = &pf_main_ruleset;
|
||||
struct pf_krule *rule;
|
||||
|
||||
PF_RULES_WLOCK();
|
||||
TAILQ_FOREACH(rule,
|
||||
@ -2775,7 +2958,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
|
||||
struct pf_pool *pool;
|
||||
struct pf_pooladdr *oldpa = NULL, *newpa = NULL;
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pfi_kif *kif = NULL;
|
||||
|
||||
if (pca->action < PF_CHANGE_ADD_HEAD ||
|
||||
@ -2815,7 +2998,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
}
|
||||
#define ERROUT(x) { error = (x); goto DIOCCHANGEADDR_error; }
|
||||
PF_RULES_WLOCK();
|
||||
ruleset = pf_find_ruleset(pca->anchor);
|
||||
ruleset = pf_find_kruleset(pca->anchor);
|
||||
if (ruleset == NULL)
|
||||
ERROUT(EBUSY);
|
||||
|
||||
@ -2907,12 +3090,12 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
case DIOCGETRULESETS: {
|
||||
struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_anchor *anchor;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_kanchor *anchor;
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
pr->path[sizeof(pr->path) - 1] = 0;
|
||||
if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
|
||||
if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
|
||||
PF_RULES_RUNLOCK();
|
||||
error = ENOENT;
|
||||
break;
|
||||
@ -2920,11 +3103,11 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
pr->nr = 0;
|
||||
if (ruleset->anchor == NULL) {
|
||||
/* XXX kludge for pf_main_ruleset */
|
||||
RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)
|
||||
RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
|
||||
if (anchor->parent == NULL)
|
||||
pr->nr++;
|
||||
} else {
|
||||
RB_FOREACH(anchor, pf_anchor_node,
|
||||
RB_FOREACH(anchor, pf_kanchor_node,
|
||||
&ruleset->anchor->children)
|
||||
pr->nr++;
|
||||
}
|
||||
@ -2934,13 +3117,13 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
|
||||
case DIOCGETRULESET: {
|
||||
struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
|
||||
struct pf_ruleset *ruleset;
|
||||
struct pf_anchor *anchor;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_kanchor *anchor;
|
||||
u_int32_t nr = 0;
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
pr->path[sizeof(pr->path) - 1] = 0;
|
||||
if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
|
||||
if ((ruleset = pf_find_kruleset(pr->path)) == NULL) {
|
||||
PF_RULES_RUNLOCK();
|
||||
error = ENOENT;
|
||||
break;
|
||||
@ -2948,14 +3131,14 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
pr->name[0] = 0;
|
||||
if (ruleset->anchor == NULL) {
|
||||
/* XXX kludge for pf_main_ruleset */
|
||||
RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)
|
||||
RB_FOREACH(anchor, pf_kanchor_global, &V_pf_anchors)
|
||||
if (anchor->parent == NULL && nr++ == pr->nr) {
|
||||
strlcpy(pr->name, anchor->name,
|
||||
sizeof(pr->name));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
RB_FOREACH(anchor, pf_anchor_node,
|
||||
RB_FOREACH(anchor, pf_kanchor_node,
|
||||
&ruleset->anchor->children)
|
||||
if (nr++ == pr->nr) {
|
||||
strlcpy(pr->name, anchor->name,
|
||||
@ -3681,7 +3864,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
case DIOCXCOMMIT: {
|
||||
struct pfioc_trans *io = (struct pfioc_trans *)addr;
|
||||
struct pfioc_trans_e *ioe, *ioes;
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_kruleset *rs;
|
||||
size_t totlen;
|
||||
int i;
|
||||
|
||||
@ -3731,7 +3914,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
break;
|
||||
#endif /* ALTQ */
|
||||
case PF_RULESET_TABLE:
|
||||
rs = pf_find_ruleset(ioe->anchor);
|
||||
rs = pf_find_kruleset(ioe->anchor);
|
||||
if (rs == NULL || !rs->topen || ioe->ticket !=
|
||||
rs->tticket) {
|
||||
PF_RULES_WUNLOCK();
|
||||
@ -3748,7 +3931,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
error = EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
rs = pf_find_ruleset(ioe->anchor);
|
||||
rs = pf_find_kruleset(ioe->anchor);
|
||||
if (rs == NULL ||
|
||||
!rs->rules[ioe->rs_num].inactive.open ||
|
||||
rs->rules[ioe->rs_num].inactive.ticket !=
|
||||
|
@ -58,11 +58,11 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static void pf_hash(struct pf_addr *, struct pf_addr *,
|
||||
struct pf_poolhashkey *, sa_family_t);
|
||||
static struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
|
||||
static struct pf_krule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
|
||||
int, int, struct pfi_kif *,
|
||||
struct pf_addr *, u_int16_t, struct pf_addr *,
|
||||
uint16_t, int, struct pf_anchor_stackframe *);
|
||||
static int pf_get_sport(sa_family_t, uint8_t, struct pf_rule *,
|
||||
uint16_t, int, struct pf_kanchor_stackframe *);
|
||||
static int pf_get_sport(sa_family_t, uint8_t, struct pf_krule *,
|
||||
struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *,
|
||||
uint16_t *, uint16_t, uint16_t, struct pf_ksrc_node **);
|
||||
|
||||
@ -123,14 +123,14 @@ pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
|
||||
}
|
||||
}
|
||||
|
||||
static struct pf_rule *
|
||||
static struct pf_krule *
|
||||
pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
|
||||
int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
|
||||
struct pf_addr *daddr, uint16_t dport, int rs_num,
|
||||
struct pf_anchor_stackframe *anchor_stack)
|
||||
struct pf_kanchor_stackframe *anchor_stack)
|
||||
{
|
||||
struct pf_rule *r, *rm = NULL;
|
||||
struct pf_ruleset *ruleset = NULL;
|
||||
struct pf_krule *r, *rm = NULL;
|
||||
struct pf_kruleset *ruleset = NULL;
|
||||
int tag = -1;
|
||||
int rtableid = -1;
|
||||
int asd = 0;
|
||||
@ -212,7 +212,7 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
|
||||
}
|
||||
|
||||
static int
|
||||
pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
|
||||
pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *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_ksrc_node **sn)
|
||||
@ -311,7 +311,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,
|
||||
pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
|
||||
struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_ksrc_node **sn)
|
||||
{
|
||||
struct pf_pool *rpool = &r->rpool;
|
||||
@ -520,14 +520,14 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct pf_rule *
|
||||
struct pf_krule *
|
||||
pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
|
||||
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)
|
||||
uint16_t sport, uint16_t dport, struct pf_kanchor_stackframe *anchor_stack)
|
||||
{
|
||||
struct pf_rule *r = NULL;
|
||||
struct pf_krule *r = NULL;
|
||||
struct pf_addr *naddr;
|
||||
uint16_t *nport;
|
||||
|
||||
|
@ -134,7 +134,7 @@ static RB_GENERATE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
|
||||
static void pf_flush_fragments(void);
|
||||
static void pf_free_fragment(struct pf_fragment *);
|
||||
static void pf_remove_fragment(struct pf_fragment *);
|
||||
static int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
|
||||
static int pf_normalize_tcpopt(struct pf_krule *, struct mbuf *,
|
||||
struct tcphdr *, int, sa_family_t);
|
||||
static struct pf_frent *pf_create_fragment(u_short *);
|
||||
static int pf_frent_holes(struct pf_frent *frent);
|
||||
@ -997,7 +997,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
|
||||
struct pf_pdesc *pd)
|
||||
{
|
||||
struct mbuf *m = *m0;
|
||||
struct pf_rule *r;
|
||||
struct pf_krule *r;
|
||||
struct ip *h = mtod(m, struct ip *);
|
||||
int mff = (ntohs(h->ip_off) & IP_MF);
|
||||
int hlen = h->ip_hl << 2;
|
||||
@ -1138,7 +1138,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
|
||||
u_short *reason, struct pf_pdesc *pd)
|
||||
{
|
||||
struct mbuf *m = *m0;
|
||||
struct pf_rule *r;
|
||||
struct pf_krule *r;
|
||||
struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
|
||||
int extoff;
|
||||
int off;
|
||||
@ -1298,7 +1298,7 @@ int
|
||||
pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
|
||||
int off, void *h, struct pf_pdesc *pd)
|
||||
{
|
||||
struct pf_rule *r, *rm = NULL;
|
||||
struct pf_krule *r, *rm = NULL;
|
||||
struct tcphdr *th = pd->hdr.tcp;
|
||||
int rewrite = 0;
|
||||
u_short reason;
|
||||
@ -1901,7 +1901,7 @@ pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
|
||||
}
|
||||
|
||||
static int
|
||||
pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
|
||||
pf_normalize_tcpopt(struct pf_krule *r, struct mbuf *m, struct tcphdr *th,
|
||||
int off, sa_family_t af)
|
||||
{
|
||||
u_int16_t *mss;
|
||||
|
@ -87,8 +87,8 @@ __FBSDID("$FreeBSD$");
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef _KERNEL
|
||||
VNET_DEFINE(struct pf_anchor_global, pf_anchors);
|
||||
VNET_DEFINE(struct pf_anchor, pf_main_anchor);
|
||||
VNET_DEFINE(struct pf_kanchor_global, pf_anchors);
|
||||
VNET_DEFINE(struct pf_kanchor, pf_main_anchor);
|
||||
#else /* ! _KERNEL */
|
||||
struct pf_anchor_global pf_anchors;
|
||||
struct pf_anchor pf_main_anchor;
|
||||
@ -98,13 +98,25 @@ struct pf_anchor pf_main_anchor;
|
||||
#define pf_main_ruleset pf_main_anchor.ruleset
|
||||
#endif /* _KERNEL */
|
||||
|
||||
static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
|
||||
|
||||
#ifdef _KERNEL
|
||||
static __inline int pf_kanchor_compare(struct pf_kanchor *,
|
||||
struct pf_kanchor *);
|
||||
static struct pf_kanchor *pf_find_kanchor(const char *);
|
||||
|
||||
RB_GENERATE(pf_kanchor_global, pf_kanchor, entry_global, pf_kanchor_compare);
|
||||
RB_GENERATE(pf_kanchor_node, pf_kanchor, entry_node, pf_kanchor_compare);
|
||||
#else
|
||||
static __inline int pf_anchor_compare(struct pf_anchor *,
|
||||
struct pf_anchor *);
|
||||
static struct pf_anchor *pf_find_anchor(const char *);
|
||||
|
||||
RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
|
||||
RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _KERNEL
|
||||
static __inline int
|
||||
pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
|
||||
{
|
||||
@ -112,6 +124,15 @@ pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
|
||||
|
||||
return (c ? (c < 0 ? -1 : 1) : 0);
|
||||
}
|
||||
#else
|
||||
static __inline int
|
||||
pf_kanchor_compare(struct pf_kanchor *a, struct pf_kanchor *b)
|
||||
{
|
||||
int c = strcmp(a->path, b->path);
|
||||
|
||||
return (c ? (c < 0 ? -1 : 1) : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
pf_get_ruleset_number(u_int8_t action)
|
||||
@ -143,6 +164,7 @@ pf_get_ruleset_number(u_int8_t action)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _KERNEL
|
||||
void
|
||||
pf_init_ruleset(struct pf_ruleset *ruleset)
|
||||
{
|
||||
@ -170,6 +192,292 @@ pf_find_anchor(const char *path)
|
||||
rs_free(key);
|
||||
return (found);
|
||||
}
|
||||
#else
|
||||
static struct pf_kanchor *
|
||||
pf_find_kanchor(const char *path)
|
||||
{
|
||||
struct pf_kanchor *key, *found;
|
||||
|
||||
key = (struct pf_kanchor *)rs_malloc(sizeof(*key));
|
||||
if (key == NULL)
|
||||
return (NULL);
|
||||
strlcpy(key->path, path, sizeof(key->path));
|
||||
found = RB_FIND(pf_kanchor_global, &V_pf_anchors, key);
|
||||
rs_free(key);
|
||||
return (found);
|
||||
}
|
||||
|
||||
void
|
||||
pf_init_kruleset(struct pf_kruleset *ruleset)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(ruleset, 0, sizeof(struct pf_kruleset));
|
||||
for (i = 0; i < PF_RULESET_MAX; i++) {
|
||||
TAILQ_INIT(&ruleset->rules[i].queues[0]);
|
||||
TAILQ_INIT(&ruleset->rules[i].queues[1]);
|
||||
ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
|
||||
ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct pf_kruleset *
|
||||
pf_find_kruleset(const char *path)
|
||||
{
|
||||
struct pf_kanchor *anchor;
|
||||
|
||||
while (*path == '/')
|
||||
path++;
|
||||
if (!*path)
|
||||
return (&pf_main_ruleset);
|
||||
anchor = pf_find_kanchor(path);
|
||||
if (anchor == NULL)
|
||||
return (NULL);
|
||||
else
|
||||
return (&anchor->ruleset);
|
||||
}
|
||||
|
||||
struct pf_kruleset *
|
||||
pf_find_or_create_kruleset(const char *path)
|
||||
{
|
||||
char *p, *q, *r;
|
||||
struct pf_kruleset *ruleset;
|
||||
struct pf_kanchor *anchor = NULL, *dup, *parent = NULL;
|
||||
|
||||
if (path[0] == 0)
|
||||
return (&pf_main_ruleset);
|
||||
while (*path == '/')
|
||||
path++;
|
||||
ruleset = pf_find_kruleset(path);
|
||||
if (ruleset != NULL)
|
||||
return (ruleset);
|
||||
p = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
strlcpy(p, path, MAXPATHLEN);
|
||||
while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
|
||||
*q = 0;
|
||||
if ((ruleset = pf_find_kruleset(p)) != NULL) {
|
||||
parent = ruleset->anchor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (q == NULL)
|
||||
q = p;
|
||||
else
|
||||
q++;
|
||||
strlcpy(p, path, MAXPATHLEN);
|
||||
if (!*q) {
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
while ((r = strchr(q, '/')) != NULL || *q) {
|
||||
if (r != NULL)
|
||||
*r = 0;
|
||||
if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
|
||||
(parent != NULL && strlen(parent->path) >=
|
||||
MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)) {
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
anchor = (struct pf_kanchor *)rs_malloc(sizeof(*anchor));
|
||||
if (anchor == NULL) {
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
RB_INIT(&anchor->children);
|
||||
strlcpy(anchor->name, q, sizeof(anchor->name));
|
||||
if (parent != NULL) {
|
||||
strlcpy(anchor->path, parent->path,
|
||||
sizeof(anchor->path));
|
||||
strlcat(anchor->path, "/", sizeof(anchor->path));
|
||||
}
|
||||
strlcat(anchor->path, anchor->name, sizeof(anchor->path));
|
||||
if ((dup = RB_INSERT(pf_kanchor_global, &V_pf_anchors, anchor)) !=
|
||||
NULL) {
|
||||
printf("pf_find_or_create_ruleset: RB_INSERT1 "
|
||||
"'%s' '%s' collides with '%s' '%s'\n",
|
||||
anchor->path, anchor->name, dup->path, dup->name);
|
||||
rs_free(anchor);
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
if (parent != NULL) {
|
||||
anchor->parent = parent;
|
||||
if ((dup = RB_INSERT(pf_kanchor_node, &parent->children,
|
||||
anchor)) != NULL) {
|
||||
printf("pf_find_or_create_ruleset: "
|
||||
"RB_INSERT2 '%s' '%s' collides with "
|
||||
"'%s' '%s'\n", anchor->path, anchor->name,
|
||||
dup->path, dup->name);
|
||||
RB_REMOVE(pf_kanchor_global, &V_pf_anchors,
|
||||
anchor);
|
||||
rs_free(anchor);
|
||||
rs_free(p);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
pf_init_kruleset(&anchor->ruleset);
|
||||
anchor->ruleset.anchor = anchor;
|
||||
parent = anchor;
|
||||
if (r != NULL)
|
||||
q = r + 1;
|
||||
else
|
||||
*q = 0;
|
||||
}
|
||||
rs_free(p);
|
||||
return (&anchor->ruleset);
|
||||
}
|
||||
|
||||
void
|
||||
pf_remove_if_empty_kruleset(struct pf_kruleset *ruleset)
|
||||
{
|
||||
struct pf_kanchor *parent;
|
||||
int i;
|
||||
|
||||
while (ruleset != NULL) {
|
||||
if (ruleset == &pf_main_ruleset || ruleset->anchor == NULL ||
|
||||
!RB_EMPTY(&ruleset->anchor->children) ||
|
||||
ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||
|
||||
ruleset->topen)
|
||||
return;
|
||||
for (i = 0; i < PF_RULESET_MAX; ++i)
|
||||
if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
|
||||
!TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
|
||||
ruleset->rules[i].inactive.open)
|
||||
return;
|
||||
RB_REMOVE(pf_kanchor_global, &V_pf_anchors, ruleset->anchor);
|
||||
if ((parent = ruleset->anchor->parent) != NULL)
|
||||
RB_REMOVE(pf_kanchor_node, &parent->children,
|
||||
ruleset->anchor);
|
||||
rs_free(ruleset->anchor);
|
||||
if (parent == NULL)
|
||||
return;
|
||||
ruleset = &parent->ruleset;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pf_kanchor_setup(struct pf_krule *r, const struct pf_kruleset *s,
|
||||
const char *name)
|
||||
{
|
||||
char *p, *path;
|
||||
struct pf_kruleset *ruleset;
|
||||
|
||||
r->anchor = NULL;
|
||||
r->anchor_relative = 0;
|
||||
r->anchor_wildcard = 0;
|
||||
if (!name[0])
|
||||
return (0);
|
||||
path = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (path == NULL)
|
||||
return (1);
|
||||
if (name[0] == '/')
|
||||
strlcpy(path, name + 1, MAXPATHLEN);
|
||||
else {
|
||||
/* relative path */
|
||||
r->anchor_relative = 1;
|
||||
if (s->anchor == NULL || !s->anchor->path[0])
|
||||
path[0] = 0;
|
||||
else
|
||||
strlcpy(path, s->anchor->path, MAXPATHLEN);
|
||||
while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
|
||||
if (!path[0]) {
|
||||
printf("pf_anchor_setup: .. beyond root\n");
|
||||
rs_free(path);
|
||||
return (1);
|
||||
}
|
||||
if ((p = strrchr(path, '/')) != NULL)
|
||||
*p = 0;
|
||||
else
|
||||
path[0] = 0;
|
||||
r->anchor_relative++;
|
||||
name += 3;
|
||||
}
|
||||
if (path[0])
|
||||
strlcat(path, "/", MAXPATHLEN);
|
||||
strlcat(path, name, MAXPATHLEN);
|
||||
}
|
||||
if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
|
||||
r->anchor_wildcard = 1;
|
||||
*p = 0;
|
||||
}
|
||||
ruleset = pf_find_or_create_kruleset(path);
|
||||
rs_free(path);
|
||||
if (ruleset == NULL || ruleset->anchor == NULL) {
|
||||
printf("pf_anchor_setup: ruleset\n");
|
||||
return (1);
|
||||
}
|
||||
r->anchor = ruleset->anchor;
|
||||
r->anchor->refcnt++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pf_kanchor_copyout(const struct pf_kruleset *rs, const struct pf_krule *r,
|
||||
struct pfioc_rule *pr)
|
||||
{
|
||||
pr->anchor_call[0] = 0;
|
||||
if (r->anchor == NULL)
|
||||
return (0);
|
||||
if (!r->anchor_relative) {
|
||||
strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
|
||||
strlcat(pr->anchor_call, r->anchor->path,
|
||||
sizeof(pr->anchor_call));
|
||||
} else {
|
||||
char *a, *p;
|
||||
int i;
|
||||
|
||||
a = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (a == NULL)
|
||||
return (1);
|
||||
if (rs->anchor == NULL)
|
||||
a[0] = 0;
|
||||
else
|
||||
strlcpy(a, rs->anchor->path, MAXPATHLEN);
|
||||
for (i = 1; i < r->anchor_relative; ++i) {
|
||||
if ((p = strrchr(a, '/')) == NULL)
|
||||
p = a;
|
||||
*p = 0;
|
||||
strlcat(pr->anchor_call, "../",
|
||||
sizeof(pr->anchor_call));
|
||||
}
|
||||
if (strncmp(a, r->anchor->path, strlen(a))) {
|
||||
printf("pf_anchor_copyout: '%s' '%s'\n", a,
|
||||
r->anchor->path);
|
||||
rs_free(a);
|
||||
return (1);
|
||||
}
|
||||
if (strlen(r->anchor->path) > strlen(a))
|
||||
strlcat(pr->anchor_call, r->anchor->path + (a[0] ?
|
||||
strlen(a) + 1 : 0), sizeof(pr->anchor_call));
|
||||
rs_free(a);
|
||||
}
|
||||
if (r->anchor_wildcard)
|
||||
strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
|
||||
sizeof(pr->anchor_call));
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pf_kanchor_remove(struct pf_krule *r)
|
||||
{
|
||||
if (r->anchor == NULL)
|
||||
return;
|
||||
if (r->anchor->refcnt <= 0) {
|
||||
printf("pf_anchor_remove: broken refcount\n");
|
||||
r->anchor = NULL;
|
||||
return;
|
||||
}
|
||||
if (!--r->anchor->refcnt)
|
||||
pf_remove_if_empty_kruleset(&r->anchor->ruleset);
|
||||
r->anchor = NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct pf_ruleset *
|
||||
pf_find_ruleset(const char *path)
|
||||
@ -306,7 +614,6 @@ pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
|
||||
ruleset = &parent->ruleset;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
|
||||
const char *name)
|
||||
@ -362,64 +669,4 @@ pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
|
||||
r->anchor->refcnt++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pf_anchor_copyout(const struct pf_ruleset *rs, const struct pf_rule *r,
|
||||
struct pfioc_rule *pr)
|
||||
{
|
||||
pr->anchor_call[0] = 0;
|
||||
if (r->anchor == NULL)
|
||||
return (0);
|
||||
if (!r->anchor_relative) {
|
||||
strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
|
||||
strlcat(pr->anchor_call, r->anchor->path,
|
||||
sizeof(pr->anchor_call));
|
||||
} else {
|
||||
char *a, *p;
|
||||
int i;
|
||||
|
||||
a = (char *)rs_malloc(MAXPATHLEN);
|
||||
if (a == NULL)
|
||||
return (1);
|
||||
if (rs->anchor == NULL)
|
||||
a[0] = 0;
|
||||
else
|
||||
strlcpy(a, rs->anchor->path, MAXPATHLEN);
|
||||
for (i = 1; i < r->anchor_relative; ++i) {
|
||||
if ((p = strrchr(a, '/')) == NULL)
|
||||
p = a;
|
||||
*p = 0;
|
||||
strlcat(pr->anchor_call, "../",
|
||||
sizeof(pr->anchor_call));
|
||||
}
|
||||
if (strncmp(a, r->anchor->path, strlen(a))) {
|
||||
printf("pf_anchor_copyout: '%s' '%s'\n", a,
|
||||
r->anchor->path);
|
||||
rs_free(a);
|
||||
return (1);
|
||||
}
|
||||
if (strlen(r->anchor->path) > strlen(a))
|
||||
strlcat(pr->anchor_call, r->anchor->path + (a[0] ?
|
||||
strlen(a) + 1 : 0), sizeof(pr->anchor_call));
|
||||
rs_free(a);
|
||||
}
|
||||
if (r->anchor_wildcard)
|
||||
strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
|
||||
sizeof(pr->anchor_call));
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pf_anchor_remove(struct pf_rule *r)
|
||||
{
|
||||
if (r->anchor == NULL)
|
||||
return;
|
||||
if (r->anchor->refcnt <= 0) {
|
||||
printf("pf_anchor_remove: broken refcount\n");
|
||||
r->anchor = NULL;
|
||||
return;
|
||||
}
|
||||
if (!--r->anchor->refcnt)
|
||||
pf_remove_if_empty_ruleset(&r->anchor->ruleset);
|
||||
r->anchor = NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -1431,11 +1431,11 @@ pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags)
|
||||
{
|
||||
struct pfr_ktableworkq workq;
|
||||
struct pfr_ktable *p;
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_kruleset *rs;
|
||||
int xdel = 0;
|
||||
|
||||
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
|
||||
rs = pf_find_or_create_ruleset(trs->pfrt_anchor);
|
||||
rs = pf_find_or_create_kruleset(trs->pfrt_anchor);
|
||||
if (rs == NULL)
|
||||
return (ENOMEM);
|
||||
SLIST_INIT(&workq);
|
||||
@ -1453,7 +1453,7 @@ pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags)
|
||||
*ticket = ++rs->tticket;
|
||||
rs->topen = 1;
|
||||
} else
|
||||
pf_remove_if_empty_ruleset(rs);
|
||||
pf_remove_if_empty_kruleset(rs);
|
||||
if (ndel != NULL)
|
||||
*ndel = xdel;
|
||||
return (0);
|
||||
@ -1468,7 +1468,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
struct pfr_ktable *kt, *rt, *shadow, key;
|
||||
struct pfr_kentry *p;
|
||||
struct pfr_addr *ad;
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_kruleset *rs;
|
||||
int i, rv, xadd = 0, xaddr = 0;
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
@ -1479,7 +1479,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
|
||||
if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK,
|
||||
flags & PFR_FLAG_USERIOCTL))
|
||||
return (EINVAL);
|
||||
rs = pf_find_ruleset(tbl->pfrt_anchor);
|
||||
rs = pf_find_kruleset(tbl->pfrt_anchor);
|
||||
if (rs == NULL || !rs->topen || ticket != rs->tticket)
|
||||
return (EBUSY);
|
||||
tbl->pfrt_flags |= PFR_TFLAG_INACTIVE;
|
||||
@ -1565,13 +1565,13 @@ pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags)
|
||||
{
|
||||
struct pfr_ktableworkq workq;
|
||||
struct pfr_ktable *p;
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_kruleset *rs;
|
||||
int xdel = 0;
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
|
||||
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
|
||||
rs = pf_find_ruleset(trs->pfrt_anchor);
|
||||
rs = pf_find_kruleset(trs->pfrt_anchor);
|
||||
if (rs == NULL || !rs->topen || ticket != rs->tticket)
|
||||
return (0);
|
||||
SLIST_INIT(&workq);
|
||||
@ -1586,7 +1586,7 @@ pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags)
|
||||
if (!(flags & PFR_FLAG_DUMMY)) {
|
||||
pfr_setflags_ktables(&workq);
|
||||
rs->topen = 0;
|
||||
pf_remove_if_empty_ruleset(rs);
|
||||
pf_remove_if_empty_kruleset(rs);
|
||||
}
|
||||
if (ndel != NULL)
|
||||
*ndel = xdel;
|
||||
@ -1599,14 +1599,14 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
|
||||
{
|
||||
struct pfr_ktable *p, *q;
|
||||
struct pfr_ktableworkq workq;
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_kruleset *rs;
|
||||
int xadd = 0, xchange = 0;
|
||||
long tzero = time_second;
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
|
||||
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
|
||||
rs = pf_find_ruleset(trs->pfrt_anchor);
|
||||
rs = pf_find_kruleset(trs->pfrt_anchor);
|
||||
if (rs == NULL || !rs->topen || ticket != rs->tticket)
|
||||
return (EBUSY);
|
||||
|
||||
@ -1628,7 +1628,7 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
|
||||
pfr_commit_ktable(p, tzero);
|
||||
}
|
||||
rs->topen = 0;
|
||||
pf_remove_if_empty_ruleset(rs);
|
||||
pf_remove_if_empty_kruleset(rs);
|
||||
}
|
||||
if (nadd != NULL)
|
||||
*nadd = xadd;
|
||||
@ -1756,14 +1756,14 @@ pfr_fix_anchor(char *anchor)
|
||||
int
|
||||
pfr_table_count(struct pfr_table *filter, int flags)
|
||||
{
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_kruleset *rs;
|
||||
|
||||
PF_RULES_ASSERT();
|
||||
|
||||
if (flags & PFR_FLAG_ALLRSETS)
|
||||
return (V_pfr_ktable_cnt);
|
||||
if (filter->pfrt_anchor[0]) {
|
||||
rs = pf_find_ruleset(filter->pfrt_anchor);
|
||||
rs = pf_find_kruleset(filter->pfrt_anchor);
|
||||
return ((rs != NULL) ? rs->tables : -1);
|
||||
}
|
||||
return (pf_main_ruleset.tables);
|
||||
@ -1882,7 +1882,7 @@ static struct pfr_ktable *
|
||||
pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset)
|
||||
{
|
||||
struct pfr_ktable *kt;
|
||||
struct pf_ruleset *rs;
|
||||
struct pf_kruleset *rs;
|
||||
int pfr_dir, pfr_op;
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
@ -1893,7 +1893,7 @@ pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset)
|
||||
kt->pfrkt_t = *tbl;
|
||||
|
||||
if (attachruleset) {
|
||||
rs = pf_find_or_create_ruleset(tbl->pfrt_anchor);
|
||||
rs = pf_find_or_create_kruleset(tbl->pfrt_anchor);
|
||||
if (!rs) {
|
||||
pfr_destroy_ktable(kt, 0);
|
||||
return (NULL);
|
||||
@ -1972,7 +1972,7 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
|
||||
pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr);
|
||||
if (kt->pfrkt_rs != NULL) {
|
||||
kt->pfrkt_rs->tables--;
|
||||
pf_remove_if_empty_ruleset(kt->pfrkt_rs);
|
||||
pf_remove_if_empty_kruleset(kt->pfrkt_rs);
|
||||
}
|
||||
for (pfr_dir = 0; pfr_dir < PFR_DIR_MAX; pfr_dir ++) {
|
||||
for (pfr_op = 0; pfr_op < PFR_OP_TABLE_MAX; pfr_op ++) {
|
||||
@ -2120,11 +2120,11 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
|
||||
}
|
||||
|
||||
struct pfr_ktable *
|
||||
pfr_attach_table(struct pf_ruleset *rs, char *name)
|
||||
pfr_attach_table(struct pf_kruleset *rs, char *name)
|
||||
{
|
||||
struct pfr_ktable *kt, *rt;
|
||||
struct pfr_table tbl;
|
||||
struct pf_anchor *ac = rs->anchor;
|
||||
struct pf_kanchor *ac = rs->anchor;
|
||||
|
||||
PF_RULES_WASSERT();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user