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

Collapse All | Expand All

(-)b/sys/net/pfvar.h (-2 / +4 lines)
Lines 743-763 struct pf_state { Link Here
743
/*  was	PFSTATE_PFLOW		0x04 */
743
/*  was	PFSTATE_PFLOW		0x04 */
744
#define	PFSTATE_NOSYNC		0x08
744
#define	PFSTATE_NOSYNC		0x08
745
#define	PFSTATE_ACK		0x10
745
#define	PFSTATE_ACK		0x10
746
#define	PFSTATE_SETPRIO		0x0200
746
#define	PFSTATE_SETPRIO		0x0200
747
#define	PFSTATE_SETMASK   (PFSTATE_SETPRIO)
747
#define	PFSTATE_SETMASK   (PFSTATE_SETPRIO)
748
	u_int8_t		 timeout;
748
	u_int8_t		 timeout;
749
	u_int8_t		 sync_state; /* PFSYNC_S_x */
749
	u_int8_t		 sync_state; /* PFSYNC_S_x */
750
750
751
	/* XXX */
751
	/* XXX */
752
	u_int8_t		 sync_updates;
752
	u_int8_t		 sync_updates;
753
	u_int8_t		_tail[3];
753
	u_int8_t		 rt;
754
	u_int8_t		_tail[2];
754
};
755
};
755
756
756
/*
757
/*
757
 * Unified state structures for pulling states out of the kernel
758
 * Unified state structures for pulling states out of the kernel
758
 * used by pfsync(4) and the pf(4) ioctl.
759
 * used by pfsync(4) and the pf(4) ioctl.
759
 */
760
 */
760
struct pfsync_state_scrub {
761
struct pfsync_state_scrub {
761
	u_int16_t	pfss_flags;
762
	u_int16_t	pfss_flags;
762
	u_int8_t	pfss_ttl;	/* stashed TTL		*/
763
	u_int8_t	pfss_ttl;	/* stashed TTL		*/
763
#define PFSYNC_SCRUB_FLAG_VALID		0x01
764
#define PFSYNC_SCRUB_FLAG_VALID		0x01
Lines 793-813 struct pfsync_state { Link Here
793
	u_int32_t	 anchor;
794
	u_int32_t	 anchor;
794
	u_int32_t	 nat_rule;
795
	u_int32_t	 nat_rule;
795
	u_int32_t	 creation;
796
	u_int32_t	 creation;
796
	u_int32_t	 expire;
797
	u_int32_t	 expire;
797
	u_int32_t	 packets[2][2];
798
	u_int32_t	 packets[2][2];
798
	u_int32_t	 bytes[2][2];
799
	u_int32_t	 bytes[2][2];
799
	u_int32_t	 creatorid;
800
	u_int32_t	 creatorid;
800
	sa_family_t	 af;
801
	sa_family_t	 af;
801
	u_int8_t	 proto;
802
	u_int8_t	 proto;
802
	u_int8_t	 direction;
803
	u_int8_t	 direction;
803
	u_int8_t	 __spare[2];
804
	u_int8_t	 rt;
805
	u_int8_t	 __spare[1];
804
	u_int8_t	 log;
806
	u_int8_t	 log;
805
	u_int8_t	 state_flags;
807
	u_int8_t	 state_flags;
806
	u_int8_t	 timeout;
808
	u_int8_t	 timeout;
807
	u_int8_t	 sync_flags;
809
	u_int8_t	 sync_flags;
808
	u_int8_t	 updates;
810
	u_int8_t	 updates;
809
} __packed;
811
} __packed;
810
812
811
#ifdef _KERNEL
813
#ifdef _KERNEL
812
/* pfsync */
814
/* pfsync */
813
typedef int		pfsync_state_import_t(struct pfsync_state *, u_int8_t);
815
typedef int		pfsync_state_import_t(struct pfsync_state *, u_int8_t);
(-)b/sys/netpfil/pf/if_pfsync.c (+32 lines)
Lines 92-111 __FBSDID("$FreeBSD$"); Link Here
92
#include <netinet/if_ether.h>
92
#include <netinet/if_ether.h>
93
#include <netinet/in.h>
93
#include <netinet/in.h>
94
#include <netinet/in_var.h>
94
#include <netinet/in_var.h>
95
#include <netinet/ip.h>
95
#include <netinet/ip.h>
96
#include <netinet/ip_carp.h>
96
#include <netinet/ip_carp.h>
97
#include <netinet/ip_var.h>
97
#include <netinet/ip_var.h>
98
#include <netinet/tcp.h>
98
#include <netinet/tcp.h>
99
#include <netinet/tcp_fsm.h>
99
#include <netinet/tcp_fsm.h>
100
#include <netinet/tcp_seq.h>
100
#include <netinet/tcp_seq.h>
101
101
102
#ifdef INET
103
#include <netinet/in_fib.h>
104
#endif
105
#ifdef INET6
106
#include <netinet6/in6_fib.h>
107
#endif
108
102
#define PFSYNC_MINPKT ( \
109
#define PFSYNC_MINPKT ( \
103
	sizeof(struct ip) + \
110
	sizeof(struct ip) + \
104
	sizeof(struct pfsync_header) + \
111
	sizeof(struct pfsync_header) + \
105
	sizeof(struct pfsync_subheader) )
