View | Details | Raw Unified | Return to bug 230640
Collapse All | Expand All

(-)b/sys/net/pfvar.h (-2 / +6 lines)
Lines 357-376 struct pf_poolhashkey { Link Here
357
};
357
};
358
358
359
struct pf_pool {
359
struct pf_pool {
360
	struct pf_palist	 list;
360
	struct pf_palist	 list;
361
	struct pf_pooladdr	*cur;
361
	struct pf_pooladdr	*cur;
362
	struct pf_poolhashkey	 key;
362
	struct pf_poolhashkey	 key;
363
	struct pf_addr		 counter;
363
	struct pf_addr		 counter;
364
	int			 tblidx;
364
	int			 tblidx;
365
	u_int16_t		 proxy_port[2];
365
	u_int16_t		 proxy_port[2];
366
	u_int8_t		 opts;
366
	u_int8_t		 opts;
367
	struct mtx		 lock;
367
};
368
};
368
369
369
370
370
/* A packed Operating System description for fingerprinting */
371
/* A packed Operating System description for fingerprinting */
371
typedef u_int32_t pf_osfp_t;
372
typedef u_int32_t pf_osfp_t;
372
#define PF_OSFP_ANY	((pf_osfp_t)0)
373
#define PF_OSFP_ANY	((pf_osfp_t)0)
373
#define PF_OSFP_UNKNOWN	((pf_osfp_t)-1)
374
#define PF_OSFP_UNKNOWN	((pf_osfp_t)-1)
374
#define PF_OSFP_NOMATCH	((pf_osfp_t)-2)
375
#define PF_OSFP_NOMATCH	((pf_osfp_t)-2)
375
376
376
struct pf_osfp_entry {
377
struct pf_osfp_entry {
Lines 626-645 struct pf_threshold { Link Here
626
	u_int32_t	count;
627
	u_int32_t	count;
627
	u_int32_t	last;
628
	u_int32_t	last;
628
};
629
};
629
630
630
struct pf_src_node {
631
struct pf_src_node {
631
	LIST_ENTRY(pf_src_node) entry;
632
	LIST_ENTRY(pf_src_node) entry;
632
	struct pf_addr	 addr;
633
	struct pf_addr	 addr;
633
	struct pf_addr	 raddr;
634
	struct pf_addr	 raddr;
634
	union pf_rule_ptr rule;
635
	union pf_rule_ptr rule;
635
	struct pfi_kif	*kif;
636
	struct pfi_kif	*kif;
637
	struct pfi_kif	*rkif;
636
	u_int64_t	 bytes[2];
638
	u_int64_t	 bytes[2];
637
	u_int64_t	 packets[2];
639
	u_int64_t	 packets[2];
638
	u_int32_t	 states;
640
	u_int32_t	 states;
639
	u_int32_t	 conn;
641
	u_int32_t	 conn;
640
	struct pf_threshold	conn_rate;
642
	struct pf_threshold	conn_rate;
641
	u_int32_t	 creation;
643
	u_int32_t	 creation;
642
	u_int32_t	 expire;
644
	u_int32_t	 expire;
643
	sa_family_t	 af;
645
	sa_family_t	 af;
644
	u_int8_t	 ruletype;
646
	u_int8_t	 ruletype;
645
};
647
};
Lines 1578-1598 pf_release_state(struct pf_state *s) Link Here
1578
		pf_free_state(s);
1580
		pf_free_state(s);
1579
		return (1);
1581
		return (1);
1580
	} else
1582
	} else
1581
		return (0);
1583
		return (0);
1582
}
1584
}
1583
1585
1584
extern struct pf_state		*pf_find_state_byid(uint64_t, uint32_t);
1586
extern struct pf_state		*pf_find_state_byid(uint64_t, uint32_t);
1585
extern struct pf_state		*pf_find_state_all(struct pf_state_key_cmp *,
1587
extern struct pf_state		*pf_find_state_all(struct pf_state_key_cmp *,
1586
				    u_int, int *);
1588
				    u_int, int *);
