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

Collapse All | Expand All

(-)b/sbin/pfctl/pfctl.8 (-1 / +6 lines)
Lines 42-48 Link Here
42
.Op Fl F Ar modifier
42
.Op Fl F Ar modifier
43
.Op Fl f Ar file
43
.Op Fl f Ar file
44
.Op Fl i Ar interface
44
.Op Fl i Ar interface
45
.Op Fl K Ar host | network
45
.Oo Fl K Ar host | network
46
.Op Fl c Oc
46
.Xo
47
.Xo
47
.Oo Fl k
48
.Oo Fl k
48
.Ar host | network | label | id
49
.Ar host | network | label | id
Lines 189-194 as the anchor name: Link Here
189
.Bd -literal -offset indent
190
.Bd -literal -offset indent
190
# pfctl -a '*' -sr
191
# pfctl -a '*' -sr
191
.Ed
192
.Ed
193
.It Fl c
194
When removing source tracking entries, remove state entries linked to
195
them. This option can be only used in conjunction with
196
.Fl K .
192
.It Fl D Ar macro Ns = Ns Ar value
197
.It Fl D Ar macro Ns = Ns Ar value
193
Define
198
Define
194
.Ar macro
199
.Ar macro
(-)b/sbin/pfctl/pfctl.c (-6 / +14 lines)
Lines 236-242 usage(void) Link Here
236
236
237
	fprintf(stderr, "usage: %s [-AdeghmNnOPqRrvz] ", __progname);
237
	fprintf(stderr, "usage: %s [-AdeghmNnOPqRrvz] ", __progname);
238
	fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n");
238
	fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n");
239
	fprintf(stderr, "\t[-f file] [-i interface] [-K host | network]\n");
239
	fprintf(stderr, "\t[-f file] [-i interface] [-K host | network [-c]]\n");
240
	fprintf(stderr, "\t[-k host | network | label | id] ");
240
	fprintf(stderr, "\t[-k host | network | label | id] ");
241
	fprintf(stderr, "[-o level] [-p device]\n");
241
	fprintf(stderr, "[-o level] [-p device]\n");
242
	fprintf(stderr, "\t[-s modifier] ");
242
	fprintf(stderr, "\t[-s modifier] ");
Lines 449-458 pfctl_kill_src_nodes(int dev, const char *iface, int opts) Link Here
449
	struct pfioc_src_node_kill psnk;
449
	struct pfioc_src_node_kill psnk;
450
	struct addrinfo *res[2], *resp[2];
450
	struct addrinfo *res[2], *resp[2];
451
	struct sockaddr last_src, last_dst;
451
	struct sockaddr last_src, last_dst;
452
	int killed, sources, dests;
452
	int killed, killed_states, sources, dests;
453
	int ret_ga;
453
	int ret_ga;
454
454
455
	killed = sources = dests = 0;
455
	killed = killed_states = sources = dests = 0;
456
456
457
	memset(&psnk, 0, sizeof(psnk));
457
	memset(&psnk, 0, sizeof(psnk));
458
	memset(&psnk.psnk_src.addr.v.a.mask, 0xff,
458
	memset(&psnk.psnk_src.addr.v.a.mask, 0xff,
Lines 462-467 pfctl_kill_src_nodes(int dev, const char *iface, int opts) Link Here
462
462
463
	pfctl_addrprefix(src_node_kill[0], &psnk.psnk_src.addr.v.a.mask);
463
	pfctl_addrprefix(src_node_kill[0], &psnk.psnk_src.addr.v.a.mask);
464
464
465
	psnk.psnk_kill_linked_states = opts & PF_OPT_KILLLINKEDSTATES;
466
465
	if ((ret_ga = getaddrinfo(src_node_kill[0], NULL, NULL, &res[0]))) {
467
	if ((ret_ga = getaddrinfo(src_node_kill[0], NULL, NULL, &res[0]))) {
466
		errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
468
		errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
467
		/* NOTREACHED */
469
		/* NOTREACHED */
Lines 529-548 pfctl_kill_src_nodes(int dev, const char *iface, int opts) Link Here
529
				if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
531
				if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
530
					err(1, "DIOCKILLSRCNODES");
532
					err(1, "DIOCKILLSRCNODES");
531
				killed += psnk.psnk_killed;
533
				killed += psnk.psnk_killed;
534
				killed_states += psnk.psnk_killed_states;
532
			}
535
			}
533
			freeaddrinfo(res[1]);
536
			freeaddrinfo(res[1]);
534
		} else {
537
		} else {
535
			if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
538
			if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
536
				err(1, "DIOCKILLSRCNODES");
539
				err(1, "DIOCKILLSRCNODES");
537
			killed += psnk.psnk_killed;
540
			killed += psnk.psnk_killed;
541
			killed_states += psnk.psnk_killed_states;
538
		}
542
		}