112
	sizeof(struct pfsync_subheader) )
106
113
107
struct pfsync_pkt {
114
struct pfsync_pkt {
108
	struct ip *ip;
115
	struct ip *ip;
109
	struct in_addr src;
116
	struct in_addr src;
110
	u_int8_t flags;
117
	u_int8_t flags;
111
};
118
};
Lines 405-424 pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) Link Here
405
	struct pfsync_softc *sc = V_pfsyncif;
412
	struct pfsync_softc *sc = V_pfsyncif;
406
#ifndef	__NO_STRICT_ALIGNMENT
413
#ifndef	__NO_STRICT_ALIGNMENT
407
	struct pfsync_state_key key[2];
414
	struct pfsync_state_key key[2];
408
#endif
415
#endif
409
	struct pfsync_state_key *kw, *ks;
416
	struct pfsync_state_key *kw, *ks;
410
	struct pf_state	*st = NULL;
417
	struct pf_state	*st = NULL;
411
	struct pf_state_key *skw = NULL, *sks = NULL;
418
	struct pf_state_key *skw = NULL, *sks = NULL;
412
	struct pf_rule *r = NULL;
419
	struct pf_rule *r = NULL;
413
	struct pfi_kif	*kif;
420
	struct pfi_kif	*kif;
414
	int error;
421
	int error;
422
#ifdef INET
423
	struct nhop4_basic nh4;
424
#endif
425
#ifdef INET6
426
	struct nhop6_basic nh6;
427
#endif
415
428
416
	PF_RULES_RASSERT();
429
	PF_RULES_RASSERT();
417
430
418
	if (sp->creatorid == 0) {
431
	if (sp->creatorid == 0) {
419
		if (V_pf_status.debug >= PF_DEBUG_MISC)
432
		if (V_pf_status.debug >= PF_DEBUG_MISC)
420
			printf("%s: invalid creator id: %08x\n", __func__,
433
			printf("%s: invalid creator id: %08x\n", __func__,
421
			    ntohl(sp->creatorid));
434
			    ntohl(sp->creatorid));
422
		return (EINVAL);
435
		return (EINVAL);
423
	}
436
	}
424
437
Lines 508-538 pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) Link Here
508
			timeout = V_pf_default_rule.timeout[sp->timeout];
521
			timeout = V_pf_default_rule.timeout[sp->timeout];
509
522
510
		/* sp->expire may have been adaptively scaled by export. */
523
		/* sp->expire may have been adaptively scaled by export. */
511
		st->expire -= timeout - ntohl(sp->expire);
524
		st->expire -= timeout - ntohl(sp->expire);
512
	}
525
	}
513
526
514
	st->direction = sp->direction;
527
	st->direction = sp->direction;
515
	st->log = sp->log;
528
	st->log = sp->log;
516
	st->timeout = sp->timeout;
