Lines 275-295
static int pf_check_proto_cksum(struct mbuf *, int, int,
Link Here
|
275 |
u_int8_t, sa_family_t); |
275 |
u_int8_t, sa_family_t); |
276 |
static void pf_print_state_parts(struct pf_state *, |
276 |
static void pf_print_state_parts(struct pf_state *, |
277 |
struct pf_state_key *, struct pf_state_key *); |
277 |
struct pf_state_key *, struct pf_state_key *); |
278 |
static int pf_addr_wrap_neq(struct pf_addr_wrap *, |
278 |
static int pf_addr_wrap_neq(struct pf_addr_wrap *, |
279 |
struct pf_addr_wrap *); |
279 |
struct pf_addr_wrap *); |
280 |
static struct pf_state *pf_find_state(struct pfi_kif *, |
280 |
static struct pf_state *pf_find_state(struct pfi_kif *, |
281 |
struct pf_state_key_cmp *, u_int); |
281 |
struct pf_state_key_cmp *, u_int); |
282 |
static int pf_src_connlimit(struct pf_state **); |
282 |
static int pf_src_connlimit(struct pf_state **); |
283 |
static void pf_overload_task(void *v, int pending); |
283 |
static void pf_overload_task(void *v, int pending); |
284 |
static int pf_insert_src_node(struct pf_src_node **, |
284 |
static int pf_insert_src_node(struct pf_src_node **, |
285 |
struct pf_rule *, struct pf_addr *, sa_family_t); |
285 |
struct pf_rule *, struct pf_addr *, sa_family_t, |
|
|
286 |
struct pf_srchash **); |
286 |
static u_int pf_purge_expired_states(u_int, int); |
287 |
static u_int pf_purge_expired_states(u_int, int); |
287 |
static void pf_purge_unlinked_rules(void); |
288 |
static void pf_purge_unlinked_rules(void); |
288 |
static int pf_mtag_uminit(void *, int, int); |
289 |
static int pf_mtag_uminit(void *, int, int); |
289 |
static void pf_mtag_free(struct m_tag *); |
290 |
static void pf_mtag_free(struct m_tag *); |
290 |
#ifdef INET |
291 |
#ifdef INET |
291 |
static void pf_route(struct mbuf **, struct pf_rule *, int, |
292 |
static void pf_route(struct mbuf **, struct pf_rule *, int, |
292 |
struct ifnet *, struct pf_state *, |
293 |
struct ifnet *, struct pf_state *, |
293 |
struct pf_pdesc *, struct inpcb *); |
294 |
struct pf_pdesc *, struct inpcb *); |
294 |
#endif /* INET */ |
295 |
#endif /* INET */ |
295 |
#ifdef INET6 |
296 |
#ifdef INET6 |
Lines 649-747
pf_overload_task(void *v, int pending)
Link Here
|
649 |
} |
650 |
} |
650 |
SLIST_FOREACH_SAFE(pfoe, &queue, next, pfoe1) |
651 |
SLIST_FOREACH_SAFE(pfoe, &queue, next, pfoe1) |
651 |
free(pfoe, M_PFTEMP); |
652 |
free(pfoe, M_PFTEMP); |
652 |
if (V_pf_status.debug >= PF_DEBUG_MISC) |
653 |
if (V_pf_status.debug >= PF_DEBUG_MISC) |
653 |
printf("%s: %u states killed", __func__, killed); |
654 |
printf("%s: %u states killed", __func__, killed); |
654 |
|
655 |
|
655 |
CURVNET_RESTORE(); |
656 |
CURVNET_RESTORE(); |
656 |
} |
657 |
} |
657 |
|
658 |
|
658 |
/* |
659 |
/* |
659 |
* Can return locked on failure, so that we can consistently |
660 |
* Always returns locked, so that we can perform operations on found node or |
660 |
* allocate and insert a new one. |
661 |
* consistently allocate and insert a new one. |
661 |
*/ |
662 |
*/ |
662 |
struct pf_src_node * |
663 |
struct pf_src_node * |
663 |
pf_find_src_node(struct pf_addr *src, struct pf_rule *rule, sa_family_t af, |
664 |
pf_find_src_node(struct pf_addr *src, struct pf_rule *rule, sa_family_t af, |
664 |
int returnlocked) |
665 |
struct pf_srchash **sh) |
665 |
{ |
666 |
{ |
666 |
struct pf_srchash *sh; |
|
|
667 |
struct pf_src_node *n; |
667 |
struct pf_src_node *n; |
668 |
|
668 |
|
669 |
counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_SEARCH], 1); |
669 |
counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_SEARCH], 1); |
670 |
|
670 |
|
671 |
sh = &V_pf_srchash[pf_hashsrc(src, af)]; |
671 |
*sh = &V_pf_srchash[pf_hashsrc(src, af)]; |
672 |
PF_HASHROW_LOCK(sh); |
672 |
PF_HASHROW_LOCK(*sh); |
673 |
LIST_FOREACH(n, &sh->nodes, entry) |
673 |
LIST_FOREACH(n, &(*sh)->nodes, entry) |
674 |
if (n->rule.ptr == rule && n->af == af && |
674 |
if (n->rule.ptr == rule && n->af == af && |
675 |
((af == AF_INET && n->addr.v4.s_addr == src->v4.s_addr) || |
675 |
((af == AF_INET && n->addr.v4.s_addr == src->v4.s_addr) || |
676 |
(af == AF_INET6 && bcmp(&n->addr, src, sizeof(*src)) == 0))) |
676 |
(af == AF_INET6 && bcmp(&n->addr, src, sizeof(*src)) == 0))) |
677 |
break; |
677 |
break; |
678 |
if (n != NULL) { |
|
|
679 |
n->states++; |
680 |
PF_HASHROW_UNLOCK(sh); |
681 |
} else if (returnlocked == 0) |
682 |
PF_HASHROW_UNLOCK(sh); |
683 |
|
678 |
|
684 |
return (n); |
679 |
return (n); |
685 |
} |
680 |
} |
686 |
|
681 |
|
|
|
682 |
/* |
683 |
* Returns locked on success and unlocked on failure. |
684 |
*/ |
687 |
static int |
685 |
static int |
688 |
pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, |
686 |
pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, |
689 |
struct pf_addr *src, sa_family_t af) |
687 |
struct pf_addr *src, sa_family_t af, struct pf_srchash **sh) |
690 |
{ |
688 |
{ |
691 |
|
689 |
|
692 |
KASSERT((rule->rule_flag & PFRULE_RULESRCTRACK || |
690 |
KASSERT((rule->rule_flag & PFRULE_RULESRCTRACK || |
693 |
rule->rpool.opts & PF_POOL_STICKYADDR), |
691 |
rule->rpool.opts & PF_POOL_STICKYADDR), |
694 |
("%s for non-tracking rule %p", __func__, rule)); |
692 |
("%s for non-tracking rule %p", __func__, rule)); |
695 |
|
693 |
|
696 |
if (*sn == NULL) |
694 |
if (*sn == NULL) |
697 |
*sn = pf_find_src_node(src, rule, af, 1); |
695 |
*sn = pf_find_src_node(src, rule, af, sh); |
698 |
|
696 |
|
699 |
if (*sn == NULL) { |
697 |
if (*sn == NULL) { |
700 |
struct pf_srchash *sh = &V_pf_srchash[pf_hashsrc(src, af)]; |
698 |
PF_HASHROW_ASSERT(*sh); |
701 |
|
|
|
702 |
PF_HASHROW_ASSERT(sh); |
703 |
|
699 |
|
704 |
if (!rule->max_src_nodes || |
700 |
if (!rule->max_src_nodes || |
705 |
counter_u64_fetch(rule->src_nodes) < rule->max_src_nodes) |
701 |
counter_u64_fetch(rule->src_nodes) < rule->max_src_nodes) |
706 |
(*sn) = uma_zalloc(V_pf_sources_z, M_NOWAIT | M_ZERO); |
702 |
(*sn) = uma_zalloc(V_pf_sources_z, M_NOWAIT | M_ZERO); |
707 |
else |
703 |
else |
708 |
counter_u64_add(V_pf_status.lcounters[LCNT_SRCNODES], |
704 |
counter_u64_add(V_pf_status.lcounters[LCNT_SRCNODES], |
709 |
1); |
705 |
1); |
710 |
if ((*sn) == NULL) { |
706 |
if ((*sn) == NULL) { |
711 |
PF_HASHROW_UNLOCK(sh); |
|
|
712 |
return (-1); |
707 |
return (-1); |
713 |
} |
708 |
} |
714 |
|
709 |
|
715 |
pf_init_threshold(&(*sn)->conn_rate, |
710 |
pf_init_threshold(&(*sn)->conn_rate, |
716 |
rule->max_src_conn_rate.limit, |
711 |
rule->max_src_conn_rate.limit, |
717 |
rule->max_src_conn_rate.seconds); |
712 |
rule->max_src_conn_rate.seconds); |
718 |
|
713 |
|
719 |
(*sn)->af = af; |
714 |
(*sn)->af = af; |
720 |
(*sn)->rule.ptr = rule; |
715 |
(*sn)->rule.ptr = rule; |
721 |
PF_ACPY(&(*sn)->addr, src, af); |
716 |
PF_ACPY(&(*sn)->addr, src, af); |
722 |
LIST_INSERT_HEAD(&sh->nodes, *sn, entry); |
717 |
LIST_INSERT_HEAD(&(*sh)->nodes, *sn, entry); |
723 |
(*sn)->creation = time_uptime; |
718 |
(*sn)->creation = time_uptime; |
724 |
(*sn)->ruletype = rule->action; |
719 |
(*sn)->ruletype = rule->action; |
725 |
(*sn)->states = 1; |
720 |
(*sn)->states = 1; |
726 |
if ((*sn)->rule.ptr != NULL) |
721 |
if ((*sn)->rule.ptr != NULL) |
727 |
counter_u64_add((*sn)->rule.ptr->src_nodes, 1); |
722 |
counter_u64_add((*sn)->rule.ptr->src_nodes, 1); |
728 |
PF_HASHROW_UNLOCK(sh); |
|
|
729 |
counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_INSERT], 1); |
723 |
counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_INSERT], 1); |
730 |
} else { |
724 |
} else { |
731 |
if (rule->max_src_states && |
725 |
if (rule->max_src_states && |
732 |
(*sn)->states >= rule->max_src_states) { |
726 |
(*sn)->states >= rule->max_src_states) { |
733 |
counter_u64_add(V_pf_status.lcounters[LCNT_SRCSTATES], |
727 |
counter_u64_add(V_pf_status.lcounters[LCNT_SRCSTATES], |
734 |
1); |
728 |
1); |
735 |
return (-1); |
729 |
return (-1); |
736 |
} |
730 |
} |
737 |
} |
731 |
} |
|
|
732 |
(*sn)->states++; |
738 |
return (0); |
733 |
return (0); |
739 |
} |
734 |
} |
740 |
|
735 |
|
741 |
void |
736 |
void |
742 |
pf_unlink_src_node(struct pf_src_node *src) |
737 |
pf_unlink_src_node(struct pf_src_node *src) |
743 |
{ |
738 |
{ |
744 |
|
739 |
|
745 |
PF_HASHROW_ASSERT(&V_pf_srchash[pf_hashsrc(&src->addr, src->af)]); |
740 |
PF_HASHROW_ASSERT(&V_pf_srchash[pf_hashsrc(&src->addr, src->af)]); |
746 |
LIST_REMOVE(src, entry); |
741 |
LIST_REMOVE(src, entry); |
747 |
if (src->rule.ptr) |
742 |
if (src->rule.ptr) |
Lines 3602-3642
pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
Link Here
|
3602 |
struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *nk, |
3597 |
struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *nk, |
3603 |
struct pf_state_key *sk, struct mbuf *m, int off, u_int16_t sport, |
3598 |
struct pf_state_key *sk, struct mbuf *m, int off, u_int16_t sport, |
3604 |
u_int16_t dport, int *rewrite, struct pfi_kif *kif, struct pf_state **sm, |
3599 |
u_int16_t dport, int *rewrite, struct pfi_kif *kif, struct pf_state **sm, |
3605 |
int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen) |
3600 |
int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen) |
3606 |
{ |
3601 |
{ |
3607 |
struct pf_state *s = NULL; |
3602 |
struct pf_state *s = NULL; |
3608 |
struct pf_src_node *sn = NULL; |
3603 |
struct pf_src_node *sn = NULL; |
3609 |
struct tcphdr *th = pd->hdr.tcp; |
3604 |
struct tcphdr *th = pd->hdr.tcp; |
3610 |
u_int16_t mss = V_tcp_mssdflt; |
3605 |
u_int16_t mss = V_tcp_mssdflt; |
3611 |
u_short reason; |
3606 |
u_short reason; |
|
|
3607 |
struct pf_srchash *sn_sh = NULL; |
3608 |
struct pf_srchash *nsn_sh = NULL; |
3612 |
|
3609 |
|
3613 |
/* check maximums */ |
3610 |
/* check maximums */ |
3614 |
if (r->max_states && |
3611 |
if (r->max_states && |
3615 |
(counter_u64_fetch(r->states_cur) >= r->max_states)) { |
3612 |
(counter_u64_fetch(r->states_cur) >= r->max_states)) { |
3616 |
counter_u64_add(V_pf_status.lcounters[LCNT_STATES], 1); |
3613 |
counter_u64_add(V_pf_status.lcounters[LCNT_STATES], 1); |
3617 |
REASON_SET(&reason, PFRES_MAXSTATES); |
3614 |
REASON_SET(&reason, PFRES_MAXSTATES); |
3618 |
goto csfailed; |
3615 |
goto csfailed; |
3619 |
} |
3616 |
} |
3620 |
/* src node for filter rule */ |
3617 |
/* src node for filter rule */ |
3621 |
if ((r->rule_flag & PFRULE_SRCTRACK || |
3618 |
if ((r->rule_flag & PFRULE_SRCTRACK || |
3622 |
r->rpool.opts & PF_POOL_STICKYADDR) && |
3619 |
r->rpool.opts & PF_POOL_STICKYADDR) && |
3623 |
pf_insert_src_node(&sn, r, pd->src, pd->af) != 0) { |
3620 |
pf_insert_src_node(&sn, r, pd->src, pd->af, &sn_sh) != 0) { |
3624 |
REASON_SET(&reason, PFRES_SRCLIMIT); |
3621 |
REASON_SET(&reason, PFRES_SRCLIMIT); |
3625 |
goto csfailed; |
3622 |
goto csfailed; |
3626 |
} |
3623 |
} |
|
|
3624 |
|
3627 |
/* src node for translation rule */ |
3625 |
/* src node for translation rule */ |
3628 |
if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && |
3626 |
if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && |
3629 |
pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx], pd->af)) { |
3627 |
pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx], pd->af, &nsn_sh)) { |
3630 |
REASON_SET(&reason, PFRES_SRCLIMIT); |
3628 |
REASON_SET(&reason, PFRES_SRCLIMIT); |
3631 |
goto csfailed; |
3629 |
goto csfailed; |
3632 |
} |
3630 |
} |
|
|
3631 |
|
3633 |
s = uma_zalloc(V_pf_state_z, M_NOWAIT | M_ZERO); |
3632 |
s = uma_zalloc(V_pf_state_z, M_NOWAIT | M_ZERO); |
3634 |
if (s == NULL) { |
3633 |
if (s == NULL) { |
3635 |
REASON_SET(&reason, PFRES_MEMORY); |
3634 |
REASON_SET(&reason, PFRES_MEMORY); |
3636 |
goto csfailed; |
3635 |
goto csfailed; |
3637 |
} |
3636 |
} |
3638 |
s->rule.ptr = r; |
3637 |
s->rule.ptr = r; |
3639 |
s->nat_rule.ptr = nr; |
3638 |
s->nat_rule.ptr = nr; |
3640 |
s->anchor.ptr = a; |
3639 |
s->anchor.ptr = a; |
3641 |
STATE_INC_COUNTERS(s); |
3640 |
STATE_INC_COUNTERS(s); |
3642 |
if (r->allow_opts) |
3641 |
if (r->allow_opts) |
Lines 3694-3732
pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
Link Here
|
3694 |
#endif |
3693 |
#endif |
3695 |
s->timeout = PFTM_ICMP_FIRST_PACKET; |
3694 |
s->timeout = PFTM_ICMP_FIRST_PACKET; |
3696 |
break; |
3695 |
break; |
3697 |
default: |
3696 |
default: |
3698 |
s->src.state = PFOTHERS_SINGLE; |
3697 |
s->src.state = PFOTHERS_SINGLE; |
3699 |
s->dst.state = PFOTHERS_NO_TRAFFIC; |
3698 |
s->dst.state = PFOTHERS_NO_TRAFFIC; |
3700 |
s->timeout = PFTM_OTHER_FIRST_PACKET; |
3699 |
s->timeout = PFTM_OTHER_FIRST_PACKET; |
3701 |
} |
3700 |
} |
3702 |
|
3701 |
|
3703 |
if (r->rt && r->rt != PF_FASTROUTE) { |
3702 |
if (r->rt && r->rt != PF_FASTROUTE) { |
3704 |
if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) { |
3703 |
if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, &s->rt_kif, |
|
|
3704 |
NULL, &sn, 1)) { |
3705 |
REASON_SET(&reason, PFRES_MAPFAILED); |
3705 |
REASON_SET(&reason, PFRES_MAPFAILED); |
3706 |
pf_src_tree_remove_state(s); |
3706 |
pf_src_tree_remove_state(s); |
3707 |
STATE_DEC_COUNTERS(s); |
3707 |
STATE_DEC_COUNTERS(s); |
3708 |
uma_zfree(V_pf_state_z, s); |
3708 |
uma_zfree(V_pf_state_z, s); |
3709 |
goto csfailed; |
3709 |
goto csfailed; |
3710 |
} |
3710 |
} |
3711 |
s->rt_kif = r->rpool.cur->kif; |
|
|
3712 |
} |
3711 |
} |
3713 |
|
3712 |
|
3714 |
s->creation = time_uptime; |
3713 |
s->creation = time_uptime; |
3715 |
s->expire = time_uptime; |
3714 |
s->expire = time_uptime; |
3716 |
|
3715 |
|
3717 |
if (sn != NULL) |
3716 |
if (sn != NULL) { |
3718 |
s->src_node = sn; |
3717 |
s->src_node = sn; |
|
|
3718 |
sn->states++; |
3719 |
PF_HASHROW_UNLOCK(sn_sh); |
3720 |
} |
3719 |
if (nsn != NULL) { |
3721 |
if (nsn != NULL) { |
3720 |
/* XXX We only modify one side for now. */ |
3722 |
/* XXX We only modify one side for now. */ |
3721 |
PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af); |
3723 |
PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af); |
3722 |
s->nat_src_node = nsn; |
3724 |
s->nat_src_node = nsn; |
|
|
3725 |
nsn->states++; |
3726 |
PF_HASHROW_UNLOCK(nsn_sh); |
3723 |
} |
3727 |
} |
3724 |
if (pd->proto == IPPROTO_TCP) { |
3728 |
if (pd->proto == IPPROTO_TCP) { |
3725 |
if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, |
3729 |
if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, |
3726 |
off, pd, th, &s->src, &s->dst)) { |
3730 |
off, pd, th, &s->src, &s->dst)) { |
3727 |
REASON_SET(&reason, PFRES_MEMORY); |
3731 |
REASON_SET(&reason, PFRES_MEMORY); |
3728 |
pf_src_tree_remove_state(s); |
3732 |
pf_src_tree_remove_state(s); |
3729 |
STATE_DEC_COUNTERS(s); |
3733 |
STATE_DEC_COUNTERS(s); |
3730 |
uma_zfree(V_pf_state_z, s); |
3734 |
uma_zfree(V_pf_state_z, s); |
3731 |
return (PF_DROP); |
3735 |
return (PF_DROP); |
3732 |
} |
3736 |
} |
Lines 3811-3856
pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
Link Here
|
3811 |
|
3815 |
|
3812 |
return (PF_PASS); |
3816 |
return (PF_PASS); |
3813 |
|
3817 |
|
3814 |
csfailed: |
3818 |
csfailed: |
3815 |
if (sk != NULL) |
3819 |
if (sk != NULL) |
3816 |
uma_zfree(V_pf_state_key_z, sk); |
3820 |
uma_zfree(V_pf_state_key_z, sk); |
3817 |
if (nk != NULL) |
3821 |
if (nk != NULL) |
3818 |
uma_zfree(V_pf_state_key_z, nk); |
3822 |
uma_zfree(V_pf_state_key_z, nk); |
3819 |
|
3823 |
|
3820 |
if (sn != NULL) { |
3824 |
if (sn != NULL) { |
3821 |
struct pf_srchash *sh; |
|
|
3822 |
|
3823 |
sh = &V_pf_srchash[pf_hashsrc(&sn->addr, sn->af)]; |
3824 |
PF_HASHROW_LOCK(sh); |
3825 |
if (--sn->states == 0 && sn->expire == 0) { |
3825 |
if (--sn->states == 0 && sn->expire == 0) { |
3826 |
pf_unlink_src_node(sn); |
3826 |
pf_unlink_src_node(sn); |
3827 |
uma_zfree(V_pf_sources_z, sn); |
3827 |
uma_zfree(V_pf_sources_z, sn); |
3828 |
counter_u64_add( |
3828 |
counter_u64_add( |
3829 |
V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS], 1); |
3829 |
V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS], 1); |
3830 |
} |
3830 |
} |
3831 |
PF_HASHROW_UNLOCK(sh); |
|
|
3832 |
} |
3831 |
} |
|
|
3832 |
if (sn_sh) |
3833 |
PF_HASHROW_UNLOCK(sn_sh); |
3833 |
|
3834 |
|
3834 |
if (nsn != sn && nsn != NULL) { |
3835 |
if (nsn != sn && nsn != NULL) { |
3835 |
struct pf_srchash *sh; |
|
|
3836 |
|
3837 |
sh = &V_pf_srchash[pf_hashsrc(&nsn->addr, nsn->af)]; |
3838 |
PF_HASHROW_LOCK(sh); |
3839 |
if (--nsn->states == 0 && nsn->expire == 0) { |
3836 |
if (--nsn->states == 0 && nsn->expire == 0) { |
3840 |
pf_unlink_src_node(nsn); |
3837 |
pf_unlink_src_node(nsn); |
3841 |
uma_zfree(V_pf_sources_z, nsn); |
3838 |
uma_zfree(V_pf_sources_z, nsn); |
3842 |
counter_u64_add( |
3839 |
counter_u64_add( |
3843 |
V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS], 1); |
3840 |
V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS], 1); |
3844 |
} |
3841 |
} |
3845 |
PF_HASHROW_UNLOCK(sh); |
|
|
3846 |
} |
3842 |
} |
|
|
3843 |
if (nsn_sh) |
3844 |
PF_HASHROW_UNLOCK(nsn_sh); |
3847 |
|
3845 |
|
3848 |
return (PF_DROP); |
3846 |
return (PF_DROP); |
3849 |
} |
3847 |
} |
3850 |
|
3848 |
|
3851 |
static int |
3849 |
static int |
3852 |
pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, |
3850 |
pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, |
3853 |
struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, |
3851 |
struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, |
3854 |
struct pf_ruleset **rsm) |
3852 |
struct pf_ruleset **rsm) |
3855 |
{ |
3853 |
{ |
3856 |
struct pf_rule *r, *a = NULL; |
3854 |
struct pf_rule *r, *a = NULL; |
Lines 5460-5479
pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif,
Link Here
|
5460 |
} |
5458 |
} |
5461 |
|
5459 |
|
5462 |
#ifdef INET |
5460 |
#ifdef INET |
5463 |
static void |
5461 |
static void |
5464 |
pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, |
5462 |
pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, |
5465 |
struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp) |
5463 |
struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp) |
5466 |
{ |
5464 |
{ |
5467 |
struct mbuf *m0, *m1; |
5465 |
struct mbuf *m0, *m1; |
5468 |
struct sockaddr_in dst; |
5466 |
struct sockaddr_in dst; |
5469 |
struct ip *ip; |
5467 |
struct ip *ip; |
|
|
5468 |
struct pfi_kif *rt_kif = NULL; |
5470 |
struct ifnet *ifp = NULL; |
5469 |
struct ifnet *ifp = NULL; |
5471 |
struct pf_addr naddr; |
5470 |
struct pf_addr naddr; |
5472 |
struct pf_src_node *sn = NULL; |
5471 |
struct pf_src_node *sn = NULL; |
5473 |
int error = 0; |
5472 |
int error = 0; |
5474 |
uint16_t ip_len, ip_off; |
5473 |
uint16_t ip_len, ip_off; |
5475 |
|
5474 |
|
5476 |
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); |
5475 |
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); |
5477 |
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction", |
5476 |
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction", |
5478 |
__func__)); |
5477 |
__func__)); |
5479 |
|
5478 |
|
Lines 5523-5547
pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
Link Here
|
5523 |
ifp = nh4.nh_ifp; |
5522 |
ifp = nh4.nh_ifp; |
5524 |
dst.sin_addr = nh4.nh_addr; |
5523 |
dst.sin_addr = nh4.nh_addr; |
5525 |
} else { |
5524 |
} else { |
5526 |
if (TAILQ_EMPTY(&r->rpool.list)) { |
5525 |
if (TAILQ_EMPTY(&r->rpool.list)) { |
5527 |
DPFPRINTF(PF_DEBUG_URGENT, |
5526 |
DPFPRINTF(PF_DEBUG_URGENT, |
5528 |
("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); |
5527 |
("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); |
5529 |
goto bad_locked; |
5528 |
goto bad_locked; |
5530 |
} |
5529 |
} |
5531 |
if (s == NULL) { |
5530 |
if (s == NULL) { |
5532 |
pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, |
5531 |
pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, |
5533 |
&naddr, NULL, &sn); |
5532 |
&naddr, &rt_kif, NULL, &sn, 0); |
5534 |
if (!PF_AZERO(&naddr, AF_INET)) |
5533 |
if (!PF_AZERO(&naddr, AF_INET)) |
5535 |
dst.sin_addr.s_addr = naddr.v4.s_addr; |
5534 |
dst.sin_addr.s_addr = naddr.v4.s_addr; |
5536 |
ifp = r->rpool.cur->kif ? |
5535 |
ifp = rt_kif ? rt_kif->pfik_ifp : NULL; |
5537 |
r->rpool.cur->kif->pfik_ifp : NULL; |
|
|
5538 |
} else { |
5536 |
} else { |
5539 |
if (!PF_AZERO(&s->rt_addr, AF_INET)) |
5537 |
if (!PF_AZERO(&s->rt_addr, AF_INET)) |
5540 |
dst.sin_addr.s_addr = |
5538 |
dst.sin_addr.s_addr = |
5541 |
s->rt_addr.v4.s_addr; |
5539 |
s->rt_addr.v4.s_addr; |
5542 |
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; |
5540 |
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; |
5543 |
PF_STATE_UNLOCK(s); |
5541 |
PF_STATE_UNLOCK(s); |
5544 |
} |
5542 |
} |
5545 |
} |
5543 |
} |
5546 |
if (ifp == NULL) |
5544 |
if (ifp == NULL) |
5547 |
goto bad; |
5545 |
goto bad; |
Lines 5638-5657
pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
Link Here
|
5638 |
#endif /* INET */ |
5636 |
#endif /* INET */ |
5639 |
|
5637 |
|
5640 |
#ifdef INET6 |
5638 |
#ifdef INET6 |
5641 |
static void |
5639 |
static void |
5642 |
pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, |
5640 |
pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, |
5643 |
struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp) |
5641 |
struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp) |
5644 |
{ |
5642 |
{ |
5645 |
struct mbuf *m0; |
5643 |
struct mbuf *m0; |
5646 |
struct sockaddr_in6 dst; |
5644 |
struct sockaddr_in6 dst; |
5647 |
struct ip6_hdr *ip6; |
5645 |
struct ip6_hdr *ip6; |
|
|
5646 |
struct pfi_kif *rt_kif = NULL; |
5648 |
struct ifnet *ifp = NULL; |
5647 |
struct ifnet *ifp = NULL; |
5649 |
struct pf_addr naddr; |
5648 |
struct pf_addr naddr; |
5650 |
struct pf_src_node *sn = NULL; |
5649 |
struct pf_src_node *sn = NULL; |
5651 |
|
5650 |
|
5652 |
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); |
5651 |
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__)); |
5653 |
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction", |
5652 |
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction", |
5654 |
__func__)); |
5653 |
__func__)); |
5655 |
|
5654 |
|
5656 |
if ((pd->pf_mtag == NULL && |
5655 |
if ((pd->pf_mtag == NULL && |
5657 |
((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) || |
5656 |
((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) || |
Lines 5693-5717
pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
Link Here
|
5693 |
return; |
5692 |
return; |
5694 |
} |
5693 |
} |
5695 |
|
5694 |
|
5696 |
if (TAILQ_EMPTY(&r->rpool.list)) { |
5695 |
if (TAILQ_EMPTY(&r->rpool.list)) { |
5697 |
DPFPRINTF(PF_DEBUG_URGENT, |
5696 |
DPFPRINTF(PF_DEBUG_URGENT, |
5698 |
("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); |
5697 |
("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); |
5699 |
goto bad_locked; |
5698 |
goto bad_locked; |
5700 |
} |
5699 |
} |
5701 |
if (s == NULL) { |
5700 |
if (s == NULL) { |
5702 |
pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, |
5701 |
pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, |
5703 |
&naddr, NULL, &sn); |
5702 |
&naddr, &rt_kif, NULL, &sn, 0); |
5704 |
if (!PF_AZERO(&naddr, AF_INET6)) |
5703 |
if (!PF_AZERO(&naddr, AF_INET6)) |
5705 |
PF_ACPY((struct pf_addr *)&dst.sin6_addr, |
5704 |
PF_ACPY((struct pf_addr *)&dst.sin6_addr, |
5706 |
&naddr, AF_INET6); |
5705 |
&naddr, AF_INET6); |
5707 |
ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; |
5706 |
ifp = rt_kif ? rt_kif->pfik_ifp : NULL; |
5708 |
} else { |
5707 |
} else { |
5709 |
if (!PF_AZERO(&s->rt_addr, AF_INET6)) |
5708 |
if (!PF_AZERO(&s->rt_addr, AF_INET6)) |
5710 |
PF_ACPY((struct pf_addr *)&dst.sin6_addr, |
5709 |
PF_ACPY((struct pf_addr *)&dst.sin6_addr, |
5711 |
&s->rt_addr, AF_INET6); |
5710 |
&s->rt_addr, AF_INET6); |
5712 |
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; |
5711 |
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; |
5713 |
} |
5712 |
} |
5714 |
|
5713 |
|
5715 |
if (s) |
5714 |
if (s) |
5716 |
PF_STATE_UNLOCK(s); |
5715 |
PF_STATE_UNLOCK(s); |
5717 |
|
5716 |
|