1587
extern struct pf_src_node	*pf_find_src_node(struct pf_addr *,
1589
extern struct pf_src_node	*pf_find_src_node(struct pf_addr *,
1588
				    struct pf_rule *, sa_family_t, int);
1590
				    struct pf_rule *, sa_family_t,
1591
				    struct pf_srchash **);
1589
extern void			 pf_unlink_src_node(struct pf_src_node *);
1592
extern void			 pf_unlink_src_node(struct pf_src_node *);
1590
extern u_int			 pf_free_src_nodes(struct pf_src_node_list *);
1593
extern u_int			 pf_free_src_nodes(struct pf_src_node_list *);
1591
extern void			 pf_print_state(struct pf_state *);
1594
extern void			 pf_print_state(struct pf_state *);
1592
extern void			 pf_print_flags(u_int8_t);
1595
extern void			 pf_print_flags(u_int8_t);
1593
extern u_int16_t		 pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
1596
extern u_int16_t		 pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
1594
				    u_int8_t);
1597
				    u_int8_t);
1595
extern u_int16_t		 pf_proto_cksum_fixup(struct mbuf *, u_int16_t,
1598
extern u_int16_t		 pf_proto_cksum_fixup(struct mbuf *, u_int16_t,
1596
				    u_int16_t, u_int16_t, u_int8_t);
1599
				    u_int16_t, u_int16_t, u_int8_t);
1597
1600
1598
VNET_DECLARE(struct ifnet *,		 sync_ifp);
1601
VNET_DECLARE(struct ifnet *,		 sync_ifp);
Lines 1767-1787 void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); Link Here
1767
1770
1768
void			 pf_step_into_anchor(struct pf_anchor_stackframe *, int *,
1771
void			 pf_step_into_anchor(struct pf_anchor_stackframe *, int *,
1769
			    struct pf_ruleset **, int, struct pf_rule **,
1772
			    struct pf_ruleset **, int, struct pf_rule **,
1770
			    struct pf_rule **, int *);
1773
			    struct pf_rule **, int *);
1771
int			 pf_step_out_of_anchor(struct pf_anchor_stackframe *, int *,
1774
int			 pf_step_out_of_anchor(struct pf_anchor_stackframe *, int *,
1772
			    struct pf_ruleset **, int, struct pf_rule **,
1775
			    struct pf_ruleset **, int, struct pf_rule **,
1773
			    struct pf_rule **, int *);
1776
			    struct pf_rule **, int *);
1774
1777
1775
int			 pf_map_addr(u_int8_t, struct pf_rule *,
1778
int			 pf_map_addr(u_int8_t, struct pf_rule *,
1776
			    struct pf_addr *, struct pf_addr *,
1779
			    struct pf_addr *, struct pf_addr *,
1777
			    struct pf_addr *, struct pf_src_node **);
1780
			    struct pfi_kif **, struct pf_addr *,
1781
			    struct pf_src_node **, int);
1778
struct pf_rule		*pf_get_translation(struct pf_pdesc *, struct mbuf *,
1782
struct pf_rule		*pf_get_translation(struct pf_pdesc *, struct mbuf *,
1779
			    int, int, struct pfi_kif *, struct pf_src_node **,
1783
			    int, int, struct pfi_kif *, struct pf_src_node **,
1780
			    struct pf_state_key **, struct pf_state_key **,
1784
			    struct pf_state_key **, struct pf_state_key **,
1781
			    struct pf_addr *, struct pf_addr *,
1785
			    struct pf_addr *, struct pf_addr *,
1782
			    uint16_t, uint16_t, struct pf_anchor_stackframe *);
1786
			    uint16_t, uint16_t, struct pf_anchor_stackframe *);
1783
1787
1784
struct pf_state_key	*pf_state_key_setup(struct pf_pdesc *, struct pf_addr *,
1788
struct pf_state_key	*pf_state_key_setup(struct pf_pdesc *, struct pf_addr *,
1785
			    struct pf_addr *, u_int16_t, u_int16_t);
1789
			    struct pf_addr *, u_int16_t, u_int16_t);