529
	st->timeout = sp->timeout;
517
	st->state_flags = sp->state_flags;
530
	st->state_flags = sp->state_flags;
531
	st->rt = sp->rt;
518
532
519
	st->id = sp->id;
533
	st->id = sp->id;
520
	st->creatorid = sp->creatorid;
534
	st->creatorid = sp->creatorid;
521
	pf_state_peer_ntoh(&sp->src, &st->src);
535
	pf_state_peer_ntoh(&sp->src, &st->src);
522
	pf_state_peer_ntoh(&sp->dst, &st->dst);
536
	pf_state_peer_ntoh(&sp->dst, &st->dst);
523
537
524
	st->rule.ptr = r;
538
	st->rule.ptr = r;
525
	st->nat_rule.ptr = NULL;
539
	st->nat_rule.ptr = NULL;
526
	st->anchor.ptr = NULL;
540
	st->anchor.ptr = NULL;
527
	st->rt_kif = NULL;
541
	st->rt_kif = NULL;
528
542
543
	if (st->rt) {
544
		/* Do our best to reconstruct original route-to interface. */
545
		switch (sp->af) {
546
#ifdef INET
547
			case AF_INET:
548
			fib4_lookup_nh_basic(0, st->rt_addr.v4, 0, 0, &nh4);
549
			st->rt_kif = pfi_kif_find(nh4.nh_ifp->if_xname);
550
			break;
551
#endif
552
#ifdef INET6
553
			case AF_INET6:
554
			fib6_lookup_nh_basic(0, &(st->rt_addr.v6), 0, 0, 0, &nh6);
555
			st->rt_kif = pfi_kif_find(nh6.nh_ifp->if_xname);
556
			break;
557
#endif
558
		}
559
	}
560
529
	st->pfsync_time = time_uptime;
561
	st->pfsync_time = time_uptime;
530
	st->sync_state = PFSYNC_S_NONE;
562
	st->sync_state = PFSYNC_S_NONE;
531
563
532
	if (!(flags & PFSYNC_SI_IOCTL))
564
	if (!(flags & PFSYNC_SI_IOCTL))
533
		st->state_flags |= PFSTATE_NOSYNC;
565
		st->state_flags |= PFSTATE_NOSYNC;
534
566
535
	if ((error = pf_state_insert(kif, skw, sks, st)) != 0)
567
	if ((error = pf_state_insert(kif, skw, sks, st)) != 0)
536
		goto cleanup_state;
568
		goto cleanup_state;
537
569
538
	/* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
570
	/* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
(-)b/sys/netpfil/pf/pf.c (-24 / +47 lines)
Lines 3704-3723 pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, Link Here
3704
3704
3705
	if (r->rt) {
3705
	if (r->rt) {
3706
		if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) {
3706
		if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) {
3707
			REASON_SET(&reason, PFRES_MAPFAILED);
3707
			REASON_SET(&reason, PFRES_MAPFAILED);
3708
			pf_src_tree_remove_state(s);
3708
			pf_src_tree_remove_state(s);
3709
			STATE_DEC_COUNTERS(s);
3709
			STATE_DEC_COUNTERS(s);
3710
			uma_zfree(V_pf_state_z, s);
3710
			uma_zfree(V_pf_state_z, s);
3711
			goto csfailed;
3711
			goto csfailed;
3712
		}
3712
		}
3713
		s->rt_kif = r->rpool.cur->kif;
3713
		s->rt_kif = r->rpool.cur->kif;
3714
		s->rt = r->rt;
3714
	}
3715
	}
3715
3716
3716
	s->creation = time_uptime;
3717
	s->creation = time_uptime;
3717
	s->expire = time_uptime;
3718
	s->expire = time_uptime;
3718
3719
3719
	if (sn != NULL)
3720
	if (sn != NULL)
3720
		s->src_node = sn;
3721
		s->src_node = sn;
3721
	if (nsn != NULL) {
3722
	if (nsn != NULL) {
3722
		/* XXX We only modify one side for now. */
3723
		/* XXX We only modify one side for now. */
3723
		PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af);
