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

Collapse All | Expand All

(-)b/sbin/pfctl/parse.y (-2 / +20 lines)
Lines 70-89 __FBSDID("$FreeBSD$"); Link Here
70
#include "pfctl.h"
70
#include "pfctl.h"
71
71
72
static struct pfctl	*pf = NULL;
72
static struct pfctl	*pf = NULL;
73
static int		 debug = 0;
73
static int		 debug = 0;
74
static int		 rulestate = 0;
74
static int		 rulestate = 0;
75
static u_int16_t	 returnicmpdefault =
75
static u_int16_t	 returnicmpdefault =
76
			    (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
76
			    (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
77
static u_int16_t	 returnicmp6default =
77
static u_int16_t	 returnicmp6default =
78
			    (ICMP6_DST_UNREACH << 8) | ICMP6_DST_UNREACH_NOPORT;
78
			    (ICMP6_DST_UNREACH << 8) | ICMP6_DST_UNREACH_NOPORT;
79
static int		 blockpolicy = PFRULE_DROP;
79
static int		 blockpolicy = PFRULE_DROP;
80
static int		 failpolicy = PFRULE_DROP;
80
static int		 require_order = 1;
81
static int		 require_order = 1;
81
static int		 default_statelock;
82
static int		 default_statelock;
82
83
83
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
84
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
84
static struct file {
85
static struct file {
85
	TAILQ_ENTRY(file)	 entry;
86
	TAILQ_ENTRY(file)	 entry;
86
	FILE			*stream;
87
	FILE			*stream;
87
	char			*name;
88
	char			*name;
88
	int			 lineno;
89
	int			 lineno;
89
	int			 errors;
90
	int			 errors;
Lines 444-465 int parseport(char *, struct range *r, int); Link Here
444
	!isdigit((addr).v.ifname[strlen((addr).v.ifname)-1])))
445
	!isdigit((addr).v.ifname[strlen((addr).v.ifname)-1])))
445
446
446
%}
447
%}
447
448
448
%token	PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
449
%token	PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
449
%token	RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
450
%token	RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
450
%token	ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
451
%token	ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
451
%token	MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL
452
%token	MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL
452
%token	NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE
453
%token	NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE
453
%token	REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
454
%token	REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
454
%token	SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID
455
%token	SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY FAILPOLICY
455
%token	REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
456
%token	RANDOMID REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
456
%token	ANTISPOOF FOR INCLUDE
457
%token	ANTISPOOF FOR INCLUDE
457
%token	BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
458
%token	BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
458
%token	ALTQ CBQ CODEL PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME
459
%token	ALTQ CBQ CODEL PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME
459
%token	UPPERLIMIT QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE TARGET INTERVAL
460
%token	UPPERLIMIT QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE TARGET INTERVAL
460
%token	LOAD RULESET_OPTIMIZATION PRIO
461
%token	LOAD RULESET_OPTIMIZATION PRIO
461
%token	STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
462
%token	STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
462
%token	MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
463
%token	MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
463
%token	TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
464
%token	TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE SETTOS
464
%token	DIVERTTO DIVERTREPLY
465
%token	DIVERTTO DIVERTREPLY
465
%token	<v.string>		STRING
466
%token	<v.string>		STRING
Lines 629-648 option : SET OPTIMIZATION STRING { Link Here
629
				YYERROR;
630
				YYERROR;
630
			blockpolicy = PFRULE_DROP;
631
			blockpolicy = PFRULE_DROP;
631
		}
632
		}
632
		| SET BLOCKPOLICY RETURN {
633
		| SET BLOCKPOLICY RETURN {
633
			if (pf->opts & PF_OPT_VERBOSE)
634
			if (pf->opts & PF_OPT_VERBOSE)
634
				printf("set block-policy return\n");
635
				printf("set block-policy return\n");
635
			if (check_rulestate(PFCTL_STATE_OPTION))
636
			if (check_rulestate(PFCTL_STATE_OPTION))
636
				YYERROR;
637
				YYERROR;
637
			blockpolicy = PFRULE_RETURN;
638
			blockpolicy = PFRULE_RETURN;
638
		}
639
		}
