Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Apr 2018 15:22:28 +0000 (UTC)
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r332513 - in stable/11: share/man/man9 sys/net sys/netinet sys/netinet6 sys/netpfil/pf
Message-ID:  <201804151522.w3FFMSft042609@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kp
Date: Sun Apr 15 15:22:28 2018
New Revision: 332513
URL: https://svnweb.freebsd.org/changeset/base/332513

Log:
  MFC r331436:
  
  netpfil: Introduce PFIL_FWD flag
  
  Forwarded packets passed through PFIL_OUT, which made it difficult for
  firewalls to figure out if they were forwarding or producing packets. This in
  turn is an issue for pf for IPv6 fragment handling: it needs to call
  ip6_output() or ip6_forward() to handle the fragments. Figuring out which was
  difficult (and until now, incorrect).
  Having pfil distinguish the two removes an ugly piece of code from pf.
  
  Introduce a new variant of the netpfil callbacks with a flags variable, which
  has PFIL_FWD set for forwarded packets. This allows pf to reliably work out if
  a packet is forwarded.

Modified:
  stable/11/share/man/man9/pfil.9
  stable/11/sys/net/if_bridge.c
  stable/11/sys/net/if_enc.c
  stable/11/sys/net/if_ethersubr.c
  stable/11/sys/net/pfil.c
  stable/11/sys/net/pfil.h
  stable/11/sys/net/pfvar.h
  stable/11/sys/netinet/ip_fastfwd.c
  stable/11/sys/netinet/ip_input.c
  stable/11/sys/netinet/ip_output.c
  stable/11/sys/netinet6/ip6_fastfwd.c
  stable/11/sys/netinet6/ip6_forward.c
  stable/11/sys/netinet6/ip6_input.c
  stable/11/sys/netinet6/ip6_output.c
  stable/11/sys/netpfil/pf/pf.c
  stable/11/sys/netpfil/pf/pf.h
  stable/11/sys/netpfil/pf/pf_ioctl.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/share/man/man9/pfil.9
==============================================================================
--- stable/11/share/man/man9/pfil.9	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/share/man/man9/pfil.9	Sun Apr 15 15:22:28 2018	(r332513)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 23, 2013
+.Dd April 15, 2018
 .Dt PFIL 9
 .Os
 .Sh NAME
@@ -37,7 +37,9 @@
 .Nm pfil_head_unregister ,
 .Nm pfil_head_get ,
 .Nm pfil_add_hook ,
+.Nm pfil_add_hook_flags ,
 .Nm pfil_remove_hook ,
+.Nm pfil_remove_hook_flags ,
 .Nm pfil_run_hooks ,
 .Nm pfil_rlock ,
 .Nm pfil_runlock ,
@@ -51,6 +53,8 @@
 .In net/pfil.h
 .Bd -literal
 typedef int (*pfil_func_t)(void *arg, struct mbuf **mp, struct ifnet *, int dir, struct inpcb);
+.Bd -literal
+typedef int (*pfil_func_flags_t)(void *arg, struct mbuf **mp, struct ifnet *, int dir, int flags, struct inpcb);
 .Ft int
 .Fn pfil_head_register "struct pfil_head *head"
 .Ft int
