View | Details | Raw Unified | Return to bug 219803 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/net/pfvar.h (-1 / +43 lines)
Lines 683-688 struct pf_state_peer { Link Here
683
	u_int8_t	pad[1];
683
	u_int8_t	pad[1];
684
};
684
};
685
685
686
/* Keep synced with struct pf_udp_endpoint. */
687
struct pf_udp_endpoint_cmp {
688
	struct pf_addr	addr;
689
	u_int16_t	port;
690
	sa_family_t	af;
691
	u_int8_t	pad[1];
692
};
693
694
struct pf_udp_endpoint {
695
	struct pf_addr	addr;
696
	u_int16_t	port;
697
	sa_family_t	af;
698
	u_int8_t	pad[1];
699
700
	struct pf_udp_mapping *mapping;
701
	LIST_ENTRY(pf_udp_endpoint) entry;
702
};
703
704
struct pf_udp_mapping {
705
	struct pf_udp_endpoint endpoints[2];
706
	u_int refs;
707
};
708
686
/* Keep synced with struct pf_state_key. */
709
/* Keep synced with struct pf_state_key. */
687
struct pf_state_key_cmp {
710
struct pf_state_key_cmp {
688
	struct pf_addr	 addr[2];
711
	struct pf_addr	 addr[2];
Lines 728-733 struct pf_state { Link Here
728
	union pf_rule_ptr	 nat_rule;
751
	union pf_rule_ptr	 nat_rule;
729
	struct pf_addr		 rt_addr;
752
	struct pf_addr		 rt_addr;
730
	struct pf_state_key	*key[2];	/* addresses stack and wire  */
753
	struct pf_state_key	*key[2];	/* addresses stack and wire  */
754
	struct pf_udp_mapping	*udp_mapping;
731
	struct pfi_kif		*kif;
755
	struct pfi_kif		*kif;
732
	struct pfi_kif		*rt_kif;
756
	struct pfi_kif		*rt_kif;
733
	struct pf_src_node	*src_node;
757
	struct pf_src_node	*src_node;
Lines 1452-1457 struct pf_srchash { Link Here
1452
	struct mtx			lock;
1476
	struct mtx			lock;
1453
};
1477
};
1454
1478
1479
struct pf_udpendpointhash {
1480
	LIST_HEAD(, pf_udp_endpoint)	endpoints;
1481
	struct mtx			lock;
1482
};
1483
1455
struct pf_keyhash {
1484
struct pf_keyhash {
1456
	LIST_HEAD(, pf_state_key)	keys;
1485
	LIST_HEAD(, pf_state_key)	keys;
1457
	struct mtx			lock;
1486
	struct mtx			lock;
Lines 1465-1472 struct pf_idhash { Link Here
1465
extern u_long		pf_hashmask;
1494
extern u_long		pf_hashmask;
1466
extern u_long		pf_srchashmask;
1495
extern u_long		pf_srchashmask;
1467
#define	PF_HASHSIZ	(32768)
1496
#define	PF_HASHSIZ	(32768)
1497
VNET_DECLARE(struct pf_udpendpointhash *, pf_udpendpointhash);
1468
VNET_DECLARE(struct pf_keyhash *, pf_keyhash);
1498
VNET_DECLARE(struct pf_keyhash *, pf_keyhash);
1469
VNET_DECLARE(struct pf_idhash *, pf_idhash);
1499
VNET_DECLARE(struct pf_idhash *, pf_idhash);
1500
#define V_pf_udpendpointhash	VNET(pf_udpendpointhash)
1470
#define V_pf_keyhash	VNET(pf_keyhash)
1501
#define V_pf_keyhash	VNET(pf_keyhash)
1471
#define	V_pf_idhash	VNET(pf_idhash)
1502
#define	V_pf_idhash	VNET(pf_idhash)
1472
VNET_DECLARE(struct pf_srchash *, pf_srchash);
1503
VNET_DECLARE(struct pf_srchash *, pf_srchash);
Lines 1517-1522 VNET_DECLARE(uma_zone_t, pf_state_z); Link Here
1517
#define	V_pf_state_z		 VNET(pf_state_z)
1548
#define	V_pf_state_z		 VNET(pf_state_z)
1518
VNET_DECLARE(uma_zone_t,	 pf_state_key_z);
1549
VNET_DECLARE(uma_zone_t,	 pf_state_key_z);
1519
#define	V_pf_state_key_z	 VNET(pf_state_key_z)
1550
#define	V_pf_state_key_z	 VNET(pf_state_key_z)
1551
VNET_DECLARE(uma_zone_t,	 pf_udp_mapping_z);
1552
#define	V_pf_udp_mapping_z	 VNET(pf_udp_mapping_z)
1520
VNET_DECLARE(uma_zone_t,	 pf_state_scrub_z);
1553
VNET_DECLARE(uma_zone_t,	 pf_state_scrub_z);
1521
#define	V_pf_state_scrub_z	 VNET(pf_state_scrub_z)
1554
#define	V_pf_state_scrub_z	 VNET(pf_state_scrub_z)
1522
1555
Lines 1555-1560 pf_release_state(struct pf_state *s) Link Here
1555
extern struct pf_state		*pf_find_state_byid(uint64_t, uint32_t);
1588
extern struct pf_state		*pf_find_state_byid(uint64_t, uint32_t);
1556
extern struct pf_state		*pf_find_state_all(struct pf_state_key_cmp *,
1589
extern struct pf_state		*pf_find_state_all(struct pf_state_key_cmp *,
1557
				    u_int, int *);
1590
				    u_int, int *);
1591
extern struct pf_udp_mapping	*pf_udp_mapping_find(struct pf_udp_endpoint_cmp *endpoint);
1592
extern struct pf_udp_mapping	*pf_udp_mapping_create(sa_family_t af,
1593
				    struct pf_addr *src_addr, u_int16_t src_port,
1594
				    struct pf_addr *nat_addr, u_int16_t nat_port);
1595
extern int			 pf_udp_mapping_insert(struct pf_udp_mapping *mapping);
1596
extern void			 pf_udp_mapping_release(struct pf_udp_mapping *mapping);
1597
1598
1558
extern struct pf_src_node	*pf_find_src_node(struct pf_addr *,
1599
extern struct pf_src_node	*pf_find_src_node(struct pf_addr *,
1559
				    struct pf_rule *, sa_family_t, int);
1600
				    struct pf_rule *, sa_family_t, int);
1560
extern void			 pf_unlink_src_node(struct pf_src_node *);
1601
extern void			 pf_unlink_src_node(struct pf_src_node *);
Lines 1749-1755 struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *, Link Here
1749
			    int, int, struct pfi_kif *, struct pf_src_node **,
1790
			    int, int, struct pfi_kif *, struct pf_src_node **,
1750
			    struct pf_state_key **, struct pf_state_key **,
1791
			    struct pf_state_key **, struct pf_state_key **,
1751
			    struct pf_addr *, struct pf_addr *,
1792
			    struct pf_addr *, struct pf_addr *,
1752
			    uint16_t, uint16_t, struct pf_anchor_stackframe *);
1793
			    uint16_t, uint16_t, struct pf_anchor_stackframe *,
1794
			    struct pf_udp_mapping **udp_mapping);
1753
1795
1754
struct pf_state_key	*pf_state_key_setup(struct pf_pdesc *, struct pf_addr *,
1796
struct pf_state_key	*pf_state_key_setup(struct pf_pdesc *, struct pf_addr *,
1755
			    struct pf_addr *, u_int16_t, u_int16_t);
1797
			    struct pf_addr *, u_int16_t, u_int16_t);
(-)b/sys/netinet/libalias/alias_db.c (-15 / +81 lines)
Lines 385-393 Miscellaneous: Link Here
385
/* Local prototypes */
385
/* Local prototypes */
386
static u_int	StartPointIn(struct in_addr, u_short, int);
386
static u_int	StartPointIn(struct in_addr, u_short, int);
387
387
388
static		u_int
388
static u_int	StartPointOut(struct in_addr, u_short, int);
389
StartPointOut(struct in_addr, struct in_addr,
390
    u_short, u_short, int);
391
389
392
static int	SeqDiff(u_long, u_long);
390
static int	SeqDiff(u_long, u_long);
393
391
Lines 422-437 StartPointIn(struct in_addr alias_addr, Link Here
422
420
423
421
424
static		u_int
422
static		u_int
425
StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
423
StartPointOut(struct in_addr src_addr,
426
    u_short src_port, u_short dst_port, int link_type)
424
    u_short src_port,
425
    int link_type)
427
{
426
{
428
	u_int n;
427
	u_int n;
429
428
430
	n = src_addr.s_addr;
429
	n = src_addr.s_addr;
431
	n += dst_addr.s_addr;
432
	if (link_type != LINK_PPTP) {
430
	if (link_type != LINK_PPTP) {
433
		n += src_port;
431
		n += src_port;
434
		n += dst_port;
435
	}
432
	}
436
	n += link_type;
433
	n += link_type;
437
434
Lines 553-560 static struct alias_link * Link Here
553
		FindLinkOut   (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
550
		FindLinkOut   (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
554
551
555
static struct alias_link *
552
static struct alias_link *
553
		FindLinkOutBySource   (struct libalias *, struct in_addr, u_short, int);
554
555
static struct alias_link *
556
		FindLinkIn    (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
556
		FindLinkIn    (struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
557
557
558
static struct alias_link *
559
		FindLinkInByAlias    (struct libalias *, struct in_addr, u_short, int);
560
561
558
562
559
#define ALIAS_PORT_BASE            0x08000
563
#define ALIAS_PORT_BASE            0x08000
560
#define ALIAS_PORT_MASK            0x07fff
564
#define ALIAS_PORT_MASK            0x07fff
Lines 594-599 GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) Link Here
594
		 */
598
		 */
595
		max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
599
		max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
596
600
601
		if (lnk->link_type == LINK_UDP) {
602
			/*
603
			 * For UDP, we try to reuse the alias address:port for all destinations
604
			 * from the same internal address:port, as per RFC 4787.
605
			 */
606
			struct alias_link *search_result;
607
			search_result = FindLinkOutBySource(la, lnk->src_addr, lnk->src_port, LINK_UDP);
608
			if (search_result != NULL) {
609
				lnk->alias_port = search_result->alias_port;
610
				return (0);
611
			}
612
		}
613
597
		if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
614
		if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
598
			/*
615
			/*
599
			 * When the PKT_ALIAS_SAME_PORTS option is chosen,
616
			 * When the PKT_ALIAS_SAME_PORTS option is chosen,
Lines 626-634 GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) Link Here
626
		int go_ahead;
643
		int go_ahead;
627
		struct alias_link *search_result;
644
		struct alias_link *search_result;
628
645
629
		search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr,
646
		if (lnk->link_type == LINK_UDP) {
630
		    lnk->dst_port, port_net,
647
			search_result = FindLinkInByAlias(la, lnk->alias_addr,
631
		    lnk->link_type, 0);
648
			    port_net, lnk->link_type);
649
		} else {
650
			search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr,
651
			    lnk->dst_port, port_net,
652
			    lnk->link_type, 0);
653
		}
632
654
633
		if (search_result == NULL)
655
		if (search_result == NULL)
634
			go_ahead = 1;
656
			go_ahead = 1;
Lines 1040-1047 AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, Link Here
1040
		}
1062
		}
1041
1063
1042
		/* Set up pointers for output lookup table */
1064
		/* Set up pointers for output lookup table */
1043
		start_point = StartPointOut(src_addr, dst_addr,
1065
		start_point = StartPointOut(src_addr, src_port, link_type);
1044
		    src_port, dst_port, link_type);
1045
		LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, list_out);
1066
		LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, list_out);
1046
1067
1047
		/* Set up pointers for input lookup table */
1068
		/* Set up pointers for input lookup table */
Lines 1100-1106 _FindLinkOut(struct libalias *la, struct in_addr src_addr, Link Here
1100
	struct alias_link *lnk;
1121
	struct alias_link *lnk;
1101
1122
1102
	LIBALIAS_LOCK_ASSERT(la);
1123
	LIBALIAS_LOCK_ASSERT(la);
1103
	i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
1124
	i = StartPointOut(src_addr, src_port, link_type);
1104
	LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) {
1125
	LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) {
1105
		if (lnk->dst_addr.s_addr == dst_addr.s_addr &&
1126
		if (lnk->dst_addr.s_addr == dst_addr.s_addr &&
1106
		    lnk->src_addr.s_addr == src_addr.s_addr &&
1127
		    lnk->src_addr.s_addr == src_addr.s_addr &&
Lines 1169-1174 FindLinkOut(struct libalias *la, struct in_addr src_addr, Link Here
1169
1190
1170
1191
1171
static struct alias_link *
1192
static struct alias_link *
1193
FindLinkOutBySource(struct libalias *la, struct in_addr src_addr,
1194
    u_short src_port,
1195
    int link_type)
1196
{
1197
	u_int i;
1198
	struct alias_link *lnk;
1199
1200
	LIBALIAS_LOCK_ASSERT(la);
1201
1202
	i = StartPointOut(src_addr, src_port, link_type);
1203
	LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) {
1204
		if (lnk->src_addr.s_addr == src_addr.s_addr &&
1205
		    lnk->src_port == src_port &&
1206
		    lnk->link_type == link_type &&
1207
		    lnk->server == NULL) {
1208
			break;
1209
		}
1210
	}
1211
	return lnk;
1212
}
1213
1214
1215
static struct alias_link *
1216
FindLinkInByAlias(struct libalias *la, struct in_addr alias_addr,
1217
    u_short alias_port,
1218
    int link_type)
1219
{
1220
	u_int i;
1221
	struct alias_link *lnk;
1222
1223
	LIBALIAS_LOCK_ASSERT(la);
1224
1225
	i = StartPointIn(alias_addr, alias_port, link_type);
1226
	LIST_FOREACH(lnk, &la->linkTableIn[i], list_in) {
1227
		if (lnk->alias_addr.s_addr == alias_addr.s_addr &&
1228
		    lnk->alias_port == alias_port &&
1229
		    lnk->link_type == link_type) {
1230
			break;
1231
		}
1232
	}
1233
	return lnk;
1234
}
1235
1236
1237
static struct alias_link *
1172
_FindLinkIn(struct libalias *la, struct in_addr dst_addr,
1238
_FindLinkIn(struct libalias *la, struct in_addr dst_addr,
1173
    struct in_addr alias_addr,
1239
    struct in_addr alias_addr,
1174
    u_short dst_port,
1240
    u_short dst_port,
Lines 1592-1598 FindPptpOutByCallId(struct libalias *la, struct in_addr src_addr, Link Here
1592
	struct alias_link *lnk;
1658
	struct alias_link *lnk;
1593
1659
1594
	LIBALIAS_LOCK_ASSERT(la);
1660
	LIBALIAS_LOCK_ASSERT(la);
1595
	i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
1661
	i = StartPointOut(src_addr, 0, LINK_PPTP);
1596
	LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
1662
	LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
1597
	    if (lnk->link_type == LINK_PPTP &&
1663
	    if (lnk->link_type == LINK_PPTP &&
1598
	    lnk->src_addr.s_addr == src_addr.s_addr &&
1664
	    lnk->src_addr.s_addr == src_addr.s_addr &&
Lines 1613-1619 FindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr, Link Here
1613
	struct alias_link *lnk;
1679
	struct alias_link *lnk;
1614
1680
1615
	LIBALIAS_LOCK_ASSERT(la);
1681
	LIBALIAS_LOCK_ASSERT(la);
1616
	i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
1682
	i = StartPointOut(src_addr, 0, LINK_PPTP);
1617
	LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
1683
	LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
1618
	    if (lnk->link_type == LINK_PPTP &&
1684
	    if (lnk->link_type == LINK_PPTP &&
1619
	    lnk->src_addr.s_addr == src_addr.s_addr &&
1685
	    lnk->src_addr.s_addr == src_addr.s_addr &&
(-)b/sys/netpfil/pf/pf.c (-9 / +153 lines)
Lines 194-199 static VNET_DEFINE(uma_zone_t, pf_sources_z); Link Here
194
uma_zone_t		pf_mtag_z;
194
uma_zone_t		pf_mtag_z;
195
VNET_DEFINE(uma_zone_t,	 pf_state_z);
195
VNET_DEFINE(uma_zone_t,	 pf_state_z);
196
VNET_DEFINE(uma_zone_t,	 pf_state_key_z);
196
VNET_DEFINE(uma_zone_t,	 pf_state_key_z);
197
VNET_DEFINE(uma_zone_t,	 pf_udp_mapping_z);
197
198
198
VNET_DEFINE(uint64_t, pf_stateid[MAXCPU]);
199
VNET_DEFINE(uint64_t, pf_stateid[MAXCPU]);
199
#define	PFID_CPUBITS	8
200
#define	PFID_CPUBITS	8
Lines 241-247 static int pf_create_state(struct pf_rule *, struct pf_rule *, Link Here
241
			    struct pf_state_key *, struct mbuf *, int,
242
			    struct pf_state_key *, struct mbuf *, int,
242
			    u_int16_t, u_int16_t, int *, struct pfi_kif *,
243
			    u_int16_t, u_int16_t, int *, struct pfi_kif *,
243
			    struct pf_state **, int, u_int16_t, u_int16_t,
244
			    struct pf_state **, int, u_int16_t, u_int16_t,
244
			    int);
245
			    int, struct pf_udp_mapping *);
245
static int		 pf_test_fragment(struct pf_rule **, int,
246
static int		 pf_test_fragment(struct pf_rule **, int,
246
			    struct pfi_kif *, struct mbuf *, void *,
247
			    struct pfi_kif *, struct mbuf *, void *,
247
			    struct pf_pdesc *, struct pf_rule **,
248
			    struct pf_pdesc *, struct pf_rule **,
Lines 356-361 static MALLOC_DEFINE(M_PFHASH, "pf_hash", "pf(4) hash header structures"); Link Here
356
VNET_DEFINE(struct pf_keyhash *, pf_keyhash);
357
VNET_DEFINE(struct pf_keyhash *, pf_keyhash);
357
VNET_DEFINE(struct pf_idhash *, pf_idhash);
358
VNET_DEFINE(struct pf_idhash *, pf_idhash);
358
VNET_DEFINE(struct pf_srchash *, pf_srchash);
359
VNET_DEFINE(struct pf_srchash *, pf_srchash);
360
VNET_DEFINE(struct pf_udpendpointhash *, pf_udpendpointhash);
359
361
360
SYSCTL_NODE(_net, OID_AUTO, pf, CTLFLAG_RW, 0, "pf(4)");
362
SYSCTL_NODE(_net, OID_AUTO, pf, CTLFLAG_RW, 0, "pf(4)");
361
363
Lines 426-431 pf_hashkey(struct pf_state_key *sk) Link Here
426
}
428
}
427
429
428
static __inline uint32_t
430
static __inline uint32_t
431
pf_hashudpendpoint(struct pf_udp_endpoint *endpoint)
432
{
433
	uint32_t h;
434
435
	h = murmur3_32_hash32((uint32_t *)endpoint,
436
	    sizeof(struct pf_udp_endpoint_cmp)/sizeof(uint32_t),
437
	    V_pf_hashseed);
438
439
	return (h & pf_hashmask);
440
}
441
442
static __inline uint32_t
429
pf_hashsrc(struct pf_addr *addr, sa_family_t af)
443
pf_hashsrc(struct pf_addr *addr, sa_family_t af)
430
{
444
{
431
	uint32_t h;
445
	uint32_t h;
Lines 779-784 pf_initialize() Link Here
779
{
793
{
780
	struct pf_keyhash	*kh;
794
	struct pf_keyhash	*kh;
781
	struct pf_idhash	*ih;
795
	struct pf_idhash	*ih;
796
	struct pf_udpendpointhash *uh;
782
	struct pf_srchash	*sh;
797
	struct pf_srchash	*sh;
783
	u_int i;
798
	u_int i;
784
799
Lines 799-813 pf_initialize() Link Here
799
	V_pf_state_key_z = uma_zcreate("pf state keys",
814
	V_pf_state_key_z = uma_zcreate("pf state keys",
800
	    sizeof(struct pf_state_key), pf_state_key_ctor, NULL, NULL, NULL,
815
	    sizeof(struct pf_state_key), pf_state_key_ctor, NULL, NULL, NULL,
801
	    UMA_ALIGN_PTR, 0);
816
	    UMA_ALIGN_PTR, 0);
817
	V_pf_udp_mapping_z = uma_zcreate("pf UDP mappings",
818
	    sizeof(struct pf_udp_mapping), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
802
	V_pf_keyhash = malloc(pf_hashsize * sizeof(struct pf_keyhash),
819
	V_pf_keyhash = malloc(pf_hashsize * sizeof(struct pf_keyhash),
803
	    M_PFHASH, M_WAITOK | M_ZERO);
820
	    M_PFHASH, M_WAITOK | M_ZERO);
804
	V_pf_idhash = malloc(pf_hashsize * sizeof(struct pf_idhash),
821
	V_pf_idhash = malloc(pf_hashsize * sizeof(struct pf_idhash),
805
	    M_PFHASH, M_WAITOK | M_ZERO);
822
	    M_PFHASH, M_WAITOK | M_ZERO);
823
	V_pf_udpendpointhash = malloc(pf_hashsize * sizeof(struct pf_udpendpointhash),
824
	    M_PFHASH, M_WAITOK | M_ZERO);
806
	pf_hashmask = pf_hashsize - 1;
825
	pf_hashmask = pf_hashsize - 1;
807
	for (i = 0, kh = V_pf_keyhash, ih = V_pf_idhash; i <= pf_hashmask;
826
	for (i = 0, kh = V_pf_keyhash, ih = V_pf_idhash, uh=V_pf_udpendpointhash; i <= pf_hashmask;
808
	    i++, kh++, ih++) {
827
	    i++, kh++, ih++, uh++) {
809
		mtx_init(&kh->lock, "pf_keyhash", NULL, MTX_DEF | MTX_DUPOK);
828
		mtx_init(&kh->lock, "pf_keyhash", NULL, MTX_DEF | MTX_DUPOK);
810
		mtx_init(&ih->lock, "pf_idhash", NULL, MTX_DEF);
829
		mtx_init(&ih->lock, "pf_idhash", NULL, MTX_DEF);
830
		mtx_init(&uh->lock, "pf_udpendpointhash", NULL, MTX_DEF | MTX_DUPOK);
811
	}
831
	}
812
832
813
	/* Source nodes. */
833
	/* Source nodes. */
Lines 851-871 pf_cleanup() Link Here
851
{
871
{
852
	struct pf_keyhash	*kh;
872
	struct pf_keyhash	*kh;
853
	struct pf_idhash	*ih;
873
	struct pf_idhash	*ih;
874
	struct pf_udpendpointhash *uh;
854
	struct pf_srchash	*sh;
875
	struct pf_srchash	*sh;
855
	struct pf_send_entry	*pfse, *next;
876
	struct pf_send_entry	*pfse, *next;
856
	u_int i;
877
	u_int i;
857
878
858
	for (i = 0, kh = V_pf_keyhash, ih = V_pf_idhash; i <= pf_hashmask;
879
	for (i = 0, kh = V_pf_keyhash, ih = V_pf_idhash, uh=V_pf_udpendpointhash; i <= pf_hashmask;
859
	    i++, kh++, ih++) {
880
	    i++, kh++, ih++, uh++) {
860
		KASSERT(LIST_EMPTY(&kh->keys), ("%s: key hash not empty",
881
		KASSERT(LIST_EMPTY(&kh->keys), ("%s: key hash not empty",
861
		    __func__));
882
		    __func__));
862
		KASSERT(LIST_EMPTY(&ih->states), ("%s: id hash not empty",
883
		KASSERT(LIST_EMPTY(&ih->states), ("%s: id hash not empty",
863
		    __func__));
884
		    __func__));
885
		KASSERT(LIST_EMPTY(&uh->endpoints), ("%s: udpendpoint hash not empty",
886
		    __func__));
864
		mtx_destroy(&kh->lock);
887
		mtx_destroy(&kh->lock);
865
		mtx_destroy(&ih->lock);
888
		mtx_destroy(&ih->lock);
889
		mtx_destroy(&uh->lock);
866
	}
890
	}
867
	free(V_pf_keyhash, M_PFHASH);
891
	free(V_pf_keyhash, M_PFHASH);
868
	free(V_pf_idhash, M_PFHASH);
892
	free(V_pf_idhash, M_PFHASH);
893
	free(V_pf_udpendpointhash, M_PFHASH);
869
894
870
	for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask; i++, sh++) {
895
	for (i = 0, sh = V_pf_srchash; i <= pf_srchashmask; i++, sh++) {
871
		KASSERT(LIST_EMPTY(&sh->nodes),
896
		KASSERT(LIST_EMPTY(&sh->nodes),
Lines 882-887 pf_cleanup() Link Here
882
	uma_zdestroy(V_pf_sources_z);
907
	uma_zdestroy(V_pf_sources_z);
883
	uma_zdestroy(V_pf_state_z);
908
	uma_zdestroy(V_pf_state_z);
884
	uma_zdestroy(V_pf_state_key_z);
909
	uma_zdestroy(V_pf_state_key_z);
910
	uma_zdestroy(V_pf_udp_mapping_z);
885
}
911
}
886
912
887
static int
913
static int
Lines 1369-1374 second_run: Link Here
1369
	return (ret);
1395
	return (ret);
1370
}
1396
}
1371
1397
1398
struct pf_udp_mapping*
1399
pf_udp_mapping_create(sa_family_t af, struct pf_addr *src_addr, u_int16_t src_port,
1400
    struct pf_addr *nat_addr, u_int16_t nat_port)
1401
{
1402
	struct pf_udp_mapping *mapping = uma_zalloc(V_pf_udp_mapping_z, M_NOWAIT | M_ZERO);
1403
	if (mapping == NULL)
1404
		return NULL;
1405
	PF_ACPY(&mapping->endpoints[0].addr, src_addr, af);
1406
	mapping->endpoints[0].port = src_port;
1407
	mapping->endpoints[0].af = af;
1408
	mapping->endpoints[0].mapping = mapping;
1409
	PF_ACPY(&mapping->endpoints[1].addr, nat_addr, af);
1410
	mapping->endpoints[1].port = nat_port;
1411
	mapping->endpoints[1].af = af;
1412
	mapping->endpoints[1].mapping = mapping;
1413
	refcount_init(&mapping->refs, 1);
1414
	return mapping;
1415
}
1416
1417
int
1418
pf_udp_mapping_insert(struct pf_udp_mapping *mapping)
1419
{
1420
	struct pf_udpendpointhash *h0, *h1;
1421
	struct pf_udp_endpoint *endpoint;
1422
	int ret = 1;
1423
1424
	h0 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[0])];
1425
	h1 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[1])];
1426
	if (h0 == h1) {
1427
		PF_HASHROW_LOCK(h0);
1428
	} else if (h0 < h1) {
1429
		PF_HASHROW_LOCK(h0);
1430
		PF_HASHROW_LOCK(h1);
1431
	} else {
1432
		PF_HASHROW_LOCK(h1);
1433
		PF_HASHROW_LOCK(h0);
1434
	}
1435
1436
	LIST_FOREACH(endpoint, &h0->endpoints, entry)
1437
		if (bcmp(endpoint, &mapping->endpoints[0], sizeof(struct pf_udp_endpoint_cmp)) == 0)
1438
			break;
1439
	if (endpoint != NULL)
1440
		goto cleanup;
1441
	LIST_FOREACH(endpoint, &h1->endpoints, entry)
1442
		if (bcmp(endpoint, &mapping->endpoints[1], sizeof(struct pf_udp_endpoint_cmp)) == 0)
1443
			break;
1444
	if (endpoint != NULL)
1445
		goto cleanup;
1446
	LIST_INSERT_HEAD(&h0->endpoints, &mapping->endpoints[0], entry);
1447
	LIST_INSERT_HEAD(&h1->endpoints, &mapping->endpoints[1], entry);
1448
	ret = 0;
1449
1450
cleanup:
1451
	if (h0 != h1) {
1452
		PF_HASHROW_UNLOCK(h0);
1453
		PF_HASHROW_UNLOCK(h1);
1454
	} else {
1455
		PF_HASHROW_UNLOCK(h0);
1456
	}
1457
	return ret;
1458
}
1459
1460
void
1461
pf_udp_mapping_release(struct pf_udp_mapping *mapping)
1462
{
1463
	/* refcount is synchronized on the source endpoint's row lock */
1464
	struct pf_udpendpointhash *h0, *h1;
1465
	h0 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[0])];
1466
	PF_HASHROW_LOCK(h0);
1467
	if (refcount_release(&mapping->refs)) {
1468
		LIST_REMOVE(&mapping->endpoints[0], entry);
1469
		PF_HASHROW_UNLOCK(h0);
1470
		h1 = &V_pf_udpendpointhash[pf_hashudpendpoint(&mapping->endpoints[1])];
1471
		PF_HASHROW_LOCK(h1);
1472
		LIST_REMOVE(&mapping->endpoints[1], entry);
1473
		PF_HASHROW_UNLOCK(h1);
1474
1475
		uma_zfree(V_pf_udp_mapping_z, mapping);
1476
	} else {
1477
		PF_HASHROW_UNLOCK(h0);
1478
	}
1479
}
1480
1481
struct pf_udp_mapping *
1482
pf_udp_mapping_find(struct pf_udp_endpoint_cmp *key)
1483
{
1484
	struct pf_udpendpointhash *uh;
1485
	struct pf_udp_endpoint *endpoint;
1486
1487
	uh = &V_pf_udpendpointhash[pf_hashudpendpoint((struct pf_udp_endpoint*)key)];
1488
1489
	PF_HASHROW_LOCK(uh);
1490
	LIST_FOREACH(endpoint, &uh->endpoints, entry)
1491
		if (bcmp(endpoint, key, sizeof(struct pf_udp_endpoint_cmp)) == 0 &&
1492
				bcmp(endpoint, &endpoint->mapping->endpoints[0], sizeof(struct pf_udp_endpoint_cmp)) == 0)
1493
			break;
1494
	if (endpoint == NULL) {
1495
		PF_HASHROW_UNLOCK(uh);
1496
		return NULL;
1497
	}
1498
	refcount_acquire(&endpoint->mapping->refs);
1499
	PF_HASHROW_UNLOCK(uh);
1500
	return endpoint->mapping;
1501
}
1502
1372
/* END state table stuff */
1503
/* END state table stuff */
1373
1504
1374
static void
1505
static void
Lines 1650-1655 pf_unlink_state(struct pf_state *s, u_int flags) Link Here
1650
	pf_detach_state(s);
1781
	pf_detach_state(s);
1651
	refcount_release(&s->refs);
1782
	refcount_release(&s->refs);
1652
1783
1784
	if (s->udp_mapping)
1785
		pf_udp_mapping_release(s->udp_mapping);
1786
1653
	return (pf_release_state(s));
1787
	return (pf_release_state(s));
1654
}
1788
}
1655
1789
Lines 3136-3141 pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, Link Here
3136
	u_int16_t		 bproto_sum = 0, bip_sum = 0;
3270
	u_int16_t		 bproto_sum = 0, bip_sum = 0;
3137
	u_int8_t		 icmptype = 0, icmpcode = 0;
3271
	u_int8_t		 icmptype = 0, icmpcode = 0;
3138
	struct pf_anchor_stackframe	anchor_stack[PF_ANCHOR_STACKSIZE];
3272
	struct pf_anchor_stackframe	anchor_stack[PF_ANCHOR_STACKSIZE];
3273
	struct pf_udp_mapping	*udp_mapping = NULL;
3139
3274
3140
	PF_RULES_RASSERT();
3275
	PF_RULES_RASSERT();
3141
3276
Lines 3199-3205 pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, Link Here
3199
3334
3200
	/* check packet for BINAT/NAT/RDR */
3335
	/* check packet for BINAT/NAT/RDR */
3201
	if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn, &sk,
3336
	if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn, &sk,
3202
	    &nk, saddr, daddr, sport, dport, anchor_stack)) != NULL) {
3337
	    &nk, saddr, daddr, sport, dport, anchor_stack, &udp_mapping)) != NULL) {
3203
		KASSERT(sk != NULL, ("%s: null sk", __func__));
3338
		KASSERT(sk != NULL, ("%s: null sk", __func__));
3204
		KASSERT(nk != NULL, ("%s: null nk", __func__));
3339
		KASSERT(nk != NULL, ("%s: null nk", __func__));
3205
3340
Lines 3506-3519 pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, Link Here
3506
		int action;
3641
		int action;
3507
		action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off,
3642
		action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off,
3508
		    sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum,
3643
		    sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum,
3509
		    hdrlen);
3644
		    hdrlen, udp_mapping);
3510
		if (action != PF_PASS)
3645
		if (action != PF_PASS) {
3646
			if (udp_mapping != NULL)
3647
				pf_udp_mapping_release(udp_mapping);
3511
			return (action);
3648
			return (action);
3649
		}
3512
	} else {
3650
	} else {
3513
		if (sk != NULL)
3651
		if (sk != NULL)
3514
			uma_zfree(V_pf_state_key_z, sk);
3652
			uma_zfree(V_pf_state_key_z, sk);
3515
		if (nk != NULL)
3653
		if (nk != NULL)
3516
			uma_zfree(V_pf_state_key_z, nk);
3654
			uma_zfree(V_pf_state_key_z, nk);
3655
		if (udp_mapping != NULL)
3656
			pf_udp_mapping_release(udp_mapping);
3517
	}
3657
	}
3518
3658
3519
	/* copy back packet headers if we performed NAT operations */
3659
	/* copy back packet headers if we performed NAT operations */
Lines 3538-3543 cleanup: Link Here
3538
		uma_zfree(V_pf_state_key_z, sk);
3678
		uma_zfree(V_pf_state_key_z, sk);
3539
	if (nk != NULL)
3679
	if (nk != NULL)
3540
		uma_zfree(V_pf_state_key_z, nk);
3680
		uma_zfree(V_pf_state_key_z, nk);
3681
	if (udp_mapping != NULL)
3682
		pf_udp_mapping_release(udp_mapping);
3541
	return (PF_DROP);
3683
	return (PF_DROP);
3542
}
3684
}
3543
3685
Lines 3546-3552 pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, Link Here
3546
    struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *nk,
3688
    struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *nk,
3547
    struct pf_state_key *sk, struct mbuf *m, int off, u_int16_t sport,
3689
    struct pf_state_key *sk, struct mbuf *m, int off, u_int16_t sport,
3548
    u_int16_t dport, int *rewrite, struct pfi_kif *kif, struct pf_state **sm,
3690
    u_int16_t dport, int *rewrite, struct pfi_kif *kif, struct pf_state **sm,
3549
    int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen)
3691
    int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen,
3692
    struct pf_udp_mapping *udp_mapping)
3550
{
3693
{
3551
	struct pf_state		*s = NULL;
3694
	struct pf_state		*s = NULL;
3552
	struct pf_src_node	*sn = NULL;
3695
	struct pf_src_node	*sn = NULL;
Lines 3752-3757 pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, Link Here
3752
		REASON_SET(&reason, PFRES_SYNPROXY);
3895
		REASON_SET(&reason, PFRES_SYNPROXY);
3753
		return (PF_SYNPROXY_DROP);
3896
		return (PF_SYNPROXY_DROP);
3754
	}
3897
	}
3898
	s->udp_mapping = udp_mapping;
3755
3899
3756
	return (PF_PASS);
3900
	return (PF_PASS);
3757
3901
(-)b/sys/netpfil/pf/pf_lb.c (-19 / +74 lines)
Lines 63-69 static struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, Link Here
63
			    uint16_t, int, struct pf_anchor_stackframe *);