1786
struct pf_state_key	*pf_state_key_clone(struct pf_state_key *);
1790
struct pf_state_key	*pf_state_key_clone(struct pf_state_key *);
1787
#endif /* _KERNEL */
1791
#endif /* _KERNEL */
(-)b/sys/netpfil/pf/pf.c (-41 / +40 lines)
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
(-)b/sys/netpfil/pf/pf_ioctl.c (+2 lines)
Lines 413-432 pf_free_rule(struct pf_rule *rule) Link Here
413
		break;
413
		break;
414
	case PF_ADDR_TABLE:
414
	case PF_ADDR_TABLE:
415
		pfr_detach_table(rule->dst.addr.p.tbl);
415
		pfr_detach_table(rule->dst.addr.p.tbl);
416
		break;
416
		break;
417
	}
417
	}
418
	if (rule->overload_tbl)
418
	if (rule->overload_tbl)
419
		pfr_detach_table(rule->overload_tbl);
419
		pfr_detach_table(rule->overload_tbl);
420
	if (rule->kif)
420
	if (rule->kif)
421
		pfi_kif_unref(rule->kif);
421
		pfi_kif_unref(rule->kif);
422
	pf_anchor_remove(rule);
422
	pf_anchor_remove(rule);
423
	mtx_destroy(&rule->rpool.lock);
423
	pf_empty_pool(&rule->rpool.list);
424
	pf_empty_pool(&rule->rpool.list);
424
	counter_u64_free(rule->states_cur);
425
	counter_u64_free(rule->states_cur);
425
	counter_u64_free(rule->states_tot);
426
	counter_u64_free(rule->states_tot);
426
	counter_u64_free(rule->src_nodes);
427
	counter_u64_free(rule->src_nodes);
427
	free(rule, M_PFRULE);
428
	free(rule, M_PFRULE);
428
}
429
}
429
430
430
static u_int16_t
431
static u_int16_t
431
tagname2tag(struct pf_tags *head, char *tagname)
432
tagname2tag(struct pf_tags *head, char *tagname)
432
{
433
{
Lines 1165-1184 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td Link Here
1165
		}
1166
		}
1166
#endif /* INET6 */
1167
#endif /* INET6 */
1167
1168
1168
		rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
1169
		rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
1169
		bcopy(&pr->rule, rule, sizeof(struct pf_rule));
1170
		bcopy(&pr->rule, rule, sizeof(struct pf_rule));
1170
		if (rule->ifname[0])
1171
		if (rule->ifname[0])
1171
			kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK);
1172
			kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK);
1172
		rule->states_cur = counter_u64_alloc(M_WAITOK);
1173
		rule->states_cur = counter_u64_alloc(M_WAITOK);
1173
		rule->states_tot = counter_u64_alloc(M_WAITOK);
1174
		rule->states_tot = counter_u64_alloc(M_WAITOK);
1174
		rule->src_nodes = counter_u64_alloc(M_WAITOK);
1175
		rule->src_nodes = counter_u64_alloc(M_WAITOK);
1176
		mtx_init(&rule->rpool.lock, "pf_pool", NULL, MTX_DEF);
1175
		rule->cuid = td->td_ucred->cr_ruid;
1177
		rule->cuid = td->td_ucred->cr_ruid;
1176
		rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
1178
		rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
1177
		TAILQ_INIT(&rule->rpool.list);
1179
		TAILQ_INIT(&rule->rpool.list);
1178
1180
1179
#define	ERROUT(x)	{ error = (x); goto DIOCADDRULE_error; }
1181
#define	ERROUT(x)	{ error = (x); goto DIOCADDRULE_error; }
1180
1182
1181
		PF_RULES_WLOCK();
1183
		PF_RULES_WLOCK();
1182
		pr->anchor[sizeof(pr->anchor) - 1] = 0;
1184
		pr->anchor[sizeof(pr->anchor) - 1] = 0;
1183
		ruleset = pf_find_ruleset(pr->anchor);