@@ -58,11 +62,15 @@ typedef int (*pfil_func_t)(void *arg, struct mbuf **mp
 .Ft "struct pfil_head *"
 .Fn pfil_head_get "int af" "u_long dlt"
 .Ft void
-.Fn pfil_add_hook "pfil_func_t" "void *arg" "int flags" "struct pfil_head *"
+.Fn pfil_add_hook "pfil_func_t" "void *arg" "struct pfil_head *"
 .Ft void
-.Fn pfil_remove_hook "pfil_func_t" "void *arg" "int flags" "struct pfil_head *"
+.Fn pfil_add_hook_flags "pfil_func_flags_t" "void *arg" "int flags" "struct pfil_head *"
 .Ft int
-.Fn pfil_run_hooks "struct pfil_head *head" "struct mbuf **mp" "struct ifnet *" "int dir" "struct inpcb *"
+.Fn pfil_remove_hook "pfil_func_t" "void *arg" "struct pfil_head *"
+.Ft int
+.Fn pfil_remove_hook_flags "pfil_func_flags_t" "void *arg" "int flags" "struct pfil_head *"
+.Ft int
+.Fn pfil_run_hooks "struct pfil_head *head" "struct mbuf **mp" "struct ifnet *" "int dir" "int flags" "struct inpcb *"
 .Ft void
 .Fn pfil_rlock "struct pfil_head *" "struct rm_priotracker *"
 .Ft void
@@ -116,6 +124,7 @@ with the
 and
 .Fn pfil_remove_hook
 functions, respectively.
+.I
 The head is looked up using the
 .Fn pfil_head_get
 function, which takes the key and data link type that the packet filter
@@ -135,6 +144,10 @@ interface that the packet is traversing, and the direc
 or
 .Dv PFIL_OUT )
 that the packet is traveling.
+The
+.Vt flags
+argument will indicate if an outgoing packet is simply being forwarded with the
+value PFIL_FWD.
 The filter may change which mbuf the
 .Vt "mbuf\ **"
 argument references.

Modified: stable/11/sys/net/if_bridge.c
==============================================================================
--- stable/11/sys/net/if_bridge.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/net/if_bridge.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -3170,7 +3170,8 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, stru
 	if (PFIL_HOOKED(&V_link_pfil_hook) && V_pfil_ipfw != 0 &&
 			dir == PFIL_OUT && ifp != NULL) {
 
-		error = pfil_run_hooks(&V_link_pfil_hook, mp, ifp, dir, NULL);
+		error = pfil_run_hooks(&V_link_pfil_hook, mp, ifp, dir, 0,
+		    NULL);
 
 		if (*mp == NULL || error != 0) /* packet consumed by filter */
 			return (error);
@@ -3222,21 +3223,21 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, stru
 		 */
 		if (V_pfil_bridge && dir == PFIL_OUT && bifp != NULL)
 			error = pfil_run_hooks(&V_inet_pfil_hook, mp, bifp,
-					dir, NULL);
+					dir, 0, NULL);
 
 		if (*mp == NULL || error != 0) /* filter may consume */
 			break;
 
 		if (V_pfil_member && ifp != NULL)
 			error = pfil_run_hooks(&V_inet_pfil_hook, mp, ifp,
-					dir, NULL);
+					dir, 0, NULL);
 
 		if (*mp == NULL || error != 0) /* filter may consume */
 			break;
 
 		if (V_pfil_bridge && dir == PFIL_IN && bifp != NULL)
 			error = pfil_run_hooks(&V_inet_pfil_hook, mp, bifp,
-					dir, NULL);
+					dir, 0, NULL);
 
 		if (*mp == NULL || error != 0) /* filter may consume */
 			break;
@@ -3276,21 +3277,21 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, stru
 	case ETHERTYPE_IPV6:
 		if (V_pfil_bridge && dir == PFIL_OUT && bifp != NULL)
 			error = pfil_run_hooks(&V_inet6_pfil_hook, mp, bifp,
-					dir, NULL);
+					dir, 0, NULL);
 
 		if (*mp == NULL || error != 0) /* filter may consume */
 			break;
 
 		if (V_pfil_member && ifp != NULL)
 			error = pfil_run_hooks(&V_inet6_pfil_hook, mp, ifp,
-					dir, NULL);
+					dir, 0, NULL);
 
 		if (*mp == NULL || error != 0) /* filter may consume */
 			break;
 
 		if (V_pfil_bridge && dir == PFIL_IN && bifp != NULL)
 			error = pfil_run_hooks(&V_inet6_pfil_hook, mp, bifp,
-					dir, NULL);
+					dir, 0, NULL);
 		break;
 #endif
 	default:

Modified: stable/11/sys/net/if_enc.c
==============================================================================
--- stable/11/sys/net/if_enc.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/net/if_enc.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -299,7 +299,7 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, void *
 	/* Make a packet looks like it was received on enc(4) */
 	rcvif = (*ctx->mp)->m_pkthdr.rcvif;
 	(*ctx->mp)->m_pkthdr.rcvif = ifp;
-	if (pfil_run_hooks(ph, ctx->mp, ifp, pdir, ctx->inp) != 0 ||
+	if (pfil_run_hooks(ph, ctx->mp, ifp, pdir, 0, ctx->inp) != 0 ||
 	    *ctx->mp == NULL) {
 		*ctx->mp = NULL; /* consumed by filter */
 		return (EACCES);

Modified: stable/11/sys/net/if_ethersubr.c
==============================================================================
--- stable/11/sys/net/if_ethersubr.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/net/if_ethersubr.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -445,7 +445,8 @@ ether_output_frame(struct ifnet *ifp, struct mbuf *m)
 	int i;
 
 	if (PFIL_HOOKED(&V_link_pfil_hook)) {
-		i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_OUT, NULL);
+		i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_OUT, 0,
+		    NULL);
 
 		if (i != 0)
 			return (EACCES);
@@ -778,7 +779,8 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
 
 	/* Do not grab PROMISC frames in case we are re-entered. */
 	if (PFIL_HOOKED(&V_link_pfil_hook) && !(m->m_flags & M_PROMISC)) {
-		i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_IN, NULL);
+		i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_IN, 0,
+		    NULL);
 
 		if (i != 0 || m == NULL)
 			return;

Modified: stable/11/sys/net/pfil.c
==============================================================================
--- stable/11/sys/net/pfil.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/net/pfil.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -55,7 +55,8 @@ MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_
 
 static struct packet_filter_hook *pfil_chain_get(int, struct pfil_head *);
 static int pfil_chain_add(pfil_chain_t *, struct packet_filter_hook *, int);
-static int pfil_chain_remove(pfil_chain_t *, pfil_func_t, void *);
+static int pfil_chain_remove(pfil_chain_t *, void *, void *);
+static int pfil_add_hook_priv(void *, void *, int, struct pfil_head *, bool);
 
 LIST_HEAD(pfilheadhead, pfil_head);
 VNET_DEFINE(struct pfilheadhead, pfil_head_list);
@@ -93,7 +94,7 @@ VNET_DEFINE(struct rmlock, pfil_lock);
  */
 int
 pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