640
		| SET FAILPOLICY DROP	{
641
			if (pf->opts & PF_OPT_VERBOSE)
642
				printf("set fail-policy drop\n");
643
			if (check_rulestate(PFCTL_STATE_OPTION))
644
				YYERROR;
645
			failpolicy= PFRULE_DROP;
646
		}
647
		| SET FAILPOLICY RETURN {
648
			if (pf->opts & PF_OPT_VERBOSE)
649
				printf("set fail-policy return\n");
650
			if (check_rulestate(PFCTL_STATE_OPTION))
651
				YYERROR;
652
			failpolicy = PFRULE_FAILRETURN;
653
		}
639
		| SET REQUIREORDER yesno {
654
		| SET REQUIREORDER yesno {
640
			if (pf->opts & PF_OPT_VERBOSE)
655
			if (pf->opts & PF_OPT_VERBOSE)
641
				printf("set require-order %s\n",
656
				printf("set require-order %s\n",
642
				    $3 == 1 ? "yes" : "no");
657
				    $3 == 1 ? "yes" : "no");
643
			require_order = $3;
658
			require_order = $3;
644
		}
659
		}
645
		| SET FINGERPRINTS STRING {
660
		| SET FINGERPRINTS STRING {
646
			if (pf->opts & PF_OPT_VERBOSE)
661
			if (pf->opts & PF_OPT_VERBOSE)
647
				printf("set fingerprints \"%s\"\n", $3);
662
				printf("set fingerprints \"%s\"\n", $3);
648
			if (check_rulestate(PFCTL_STATE_OPTION)) {
663
			if (check_rulestate(PFCTL_STATE_OPTION)) {
Lines 2306-2325 pfrule : action dir logquick interface route af proto fromto Link Here
2306
					    r.max_src_conn_rate.seconds;
2321
					    r.max_src_conn_rate.seconds;
2307
				r.rule_flag |= PFRULE_SRCTRACK;
2322
				r.rule_flag |= PFRULE_SRCTRACK;
2308
				if (srctrack == PF_SRCTRACK_RULE)
2323
				if (srctrack == PF_SRCTRACK_RULE)
2309
					r.rule_flag |= PFRULE_RULESRCTRACK;
2324
					r.rule_flag |= PFRULE_RULESRCTRACK;
2310
			}
2325
			}
2311
			if (r.keep_state && !statelock)
2326
			if (r.keep_state && !statelock)
2312
				r.rule_flag |= default_statelock;
2327
				r.rule_flag |= default_statelock;
2313
2328
2314
			if ($9.fragment)
2329
			if ($9.fragment)
2315
				r.rule_flag |= PFRULE_FRAGMENT;
2330
				r.rule_flag |= PFRULE_FRAGMENT;
2331
			r.rule_flag |= failpolicy;
2316
			r.allow_opts = $9.allowopts;
2332
			r.allow_opts = $9.allowopts;
2317
2333
2318
			decide_address_family($8.src.host, &r.af);
2334
			decide_address_family($8.src.host, &r.af);
2319
			decide_address_family($8.dst.host, &r.af);
2335
			decide_address_family($8.dst.host, &r.af);
2320
2336
2321
			if ($5.rt) {
2337
			if ($5.rt) {
2322
				if (!r.direction) {
2338
				if (!r.direction) {
2323
					yyerror("direction must be explicit "
2339
					yyerror("direction must be explicit "
2324
					    "with rules that specify routing");
2340
					    "with rules that specify routing");
2325
					YYERROR;
2341
					YYERROR;
Lines 5454-5473 lookup(char *s) Link Here
5454
		{ "cbq",		CBQ},
5470
		{ "cbq",		CBQ},
5455
		{ "code",		CODE},
5471
		{ "code",		CODE},
5456
		{ "codelq",		CODEL},
5472
		{ "codelq",		CODEL},
5457
		{ "crop",		FRAGCROP},
5473
		{ "crop",		FRAGCROP},
5458
		{ "debug",		DEBUG},
5474
		{ "debug",		DEBUG},
5459
		{ "divert-reply",	DIVERTREPLY},
5475
		{ "divert-reply",	DIVERTREPLY},
5460
		{ "divert-to",		DIVERTTO},
5476
		{ "divert-to",		DIVERTTO},
5461
		{ "drop",		DROP},
5477
		{ "drop",		DROP},
5462
		{ "drop-ovl",		FRAGDROP},
5478
		{ "drop-ovl",		FRAGDROP},
5463
		{ "dup-to",		DUPTO},
5479
		{ "dup-to",		DUPTO},
5480
		{ "fail-policy",	FAILPOLICY},
5464
		{ "fairq",		FAIRQ},
5481
		{ "fairq",		FAIRQ},
5465
		{ "fastroute",		FASTROUTE},
5482
		{ "fastroute",		FASTROUTE},
5466
		{ "file",		FILENAME},
5483
		{ "file",		FILENAME},
5467
		{ "fingerprints",	FINGERPRINTS},
5484
		{ "fingerprints",	FINGERPRINTS},
5468
		{ "flags",		FLAGS},
5485
		{ "flags",		FLAGS},
5469
		{ "floating",		FLOATING},
5486
		{ "floating",		FLOATING},
5470
		{ "flush",		FLUSH},
5487
		{ "flush",		FLUSH},
5471
		{ "for",		FOR},
5488
		{ "for",		FOR},
5472
		{ "fragment",		FRAGMENT},
5489
		{ "fragment",		FRAGMENT},
5473
		{ "from",		FROM},
5490
		{ "from",		FROM},
Lines 5918-5937 parse_config(char *filename, struct pfctl *xpf) Link Here
5918
	int		 errors = 0;
5935
	int		 errors = 0;
5919
	struct sym	*sym;
5936
	struct sym	*sym;
5920
5937
5921
	pf = xpf;
5938
	pf = xpf;
5922
	errors = 0;
5939
	errors = 0;
5923
	rulestate = PFCTL_STATE_NONE;
5940
	rulestate = PFCTL_STATE_NONE;
5924
	returnicmpdefault = (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
5941
	returnicmpdefault = (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
5925
	returnicmp6default =
5942
	returnicmp6default =
5926
	    (ICMP6_DST_UNREACH << 8) | ICMP6_DST_UNREACH_NOPORT;
5943
	    (ICMP6_DST_UNREACH << 8) | ICMP6_DST_UNREACH_NOPORT;
5927
	blockpolicy = PFRULE_DROP;
5944
	blockpolicy = PFRULE_DROP;
5945
	failpolicy = PFRULE_DROP;
5928
	require_order = 1;
5946
	require_order = 1;
5929
5947
5930
	if ((file = pushfile(filename, 0)) == NULL) {
5948
	if ((file = pushfile(filename, 0)) == NULL) {
5931
		warn("cannot open the main config file!");
5949
		warn("cannot open the main config file!");
5932
		return (-1);
5950
		return (-1);
5933
	}
5951
	}
5934
5952
5935
	yyparse();
5953
	yyparse();
5936
	errors = file->errors;
5954
	errors = file->errors;
5937
	popfile();
5955
	popfile();
(-)b/share/man/man5/pf.conf.5 (+25 lines)
Lines 491-510 Packet is silently dropped. Link Here
491
.It Ar return
491
.It Ar return
492
A TCP RST is returned for blocked TCP packets,
492
A TCP RST is returned for blocked TCP packets,
493
an ICMP UNREACHABLE is returned for blocked UDP packets,
493
an ICMP UNREACHABLE is returned for blocked UDP packets,
494
and all other packets are silently dropped.
494
and all other packets are silently dropped.
495
.El
495
.El
496
.Pp
496
.Pp
497
For example:
497
For example:
498
.Bd -literal -offset indent
498
.Bd -literal -offset indent
499
set block-policy return
499
set block-policy return
500
.Ed
500
.Ed
501
502
.It Ar set fail-policy
503
The
504
.Ar fail-policy
505
option sets the behaviour of rules which should pass a packet but unable to
506
do so. This might happen when a nat or route-to rule uses an empty table as list
507
of targets or if a rule fails to create state or source node.
508
The following
509
.Ar block
510
actions are possible:
511
.Pp
512
.Bl -tag -width xxxxxxxx -compact
513
.It Ar drop
514
Incoming packet is silently dropped.
515
.It Ar return
516
Incoming packet is dropped and TCP RST is returned for TCP packets,
517
an ICMP UNREACHABLE is returned for UDP packets,
518
and no response is sent for other packets.
519
.El
520
.Pp
521
For example:
522
.Bd -literal -offset indent
523
set fail-policy return
524
.Ed
525
501
.It Ar set state-policy
526
.It Ar set state-policy
502
The
527
The
503
.Ar state-policy
528
.Ar state-policy
504
option sets the default behaviour for states:
529
option sets the default behaviour for states:
505
.Pp
530
.Pp
506
.Bl -tag -width group-bound -compact
531
.Bl -tag -width group-bound -compact
507
.It Ar if-bound
532
.It Ar if-bound
508
States are bound to interface.
533
States are bound to interface.
509
.It Ar floating
534
.It Ar floating
510
States can match packets on any interfaces (the default).
535
States can match packets on any interfaces (the default).
(-)b/sys/net/pfvar.h (+1 lines)
Lines 605-624 struct pf_rule { Link Here
605
605
606
/* scrub flags */
606
/* scrub flags */
607
#define	PFRULE_NODF		0x0100
607
#define	PFRULE_NODF		0x0100
608
#define PFRULE_RANDOMID		0x0800
608
#define PFRULE_RANDOMID		0x0800
609
#define PFRULE_REASSEMBLE_TCP	0x1000
609
#define PFRULE_REASSEMBLE_TCP	0x1000
610
#define PFRULE_SET_TOS		0x2000
610
#define PFRULE_SET_TOS		0x2000
611
611
612
/* rule flags again */
612
/* rule flags again */
613
#define PFRULE_IFBOUND		0x00010000	/* if-bound */
613
#define PFRULE_IFBOUND		0x00010000	/* if-bound */
614
#define PFRULE_STATESLOPPY	0x00020000	/* sloppy state tracking */
614
#define PFRULE_STATESLOPPY	0x00020000	/* sloppy state tracking */
615
#define PFRULE_FAILRETURN	0x00040000	/* return on failed rules */
615
616
616
#define PFSTATE_HIWAT		10000	/* default state table size */
617
#define PFSTATE_HIWAT		10000	/* default state table size */
617
#define PFSTATE_ADAPT_START	6000	/* default adaptive timeout start */
618
#define PFSTATE_ADAPT_START	6000	/* default adaptive timeout start */
618
#define PFSTATE_ADAPT_END	12000	/* default adaptive timeout end */
619
#define PFSTATE_ADAPT_END	12000	/* default adaptive timeout end */
619
620
620
621
621
struct pf_threshold {
622
struct pf_threshold {
622
	u_int32_t	limit;
623
	u_int32_t	limit;
623
#define	PF_THRESHOLD_MULT	1000
624
#define	PF_THRESHOLD_MULT	1000
624
#define PF_THRESHOLD_MAX	0xffffffff / PF_THRESHOLD_MULT
625
#define PF_THRESHOLD_MAX	0xffffffff / PF_THRESHOLD_MULT
(-)b/sys/netpfil/pf/pf.c (-63 / +81 lines)
Lines 2466-2485 pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, Link Here
2466
		h6->ip6_hlim = IPV6_DEFHLIM;
2466
		h6->ip6_hlim = IPV6_DEFHLIM;
2467
2467
2468
		pfse->pfse_type = PFSE_IP6;
2468
		pfse->pfse_type = PFSE_IP6;
2469
		break;
2469
		break;
2470
#endif /* INET6 */
2470
#endif /* INET6 */
2471
	}
2471
	}
2472
	pfse->pfse_m = m;
2472
	pfse->pfse_m = m;
2473
	pf_send(pfse);
2473
	pf_send(pfse);
2474
}
2474
}
2475
2475
2476
static void
2477
pf_return(struct pf_rule *r, struct pf_rule *nr, struct pf_pdesc *pd,
2478
    struct pf_state_key *sk, int off, struct mbuf *m, struct tcphdr *th,
2479
    struct pfi_kif *kif, u_int16_t bproto_sum, u_int16_t bip_sum, int hdrlen,
2480
    u_short *reason)
2481
{
2482
	struct pf_addr	* const saddr = pd->src;
2483
	struct pf_addr	* const daddr = pd->dst;
2484
	sa_family_t	 af = pd->af;
2485
2486
	/* undo NAT changes, if they have taken place */
2487
	if (nr != NULL) {
2488
		PF_ACPY(saddr, &sk->addr[pd->sidx], af);
2489
		PF_ACPY(daddr, &sk->addr[pd->didx], af);
2490
		if (pd->sport)
2491
			*pd->sport = sk->port[pd->sidx];
2492
		if (pd->dport)
2493
			*pd->dport = sk->port[pd->didx];
2494
		if (pd->proto_sum)
2495
			*pd->proto_sum = bproto_sum;
2496
		if (pd->ip_sum)
2497
			*pd->ip_sum = bip_sum;
2498
		m_copyback(m, off, hdrlen, pd->hdr.any);
2499
	}
2500
	if (pd->proto == IPPROTO_TCP &&
2501
	    ((r->rule_flag & PFRULE_RETURNRST) ||
2502
	    (r->rule_flag & PFRULE_RETURN)) &&
2503
	    !(th->th_flags & TH_RST)) {
2504
		u_int32_t	 ack = ntohl(th->th_seq) + pd->p_len;
2505
		int		 len = 0;
2506
#ifdef INET
2507
		struct ip	*h4;
2508
#endif
2509
#ifdef INET6
2510
		struct ip6_hdr	*h6;
2511
#endif
2512
2513
		switch (af) {
2514
#ifdef INET
2515
		case AF_INET:
2516
			h4 = mtod(m, struct ip *);
2517
			len = ntohs(h4->ip_len) - off;
2518
			break;
2519
#endif
2520
#ifdef INET6
2521
		case AF_INET6:
2522
			h6 = mtod(m, struct ip6_hdr *);
2523
			len = ntohs(h6->ip6_plen) - (off - sizeof(*h6));
2524
			break;
2525
#endif
2526
		}
2527
2528
		if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af))
2529
			REASON_SET(reason, PFRES_PROTCKSUM);
2530
		else {
2531
			if (th->th_flags & TH_SYN)
2532
				ack++;
2533
			if (th->th_flags & TH_FIN)
2534
				ack++;
2535
			pf_send_tcp(m, r, af, pd->dst,
2536
				pd->src, th->th_dport, th->th_sport,
2537
				ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
2538
				r->return_ttl, 1, 0, kif->pfik_ifp);
2539
		}
2540
	} else if (pd->proto != IPPROTO_ICMP && af == AF_INET &&
2541
		r->return_icmp)
2542
		pf_send_icmp(m, r->return_icmp >> 8,
2543
			r->return_icmp & 255, af, r);
2544
	else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 &&
2545
		r->return_icmp6)
2546
		pf_send_icmp(m, r->return_icmp6 >> 8,
2547
			r->return_icmp6 & 255, af, r);
2548
}
2549
2550
2476
static int
2551
static int
2477
pf_ieee8021q_setpcp(struct mbuf *m, u_int8_t prio)
2552
pf_ieee8021q_setpcp(struct mbuf *m, u_int8_t prio)
2478
{
2553
{
2479
	struct m_tag *mtag;
2554
	struct m_tag *mtag;
2480
2555
2481
	KASSERT(prio <= PF_PRIO_MAX,
2556
	KASSERT(prio <= PF_PRIO_MAX,
2482
	    ("%s with invalid pcp", __func__));
2557
	    ("%s with invalid pcp", __func__));
2483
2558
2484
	mtag = m_tag_locate(m, MTAG_8021Q, MTAG_8021Q_PCP_OUT, NULL);
2559
	mtag = m_tag_locate(m, MTAG_8021Q, MTAG_8021Q_PCP_OUT, NULL);
2485
	if (mtag == NULL) {
2560
	if (mtag == NULL) {
Lines 3430-3531 pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, Link Here
3430
		if (rewrite)
3505
		if (rewrite)
3431
			m_copyback(m, off, hdrlen, pd->hdr.any);
3506
			m_copyback(m, off, hdrlen, pd->hdr.any);
3432
		PFLOG_PACKET(kif, m, af, direction, reason, r->log ? r : nr, a,
3507
		PFLOG_PACKET(kif, m, af, direction, reason, r->log ? r : nr, a,
3433
		    ruleset, pd, 1);
3508
		    ruleset, pd, 1);
3434
	}
3509
	}
3435
3510
3436
	if ((r->action == PF_DROP) &&
3511
	if ((r->action == PF_DROP) &&
3437
	    ((r->rule_flag & PFRULE_RETURNRST) ||
3512
	    ((r->rule_flag & PFRULE_RETURNRST) ||
3438
	    (r->rule_flag & PFRULE_RETURNICMP) ||
3513
	    (r->rule_flag & PFRULE_RETURNICMP) ||
3439
	    (r->rule_flag & PFRULE_RETURN))) {
3514
	    (r->rule_flag & PFRULE_RETURN))) {
3440
		/* undo NAT changes, if they have taken place */
3515
		pf_return(r, nr, pd, sk, off, m, th, kif, bproto_sum,
3441
		if (nr != NULL) {
3516
		    bip_sum, hdrlen, &reason);
3442
			PF_ACPY(saddr, &sk->addr[pd->sidx], af);
3443
			PF_ACPY(daddr, &sk->addr[pd->didx], af);
3444
			if (pd->sport)
3445
				*pd->sport = sk->port[pd->sidx];
3446
			if (pd->dport)
3447
				*pd->dport = sk->port[pd->didx];
3448
			if (pd->proto_sum)
3449
				*pd->proto_sum = bproto_sum;
3450
			if (pd->ip_sum)
3451
				*pd->ip_sum = bip_sum;
3452
			m_copyback(m, off, hdrlen, pd->hdr.any);
3453
		}
3454
		if (pd->proto == IPPROTO_TCP &&
3455
		    ((r->rule_flag & PFRULE_RETURNRST) ||
3456
		    (r->rule_flag & PFRULE_RETURN)) &&
3457
		    !(th->th_flags & TH_RST)) {
3458
			u_int32_t	 ack = ntohl(th->th_seq) + pd->p_len;
3459
			int		 len = 0;
3460
#ifdef INET
3461
			struct ip	*h4;
3462
#endif
3463
#ifdef INET6
3464
			struct ip6_hdr	*h6;
3465
#endif
3466
3467
			switch (af) {
3468
#ifdef INET
3469
			case AF_INET:
3470
				h4 = mtod(m, struct ip *);
3471
				len = ntohs(h4->ip_len) - off;
3472
				break;
3473
#endif
3474
#ifdef INET6
3475
			case AF_INET6:
3476
				h6 = mtod(m, struct ip6_hdr *);
3477
				len = ntohs(h6->ip6_plen) - (off - sizeof(*h6));
3478
				break;
3479
#endif
3480
			}
3481
3482
			if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af))
3483
				REASON_SET(&reason, PFRES_PROTCKSUM);
3484
			else {
3485
				if (th->th_flags & TH_SYN)
3486
					ack++;
3487
				if (th->th_flags & TH_FIN)
3488
					ack++;
3489
				pf_send_tcp(m, r, af, pd->dst,
3490
				    pd->src, th->th_dport, th->th_sport,
3491
				    ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
3492
				    r->return_ttl, 1, 0, kif->pfik_ifp);
3493
			}
3494
		} else if (pd->proto != IPPROTO_ICMP && af == AF_INET &&
3495
		    r->return_icmp)
3496
			pf_send_icmp(m, r->return_icmp >> 8,
3497
			    r->return_icmp & 255, af, r);
3498
		else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 &&
3499
		    r->return_icmp6)
3500
			pf_send_icmp(m, r->return_icmp6 >> 8,
3501
			    r->return_icmp6 & 255, af, r);
3502
	}
3517
	}
3503
3518
3504
	if (r->action == PF_DROP)
3519
	if (r->action == PF_DROP)
3505
		goto cleanup;
3520
		goto cleanup;
3506
3521
3507
	if (tag > 0 && pf_tag_packet(m, pd, tag)) {
3522
	if (tag > 0 && pf_tag_packet(m, pd, tag)) {
3508
		REASON_SET(&reason, PFRES_MEMORY);
3523
		REASON_SET(&reason, PFRES_MEMORY);
3509
		goto cleanup;
3524
		goto cleanup;
3510
	}
3525
	}
3511
	if (rtableid >= 0)
3526
	if (rtableid >= 0)
3512
		M_SETFIB(m, rtableid);
3527
		M_SETFIB(m, rtableid);
3513
3528
3514
	if (!state_icmp && (r->keep_state || nr != NULL ||
3529
	if (!state_icmp && (r->keep_state || nr != NULL ||
3515
	    (pd->flags & PFDESC_TCP_NORM))) {
3530
	    (pd->flags & PFDESC_TCP_NORM))) {
3516
		int action;
3531
		int action;
3517
		action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off,
3532
		action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off,
3518
		    sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum,
3533
		    sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum,
3519
		    hdrlen);
3534
		    hdrlen);
3520
		if (action != PF_PASS)
3535
		if (action != PF_PASS && r->rule_flag & PFRULE_FAILRETURN) {
3536
			pf_return(r, nr, pd, sk, off, m, th, kif,
3537
			    bproto_sum, bip_sum, hdrlen, &reason);
3521
			return (action);
3538
			return (action);
3539
		}
3522
	} else {
3540
	} else {
3523
		if (sk != NULL)
3541
		if (sk != NULL)
3524
			uma_zfree(V_pf_state_key_z, sk);
3542
			uma_zfree(V_pf_state_key_z, sk);
3525
		if (nk != NULL)
3543
		if (nk != NULL)
3526
			uma_zfree(V_pf_state_key_z, nk);
3544
			uma_zfree(V_pf_state_key_z, nk);
3527
	}
3545
	}
3528
3546
3529
	/* copy back packet headers if we performed NAT operations */
3547
	/* copy back packet headers if we performed NAT operations */
3530
	if (rewrite)
3548
	if (rewrite)
3531
		m_copyback(m, off, hdrlen, pd->hdr.any);
3549
		m_copyback(m, off, hdrlen, pd->hdr.any);

Return to bug 226850