1185
		ruleset = pf_find_ruleset(pr->anchor);
1184
		if (ruleset == NULL)
1186
		if (ruleset == NULL)
(-)b/sys/netpfil/pf/pf_lb.c (-22 / +55 lines)
Lines 40-59 __FBSDID("$FreeBSD$"); Link Here
40
#include "opt_pf.h"
40
#include "opt_pf.h"
41
#include "opt_inet.h"
41
#include "opt_inet.h"
42
#include "opt_inet6.h"
42
#include "opt_inet6.h"
43
43
44
#include <sys/param.h>
44
#include <sys/param.h>
45
#include <sys/lock.h>
45
#include <sys/lock.h>
46
#include <sys/mbuf.h>
46
#include <sys/mbuf.h>
47
#include <sys/rwlock.h>
47
#include <sys/rwlock.h>
48
#include <sys/socket.h>
48
#include <sys/socket.h>
49
#include <sys/sysctl.h>
49
#include <sys/sysctl.h>
50
#include <sys/mutex.h>
50
51
51
#include <net/if.h>
52
#include <net/if.h>
52
#include <net/vnet.h>
53
#include <net/vnet.h>
53
#include <net/pfvar.h>
54
#include <net/pfvar.h>
54
#include <net/if_pflog.h>
55
#include <net/if_pflog.h>
55
56
56
#define DPFPRINTF(n, x)	if (V_pf_status.debug >= (n)) printf x
57
#define DPFPRINTF(n, x)	if (V_pf_status.debug >= (n)) printf x
57
58
58
static void		 pf_hash(struct pf_addr *, struct pf_addr *,
59
static void		 pf_hash(struct pf_addr *, struct pf_addr *,
59
			    struct pf_poolhashkey *, sa_family_t);
60
			    struct pf_poolhashkey *, sa_family_t);
Lines 213-233 pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, Link Here
213
static int
214
static int
214
pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
215
pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
215
    struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr,
216
    struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr,
216
    uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low,
217
    uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low,
217
    uint16_t high, struct pf_src_node **sn)
218
    uint16_t high, struct pf_src_node **sn)
218
{
219
{
219
	struct pf_state_key_cmp	key;
220
	struct pf_state_key_cmp	key;
220
	struct pf_addr		init_addr;
221
	struct pf_addr		init_addr;
221
222
222
	bzero(&init_addr, sizeof(init_addr));
223
	bzero(&init_addr, sizeof(init_addr));
223
	if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
224
	if (pf_map_addr(af, r, saddr, naddr, NULL, &init_addr, sn, 0))
224
		return (1);
225
		return (1);
225
226
226
	if (proto == IPPROTO_ICMP) {
227
	if (proto == IPPROTO_ICMP) {
227
		low = 1;
228
		low = 1;
228
		high = 65535;
229
		high = 65535;
229
	}
230
	}
230
231
231
	bzero(&key, sizeof(key));
232
	bzero(&key, sizeof(key));
232
	key.af = af;
233
	key.af = af;
233
	key.proto = proto;
234
	key.proto = proto;
Lines 285-376 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, Link Here
285
				    NULL) {
286
				    NULL) {
286
					*nport = htons(tmp);
287
					*nport = htons(tmp);
287
					return (0);
288
					return (0);
288
				}
289
				}
289
			}
290
			}
290
		}
291
		}
291
292
292
		switch (r->rpool.opts & PF_POOL_TYPEMASK) {
293
		switch (r->rpool.opts & PF_POOL_TYPEMASK) {
293
		case PF_POOL_RANDOM:
294
		case PF_POOL_RANDOM:
294
		case PF_POOL_ROUNDROBIN:
295
		case PF_POOL_ROUNDROBIN:
295
			if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
296
			if (pf_map_addr(af, r, saddr, naddr, NULL, &init_addr,
297
			    sn, 0))
296
				return (1);
298
				return (1);
297
			break;
299
			break;
298
		case PF_POOL_NONE:
300
		case PF_POOL_NONE:
299
		case PF_POOL_SRCHASH:
301
		case PF_POOL_SRCHASH:
300
		case PF_POOL_BITMASK:
302
		case PF_POOL_BITMASK:
301
		default:
303
		default:
302
			return (1);
304
			return (1);
303
		}
305
		}