3724
		PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af);
Lines 5456-5529 pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif, Link Here
5456
		return (0);
5457
		return (0);
5457
5458
5458
	/* Perform uRPF check if passed input interface */
5459
	/* Perform uRPF check if passed input interface */
5459
	if (kif->pfik_ifp == ifp)
5460
	if (kif->pfik_ifp == ifp)
5460
		return (1);
5461
		return (1);
5461
	return (0);
5462
	return (0);
5462
}
5463
}
5463
5464
5464
#ifdef INET
5465
#ifdef INET
5465
static void
5466
static void
5466
pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5467
pf_route(struct mbuf **m, struct pf_rule * r, int p_dir, struct ifnet *oifp,
5467
    struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp)
5468
    struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp)
5468
{
5469
{
5469
	struct mbuf		*m0, *m1;
5470
	struct mbuf		*m0, *m1;
5470
	struct sockaddr_in	dst;
5471
	struct sockaddr_in	dst;
5471
	struct ip		*ip;
5472
	struct ip		*ip;
5472
	struct ifnet		*ifp = NULL;
5473
	struct ifnet		*ifp = NULL;
5473
	struct pf_addr		 naddr;
5474
	struct pf_addr		 naddr;
5474
	struct pf_src_node	*sn = NULL;
5475
	struct pf_src_node	*sn = NULL;
5475
	int			 error = 0;
5476
	int			 error = 0;
5476
	uint16_t		 ip_len, ip_off;
5477
	uint16_t		 ip_len, ip_off;
5478
	int			 r_rt, r_dir;
5477
5479
5478
	KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
5480
	KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
5479
	KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
5481
5482
	if (s) {
5483
		r_rt = s->rt;
5484
		r_dir = s->direction;
5485
	} else {
5486
		r_rt = r->rt;
5487
		r_dir = r->direction;
5488
	}
5489
5490
	KASSERT(p_dir == PF_IN || p_dir == PF_OUT ||
5491
	    r_dir = PF_IN || r_dir == PF_OUT, ("%s: invalid direction",
5480
	    __func__));
5492
	    __func__));