-    int dir, struct inpcb *inp)
+    int dir, int flags, struct inpcb *inp)
 {
 	struct rm_priotracker rmpt;
 	struct packet_filter_hook *pfh;
@@ -104,6 +105,12 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp,
 	KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0"));
 	for (pfh = pfil_chain_get(dir, ph); pfh != NULL;
 	     pfh = TAILQ_NEXT(pfh, pfil_chain)) {
+		if (pfh->pfil_func_flags != NULL) {
+			rv = (*pfh->pfil_func_flags)(pfh->pfil_arg, &m, ifp,
+			    dir, flags, inp);
+			if (rv != 0 || m == NULL)
+				break;
+		}
 		if (pfh->pfil_func != NULL) {
 			rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir,
 			    inp);
@@ -254,6 +261,21 @@ pfil_head_get(int type, u_long val)
 }
 
 /*
+ * pfil_add_hook_flags() adds a function to the packet filter hook.  the
+ * flags are:
+ *	PFIL_IN		call me on incoming packets
+ *	PFIL_OUT	call me on outgoing packets
+ *	PFIL_ALL	call me on all of the above
+ *	PFIL_WAITOK	OK to call malloc with M_WAITOK.
+ */
+int
+pfil_add_hook_flags(pfil_func_flags_t func, void *arg, int flags,
+    struct pfil_head *ph)
+{
+	return (pfil_add_hook_priv(func, arg, flags, ph, true));
+}
+
+/*
  * pfil_add_hook() adds a function to the packet filter hook.  the
  * flags are:
  *	PFIL_IN		call me on incoming packets
@@ -264,6 +286,13 @@ pfil_head_get(int type, u_long val)
 int
 pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
 {
+	return (pfil_add_hook_priv(func, arg, flags, ph, false));
+}
+
+static int
+pfil_add_hook_priv(void *func, void *arg, int flags,
+    struct pfil_head *ph, bool hasflags)
+{
 	struct packet_filter_hook *pfh1 = NULL;
 	struct packet_filter_hook *pfh2 = NULL;
 	int err;
@@ -286,7 +315,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, 
 	}
 	PFIL_WLOCK(ph);
 	if (flags & PFIL_IN) {
-		pfh1->pfil_func = func;
+		pfh1->pfil_func_flags = hasflags ? func : NULL;
+		pfh1->pfil_func = hasflags ? NULL : func;
 		pfh1->pfil_arg = arg;
 		err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT);
 		if (err)
@@ -294,7 +324,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, 
 		ph->ph_nhooks++;
 	}
 	if (flags & PFIL_OUT) {
-		pfh2->pfil_func = func;
+		pfh2->pfil_func_flags = hasflags ? func : NULL;
+		pfh2->pfil_func = hasflags ? NULL : func;
 		pfh2->pfil_arg = arg;
 		err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN);
 		if (err) {
@@ -317,6 +348,17 @@ error:
 }
 
 /*
+ * pfil_remove_hook_flags removes a specific function from the packet filter hook
+ * chain.
+ */
+int
+pfil_remove_hook_flags(pfil_func_flags_t func, void *arg, int flags,
+    struct pfil_head *ph)
+{
+	return (pfil_remove_hook((pfil_func_t)func, arg, flags, ph));
+}
+
+/*
  * pfil_remove_hook removes a specific function from the packet filter hook
  * chain.
  */
@@ -352,7 +394,9 @@ pfil_chain_add(pfil_chain_t *chain, struct packet_filt
 	 * First make sure the hook is not already there.
 	 */
 	TAILQ_FOREACH(pfh, chain, pfil_chain)
-		if (pfh->pfil_func == pfh1->pfil_func &&
+		if (((pfh->pfil_func != NULL && pfh->pfil_func == pfh1->pfil_func) ||
+		    (pfh->pfil_func_flags != NULL &&
+		     pfh->pfil_func_flags == pfh1->pfil_func_flags)) &&
 		    pfh->pfil_arg == pfh1->pfil_arg)
 			return (EEXIST);
 
@@ -371,12 +415,13 @@ pfil_chain_add(pfil_chain_t *chain, struct packet_filt
  * Internal: Remove a pfil hook from a hook chain.
  */
 static int
-pfil_chain_remove(pfil_chain_t *chain, pfil_func_t func, void *arg)
+pfil_chain_remove(pfil_chain_t *chain, void *func, void *arg)
 {
 	struct packet_filter_hook *pfh;
 
 	TAILQ_FOREACH(pfh, chain, pfil_chain)
-		if (pfh->pfil_func == func && pfh->pfil_arg == arg) {
+		if ((pfh->pfil_func == func || pfh->pfil_func_flags == func) &&
+		    pfh->pfil_arg == arg) {
 			TAILQ_REMOVE(chain, pfh, pfil_chain);
 			free(pfh, M_IFADDR);
 			return (0);

Modified: stable/11/sys/net/pfil.h
==============================================================================
--- stable/11/sys/net/pfil.h	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/net/pfil.h	Sun Apr 15 15:22:28 2018	(r332513)
@@ -46,6 +46,8 @@ struct inpcb;
 
 typedef	int	(*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int,
 		    struct inpcb *);
+typedef	int	(*pfil_func_flags_t)(void *, struct mbuf **, struct ifnet *,
+		    int, int, struct inpcb *);
 
 /*
  * The packet filter hooks are designed for anything to call them to
@@ -54,13 +56,15 @@ typedef	int	(*pfil_func_t)(void *, struct mbuf **, str
  */
 struct packet_filter_hook {
 	TAILQ_ENTRY(packet_filter_hook) pfil_chain;
-	pfil_func_t	 pfil_func;
-	void		*pfil_arg;
+	pfil_func_t		 pfil_func;
+	pfil_func_flags_t	 pfil_func_flags;
+	void			*pfil_arg;
 };
 
 #define PFIL_IN		0x00000001
 #define PFIL_OUT	0x00000002
 #define PFIL_WAITOK	0x00000004
+#define PFIL_FWD	0x00000008
 #define PFIL_ALL	(PFIL_IN|PFIL_OUT)
 
 typedef	TAILQ_HEAD(pfil_chain, packet_filter_hook) pfil_chain_t;
@@ -100,13 +104,15 @@ VNET_DECLARE(struct rmlock, pfil_lock);
 
 /* Public functions for pfil hook management by packet filters. */
 struct pfil_head *pfil_head_get(int, u_long);
+int	pfil_add_hook_flags(pfil_func_flags_t, void *, int, struct pfil_head *);
 int	pfil_add_hook(pfil_func_t, void *, int, struct pfil_head *);
+int	pfil_remove_hook_flags(pfil_func_flags_t, void *, int, struct pfil_head *);
 int	pfil_remove_hook(pfil_func_t, void *, int, struct pfil_head *);
 #define	PFIL_HOOKED(p) ((p)->ph_nhooks > 0)
 
 /* Public functions to run the packet inspection by protocols. */
-int	pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *,
-	    int, struct inpcb *inp);
+int	pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *, int,
+    int, struct inpcb *inp);
 
 /* Public functions for pfil head management by protocols. */
 int	pfil_head_register(struct pfil_head *);

Modified: stable/11/sys/net/pfvar.h
==============================================================================
--- stable/11/sys/net/pfvar.h	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/net/pfvar.h	Sun Apr 15 15:22:28 2018	(r332513)
@@ -1574,13 +1574,13 @@ extern void			 pf_addrcpy(struct pf_addr *, struct pf_
 void				pf_free_rule(struct pf_rule *);
 
 #ifdef INET
-int	pf_test(int, struct ifnet *, struct mbuf **, struct inpcb *);
+int	pf_test(int, int, struct ifnet *, struct mbuf **, struct inpcb *);
 int	pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *,
 	    struct pf_pdesc *);
 #endif /* INET */
 
 #ifdef INET6
-int	pf_test6(int, struct ifnet *, struct mbuf **, struct inpcb *);
+int	pf_test6(int, int, struct ifnet *, struct mbuf **, struct inpcb *);
 int	pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *,
 	    struct pf_pdesc *);
 void	pf_poolmask(struct pf_addr *, struct pf_addr*,

Modified: stable/11/sys/netinet/ip_fastfwd.c
==============================================================================
--- stable/11/sys/netinet/ip_fastfwd.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netinet/ip_fastfwd.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -230,7 +230,7 @@ ip_tryforward(struct mbuf *m)
 		goto passin;
 
 	if (pfil_run_hooks(
-	    &V_inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL) ||
+	    &V_inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, 0, NULL) ||
 	    m == NULL)
 		goto drop;
 
@@ -303,8 +303,8 @@ passin:
 	if (!PFIL_HOOKED(&V_inet_pfil_hook))
 		goto passout;
 
-	if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, NULL) ||
-	    m == NULL) {
+	if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, PFIL_FWD,
+	    NULL) || m == NULL) {
 		goto drop;
 	}
 

Modified: stable/11/sys/netinet/ip_input.c
==============================================================================
--- stable/11/sys/netinet/ip_input.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netinet/ip_input.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -598,7 +598,7 @@ tooshort:
 		goto passin;
 
 	odst = ip->ip_dst;
-	if (pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_IN, NULL) != 0)
+	if (pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_IN, 0, NULL) != 0)
 		return;
 	if (m == NULL)			/* consumed by filter */
 		return;