304
	} while (! PF_AEQ(&init_addr, naddr, af) );
306
	} while (! PF_AEQ(&init_addr, naddr, af) );
305
	return (1);					/* none available */
307
	return (1);					/* none available */
306
}
308
}
307
309
308
int
310
int
309
pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
311
pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
310
    struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
312
    struct pf_addr *naddr, struct pfi_kif **rt_kif, struct pf_addr *init_addr,
313
    struct pf_src_node **sn, int return_locked)
311
{
314
{
312
	struct pf_pool		*rpool = &r->rpool;
315
	struct pf_pool		*rpool = &r->rpool;
313
	struct pf_addr		*raddr = NULL, *rmask = NULL;
316
	struct pf_addr		*raddr = NULL, *rmask = NULL;
317
	bool			 pool_locked = false;
318
	struct pf_srchash	*sh = NULL;
314
319
315
	/* Try to find a src_node if none was given and this
320
	/* Try to find a src_node if none was given and this
316
	   is a sticky-address rule. */
321
	   is a sticky-address rule. */
317
	if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
322
	if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
318
	    (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
323
	    (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
319
		*sn = pf_find_src_node(saddr, r, af, 0);
324
		*sn = pf_find_src_node(saddr, r, af, &sh);
320
325
321
	/* If a src_node was found or explicitly given and it has a non-zero
326
	/* If a src_node was found or explicitly given and it has a non-zero
322
	   route address, use this address. A zeroed address is found if the
327
	   route address, use this address. A zeroed address is found if the
323
	   src node was created just a moment ago in pf_create_state and it
328
	   src node was created just a moment ago in pf_create_state and it
324
	   needs to be filled in with routing decision calculated here. */
329
	   needs to be filled in with routing decision calculated here. */
325
	if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
330
	if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
326
		PF_ACPY(naddr, &(*sn)->raddr, af);
331
		PF_ACPY(naddr, &(*sn)->raddr, af);
332
		if (rt_kif)
333
			*rt_kif = (*sn)->rkif;
327
		if (V_pf_status.debug >= PF_DEBUG_MISC) {
334
		if (V_pf_status.debug >= PF_DEBUG_MISC) {
328
			printf("pf_map_addr: src tracking maps ");
335
			printf("pf_map_addr: src tracking maps ");
329
			pf_print_host(saddr, 0, af);
336
			pf_print_host(saddr, 0, af);
330
			printf(" to ");
337
			printf(" to ");
331
			pf_print_host(naddr, 0, af);
338
			pf_print_host(naddr, 0, af);
332
			printf("\n");
339
			printf("\n");
333
		}
340
		}
341
		if (!return_locked)
342
			PF_HASHROW_UNLOCK(sh);
334
		return (0);
343
		return (0);
335
	}
344
	}
336
345
337
	/* Find the route using chosen algorithm. Store the found route
346
	/* Find the route using chosen algorithm. Store the found route
338
	   in src_node if it was given or found. */
347
	   in src_node if it was given or found. */
339
	if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
348
	if (rpool->cur->addr.type == PF_ADDR_NOROUTE) {
349
		if (sh && !return_locked)
350
			PF_HASHROW_UNLOCK(sh);
340
		return (1);
351
		return (1);
352
	}
341
	if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
353
	if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
342
		switch (af) {
354
		switch (af) {
343
#ifdef INET
355
#ifdef INET
344
		case AF_INET:
356
		case AF_INET:
345
			if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
357
			if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
346
			    (rpool->opts & PF_POOL_TYPEMASK) !=
358
			    (rpool->opts & PF_POOL_TYPEMASK) !=
347
			    PF_POOL_ROUNDROBIN)
359
			    PF_POOL_ROUNDROBIN) {
360
				if (sh && !return_locked)
361
					PF_HASHROW_UNLOCK(sh);
348
				return (1);
362
				return (1);
363
			    }
349
			 raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
364
			 raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
350
			 rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
365
			 rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
351
			break;
366
			break;
352
#endif /* INET */
367
#endif /* INET */
353
#ifdef INET6
368
#ifdef INET6
354
		case AF_INET6:
369
		case AF_INET6:
355
			if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
370
			if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
356
			    (rpool->opts & PF_POOL_TYPEMASK) !=
371
			    (rpool->opts & PF_POOL_TYPEMASK) !=
357
			    PF_POOL_ROUNDROBIN)
372
			    PF_POOL_ROUNDROBIN) {
373
				if (sh && !return_locked)
374
					PF_HASHROW_UNLOCK(sh);
358
				return (1);
375
				return (1);
376
			    }