63
			    uint16_t, int, struct pf_anchor_stackframe *);
64
static int pf_get_sport(sa_family_t, uint8_t, struct pf_rule *,
64
static int pf_get_sport(sa_family_t, uint8_t, struct pf_rule *,
65
    struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *,
65
    struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *,
66
    uint16_t *, uint16_t, uint16_t, struct pf_src_node **);
66
    uint16_t *, uint16_t, uint16_t, struct pf_src_node **,
67
    struct pf_udp_mapping**);
67
68
68
#define mix(a,b,c) \
69
#define mix(a,b,c) \
69
	do {					\
70
	do {					\
Lines 214-227 static int Link Here
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, struct pf_udp_mapping **udp_mapping)
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
223
	if (proto == IPPROTO_UDP) {
224
		struct pf_udp_endpoint_cmp udp_source;
225
		bzero(&udp_source, sizeof(udp_source));
226
		udp_source.af = af;
227
		PF_ACPY(&udp_source.addr, saddr, af);
228
		udp_source.port = sport;
229
		*udp_mapping = pf_udp_mapping_find(&udp_source);
230
		if (*udp_mapping) {
231
			PF_ACPY(naddr, &(*udp_mapping)->endpoints[1].addr, af);
232
			*nport = (*udp_mapping)->endpoints[1].port;
233
			/* as per pf_map_addr(): */
234
			if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
235
			    (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE)
236
				*sn = pf_find_src_node(saddr, r, af, 0);
237
			return (0);
238
		} else {
239
			*udp_mapping = pf_udp_mapping_create(af, saddr, sport, &init_addr, 0);
240
			if (*udp_mapping == NULL)
241
				return (1);
242
		}
243
	}
244
222
	bzero(&init_addr, sizeof(init_addr));
245
	bzero(&init_addr, sizeof(init_addr));
223
	if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
246
	if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
224
		return (1);
247
		goto failed;
225
248
226
	if (proto == IPPROTO_ICMP) {
249
	if (proto == IPPROTO_ICMP) {
227
		low = 1;
250
		low = 1;
Lines 236-241 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, Link Here
236
259
237
	do {
260
	do {
238
		PF_ACPY(&key.addr[1], naddr, key.af);
261
		PF_ACPY(&key.addr[1], naddr, key.af);
262
		if ((*udp_mapping))
263
			PF_ACPY(&(*udp_mapping)->endpoints[1].addr, naddr, af);
239
264
240
		/*
265
		/*
241
		 * port search; start random, step;
266
		 * port search; start random, step;
Lines 255-262 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, Link Here
255
		} else if (low == high) {
280
		} else if (low == high) {
256
			key.port[1] = htons(low);
281
			key.port[1] = htons(low);
257
			if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
282
			if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
258
				*nport = htons(low);
283
				if (proto == IPPROTO_UDP) {
259
				return (0);
284
					(*udp_mapping)->endpoints[1].port = htons(low);
285
					if (pf_udp_mapping_insert(*udp_mapping) == 0) {
286
						*nport = htons(low);
287
						return (0);
288
					}
289
				} else {
290
					*nport = htons(low);
291
					return (0);
292
				}
260
			}
293
			}
261
		} else {
294
		} else {
262
			uint16_t tmp, cut;
295
			uint16_t tmp, cut;
Lines 270-288 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, Link Here
270
			cut = arc4random() % (1 + high - low) + low;
303
			cut = arc4random() % (1 + high - low) + low;
271
			/* low <= cut <= high */
304
			/* low <= cut <= high */
272
			for (tmp = cut; tmp <= high; ++(tmp)) {
305
			for (tmp = cut; tmp <= high; ++(tmp)) {
273
				key.port[1] = htons(tmp);
306
				if (proto == IPPROTO_UDP) {
274
				if (pf_find_state_all(&key, PF_IN, NULL) ==
307
					(*udp_mapping)->endpoints[1].port = htons(tmp);
275
				    NULL) {
308
					if (pf_udp_mapping_insert(*udp_mapping) == 0) {
276
					*nport = htons(tmp);
309
						*nport = htons(tmp);
277
					return (0);
310
						return (0);
311
					}
312
				} else {
313
					key.port[1] = htons(tmp);
314
					if (pf_find_state_all(&key, PF_IN, NULL) ==
315
					    NULL) {
316
						*nport = htons(tmp);
317
						return (0);
318
					}
278
				}
319
				}
279
			}
320
			}
280
			for (tmp = cut - 1; tmp >= low; --(tmp)) {
321
			for (tmp = cut - 1; tmp >= low; --(tmp)) {
281
				key.port[1] = htons(tmp);
322
				if (proto == IPPROTO_UDP) {
282
				if (pf_find_state_all(&key, PF_IN, NULL) ==
323
					(*udp_mapping)->endpoints[1].port = htons(tmp);
283
				    NULL) {
324
					if (pf_udp_mapping_insert(*udp_mapping) == 0) {
284
					*nport = htons(tmp);
325
						*nport = htons(tmp);
285
					return (0);
326
						return (0);
327
					}
328
				} else {
329
					key.port[1] = htons(tmp);
330
					if (pf_find_state_all(&key, PF_IN, NULL) ==
331
					    NULL) {
332
						*nport = htons(tmp);
333
						return (0);
334
					}
286
				}
335
				}
287
			}
336
			}
288
		}
337
		}
Lines 300-306 pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, Link Here
300
			return (1);
349
			return (1);
301
		}
350
		}
302
	} while (! PF_AEQ(&init_addr, naddr, af) );