5481
5493
5482
	if ((pd->pf_mtag == NULL &&
5494
	if ((pd->pf_mtag == NULL &&
5483
	    ((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) ||
5495
	    ((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) ||
5484
	    pd->pf_mtag->routed++ > 3) {
5496
	    pd->pf_mtag->routed++ > 3) {
5485
		m0 = *m;
5497
		m0 = *m;
5486
		*m = NULL;
5498
		*m = NULL;
5487
		goto bad_locked;
5499
		goto bad_locked;
5488
	}
5500
	}
5489
5501
5490
	if (r->rt == PF_DUPTO) {
5502
	if (r_rt == PF_DUPTO) {
5491
		if ((m0 = m_dup(*m, M_NOWAIT)) == NULL) {
5503
		if ((m0 = m_dup(*m, M_NOWAIT)) == NULL) {
5492
			if (s)
5504
			if (s)
5493
				PF_STATE_UNLOCK(s);
5505
				PF_STATE_UNLOCK(s);
5494
			return;
5506
			return;
5495
		}
5507
		}
5496
	} else {
5508
	} else {
5497
		if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
5509
		if ((r_rt == PF_REPLYTO) == (r_dir == p_dir)) {
5498
			if (s)
5510
			if (s)
5499
				PF_STATE_UNLOCK(s);
5511
				PF_STATE_UNLOCK(s);
5500
			return;
5512
			return;
5501
		}
5513
		}
5502
		m0 = *m;
5514
		m0 = *m;
5503
	}
5515
	}
5504
5516
5505
	ip = mtod(m0, struct ip *);
5517
	ip = mtod(m0, struct ip *);
5506
5518
5507
	bzero(&dst, sizeof(dst));
5519
	bzero(&dst, sizeof(dst));
5508
	dst.sin_family = AF_INET;
5520
	dst.sin_family = AF_INET;
5509
	dst.sin_len = sizeof(dst);
5521
	dst.sin_len = sizeof(dst);
5510
	dst.sin_addr = ip->ip_dst;
5522
	dst.sin_addr = ip->ip_dst;
5511
5523
5512
	bzero(&naddr, sizeof(naddr));
5524
	bzero(&naddr, sizeof(naddr));
5513
5525
5514
	if (TAILQ_EMPTY(&r->rpool.list)) {
5515
		DPFPRINTF(PF_DEBUG_URGENT,
5516
		    ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
5517
		goto bad_locked;
5518
	}
5519
	if (s == NULL) {
5526
	if (s == NULL) {
5527
		if (TAILQ_EMPTY(&r->rpool.list)) {
5528
			DPFPRINTF(PF_DEBUG_URGENT,
5529
			    ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
5530
			goto bad_locked;
5531
		}
5520
		pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
5532
		pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
5521
		    &naddr, NULL, &sn);
5533
		    &naddr, NULL, &sn);
5522
		if (!PF_AZERO(&naddr, AF_INET))
5534
		if (!PF_AZERO(&naddr, AF_INET))
5523
			dst.sin_addr.s_addr = naddr.v4.s_addr;
5535
			dst.sin_addr.s_addr = naddr.v4.s_addr;
5524
		ifp = r->rpool.cur->kif ?
5536
		ifp = r->rpool.cur->kif ?
5525
		    r->rpool.cur->kif->pfik_ifp : NULL;
5537
		    r->rpool.cur->kif->pfik_ifp : NULL;
5526
	} else {
5538
	} else {
5527
		if (!PF_AZERO(&s->rt_addr, AF_INET))
5539
		if (!PF_AZERO(&s->rt_addr, AF_INET))
5528
			dst.sin_addr.s_addr =
5540
			dst.sin_addr.s_addr =
5529
			    s->rt_addr.v4.s_addr;
5541
			    s->rt_addr.v4.s_addr;
Lines 5578-5598 pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, Link Here
5578
		}
5590
		}
5579
		m_clrprotoflags(m0);	/* Avoid confusing lower layers. */
5591
		m_clrprotoflags(m0);	/* Avoid confusing lower layers. */
5580
		error = (*ifp->if_output)(ifp, m0, sintosa(&dst), NULL);
5592
		error = (*ifp->if_output)(ifp, m0, sintosa(&dst), NULL);
5581
		goto done;
5593
		goto done;
5582
	}
5594
	}
5583
5595
5584
	/* Balk when DF bit is set or the interface didn't support TSO. */
5596
	/* Balk when DF bit is set or the interface didn't support TSO. */
5585
	if ((ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) {
5597
	if ((ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) {
5586
		error = EMSGSIZE;
5598
		error = EMSGSIZE;
5587
		KMOD_IPSTAT_INC(ips_cantfrag);
5599
		KMOD_IPSTAT_INC(ips_cantfrag);
5588
		if (r->rt != PF_DUPTO) {
5600
		if (r_rt != PF_DUPTO) {
5589
			icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5601
			icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
5590
			    ifp->if_mtu);
5602
			    ifp->if_mtu);
5591
			goto done;
5603
			goto done;
5592
		} else
5604
		} else
5593
			goto bad;
5605
			goto bad;
5594
	}
5606
	}
5595
5607
5596
	error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist);
5608
	error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist);
5597
	if (error)
5609
	if (error)
5598
		goto bad;
5610
		goto bad;
Lines 5604-5690 pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, Link Here
5604
			m_clrprotoflags(m0);
5616
			m_clrprotoflags(m0);
5605
			error = (*ifp->if_output)(ifp, m0, sintosa(&dst), NULL);
5617
			error = (*ifp->if_output)(ifp, m0, sintosa(&dst), NULL);
5606
		} else
5618
		} else
5607
			m_freem(m0);
5619
			m_freem(m0);
5608
	}
5620
	}
5609
5621
5610
	if (error == 0)
5622
	if (error == 0)
5611
		KMOD_IPSTAT_INC(ips_fragmented);
5623
		KMOD_IPSTAT_INC(ips_fragmented);
5612
5624
5613
done:
5625
done:
5614
	if (r->rt != PF_DUPTO)