539
	}
543
	}
540
544
541
	freeaddrinfo(res[0]);
545
	freeaddrinfo(res[0]);
542
546
543
	if ((opts & PF_OPT_QUIET) == 0)
547
	if ((opts & PF_OPT_QUIET) == 0)
544
		fprintf(stderr, "killed %d src nodes from %d sources and %d "
548
		fprintf(stderr, "killed %d src nodes and %d linked states "
545
		    "destinations\n", killed, sources, dests);
549
		    "from %d sources and %d destinations\n",
550
		    killed, killed_states, sources, dests);
546
	return (0);
551
	return (0);
547
}
552
}
548
553
Lines 2002-2012 main(int argc, char *argv[]) Link Here
2002
		usage();
2007
		usage();
2003
2008
2004
	while ((ch = getopt(argc, argv,
2009
	while ((ch = getopt(argc, argv,
2005
	    "a:AdD:eqf:F:ghi:k:K:mnNOo:Pp:rRs:t:T:vx:z")) != -1) {
2010
	    "a:AcdD:eqf:F:ghi:k:K:mnNOo:Pp:rRs:t:T:vx:z")) != -1) {
2006
		switch (ch) {
2011
		switch (ch) {
2007
		case 'a':
2012
		case 'a':
2008
			anchoropt = optarg;
2013
			anchoropt = optarg;
2009
			break;
2014
			break;
2015
		case 'c':
2016
			opts |= PF_OPT_KILLLINKEDSTATES;
2017
			break;
2010
		case 'd':
2018
		case 'd':
2011
			opts |= PF_OPT_DISABLE;
2019
			opts |= PF_OPT_DISABLE;
2012
			mode = O_RDWR;
2020
			mode = O_RDWR;
(-)b/sbin/pfctl/pfctl_parser.h (+1 lines)
Lines 51-56 Link Here
51
#define PF_OPT_NUMERIC		0x1000
51
#define PF_OPT_NUMERIC		0x1000
52
#define PF_OPT_MERGE		0x2000
52
#define PF_OPT_MERGE		0x2000
53
#define PF_OPT_RECURSE		0x4000
53
#define PF_OPT_RECURSE		0x4000
54
#define PF_OPT_KILLLINKEDSTATES	0x8000
54
55
55
#define PF_TH_ALL		0xFF
56
#define PF_TH_ALL		0xFF
56
57
(-)b/sys/net/pfvar.h (+4 lines)
Lines 697-702 struct pf_threshold { Link Here
697
697
698
struct pf_src_node {
698
struct pf_src_node {
699
	LIST_ENTRY(pf_src_node) entry;
699
	LIST_ENTRY(pf_src_node) entry;
700
	TAILQ_HEAD(, pf_state)	state_list;
700
	struct pf_addr	 addr;
701
	struct pf_addr	 addr;
701
	struct pf_addr	 raddr;
702
	struct pf_addr	 raddr;
702
	union pf_rule_ptr rule;
703
	union pf_rule_ptr rule;
Lines 787-792 struct pf_state { Link Here
787
	TAILQ_ENTRY(pf_state)	 sync_list;
788
	TAILQ_ENTRY(pf_state)	 sync_list;
788
	TAILQ_ENTRY(pf_state)	 key_list[2];
789
	TAILQ_ENTRY(pf_state)	 key_list[2];
789
	LIST_ENTRY(pf_state)	 entry;
790
	LIST_ENTRY(pf_state)	 entry;
791
	TAILQ_ENTRY(pf_state)	 srcnode_link;
790
	struct pf_state_peer	 src;
792
	struct pf_state_peer	 src;
791
	struct pf_state_peer	 dst;
793
	struct pf_state_peer	 dst;
792
	union pf_rule_ptr	 rule;
794
	union pf_rule_ptr	 rule;
Lines 1445-1450 struct pfioc_src_node_kill { Link Here
1445
	struct pf_rule_addr psnk_src;
1447
	struct pf_rule_addr psnk_src;
1446
	struct pf_rule_addr psnk_dst;
1448
	struct pf_rule_addr psnk_dst;
1447
	u_int		    psnk_killed;
1449
	u_int		    psnk_killed;
1450
	u_int		    psnk_killed_states;
1451
	u_int		    psnk_kill_linked_states;
1448
};
1452
};
1449
1453
1450
struct pfioc_state_kill {
1454
struct pfioc_state_kill {
(-)b/sys/netpfil/pf/pf.c (+23 lines)
Lines 652-657 pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, Link Here
652
		    rule->max_src_conn_rate.limit,
652
		    rule->max_src_conn_rate.limit,
653
		    rule->max_src_conn_rate.seconds);
653
		    rule->max_src_conn_rate.seconds);
654
654
655
		TAILQ_INIT(&(*sn)->state_list);
656
655
		(*sn)->af = af;
657
		(*sn)->af = af;
656
		(*sn)->rule.ptr = rule;
658
		(*sn)->rule.ptr = rule;
657
		PF_ACPY(&(*sn)->addr, src, af);
659
		PF_ACPY(&(*sn)->addr, src, af);
Lines 1482-1487 static void Link Here
1482
pf_src_tree_remove_state(struct pf_state *s)
1484
pf_src_tree_remove_state(struct pf_state *s)
1483
{
1485
{
1484
	u_int32_t timeout;
1486
	u_int32_t timeout;
1487
	struct pf_srchash *sh = NULL;
1485
1488
1486
	if (s->src_node != NULL) {
1489
	if (s->src_node != NULL) {
1487
		if (s->src.tcp_est)
1490
		if (s->src.tcp_est)
Lines 1493-1498 pf_src_tree_remove_state(struct pf_state *s) Link Here
1493
				    V_pf_default_rule.timeout[PFTM_SRC_NODE];
1496
				    V_pf_default_rule.timeout[PFTM_SRC_NODE];
1494
			s->src_node->expire = time_uptime + timeout;
1497
			s->src_node->expire = time_uptime + timeout;
1495
		}
1498
		}
1499
		sh = &V_pf_srchash[pf_hashsrc(&s->src_node->addr, s->src_node->af)];
1500
		PF_HASHROW_LOCK(sh);
1501
		if (!TAILQ_EMPTY(&s->src_node->state_list))
1502
			TAILQ_REMOVE(&s->src_node->state_list, s, srcnode_link);
1503
		PF_HASHROW_UNLOCK(sh);
1504
1496
	}
1505
	}
1497
	if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
1506
	if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
1498
		if (--s->nat_src_node->states <= 0) {
1507
		if (--s->nat_src_node->states <= 0) {
Lines 1502-1507 pf_src_tree_remove_state(struct pf_state *s) Link Here
1502
				    V_pf_default_rule.timeout[PFTM_SRC_NODE];
1511
				    V_pf_default_rule.timeout[PFTM_SRC_NODE];
1503
			s->nat_src_node->expire = time_uptime + timeout;
1512
			s->nat_src_node->expire = time_uptime + timeout;
1504
		}
1513
		}
1514
		sh = &V_pf_srchash[pf_hashsrc(&s->nat_src_node->addr, s->nat_src_node->af)];
1515
		PF_HASHROW_LOCK(sh);
1516
		if (!TAILQ_EMPTY(&s->nat_src_node->state_list))
1517
			TAILQ_REMOVE(&s->nat_src_node->state_list, s, srcnode_link);
1518
		PF_HASHROW_UNLOCK(sh);
1505
	}
1519
	}
1506
	s->src_node = s->nat_src_node = NULL;
1520
	s->src_node = s->nat_src_node = NULL;
1507
}
1521
}
Lines 3407-3412 pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, Link Here
3407
    int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen)
3421
    int tag, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen)
3408
{
3422
{
3409
	struct pf_state		*s = NULL;
3423
	struct pf_state		*s = NULL;
3424
	struct pf_srchash	*sh = NULL;
3410
	struct pf_src_node	*sn = NULL;
3425
	struct pf_src_node	*sn = NULL;
3411
	struct tcphdr		*th = pd->hdr.tcp;
3426
	struct tcphdr		*th = pd->hdr.tcp;
3412
	u_int16_t		 mss = V_tcp_mssdflt;
3427
	u_int16_t		 mss = V_tcp_mssdflt;
Lines 3505-3518 pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, Link Here
3505
	s->expire = time_uptime;
3520
	s->expire = time_uptime;
3506
3521
3507
	if (sn != NULL) {
3522
	if (sn != NULL) {
3523
		sh = &V_pf_srchash[pf_hashsrc(&sn->addr, sn->af)];
3524
		PF_HASHROW_LOCK(sh);
3508
		s->src_node = sn;
3525
		s->src_node = sn;
3509
		s->src_node->states++;
3526
		s->src_node->states++;
3527
		TAILQ_INSERT_HEAD(&sn->state_list, s, srcnode_link);
3528
		PF_HASHROW_UNLOCK(sh);
3510
	}
3529
	}
3511
	if (nsn != NULL) {
3530
	if (nsn != NULL) {
3512
		/* XXX We only modify one side for now. */
3531
		/* XXX We only modify one side for now. */
3532
		sh = &V_pf_srchash[pf_hashsrc(&nsn->addr, nsn->af)];
3533
		PF_HASHROW_LOCK(sh);
3513
		PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af);
3534
		PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af);
3514
		s->nat_src_node = nsn;
3535
		s->nat_src_node = nsn;
3515
		s->nat_src_node->states++;
3536
		s->nat_src_node->states++;
3537
		TAILQ_INSERT_HEAD(&nsn->state_list, s, srcnode_link);
3538
		PF_HASHROW_UNLOCK(sh);
3516
	}
3539
	}
3517
	if (pd->proto == IPPROTO_TCP) {
3540
	if (pd->proto == IPPROTO_TCP) {
3518
		if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
3541
		if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
(-)b/sys/netpfil/pf/pf_ioctl.c (-20 / +38 lines)
Lines 150-156 struct cdev *pf_dev; Link Here
150
 */
150
 */
151
static void		 pf_clear_states(void);
151
static void		 pf_clear_states(void);
152
static int		 pf_clear_tables(void);
152
static int		 pf_clear_tables(void);
153
static void		 pf_clear_srcnodes(struct pf_src_node *);
153
static u_int32_t	 pf_clear_srcnodes(struct pf_src_node *,
154
    int kill_states);
154
static void		 pf_tbladdr_copyout(struct pf_addr_wrap *);
155
static void		 pf_tbladdr_copyout(struct pf_addr_wrap *);
155
156
156
/*
157
/*
Lines 3134-3140 DIOCCHANGEADDR_error: Link Here
3134
3135
3135
	case DIOCCLRSRCNODES: {
3136
	case DIOCCLRSRCNODES: {
3136
3137
3137
		pf_clear_srcnodes(NULL);
3138
		pf_clear_srcnodes(NULL, 0);
3138
		pf_purge_expired_src_nodes();
3139
		pf_purge_expired_src_nodes();
3139
		V_pf_status.src_nodes = 0;
3140
		V_pf_status.src_nodes = 0;
3140
		break;
3141
		break;
Lines 3145-3151 DIOCCHANGEADDR_error: Link Here
3145
		    (struct pfioc_src_node_kill *)addr;
3146
		    (struct pfioc_src_node_kill *)addr;
3146
		struct pf_srchash	*sh;
3147
		struct pf_srchash	*sh;
3147
		struct pf_src_node	*sn;
3148
		struct pf_src_node	*sn;
3148
		u_int			i, killed = 0;
3149
		u_int			i, killed = 0, killed_states = 0;
3149
3150
3150
		for (i = 0, sh = V_pf_srchash; i < V_pf_srchashmask;
3151
		for (i = 0, sh = V_pf_srchash; i < V_pf_srchashmask;
3151
		    i++, sh++) {
3152
		    i++, sh++) {
Lines 3166-3172 DIOCCHANGEADDR_error: Link Here
3166
				&sn->raddr, sn->af)) {
3167
				&sn->raddr, sn->af)) {
3167
				/* Handle state to src_node linkage */
3168
				/* Handle state to src_node linkage */
3168
				if (sn->states != 0)
3169
				if (sn->states != 0)
3169
					pf_clear_srcnodes(sn);
3170
					killed_states += pf_clear_srcnodes(sn,  psnk->psnk_kill_linked_states);
3170
				sn->expire = 1;
3171
				sn->expire = 1;
3171
				killed++;
3172
				killed++;
3172
			}
3173
			}
Lines 3177-3182 DIOCCHANGEADDR_error: Link Here
3177
			pf_purge_expired_src_nodes();
3178
			pf_purge_expired_src_nodes();
3178
3179
3179
		psnk->psnk_killed = killed;
3180
		psnk->psnk_killed = killed;
3181
		psnk->psnk_killed_states = killed_states;
3180
		break;
3182
		break;
3181
	}