359
			raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
377
			raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
360
			rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
378
			rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
361
			break;
379
			break;
362
#endif /* INET6 */
380
#endif /* INET6 */
363
		}
381
		}
364
	} else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
382
	} else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
365
		if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
383
		if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) {
384
			if (sh && !return_locked)
385
				PF_HASHROW_UNLOCK(sh);
366
			return (1); /* unsupported */
386
			return (1); /* unsupported */
387
		}
367
	} else {
388
	} else {
368
		raddr = &rpool->cur->addr.v.a.addr;
389
		raddr = &rpool->cur->addr.v.a.addr;
369
		rmask = &rpool->cur->addr.v.a.mask;
390
		rmask = &rpool->cur->addr.v.a.mask;
370
	}
391
	}
371
392
372
	switch (rpool->opts & PF_POOL_TYPEMASK) {
393
	switch (rpool->opts & PF_POOL_TYPEMASK) {
373
	case PF_POOL_NONE:
394
	case PF_POOL_NONE:
374
		PF_ACPY(naddr, raddr, af);
395
		PF_ACPY(naddr, raddr, af);
375
		break;
396
		break;
376
	case PF_POOL_BITMASK:
397
	case PF_POOL_BITMASK:
Lines 418-458 pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, Link Here
418
	case PF_POOL_SRCHASH:
439
	case PF_POOL_SRCHASH:
419
	    {
440
	    {
420
		unsigned char hash[16];
441
		unsigned char hash[16];
421
442
422
		pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
443
		pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
423
		PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
444
		PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
424
		break;
445
		break;
425
	    }
446
	    }
426
	case PF_POOL_ROUNDROBIN:
447
	case PF_POOL_ROUNDROBIN:
427
	    {
448
	    {
449
		mtx_lock(&rpool->lock);
450
		pool_locked = true;
428
		struct pf_pooladdr *acur = rpool->cur;
451
		struct pf_pooladdr *acur = rpool->cur;
429
452
430
		/*
453
		/*
431
		 * XXXGL: in the round-robin case we need to store
454
		 * XXXGL: in the round-robin case we need to store
432
		 * the round-robin machine state in the rule, thus
455
		 * the round-robin machine state in the rule, thus
433
		 * forwarding thread needs to modify rule.
456
		 * forwarding thread needs to modify rule.
434
		 *
457
		 *
435
		 * This is done w/o locking, because performance is assumed
436
		 * more important than round-robin precision.
437
		 *
438
		 * In the simpliest case we just update the "rpool->cur"
458
		 * In the simpliest case we just update the "rpool->cur"
439
		 * pointer. However, if pool contains tables or dynamic
459
		 * pointer. However, if pool contains tables or dynamic
440
		 * addresses, then "tblidx" is also used to store machine
460
		 * addresses, then "tblidx" is also used to store machine
441
		 * state. Since "tblidx" is int, concurrent access to it can't
461
		 * state.
442
		 * lead to inconsistence, only to lost of precision.
443
		 *
444
		 * Things get worse, if table contains not hosts, but
445
		 * prefixes. In this case counter also stores machine state,
446
		 * and for IPv6 address, counter can't be updated atomically.
447
		 * Probably, using round-robin on a table containing IPv6
448
		 * prefixes (or even IPv4) would cause a panic.
449
		 */
462
		 */
450
463
451
		if (rpool->cur->addr.type == PF_ADDR_TABLE) {
464
		if (rpool->cur->addr.type == PF_ADDR_TABLE) {
452
			if (!pfr_pool_get(rpool->cur->addr.p.tbl,
465
			if (!pfr_pool_get(rpool->cur->addr.p.tbl,
453
			    &rpool->tblidx, &rpool->counter, af))
466
			    &rpool->tblidx, &rpool->counter, af))
454
				goto get_addr;
467
				goto get_addr;
455
		} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
468
		} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
456
			if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
469
			if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
457
			    &rpool->tblidx, &rpool->counter, af))
470
			    &rpool->tblidx, &rpool->counter, af))