5626
	if (r_rt != PF_DUPTO)
5615
		*m = NULL;
5627
		*m = NULL;
5616
	return;
5628
	return;
5617
5629
5618
bad_locked:
5630
bad_locked:
5619
	if (s)
5631
	if (s)
5620
		PF_STATE_UNLOCK(s);
5632
		PF_STATE_UNLOCK(s);
5621
bad:
5633
bad:
5622
	m_freem(m0);
5634
	m_freem(m0);
5623
	goto done;
5635
	goto done;
5624
}
5636
}
5625
#endif /* INET */
5637
#endif /* INET */
5626
5638
5627
#ifdef INET6
5639
#ifdef INET6
5628
static void
5640
static void
5629
pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
5641
pf_route6(struct mbuf **m, struct pf_rule * r, int p_dir, struct ifnet *oifp,
5630
    struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp)
5642
    struct pf_state *s, struct pf_pdesc *pd, struct inpcb *inp)
5631
{
5643
{
5632
	struct mbuf		*m0;
5644
	struct mbuf		*m0;
5633
	struct sockaddr_in6	dst;
5645
	struct sockaddr_in6	dst;
5634
	struct ip6_hdr		*ip6;
5646
	struct ip6_hdr		*ip6;
5635
	struct ifnet		*ifp = NULL;
5647
	struct ifnet		*ifp = NULL;
5636
	struct pf_addr		 naddr;
5648
	struct pf_addr		 naddr;
5637
	struct pf_src_node	*sn = NULL;
5649
	struct pf_src_node	*sn = NULL;
5650
	int 			 r_rt, r_dir;
5638
5651
5639
	KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
5652
	KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
5640
	KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
5653
5654
	if (s) {
5655
		r_rt = s->rt;
5656
		r_dir = s->direction;
5657
	} else {
5658
		r_rt = r->rt;
5659
		r_dir = r->direction;
5660
	}
5661
5662
	KASSERT(p_dir == PF_IN || p_dir == PF_OUT ||
5663
	    r_dir == PF_IN || r_dir == PF_OUT, ("%s: invalid direction",
5641
	    __func__));
5664
	    __func__));