3183
	}
3182
3184
Lines 3360-3383 pf_clear_tables(void) Link Here
3360
	return (error);
3362
	return (error);
3361
}
3363
}
3362
3364
3363
static void
3365
static u_int32_t
3364
pf_clear_srcnodes(struct pf_src_node *n)
3366
pf_clear_srcnodes(struct pf_src_node *n, int kill_states)
3365
{
3367
{
3366
	struct pf_state *s;
3368
	struct pf_state *s;
3367
	int i;
3369
	int i;
3368
3370
	int killed_states = 0;
3369
	for (i = 0; i <= V_pf_hashmask; i++) {
3370
		struct pf_idhash *ih = &V_pf_idhash[i];
3371
3372
		PF_HASHROW_LOCK(ih);
3373
		LIST_FOREACH(s, &ih->states, entry) {
3374
			if (n == NULL || n == s->src_node)
3375
				s->src_node = NULL;
3376
			if (n == NULL || n == s->nat_src_node)
3377
				s->nat_src_node = NULL;
3378
		}
3379
		PF_HASHROW_UNLOCK(ih);
3380
	}
3381
3371
3382
	if (n == NULL) {
3372
	if (n == NULL) {
3383
		struct pf_srchash *sh;
3373
		struct pf_srchash *sh;
Lines 3386-3391 pf_clear_srcnodes(struct pf_src_node *n) Link Here
3386
		    i++, sh++) {
3376
		    i++, sh++) {
3387
			PF_HASHROW_LOCK(sh);
3377
			PF_HASHROW_LOCK(sh);
3388
			LIST_FOREACH(n, &sh->nodes, entry) {
3378
			LIST_FOREACH(n, &sh->nodes, entry) {
3379
				while (!TAILQ_EMPTY(&n->state_list)) {
3380
					s = TAILQ_FIRST(&n->state_list);
3381
					if (kill_states) {
3382
						pf_unlink_state(s, 0);
3383
						killed_states++;
3384
					} else {
3385
						PF_STATE_LOCK(s);
3386
						TAILQ_REMOVE(&n->state_list, s, srcnode_link);
3387
						s->src_node = NULL;
3388
						s->nat_src_node = NULL;
3389
						PF_STATE_UNLOCK(s);
3390
					}
3391
				}
3389
				n->expire = 1;
3392
				n->expire = 1;
3390
				n->states = 0;
3393
				n->states = 0;
3391
			}
3394
			}
Lines 3393-3401 pf_clear_srcnodes(struct pf_src_node *n) Link Here
3393
		}
3396
		}
3394
	} else {
3397
	} else {
3395
		/* XXX: hash slot should already be locked here. */
3398
		/* XXX: hash slot should already be locked here. */
3399
		while (!TAILQ_EMPTY(&n->state_list)) {
3400
			s = TAILQ_FIRST(&n->state_list);
3401
			if (kill_states) {
3402
				pf_unlink_state(s, 0);
3403
				killed_states++;
3404
			} else {
3405
				PF_STATE_LOCK(s);
3406
				TAILQ_REMOVE(&n->state_list, s, srcnode_link);
3407
				s->src_node = NULL;
3408
				s->nat_src_node = NULL;
3409
				PF_STATE_UNLOCK(s);
3410
			}
3411
		}
3396
		n->expire = 1;
3412
		n->expire = 1;
3397
		n->states = 0;
3413
		n->states = 0;
3398
	}
3414
	}
3415
3416
	return killed_states;
3399
}
3417
}
3400
/*
3418
/*
3401
 * XXX - Check for version missmatch!!!
3419
 * XXX - Check for version missmatch!!!
Lines 3459-3465 shutdown_pf(void) Link Here
3459
3477
3460
		pf_clear_states();
3478
		pf_clear_states();
3461
3479
3462
		pf_clear_srcnodes(NULL);
3480
		pf_clear_srcnodes(NULL, 0);
3463
3481
3464
		/* status does not use malloced mem so no need to cleanup */
3482
		/* status does not use malloced mem so no need to cleanup */
3465
		/* fingerprints and interfaces have thier own cleanup code */
3483
		/* fingerprints and interfaces have thier own cleanup code */

Return to bug 176763