Modified: stable/11/sys/netinet/ip_output.c
==============================================================================
--- stable/11/sys/netinet/ip_output.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netinet/ip_output.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -115,7 +115,7 @@ ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, st
 
 	/* Run through list of hooks for output packets. */
 	odst.s_addr = ip->ip_dst.s_addr;
-	*error = pfil_run_hooks(&V_inet_pfil_hook, mp, ifp, PFIL_OUT, inp);
+	*error = pfil_run_hooks(&V_inet_pfil_hook, mp, ifp, PFIL_OUT, 0, inp);
 	m = *mp;
 	if ((*error) != 0 || m == NULL)
 		return 1; /* Finished */

Modified: stable/11/sys/netinet6/ip6_fastfwd.c
==============================================================================
--- stable/11/sys/netinet6/ip6_fastfwd.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netinet6/ip6_fastfwd.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -157,7 +157,7 @@ ip6_tryforward(struct mbuf *m)
 	 */
 	if (!PFIL_HOOKED(&V_inet6_pfil_hook))
 		goto passin;
-	if (pfil_run_hooks(&V_inet6_pfil_hook, &m, rcvif, PFIL_IN,
+	if (pfil_run_hooks(&V_inet6_pfil_hook, &m, rcvif, PFIL_IN, 0,
 	    NULL) != 0 || m == NULL)
 		goto dropin;
 	/*
@@ -201,7 +201,7 @@ passin:
 	if (!PFIL_HOOKED(&V_inet6_pfil_hook))
 		goto passout;
 	if (pfil_run_hooks(&V_inet6_pfil_hook, &m, nh.nh_ifp, PFIL_OUT,
-	    NULL) != 0 || m == NULL)
+	    PFIL_FWD, NULL) != 0 || m == NULL)
 		goto dropout;
 
 	/*

Modified: stable/11/sys/netinet6/ip6_forward.c
==============================================================================
--- stable/11/sys/netinet6/ip6_forward.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netinet6/ip6_forward.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -324,8 +324,9 @@ again2:
 		goto pass;
 
 	odst = ip6->ip6_dst;
-	/* Run through list of hooks for output packets. */
-	error = pfil_run_hooks(&V_inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT, NULL);
+	/* Run through list of hooks for forwarded packets. */
+	error = pfil_run_hooks(&V_inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT,
+	    PFIL_FWD, NULL);
 	if (error != 0 || m == NULL)
 		goto freecopy;		/* consumed by filter */
 	ip6 = mtod(m, struct ip6_hdr *);

Modified: stable/11/sys/netinet6/ip6_input.c
==============================================================================
--- stable/11/sys/netinet6/ip6_input.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netinet6/ip6_input.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -759,7 +759,7 @@ ip6_input(struct mbuf *m)
 
 	odst = ip6->ip6_dst;
 	if (pfil_run_hooks(&V_inet6_pfil_hook, &m,
-	    m->m_pkthdr.rcvif, PFIL_IN, NULL))
+	    m->m_pkthdr.rcvif, PFIL_IN, 0, NULL))
 		return;
 	if (m == NULL)			/* consumed by filter */
 		return;

