Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/pf/pf.c
Show First 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | |||||
#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x | #define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x | ||||
/* | /* | ||||
* Global variables | * Global variables | ||||
*/ | */ | ||||
/* state tables */ | /* state tables */ | ||||
VNET_DEFINE(struct pf_altqqueue, pf_altqs[4]); | VNET_DEFINE(struct pf_altqqueue, pf_altqs[4]); | ||||
VNET_DEFINE(struct pf_palist, pf_pabuf); | VNET_DEFINE(struct pf_kpalist, pf_pabuf); | ||||
VNET_DEFINE(struct pf_altqqueue *, pf_altqs_active); | VNET_DEFINE(struct pf_altqqueue *, pf_altqs_active); | ||||
VNET_DEFINE(struct pf_altqqueue *, pf_altq_ifs_active); | VNET_DEFINE(struct pf_altqqueue *, pf_altq_ifs_active); | ||||
VNET_DEFINE(struct pf_altqqueue *, pf_altqs_inactive); | VNET_DEFINE(struct pf_altqqueue *, pf_altqs_inactive); | ||||
VNET_DEFINE(struct pf_altqqueue *, pf_altq_ifs_inactive); | VNET_DEFINE(struct pf_altqqueue *, pf_altq_ifs_inactive); | ||||
VNET_DEFINE(struct pf_kstatus, pf_status); | VNET_DEFINE(struct pf_kstatus, pf_status); | ||||
VNET_DEFINE(u_int32_t, ticket_altqs_active); | VNET_DEFINE(u_int32_t, ticket_altqs_active); | ||||
VNET_DEFINE(u_int32_t, ticket_altqs_inactive); | VNET_DEFINE(u_int32_t, ticket_altqs_inactive); | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | static void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, | ||||
sa_family_t, struct pf_krule *); | sa_family_t, struct pf_krule *); | ||||
static void pf_detach_state(struct pf_state *); | static void pf_detach_state(struct pf_state *); | ||||
static int pf_state_key_attach(struct pf_state_key *, | static int pf_state_key_attach(struct pf_state_key *, | ||||
struct pf_state_key *, struct pf_state *); | struct pf_state_key *, struct pf_state *); | ||||
static void pf_state_key_detach(struct pf_state *, int); | static void pf_state_key_detach(struct pf_state *, int); | ||||
static int pf_state_key_ctor(void *, int, void *, int); | static int pf_state_key_ctor(void *, int, void *, int); | ||||
static u_int32_t pf_tcp_iss(struct pf_pdesc *); | static u_int32_t pf_tcp_iss(struct pf_pdesc *); | ||||
static int pf_test_rule(struct pf_krule **, struct pf_state **, | static int pf_test_rule(struct pf_krule **, struct pf_state **, | ||||
int, struct pfi_kif *, struct mbuf *, int, | int, struct pfi_kkif *, struct mbuf *, int, | ||||
struct pf_pdesc *, struct pf_krule **, | struct pf_pdesc *, struct pf_krule **, | ||||
struct pf_kruleset **, struct inpcb *); | struct pf_kruleset **, struct inpcb *); | ||||
static int pf_create_state(struct pf_krule *, struct pf_krule *, | static int pf_create_state(struct pf_krule *, struct pf_krule *, | ||||
struct pf_krule *, struct pf_pdesc *, | struct pf_krule *, struct pf_pdesc *, | ||||
struct pf_ksrc_node *, struct pf_state_key *, | struct pf_ksrc_node *, struct pf_state_key *, | ||||
struct pf_state_key *, struct mbuf *, int, | struct pf_state_key *, struct mbuf *, int, | ||||
u_int16_t, u_int16_t, int *, struct pfi_kif *, | u_int16_t, u_int16_t, int *, struct pfi_kkif *, | ||||
struct pf_state **, int, u_int16_t, u_int16_t, | struct pf_state **, int, u_int16_t, u_int16_t, | ||||
int); | int); | ||||
static int pf_test_fragment(struct pf_krule **, int, | static int pf_test_fragment(struct pf_krule **, int, | ||||
struct pfi_kif *, struct mbuf *, void *, | struct pfi_kkif *, struct mbuf *, void *, | ||||
struct pf_pdesc *, struct pf_krule **, | struct pf_pdesc *, struct pf_krule **, | ||||
struct pf_kruleset **); | struct pf_kruleset **); | ||||
static int pf_tcp_track_full(struct pf_state_peer *, | static int pf_tcp_track_full(struct pf_state_peer *, | ||||
struct pf_state_peer *, struct pf_state **, | struct pf_state_peer *, struct pf_state **, | ||||
struct pfi_kif *, struct mbuf *, int, | struct pfi_kkif *, struct mbuf *, int, | ||||
struct pf_pdesc *, u_short *, int *); | struct pf_pdesc *, u_short *, int *); | ||||
static int pf_tcp_track_sloppy(struct pf_state_peer *, | static int pf_tcp_track_sloppy(struct pf_state_peer *, | ||||
struct pf_state_peer *, struct pf_state **, | struct pf_state_peer *, struct pf_state **, | ||||
struct pf_pdesc *, u_short *); | struct pf_pdesc *, u_short *); | ||||
static int pf_test_state_tcp(struct pf_state **, int, | static int pf_test_state_tcp(struct pf_state **, int, | ||||
struct pfi_kif *, struct mbuf *, int, | struct pfi_kkif *, struct mbuf *, int, | ||||
void *, struct pf_pdesc *, u_short *); | void *, struct pf_pdesc *, u_short *); | ||||
static int pf_test_state_udp(struct pf_state **, int, | static int pf_test_state_udp(struct pf_state **, int, | ||||
struct pfi_kif *, struct mbuf *, int, | struct pfi_kkif *, struct mbuf *, int, | ||||
void *, struct pf_pdesc *); | void *, struct pf_pdesc *); | ||||
static int pf_test_state_icmp(struct pf_state **, int, | static int pf_test_state_icmp(struct pf_state **, int, | ||||
struct pfi_kif *, struct mbuf *, int, | struct pfi_kkif *, struct mbuf *, int, | ||||
void *, struct pf_pdesc *, u_short *); | void *, struct pf_pdesc *, u_short *); | ||||
static int pf_test_state_other(struct pf_state **, int, | static int pf_test_state_other(struct pf_state **, int, | ||||
struct pfi_kif *, struct mbuf *, struct pf_pdesc *); | struct pfi_kkif *, struct mbuf *, struct pf_pdesc *); | ||||
static u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, | static u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t, | ||||
sa_family_t); | sa_family_t); | ||||
static u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, | static u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t, | ||||
sa_family_t); | sa_family_t); | ||||
static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, | static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t, | ||||
int, u_int16_t); | int, u_int16_t); | ||||
static int pf_check_proto_cksum(struct mbuf *, int, int, | static int pf_check_proto_cksum(struct mbuf *, int, int, | ||||
u_int8_t, sa_family_t); | u_int8_t, sa_family_t); | ||||
static void pf_print_state_parts(struct pf_state *, | static void pf_print_state_parts(struct pf_state *, | ||||
struct pf_state_key *, struct pf_state_key *); | struct pf_state_key *, struct pf_state_key *); | ||||
static int pf_addr_wrap_neq(struct pf_addr_wrap *, | static int pf_addr_wrap_neq(struct pf_addr_wrap *, | ||||
struct pf_addr_wrap *); | struct pf_addr_wrap *); | ||||
static void pf_patch_8(struct mbuf *, u_int16_t *, u_int8_t *, u_int8_t, | static void pf_patch_8(struct mbuf *, u_int16_t *, u_int8_t *, u_int8_t, | ||||
bool, u_int8_t); | bool, u_int8_t); | ||||
static struct pf_state *pf_find_state(struct pfi_kif *, | static struct pf_state *pf_find_state(struct pfi_kkif *, | ||||
struct pf_state_key_cmp *, u_int); | struct pf_state_key_cmp *, u_int); | ||||
static int pf_src_connlimit(struct pf_state **); | static int pf_src_connlimit(struct pf_state **); | ||||
static void pf_overload_task(void *v, int pending); | static void pf_overload_task(void *v, int pending); | ||||
static int pf_insert_src_node(struct pf_ksrc_node **, | static int pf_insert_src_node(struct pf_ksrc_node **, | ||||
struct pf_krule *, 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 u_int pf_purge_expired_states(u_int, int); | ||||
static void pf_purge_unlinked_rules(void); | static void pf_purge_unlinked_rules(void); | ||||
static int pf_mtag_uminit(void *, int, int); | static int pf_mtag_uminit(void *, int, int); | ||||
▲ Show 20 Lines • Show All 948 Lines • ▼ Show 20 Lines | if (sk == NULL) | ||||
return (NULL); | return (NULL); | ||||
bcopy(orig, sk, sizeof(struct pf_state_key_cmp)); | bcopy(orig, sk, sizeof(struct pf_state_key_cmp)); | ||||
return (sk); | return (sk); | ||||
} | } | ||||
int | int | ||||
pf_state_insert(struct pfi_kif *kif, struct pf_state_key *skw, | pf_state_insert(struct pfi_kkif *kif, struct pf_state_key *skw, | ||||
struct pf_state_key *sks, struct pf_state *s) | struct pf_state_key *sks, struct pf_state *s) | ||||
{ | { | ||||
struct pf_idhash *ih; | struct pf_idhash *ih; | ||||
struct pf_state *cur; | struct pf_state *cur; | ||||
int error; | int error; | ||||
KASSERT(TAILQ_EMPTY(&sks->states[0]) && TAILQ_EMPTY(&sks->states[1]), | KASSERT(TAILQ_EMPTY(&sks->states[0]) && TAILQ_EMPTY(&sks->states[1]), | ||||
("%s: sks not pristine", __func__)); | ("%s: sks not pristine", __func__)); | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | pf_find_state_byid(uint64_t id, uint32_t creatorid) | ||||
return (s); | return (s); | ||||
} | } | ||||
/* | /* | ||||
* Find state by key. | * Find state by key. | ||||
* Returns with ID hash slot locked on success. | * Returns with ID hash slot locked on success. | ||||
*/ | */ | ||||
static struct pf_state * | static struct pf_state * | ||||
pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir) | pf_find_state(struct pfi_kkif *kif, struct pf_state_key_cmp *key, u_int dir) | ||||
{ | { | ||||
struct pf_keyhash *kh; | struct pf_keyhash *kh; | ||||
struct pf_state_key *sk; | struct pf_state_key *sk; | ||||
struct pf_state *s; | struct pf_state *s; | ||||
int idx; | int idx; | ||||
counter_u64_add(V_pf_status.fcounters[FCNT_STATE_SEARCH], 1); | counter_u64_add(V_pf_status.fcounters[FCNT_STATE_SEARCH], 1); | ||||
▲ Show 20 Lines • Show All 180 Lines • ▼ Show 20 Lines | VNET_FOREACH(vnet_iter) { | ||||
/* | /* | ||||
* Order is important: | * Order is important: | ||||
* - states and src nodes reference rules | * - states and src nodes reference rules | ||||
* - states and rules reference kifs | * - states and rules reference kifs | ||||
*/ | */ | ||||
pf_purge_expired_fragments(); | pf_purge_expired_fragments(); | ||||
pf_purge_expired_src_nodes(); | pf_purge_expired_src_nodes(); | ||||
pf_purge_unlinked_rules(); | pf_purge_unlinked_rules(); | ||||
pfi_kif_purge(); | pfi_kkif_purge(); | ||||
} | } | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
} | } | ||||
VNET_LIST_RUNLOCK(); | VNET_LIST_RUNLOCK(); | ||||
} | } | ||||
pf_end_threads++; | pf_end_threads++; | ||||
sx_xunlock(&pf_end_lock); | sx_xunlock(&pf_end_lock); | ||||
kproc_exit(0); | kproc_exit(0); | ||||
} | } | ||||
void | void | ||||
pf_unload_vnet_purge(void) | pf_unload_vnet_purge(void) | ||||
{ | { | ||||
/* | /* | ||||
* To cleanse up all kifs and rules we need | * To cleanse up all kifs and rules we need | ||||
* two runs: first one clears reference flags, | * two runs: first one clears reference flags, | ||||
* then pf_purge_expired_states() doesn't | * then pf_purge_expired_states() doesn't | ||||
* raise them, and then second run frees. | * raise them, and then second run frees. | ||||
*/ | */ | ||||
pf_purge_unlinked_rules(); | pf_purge_unlinked_rules(); | ||||
pfi_kif_purge(); | pfi_kkif_purge(); | ||||
/* | /* | ||||
* Now purge everything. | * Now purge everything. | ||||
*/ | */ | ||||
pf_purge_expired_states(0, pf_hashmask); | pf_purge_expired_states(0, pf_hashmask); | ||||
pf_purge_fragments(UINT_MAX); | pf_purge_fragments(UINT_MAX); | ||||
pf_purge_expired_src_nodes(); | pf_purge_expired_src_nodes(); | ||||
/* | /* | ||||
* Now all kifs & rules should be unreferenced, | * Now all kifs & rules should be unreferenced, | ||||
* thus should be successfully freed. | * thus should be successfully freed. | ||||
*/ | */ | ||||
pf_purge_unlinked_rules(); | pf_purge_unlinked_rules(); | ||||
pfi_kif_purge(); | pfi_kkif_purge(); | ||||
} | } | ||||
u_int32_t | u_int32_t | ||||
pf_state_expires(const struct pf_state *state) | pf_state_expires(const struct pf_state *state) | ||||
{ | { | ||||
u_int32_t timeout; | u_int32_t timeout; | ||||
u_int32_t start; | u_int32_t start; | ||||
u_int32_t end; | u_int32_t end; | ||||
▲ Show 20 Lines • Show All 1,010 Lines • ▼ Show 20 Lines | #endif /* INET6 */ | ||||
} | } | ||||
pfse->pfse_m = m; | pfse->pfse_m = m; | ||||
pf_send(pfse); | pf_send(pfse); | ||||
} | } | ||||
static void | static void | ||||
pf_return(struct pf_krule *r, struct pf_krule *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 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, | struct pfi_kkif *kif, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen, | ||||
u_short *reason) | u_short *reason) | ||||
{ | { | ||||
struct pf_addr * const saddr = pd->src; | struct pf_addr * const saddr = pd->src; | ||||
struct pf_addr * const daddr = pd->dst; | struct pf_addr * const daddr = pd->dst; | ||||
sa_family_t af = pd->af; | sa_family_t af = pd->af; | ||||
/* undo NAT changes, if they have taken place */ | /* undo NAT changes, if they have taken place */ | ||||
if (nr != NULL) { | if (nr != NULL) { | ||||
▲ Show 20 Lines • Show All 706 Lines • ▼ Show 20 Lines | |||||
#define ISN_RANDOM_INCREMENT (4096 - 1) | #define ISN_RANDOM_INCREMENT (4096 - 1) | ||||
return (digest[0] + (arc4random() & ISN_RANDOM_INCREMENT) + | return (digest[0] + (arc4random() & ISN_RANDOM_INCREMENT) + | ||||
V_pf_tcp_iss_off); | V_pf_tcp_iss_off); | ||||
#undef ISN_RANDOM_INCREMENT | #undef ISN_RANDOM_INCREMENT | ||||
} | } | ||||
static int | static int | ||||
pf_test_rule(struct pf_krule **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 pfi_kkif *kif, struct mbuf *m, int off, struct pf_pdesc *pd, | ||||
struct pf_krule **am, struct pf_kruleset **rsm, struct inpcb *inp) | struct pf_krule **am, struct pf_kruleset **rsm, struct inpcb *inp) | ||||
{ | { | ||||
struct pf_krule *nr = NULL; | struct pf_krule *nr = NULL; | ||||
struct pf_addr * const saddr = pd->src; | struct pf_addr * const saddr = pd->src; | ||||
struct pf_addr * const daddr = pd->dst; | struct pf_addr * const daddr = pd->dst; | ||||
sa_family_t af = pd->af; | sa_family_t af = pd->af; | ||||
struct pf_krule *r, *a = NULL; | struct pf_krule *r, *a = NULL; | ||||
struct pf_kruleset *ruleset = NULL; | struct pf_kruleset *ruleset = NULL; | ||||
▲ Show 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | #endif /* INET */ | ||||
} | } | ||||
if (nr->natpass) | if (nr->natpass) | ||||
r = NULL; | r = NULL; | ||||
pd->nat_rule = nr; | pd->nat_rule = nr; | ||||
} | } | ||||
while (r != NULL) { | while (r != NULL) { | ||||
counter_u64_add(r->evaluations, 1); | counter_u64_add(r->evaluations, 1); | ||||
if (pfi_kif_match(r->kif, kif) == r->ifnot) | if (pfi_kkif_match(r->kif, kif) == r->ifnot) | ||||
r = r->skip[PF_SKIP_IFP].ptr; | r = r->skip[PF_SKIP_IFP].ptr; | ||||
else if (r->direction && r->direction != direction) | else if (r->direction && r->direction != direction) | ||||
r = r->skip[PF_SKIP_DIR].ptr; | r = r->skip[PF_SKIP_DIR].ptr; | ||||
else if (r->af && r->af != af) | else if (r->af && r->af != af) | ||||
r = r->skip[PF_SKIP_AF].ptr; | r = r->skip[PF_SKIP_AF].ptr; | ||||
else if (r->proto && r->proto != pd->proto) | else if (r->proto && r->proto != pd->proto) | ||||
r = r->skip[PF_SKIP_PROTO].ptr; | r = r->skip[PF_SKIP_PROTO].ptr; | ||||
else if (PF_MISMATCHAW(&r->src.addr, saddr, af, | else if (PF_MISMATCHAW(&r->src.addr, saddr, af, | ||||
▲ Show 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | if (nk != NULL) | ||||
uma_zfree(V_pf_state_key_z, nk); | uma_zfree(V_pf_state_key_z, nk); | ||||
return (PF_DROP); | return (PF_DROP); | ||||
} | } | ||||
static int | static int | ||||
pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *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_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, | 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, | u_int16_t dport, int *rewrite, struct pfi_kkif *kif, struct pf_state **sm, | ||||
int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen) | int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen) | ||||
{ | { | ||||
struct pf_state *s = NULL; | struct pf_state *s = NULL; | ||||
struct pf_ksrc_node *sn = NULL; | struct pf_ksrc_node *sn = NULL; | ||||
struct tcphdr *th = pd->hdr.tcp; | struct tcphdr *th = pd->hdr.tcp; | ||||
u_int16_t mss = V_tcp_mssdflt; | u_int16_t mss = V_tcp_mssdflt; | ||||
u_short reason; | u_short reason; | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | if (nsn != sn && nsn != NULL) { | ||||
} | } | ||||
PF_HASHROW_UNLOCK(sh); | PF_HASHROW_UNLOCK(sh); | ||||
} | } | ||||
return (PF_DROP); | return (PF_DROP); | ||||
} | } | ||||
static int | static int | ||||
pf_test_fragment(struct pf_krule **rm, int direction, struct pfi_kif *kif, | pf_test_fragment(struct pf_krule **rm, int direction, struct pfi_kkif *kif, | ||||
struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_krule **am, | struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_krule **am, | ||||
struct pf_kruleset **rsm) | struct pf_kruleset **rsm) | ||||
{ | { | ||||
struct pf_krule *r, *a = NULL; | struct pf_krule *r, *a = NULL; | ||||
struct pf_kruleset *ruleset = NULL; | struct pf_kruleset *ruleset = NULL; | ||||
sa_family_t af = pd->af; | sa_family_t af = pd->af; | ||||
u_short reason; | u_short reason; | ||||
int tag = -1; | int tag = -1; | ||||
int asd = 0; | int asd = 0; | ||||
int match = 0; | int match = 0; | ||||
struct pf_kanchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; | struct pf_kanchor_stackframe anchor_stack[PF_ANCHOR_STACKSIZE]; | ||||
PF_RULES_RASSERT(); | PF_RULES_RASSERT(); | ||||
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); | r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); | ||||
while (r != NULL) { | while (r != NULL) { | ||||
counter_u64_add(r->evaluations, 1); | counter_u64_add(r->evaluations, 1); | ||||
if (pfi_kif_match(r->kif, kif) == r->ifnot) | if (pfi_kkif_match(r->kif, kif) == r->ifnot) | ||||
r = r->skip[PF_SKIP_IFP].ptr; | r = r->skip[PF_SKIP_IFP].ptr; | ||||
else if (r->direction && r->direction != direction) | else if (r->direction && r->direction != direction) | ||||
r = r->skip[PF_SKIP_DIR].ptr; | r = r->skip[PF_SKIP_DIR].ptr; | ||||
else if (r->af && r->af != af) | else if (r->af && r->af != af) | ||||
r = r->skip[PF_SKIP_AF].ptr; | r = r->skip[PF_SKIP_AF].ptr; | ||||
else if (r->proto && r->proto != pd->proto) | else if (r->proto && r->proto != pd->proto) | ||||
r = r->skip[PF_SKIP_PROTO].ptr; | r = r->skip[PF_SKIP_PROTO].ptr; | ||||
else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, | else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | if (tag > 0 && pf_tag_packet(m, pd, tag)) { | ||||
return (PF_DROP); | return (PF_DROP); | ||||
} | } | ||||
return (PF_PASS); | return (PF_PASS); | ||||
} | } | ||||
static int | static int | ||||
pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst, | pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst, | ||||
struct pf_state **state, struct pfi_kif *kif, struct mbuf *m, int off, | struct pf_state **state, struct pfi_kkif *kif, struct mbuf *m, int off, | ||||
struct pf_pdesc *pd, u_short *reason, int *copyback) | struct pf_pdesc *pd, u_short *reason, int *copyback) | ||||
{ | { | ||||
struct tcphdr *th = pd->hdr.tcp; | struct tcphdr *th = pd->hdr.tcp; | ||||
u_int16_t win = ntohs(th->th_win); | u_int16_t win = ntohs(th->th_win); | ||||
u_int32_t ack, end, seq, orig_seq; | u_int32_t ack, end, seq, orig_seq; | ||||
u_int8_t sws, dws; | u_int8_t sws, dws; | ||||
int ackskew; | int ackskew; | ||||
▲ Show 20 Lines • Show All 380 Lines • ▼ Show 20 Lines | else if (src->state >= TCPS_CLOSING || | ||||
(*state)->timeout = PFTM_TCP_CLOSING; | (*state)->timeout = PFTM_TCP_CLOSING; | ||||
else | else | ||||
(*state)->timeout = PFTM_TCP_ESTABLISHED; | (*state)->timeout = PFTM_TCP_ESTABLISHED; | ||||
return (PF_PASS); | return (PF_PASS); | ||||
} | } | ||||
static int | static int | ||||
pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, | pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kkif *kif, | ||||
struct mbuf *m, int off, void *h, struct pf_pdesc *pd, | struct mbuf *m, int off, void *h, struct pf_pdesc *pd, | ||||
u_short *reason) | u_short *reason) | ||||
{ | { | ||||
struct pf_state_key_cmp key; | struct pf_state_key_cmp key; | ||||
struct tcphdr *th = pd->hdr.tcp; | struct tcphdr *th = pd->hdr.tcp; | ||||
int copyback = 0; | int copyback = 0; | ||||
struct pf_state_peer *src, *dst; | struct pf_state_peer *src, *dst; | ||||
struct pf_state_key *sk; | struct pf_state_key *sk; | ||||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kkif *kif, | ||||
/* Copyback sequence modulation or stateful scrub changes if needed */ | /* Copyback sequence modulation or stateful scrub changes if needed */ | ||||
if (copyback) | if (copyback) | ||||
m_copyback(m, off, sizeof(*th), (caddr_t)th); | m_copyback(m, off, sizeof(*th), (caddr_t)th); | ||||
return (PF_PASS); | return (PF_PASS); | ||||
} | } | ||||
static int | static int | ||||
pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, | pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kkif *kif, | ||||
struct mbuf *m, int off, void *h, struct pf_pdesc *pd) | struct mbuf *m, int off, void *h, struct pf_pdesc *pd) | ||||
{ | { | ||||
struct pf_state_peer *src, *dst; | struct pf_state_peer *src, *dst; | ||||
struct pf_state_key_cmp key; | struct pf_state_key_cmp key; | ||||
struct udphdr *uh = pd->hdr.udp; | struct udphdr *uh = pd->hdr.udp; | ||||
bzero(&key, sizeof(key)); | bzero(&key, sizeof(key)); | ||||
key.af = pd->af; | key.af = pd->af; | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || | ||||
nk->port[pd->didx], 1, pd->af); | nk->port[pd->didx], 1, pd->af); | ||||
m_copyback(m, off, sizeof(*uh), (caddr_t)uh); | m_copyback(m, off, sizeof(*uh), (caddr_t)uh); | ||||
} | } | ||||
return (PF_PASS); | return (PF_PASS); | ||||
} | } | ||||
static int | static int | ||||
pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, | pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kkif *kif, | ||||
struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) | struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) | ||||
{ | { | ||||
struct pf_addr *saddr = pd->src, *daddr = pd->dst; | struct pf_addr *saddr = pd->src, *daddr = pd->dst; | ||||
u_int16_t icmpid = 0, *icmpsum; | u_int16_t icmpid = 0, *icmpsum; | ||||
u_int8_t icmptype, icmpcode; | u_int8_t icmptype, icmpcode; | ||||
int state_icmp = 0; | int state_icmp = 0; | ||||
struct pf_state_key_cmp key; | struct pf_state_key_cmp key; | ||||
▲ Show 20 Lines • Show All 587 Lines • ▼ Show 20 Lines | #endif /* INET6 */ | ||||
return (PF_PASS); | return (PF_PASS); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, | pf_test_state_other(struct pf_state **state, int direction, struct pfi_kkif *kif, | ||||
struct mbuf *m, struct pf_pdesc *pd) | struct mbuf *m, struct pf_pdesc *pd) | ||||
{ | { | ||||
struct pf_state_peer *src, *dst; | struct pf_state_peer *src, *dst; | ||||
struct pf_state_key_cmp key; | struct pf_state_key_cmp key; | ||||
bzero(&key, sizeof(key)); | bzero(&key, sizeof(key)); | ||||
key.af = pd->af; | key.af = pd->af; | ||||
key.proto = pd->proto; | key.proto = pd->proto; | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | #ifdef INET6 | ||||
} | } | ||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
} | } | ||||
m_copydata(m, off, len, p); | m_copydata(m, off, len, p); | ||||
return (p); | return (p); | ||||
} | } | ||||
int | int | ||||
pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif, | pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kkif *kif, | ||||
int rtableid) | int rtableid) | ||||
{ | { | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
/* | /* | ||||
* Skip check for addresses with embedded interface scope, | * Skip check for addresses with embedded interface scope, | ||||
* as they would always match anyway. | * as they would always match anyway. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 447 Lines • ▼ Show 20 Lines | #endif /* INET6 */ | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef INET | #ifdef INET | ||||
int | int | ||||
pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | ||||
{ | { | ||||
struct pfi_kif *kif; | struct pfi_kkif *kif; | ||||
u_short action, reason = 0, log = 0; | u_short action, reason = 0, log = 0; | ||||
struct mbuf *m = *m0; | struct mbuf *m = *m0; | ||||
struct ip *h = NULL; | struct ip *h = NULL; | ||||
struct m_tag *ipfwtag; | struct m_tag *ipfwtag; | ||||
struct pf_krule *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_state *s = NULL; | ||||
struct pf_kruleset *ruleset = NULL; | struct pf_kruleset *ruleset = NULL; | ||||
struct pf_pdesc pd; | struct pf_pdesc pd; | ||||
int off, dirndx, pqid = 0; | int off, dirndx, pqid = 0; | ||||
PF_RULES_RLOCK_TRACKER; | PF_RULES_RLOCK_TRACKER; | ||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
if (!V_pf_status.running) | if (!V_pf_status.running) | ||||
return (PF_PASS); | return (PF_PASS); | ||||
memset(&pd, 0, sizeof(pd)); | memset(&pd, 0, sizeof(pd)); | ||||
kif = (struct pfi_kif *)ifp->if_pf_kif; | kif = (struct pfi_kkif *)ifp->if_pf_kif; | ||||
if (kif == NULL) { | if (kif == NULL) { | ||||
DPFPRINTF(PF_DEBUG_URGENT, | DPFPRINTF(PF_DEBUG_URGENT, | ||||
("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); | ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); | ||||
return (PF_DROP); | return (PF_DROP); | ||||
} | } | ||||
if (kif->pfik_flags & PFI_IFLAG_SKIP) | if (kif->pfik_flags & PFI_IFLAG_SKIP) | ||||
return (PF_PASS); | return (PF_PASS); | ||||
▲ Show 20 Lines • Show All 355 Lines • ▼ Show 20 Lines | #endif /* ALTQ */ | ||||
return (action); | return (action); | ||||
} | } | ||||
#endif /* INET */ | #endif /* INET */ | ||||
#ifdef INET6 | #ifdef INET6 | ||||
int | int | ||||
pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) | ||||
{ | { | ||||
struct pfi_kif *kif; | struct pfi_kkif *kif; | ||||
u_short action, reason = 0, log = 0; | u_short action, reason = 0, log = 0; | ||||
struct mbuf *m = *m0, *n = NULL; | struct mbuf *m = *m0, *n = NULL; | ||||
struct m_tag *mtag; | struct m_tag *mtag; | ||||
struct ip6_hdr *h = NULL; | struct ip6_hdr *h = NULL; | ||||
struct pf_krule *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_state *s = NULL; | ||||
struct pf_kruleset *ruleset = NULL; | struct pf_kruleset *ruleset = NULL; | ||||
struct pf_pdesc pd; | struct pf_pdesc pd; | ||||
int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0; | int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0; | ||||
PF_RULES_RLOCK_TRACKER; | PF_RULES_RLOCK_TRACKER; | ||||
M_ASSERTPKTHDR(m); | M_ASSERTPKTHDR(m); | ||||
if (!V_pf_status.running) | if (!V_pf_status.running) | ||||
return (PF_PASS); | return (PF_PASS); | ||||
memset(&pd, 0, sizeof(pd)); | memset(&pd, 0, sizeof(pd)); | ||||
pd.pf_mtag = pf_find_mtag(m); | pd.pf_mtag = pf_find_mtag(m); | ||||
if (pd.pf_mtag && pd.pf_mtag->flags & PF_TAG_GENERATED) | if (pd.pf_mtag && pd.pf_mtag->flags & PF_TAG_GENERATED) | ||||
return (PF_PASS); | return (PF_PASS); | ||||
kif = (struct pfi_kif *)ifp->if_pf_kif; | kif = (struct pfi_kkif *)ifp->if_pf_kif; | ||||
if (kif == NULL) { | if (kif == NULL) { | ||||
DPFPRINTF(PF_DEBUG_URGENT, | DPFPRINTF(PF_DEBUG_URGENT, | ||||
("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); | ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); | ||||
return (PF_DROP); | return (PF_DROP); | ||||
} | } | ||||
if (kif->pfik_flags & PFI_IFLAG_SKIP) | if (kif->pfik_flags & PFI_IFLAG_SKIP) | ||||
return (PF_PASS); | return (PF_PASS); | ||||
▲ Show 20 Lines • Show All 369 Lines • Show Last 20 Lines |