458
				goto get_addr;
471
				goto get_addr;
Lines 464-518 pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, Link Here
464
			rpool->cur = TAILQ_FIRST(&rpool->list);
477
			rpool->cur = TAILQ_FIRST(&rpool->list);
465
		else
478
		else
466
			rpool->cur = TAILQ_NEXT(rpool->cur, entries);
479
			rpool->cur = TAILQ_NEXT(rpool->cur, entries);
467
		if (rpool->cur->addr.type == PF_ADDR_TABLE) {
480
		if (rpool->cur->addr.type == PF_ADDR_TABLE) {
468
			rpool->tblidx = -1;
481
			rpool->tblidx = -1;
469
			if (pfr_pool_get(rpool->cur->addr.p.tbl,
482
			if (pfr_pool_get(rpool->cur->addr.p.tbl,
470
			    &rpool->tblidx, &rpool->counter, af)) {
483
			    &rpool->tblidx, &rpool->counter, af)) {
471
				/* table contains no address of type 'af' */
484
				/* table contains no address of type 'af' */
472
				if (rpool->cur != acur)
485
				if (rpool->cur != acur)
473
					goto try_next;
486
					goto try_next;
487
				mtx_unlock(&rpool->lock);
488
				if (sh && !return_locked)
489
					PF_HASHROW_UNLOCK(sh);
474
				return (1);
490
				return (1);
475
			}
491
			}
476
		} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
492
		} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
477
			rpool->tblidx = -1;
493
			rpool->tblidx = -1;
478
			if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
494
			if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
479
			    &rpool->tblidx, &rpool->counter, af)) {
495
			    &rpool->tblidx, &rpool->counter, af)) {
480
				/* table contains no address of type 'af' */
496
				/* table contains no address of type 'af' */
481
				if (rpool->cur != acur)
497
				if (rpool->cur != acur)
482
					goto try_next;
498
					goto try_next;
499
				mtx_unlock(&rpool->lock);
500
				if (sh && !return_locked)
501
					PF_HASHROW_UNLOCK(sh);
483
				return (1);
502
				return (1);
484
			}
503
			}
485
		} else {
504
		} else {
486
			raddr = &rpool->cur->addr.v.a.addr;
505
			raddr = &rpool->cur->addr.v.a.addr;
487
			rmask = &rpool->cur->addr.v.a.mask;
506
			rmask = &rpool->cur->addr.v.a.mask;
488
			PF_ACPY(&rpool->counter, raddr, af);
507
			PF_ACPY(&rpool->counter, raddr, af);
489
		}
508
		}
490
509
491
	get_addr:
510
	get_addr:
492
		PF_ACPY(naddr, &rpool->counter, af);
511
		PF_ACPY(naddr, &rpool->counter, af);
493
		if (init_addr != NULL && PF_AZERO(init_addr, af))
512
		if (init_addr != NULL && PF_AZERO(init_addr, af))
494
			PF_ACPY(init_addr, naddr, af);
513
			PF_ACPY(init_addr, naddr, af);
495
		PF_AINC(&rpool->counter, af);
514
		PF_AINC(&rpool->counter, af);
515
		if (rt_kif)
516
			*rt_kif = rpool->cur->kif;