Modified: stable/11/sys/netinet6/ip6_output.c
==============================================================================
--- stable/11/sys/netinet6/ip6_output.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netinet6/ip6_output.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -790,7 +790,7 @@ again:
 
 	odst = ip6->ip6_dst;
 	/* Run through list of hooks for output packets. */
-	error = pfil_run_hooks(&V_inet6_pfil_hook, &m, ifp, PFIL_OUT, inp);
+	error = pfil_run_hooks(&V_inet6_pfil_hook, &m, ifp, PFIL_OUT, 0, inp);
 	if (error != 0 || m == NULL)
 		goto done;
 	/* adjust pointer */

Modified: stable/11/sys/netpfil/pf/pf.c
==============================================================================
--- stable/11/sys/netpfil/pf/pf.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netpfil/pf/pf.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
 #include <net/radix_mpath.h>
 #include <net/vnet.h>
 
+#include <net/pfil.h>
 #include <net/pfvar.h>
 #include <net/if_pflog.h>
 #include <net/if_pfsync.h>
@@ -5512,7 +5513,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, 
 		goto bad;
 
 	if (oifp != ifp) {
-		if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
+		if (pf_test(PF_OUT, 0, ifp, &m0, NULL) != PF_PASS)
 			goto bad;
 		else if (m0 == NULL)
 			goto done;
@@ -5684,7 +5685,7 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir,
 		goto bad;
 
 	if (oifp != ifp) {
-		if (pf_test6(PF_FWD, ifp, &m0, NULL) != PF_PASS)
+		if (pf_test6(PF_OUT, PFIL_FWD, ifp, &m0, NULL) != PF_PASS)
 			goto bad;
 		else if (m0 == NULL)
 			goto done;
@@ -5874,7 +5875,7 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len,
 
 #ifdef INET
 int
-pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
+pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
 {
 	struct pfi_kif		*kif;
 	u_short			 action, reason = 0, log = 0;
@@ -6261,7 +6262,7 @@ done:
 
 #ifdef INET6
 int
-pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
+pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
 {
 	struct pfi_kif		*kif;
 	u_short			 action, reason = 0, log = 0;
@@ -6273,28 +6274,9 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
 	struct pf_ruleset	*ruleset = NULL;
 	struct pf_pdesc		 pd;
 	int			 off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0;
-	int			 fwdir = dir;
 
 	M_ASSERTPKTHDR(m);
 
-	/* Detect packet forwarding.
-	 * If the input interface is different from the output interface we're
-	 * forwarding.
-	 * We do need to be careful about bridges. If the
-	 * net.link.bridge.pfil_bridge sysctl is set we can be filtering on a
-	 * bridge, so if the input interface is a bridge member and the output
-	 * interface is its bridge or a member of the same bridge we're not
-	 * actually forwarding but bridging.
-	 */
-	if (dir == PF_OUT && m->m_pkthdr.rcvif && ifp != m->m_pkthdr.rcvif &&
-	    (m->m_pkthdr.rcvif->if_bridge == NULL ||
-	    (m->m_pkthdr.rcvif->if_bridge != ifp->if_softc &&
-	    m->m_pkthdr.rcvif->if_bridge != ifp->if_bridge)))
-		fwdir = PF_FWD;
-
-	if (dir == PF_FWD)
-		dir = PF_OUT;
-
 	if (!V_pf_status.running)
 		return (PF_PASS);
 
@@ -6672,7 +6654,7 @@ done:
 		PF_STATE_UNLOCK(s);
 
 	/* If reassembled packet passed, create new fragments. */
-	if (action == PF_PASS && *m0 && fwdir == PF_FWD &&
+	if (action == PF_PASS && *m0 && (pflags & PFIL_FWD) &&
 	    (mtag = m_tag_find(m, PF_REASSEMBLED, NULL)) != NULL)
 		action = pf_refragment6(ifp, m0, mtag);
 

Modified: stable/11/sys/netpfil/pf/pf.h
==============================================================================
--- stable/11/sys/netpfil/pf/pf.h	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netpfil/pf/pf.h	Sun Apr 15 15:22:28 2018	(r332513)
@@ -43,7 +43,7 @@
 #endif
 #endif
 
-enum	{ PF_INOUT, PF_IN, PF_OUT, PF_FWD };
+enum	{ PF_INOUT, PF_IN, PF_OUT };
 enum	{ PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
 	  PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER };
 enum	{ PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,

Modified: stable/11/sys/netpfil/pf/pf_ioctl.c
==============================================================================
--- stable/11/sys/netpfil/pf/pf_ioctl.c	Sun Apr 15 15:06:07 2018	(r332512)
+++ stable/11/sys/netpfil/pf/pf_ioctl.c	Sun Apr 15 15:22:28 2018	(r332513)
@@ -165,15 +165,15 @@ static void		 pf_tbladdr_copyout(struct pf_addr_wrap *
  */
 #ifdef INET
 static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp,
-    int dir, struct inpcb *inp);
+    int dir, int flags, struct inpcb *inp);
 static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp,
-    int dir, struct inpcb *inp);
+    int dir, int flags, struct inpcb *inp);
 #endif
 #ifdef INET6
 static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp,
-    int dir, struct inpcb *inp);
+    int dir, int flags, struct inpcb *inp);
 static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp,
-    int dir, struct inpcb *inp);
+    int dir, int flags, struct inpcb *inp);
 #endif
 
 static int		hook_pf(void);