5642
5665
5643
	if ((pd->pf_mtag == NULL &&
5666
	if ((pd->pf_mtag == NULL &&
5644
	    ((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) ||
5667
	    ((pd->pf_mtag = pf_get_mtag(*m)) == NULL)) ||
5645
	    pd->pf_mtag->routed++ > 3) {
5668
	    pd->pf_mtag->routed++ > 3) {
5646
		m0 = *m;
5669
		m0 = *m;
5647
		*m = NULL;
5670
		*m = NULL;
5648
		goto bad_locked;
5671
		goto bad_locked;
5649
	}
5672
	}
5650
5673
5651
	if (r->rt == PF_DUPTO) {
5674
	if (r_rt == PF_DUPTO) {
5652
		if ((m0 = m_dup(*m, M_NOWAIT)) == NULL) {
5675
		if ((m0 = m_dup(*m, M_NOWAIT)) == NULL) {
5653
			if (s)
5676
			if (s)
5654
				PF_STATE_UNLOCK(s);
5677
				PF_STATE_UNLOCK(s);
5655
			return;
5678
			return;
5656
		}
5679
		}
5657
	} else {
5680
	} else {
5658
		if ((r->rt == PF_REPLYTO) == (r->direction == dir)) {
5681
		if ((r_rt == PF_REPLYTO) == (r_dir == p_dir)) {
5659
			if (s)
5682
			if (s)
5660
				PF_STATE_UNLOCK(s);
5683
				PF_STATE_UNLOCK(s);
5661
			return;
5684
			return;
5662
		}
5685
		}
5663
		m0 = *m;
5686
		m0 = *m;
5664
	}
5687
	}
5665
5688
5666
	ip6 = mtod(m0, struct ip6_hdr *);
5689
	ip6 = mtod(m0, struct ip6_hdr *);
5667
5690
5668
	bzero(&dst, sizeof(dst));
5691
	bzero(&dst, sizeof(dst));
5669
	dst.sin6_family = AF_INET6;
5692
	dst.sin6_family = AF_INET6;
5670
	dst.sin6_len = sizeof(dst);
5693
	dst.sin6_len = sizeof(dst);
5671
	dst.sin6_addr = ip6->ip6_dst;
5694
	dst.sin6_addr = ip6->ip6_dst;
5672
5695
5673
	bzero(&naddr, sizeof(naddr));
5696
	bzero(&naddr, sizeof(naddr));
5674
5697
5675
	if (TAILQ_EMPTY(&r->rpool.list)) {
5676
		DPFPRINTF(PF_DEBUG_URGENT,
5677
		    ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
5678
		goto bad_locked;
5679
	}
5680
	if (s == NULL) {
5698
	if (s == NULL) {
5699
		if (TAILQ_EMPTY(&r->rpool.list)) {
5700
			DPFPRINTF(PF_DEBUG_URGENT,
5701
			    ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__));
5702
			goto bad_locked;
5703
		}
5681
		pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
5704
		pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
5682
		    &naddr, NULL, &sn);
5705
		    &naddr, NULL, &sn);
5683
		if (!PF_AZERO(&naddr, AF_INET6))
5706
		if (!PF_AZERO(&naddr, AF_INET6))
5684
			PF_ACPY((struct pf_addr *)&dst.sin6_addr,
5707
			PF_ACPY((struct pf_addr *)&dst.sin6_addr,
5685
			    &naddr, AF_INET6);
5708
			    &naddr, AF_INET6);
5686
		ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
5709
		ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
5687
	} else {
5710
	} else {
5688
		if (!PF_AZERO(&s->rt_addr, AF_INET6))
5711
		if (!PF_AZERO(&s->rt_addr, AF_INET6))
5689
			PF_ACPY((struct pf_addr *)&dst.sin6_addr,
5712
			PF_ACPY((struct pf_addr *)&dst.sin6_addr,
5690
			    &s->rt_addr, AF_INET6);
5713
			    &s->rt_addr, AF_INET6);
Lines 5724-5751 pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, Link Here
5724
	/*
5747
	/*
5725
	 * If the packet is too large for the outgoing interface,
5748
	 * If the packet is too large for the outgoing interface,
5726
	 * send back an icmp6 error.
5749
	 * send back an icmp6 error.
5727
	 */
5750
	 */
5728
	if (IN6_IS_SCOPE_EMBED(&dst.sin6_addr))
5751
	if (IN6_IS_SCOPE_EMBED(&dst.sin6_addr))
5729
		dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
5752
		dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
5730
	if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu)
5753
	if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu)
5731
		nd6_output_ifp(ifp, ifp, m0, &dst, NULL);
5754
		nd6_output_ifp(ifp, ifp, m0, &dst, NULL);
5732
	else {
5755
	else {
5733
		in6_ifstat_inc(ifp, ifs6_in_toobig);
5756
		in6_ifstat_inc(ifp, ifs6_in_toobig);
5734
		if (r->rt != PF_DUPTO)
5757
		if (r_rt != PF_DUPTO)
5735
			icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
5758
			icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
5736
		else
5759
		else
5737
			goto bad;
5760
			goto bad;
5738
	}
5761
	}
5739
5762
5740
done:
5763
done:
5741
	if (r->rt != PF_DUPTO)
5764
	if (r_rt != PF_DUPTO)
5742
		*m = NULL;
5765
		*m = NULL;
5743
	return;
5766
	return;
5744
5767
5745
bad_locked:
5768
bad_locked:
5746
	if (s)
5769
	if (s)
5747
		PF_STATE_UNLOCK(s);
5770
		PF_STATE_UNLOCK(s);
5748
bad:
5771
bad:
5749
	m_freem(m0);
5772
	m_freem(m0);
5750
	goto done;
5773
	goto done;
5751
}
5774
}
Lines 6253-6273 pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb * Link Here
6253
	case PF_DEFER:
6276
	case PF_DEFER:
6254
		*m0 = NULL;