496
		break;
517
		break;
497
	    }
518
	    }
498
	}
519
	}
499
	if (*sn != NULL)
520
	if (*sn != NULL) {
500
		PF_ACPY(&(*sn)->raddr, naddr, af);
521
		PF_ACPY(&(*sn)->raddr, naddr, af);
522
		(*sn)->rkif = rpool->cur->kif;
523
	}
501
524
502
	if (V_pf_status.debug >= PF_DEBUG_MISC &&
525
	if (V_pf_status.debug >= PF_DEBUG_MISC &&
503
	    (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
526
	    (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
504
		printf("pf_map_addr: selected address ");
527
		printf("pf_map_addr: selected address ");
505
		pf_print_host(naddr, 0, af);
528
		pf_print_host(naddr, 0, af);
529
		if (rpool->cur->kif) {
530
			printf(" interface %s", rpool->cur->kif->pfik_name);
531
		}
532
		if (rpool->cur->addr.type == PF_ADDR_TABLE) {
533
			printf(" table %s\n",
534
			    rpool->cur->addr.p.tbl->pfrkt_name);
535
		}
506
		printf("\n");
536
		printf("\n");
507
	}
537
	}
508
538
539
	if (pool_locked)
540
		mtx_unlock(&rpool->lock);
541
	if (sh && !return_locked)
542
		PF_HASHROW_UNLOCK(sh);
509
	return (0);
543
	return (0);
510
}
544
}
511
545
512
struct pf_rule *
546
struct pf_rule *
513
pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
547
pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
514
    struct pfi_kif *kif, struct pf_src_node **sn,
548
    struct pfi_kif *kif, struct pf_src_node **sn,
515
    struct pf_state_key **skp, struct pf_state_key **nkp,
549
    struct pf_state_key **skp, struct pf_state_key **nkp,
516
    struct pf_addr *saddr, struct pf_addr *daddr,
550
    struct pf_addr *saddr, struct pf_addr *daddr,
517
    uint16_t sport, uint16_t dport, struct pf_anchor_stackframe *anchor_stack)
551
    uint16_t sport, uint16_t dport, struct pf_anchor_stackframe *anchor_stack)
518
{
552
{
Lines 635-655 pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, Link Here
635
					break;
669
					break;
636
#endif /* INET6 */
670
#endif /* INET6 */
637
				}
671
				}
638
			} else
672
			} else
639
				PF_POOLMASK(naddr, &r->src.addr.v.a.addr,
673
				PF_POOLMASK(naddr, &r->src.addr.v.a.addr,
640
				    &r->src.addr.v.a.mask, daddr, pd->af);
674
				    &r->src.addr.v.a.mask, daddr, pd->af);
641
			break;
675
			break;
642
		}
676
		}
643
		break;
677
		break;
644
	case PF_RDR: {
678
	case PF_RDR: {
645
		if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
679
		if (pf_map_addr(pd->af, r, saddr, naddr, NULL, NULL, sn, 0))
646
			goto notrans;
680
			goto notrans;
647
		if ((r->rpool.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK)
681
		if ((r->rpool.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK)
648
			PF_POOLMASK(naddr, naddr, &r->rpool.cur->addr.v.a.mask,
682
			PF_POOLMASK(naddr, naddr, &r->rpool.cur->addr.v.a.mask,
649
			    daddr, pd->af);
683
			    daddr, pd->af);
650
684
651
		if (r->rpool.proxy_port[1]) {
685
		if (r->rpool.proxy_port[1]) {
652
			uint32_t	tmp_nport;
686
			uint32_t	tmp_nport;
653
687
654
			tmp_nport = ((ntohs(dport) - ntohs(r->dst.port[0])) %
688
			tmp_nport = ((ntohs(dport) - ntohs(r->dst.port[0])) %
655
			    (r->rpool.proxy_port[1] - r->rpool.proxy_port[0] +
689
			    (r->rpool.proxy_port[1] - r->rpool.proxy_port[0] +
656
- 

Return to bug 230640