351
	} while (! PF_AEQ(&init_addr, naddr, af) );
303
	return (1);					/* none available */
352
	/* none available */
353
failed:
354
	if (*udp_mapping) {
355
		uma_zfree(V_pf_udp_mapping_z, *udp_mapping);
356
		*udp_mapping = NULL;
357
	}
358
	return (1);
304
}
359
}
305
360
306
int
361
int
Lines 512-518 pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, Link Here
512
    struct pfi_kif *kif, struct pf_src_node **sn,
567
    struct pfi_kif *kif, struct pf_src_node **sn,
513
    struct pf_state_key **skp, struct pf_state_key **nkp,
568
    struct pf_state_key **skp, struct pf_state_key **nkp,
514
    struct pf_addr *saddr, struct pf_addr *daddr,
569
    struct pf_addr *saddr, struct pf_addr *daddr,
515
    uint16_t sport, uint16_t dport, struct pf_anchor_stackframe *anchor_stack)
570
    uint16_t sport, uint16_t dport, struct pf_anchor_stackframe *anchor_stack,
571
    struct pf_udp_mapping **udp_mapping)
516
{
572
{
517
	struct pf_rule	*r = NULL;
573
	struct pf_rule	*r = NULL;
518
	struct pf_addr	*naddr;
574
	struct pf_addr	*naddr;
Lines 566-572 pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, Link Here
566
	case PF_NAT:
622
	case PF_NAT:
567
		if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, daddr,
623
		if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, daddr,
568
		    dport, naddr, nport, r->rpool.proxy_port[0],
624
		    dport, naddr, nport, r->rpool.proxy_port[0],
569
		    r->rpool.proxy_port[1], sn)) {
625
		    r->rpool.proxy_port[1], sn, udp_mapping)) {
570
			DPFPRINTF(PF_DEBUG_MISC,
626
			DPFPRINTF(PF_DEBUG_MISC,
571
			    ("pf: NAT proxy port allocation (%u-%u) failed\n",
627
			    ("pf: NAT proxy port allocation (%u-%u) failed\n",
572
			    r->rpool.proxy_port[0], r->rpool.proxy_port[1]));
628
			    r->rpool.proxy_port[0], r->rpool.proxy_port[1]));
573
- 

Return to bug 219803