6277
		*m0 = NULL;
6255
		action = PF_PASS;
6278
		action = PF_PASS;
6256
		break;
6279
		break;
6257
	case PF_DROP:
6280
	case PF_DROP:
6258
		m_freem(*m0);
6281
		m_freem(*m0);
6259
		*m0 = NULL;
6282
		*m0 = NULL;
6260
		break;
6283
		break;
6261
	default:
6284
	default:
6262
		/* pf_route() returns unlocked. */
6285
		/* pf_route() returns unlocked. */
6263
		if (r->rt) {
6286
		if (r->rt || (s != NULL && s->rt)) {
6264
			pf_route(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
6287
			pf_route(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
6265
			return (action);
6288
			return (action);
6266
		}
6289
		}
6267
		break;
6290
		break;
6268
	}
6291
	}
6269
	if (s)
6292
	if (s)
6270
		PF_STATE_UNLOCK(s);
6293
		PF_STATE_UNLOCK(s);
6271
6294
6272
	return (action);
6295
	return (action);
6273
}
6296
}
Lines 6649-6669 pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb Link Here
6649
	case PF_DEFER:
6672
	case PF_DEFER:
6650
		*m0 = NULL;
6673
		*m0 = NULL;
6651
		action = PF_PASS;
6674
		action = PF_PASS;
6652
		break;
6675
		break;
6653
	case PF_DROP:
6676
	case PF_DROP:
6654
		m_freem(*m0);
6677
		m_freem(*m0);
6655
		*m0 = NULL;
6678
		*m0 = NULL;
6656
		break;
6679
		break;
6657
	default:
6680
	default:
6658
		/* pf_route6() returns unlocked. */
6681
		/* pf_route6() returns unlocked. */
6659
		if (r->rt) {
6682
		if (r->rt || (s != NULL && s->rt)) {
6660
			pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
6683
			pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd, inp);
6661
			return (action);
6684
			return (action);
6662
		}
6685
		}
6663
		break;
6686
		break;
6664
	}
6687
	}
6665
6688
6666
	if (s)
6689
	if (s)
6667
		PF_STATE_UNLOCK(s);
6690
		PF_STATE_UNLOCK(s);
6668
6691
6669
	/* If reassembled packet passed, create new fragments. */
6692
	/* If reassembled packet passed, create new fragments. */
(-)b/sys/netpfil/pf/pf_ioctl.c (+1 lines)
Lines 3488-3507 pfsync_state_export(struct pfsync_state *sp, struct pf_state *st) Link Here
3488
	sp->expire = pf_state_expires(st);
3488
	sp->expire = pf_state_expires(st);
3489
	if (sp->expire <= time_uptime)
3489
	if (sp->expire <= time_uptime)
3490
		sp->expire = htonl(0);
3490
		sp->expire = htonl(0);
3491
	else
3491
	else
3492
		sp->expire = htonl(sp->expire - time_uptime);
3492
		sp->expire = htonl(sp->expire - time_uptime);
3493
3493
3494
	sp->direction = st->direction;
3494
	sp->direction = st->direction;
3495
	sp->log = st->log;
3495
	sp->log = st->log;
3496
	sp->timeout = st->timeout;
3496
	sp->timeout = st->timeout;
3497
	sp->state_flags = st->state_flags;
3497
	sp->state_flags = st->state_flags;
3498
	sp->rt = st->rt;
3498
	if (st->src_node)
3499
	if (st->src_node)
3499
		sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
3500
		sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
3500
	if (st->nat_src_node)
3501
	if (st->nat_src_node)
3501
		sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
3502
		sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
3502
3503
3503
	sp->id = st->id;
3504
	sp->id = st->id;
3504
	sp->creatorid = st->creatorid;
3505
	sp->creatorid = st->creatorid;
3505
	pf_state_peer_hton(&st->src, &sp->src);
3506
	pf_state_peer_hton(&st->src, &sp->src);
3506
	pf_state_peer_hton(&st->dst, &sp->dst);
3507
	pf_state_peer_hton(&st->dst, &sp->dst);
3507
3508

Return to bug 229092