@@ -3736,12 +3736,12 @@ shutdown_pf(void)
 
 #ifdef INET
 static int
-pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags,
     struct inpcb *inp)
 {
 	int chk;
 
-	chk = pf_test(PF_IN, ifp, m, inp);
+	chk = pf_test(PF_IN, flags, ifp, m, inp);
 	if (chk && *m) {
 		m_freem(*m);
 		*m = NULL;
@@ -3753,12 +3753,12 @@ pf_check_in(void *arg, struct mbuf **m, struct ifnet *
 }
 
 static int
-pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags,
     struct inpcb *inp)
 {
 	int chk;
 
-	chk = pf_test(PF_OUT, ifp, m, inp);
+	chk = pf_test(PF_OUT, flags, ifp, m, inp);
 	if (chk && *m) {
 		m_freem(*m);
 		*m = NULL;
@@ -3772,7 +3772,7 @@ pf_check_out(void *arg, struct mbuf **m, struct ifnet 
 
 #ifdef INET6
 static int
-pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags,
     struct inpcb *inp)
 {
 	int chk;
@@ -3783,7 +3783,7 @@ pf_check6_in(void *arg, struct mbuf **m, struct ifnet 
 	 * filtering we have change this to lo0 as it is the case in IPv4.
 	 */
 	CURVNET_SET(ifp->if_vnet);
-	chk = pf_test6(PF_IN, (*m)->m_flags & M_LOOP ? V_loif : ifp, m, inp);
+	chk = pf_test6(PF_IN, flags, (*m)->m_flags & M_LOOP ? V_loif : ifp, m, inp);
 	CURVNET_RESTORE();
 	if (chk && *m) {
 		m_freem(*m);
@@ -3795,13 +3795,13 @@ pf_check6_in(void *arg, struct mbuf **m, struct ifnet 
 }
 
 static int
-pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags,
     struct inpcb *inp)
 {
 	int chk;
 
 	CURVNET_SET(ifp->if_vnet);
-	chk = pf_test6(PF_OUT, ifp, m, inp);
+	chk = pf_test6(PF_OUT, flags, ifp, m, inp);
 	CURVNET_RESTORE();
 	if (chk && *m) {
 		m_freem(*m);
@@ -3830,22 +3830,22 @@ hook_pf(void)
 	pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
 	if (pfh_inet == NULL)
 		return (ESRCH); /* XXX */
-	pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
-	pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
+	pfil_add_hook_flags(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
+	pfil_add_hook_flags(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
 #endif
 #ifdef INET6
 	pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
 	if (pfh_inet6 == NULL) {
 #ifdef INET
-		pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+		pfil_remove_hook_flags(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
 		    pfh_inet);
-		pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+		pfil_remove_hook_flags(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
 		    pfh_inet);
 #endif
 		return (ESRCH); /* XXX */
 	}
-	pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
-	pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+	pfil_add_hook_flags(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
+	pfil_add_hook_flags(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
 #endif
 
 	V_pf_pfil_hooked = 1;
@@ -3869,18 +3869,18 @@ dehook_pf(void)
 	pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
 	if (pfh_inet == NULL)
 		return (ESRCH); /* XXX */
-	pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+	pfil_remove_hook_flags(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
 	    pfh_inet);
-	pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+	pfil_remove_hook_flags(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
 	    pfh_inet);
 #endif
 #ifdef INET6
 	pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
 	if (pfh_inet6 == NULL)
 		return (ESRCH); /* XXX */
-	pfil_remove_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK,
+	pfil_remove_hook_flags(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK,
 	    pfh_inet6);
-	pfil_remove_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK,
+	pfil_remove_hook_flags(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK,
 	    pfh_inet6);
 #endif
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804151522.w3FFMSft042609>