Page MenuHomeFreeBSD

D13715.id38468.diff
No OneTemporary

D13715.id38468.diff

Index: share/man/man9/pfil.9
===================================================================
--- share/man/man9/pfil.9
+++ share/man/man9/pfil.9
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 27, 2017
+.Dd January 24, 2018
.Dt PFIL 9
.Os
.Sh NAME
@@ -50,7 +50,7 @@
.In net/if.h
.In net/pfil.h
.Bd -literal
-typedef int (*pfil_func_t)(void *arg, struct mbuf **mp, struct ifnet *, int dir, struct inpcb);
+typedef int (*pfil_func_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
@@ -62,7 +62,7 @@
.Ft int
.Fn pfil_remove_hook "pfil_func_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_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
@@ -135,6 +135,10 @@
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.
Index: sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
===================================================================
--- sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
+++ sys/contrib/ipfilter/netinet/ip_fil_freebsd.c
@@ -144,7 +144,8 @@
static int
-ipf_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
+ipf_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir,
+ int flags)
{
struct ip *ip = mtod(*mp, struct ip *);
int rv;
@@ -174,7 +175,8 @@
# include <netinet/ip6.h>
static int
-ipf_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
+ipf_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir,
+ int flags)
{
int error;
Index: sys/net/if_bridge.c
===================================================================
--- sys/net/if_bridge.c
+++ sys/net/if_bridge.c
@@ -3176,7 +3176,8 @@
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);
@@ -3228,21 +3229,21 @@
*/
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;
@@ -3282,21 +3283,21 @@
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:
Index: sys/net/if_enc.c
===================================================================
--- sys/net/if_enc.c
+++ sys/net/if_enc.c
@@ -301,7 +301,7 @@
/* 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);
Index: sys/net/if_ethersubr.c
===================================================================
--- sys/net/if_ethersubr.c
+++ sys/net/if_ethersubr.c
@@ -443,7 +443,8 @@
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);
@@ -776,7 +777,8 @@
/* 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;
Index: sys/net/pfil.h
===================================================================
--- sys/net/pfil.h
+++ sys/net/pfil.h
@@ -46,7 +46,7 @@
struct ifnet;
struct inpcb;
-typedef int (*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int,
+typedef int (*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int, int,
struct inpcb *);
/*
@@ -63,6 +63,7 @@
#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;
@@ -107,8 +108,8 @@
#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 *);
Index: sys/net/pfil.c
===================================================================
--- sys/net/pfil.c
+++ sys/net/pfil.c
@@ -95,7 +95,7 @@
*/
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;
@@ -108,7 +108,7 @@
pfh = TAILQ_NEXT(pfh, pfil_chain)) {
if (pfh->pfil_func != NULL) {
rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir,
- inp);
+ flags, inp);
if (rv != 0 || m == NULL)
break;
}
Index: sys/net/pfvar.h
===================================================================
--- sys/net/pfvar.h
+++ sys/net/pfvar.h
@@ -1577,13 +1577,13 @@
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*,
Index: sys/netinet/ip_fastfwd.c
===================================================================
--- sys/netinet/ip_fastfwd.c
+++ sys/netinet/ip_fastfwd.c
@@ -232,7 +232,7 @@
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;
@@ -305,8 +305,8 @@
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;
}
Index: sys/netinet/ip_input.c
===================================================================
--- sys/netinet/ip_input.c
+++ sys/netinet/ip_input.c
@@ -600,7 +600,7 @@
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;
Index: sys/netinet/ip_output.c
===================================================================
--- sys/netinet/ip_output.c
+++ sys/netinet/ip_output.c
@@ -117,7 +117,7 @@
/* 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 */
Index: sys/netinet/siftr.c
===================================================================
--- sys/netinet/siftr.c
+++ sys/netinet/siftr.c
@@ -829,7 +829,7 @@
* that support it so that they won't sleep, otherwise you get a panic.
*/
static int
-siftr_chkpkt(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+siftr_chkpkt(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags,
struct inpcb *inp)
{
struct pkt_node *pn;
@@ -1001,7 +1001,7 @@
#ifdef SIFTR_IPV6
static int
-siftr_chkpkt6(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+siftr_chkpkt6(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int flags,
struct inpcb *inp)
{
struct pkt_node *pn;
Index: sys/netinet6/ip6_fastfwd.c
===================================================================
--- sys/netinet6/ip6_fastfwd.c
+++ sys/netinet6/ip6_fastfwd.c
@@ -157,7 +157,7 @@
*/
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 @@
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;
/*
Index: sys/netinet6/ip6_forward.c
===================================================================
--- sys/netinet6/ip6_forward.c
+++ sys/netinet6/ip6_forward.c
@@ -324,8 +324,9 @@
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 *);
Index: sys/netinet6/ip6_input.c
===================================================================
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -765,7 +765,7 @@
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;
Index: sys/netinet6/ip6_output.c
===================================================================
--- sys/netinet6/ip6_output.c
+++ sys/netinet6/ip6_output.c
@@ -785,7 +785,7 @@
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 */
Index: sys/netpfil/ipfw/ip_fw_pfil.c
===================================================================
--- sys/netpfil/ipfw/ip_fw_pfil.c
+++ sys/netpfil/ipfw/ip_fw_pfil.c
@@ -85,9 +85,9 @@
/* Forward declarations. */
static int ipfw_divert(struct mbuf **, int, struct ipfw_rule_ref *, int);
-int ipfw_check_packet(void *, struct mbuf **, struct ifnet *, int,
+int ipfw_check_packet(void *, struct mbuf **, struct ifnet *, int, int,
struct inpcb *);
-int ipfw_check_frame(void *, struct mbuf **, struct ifnet *, int,
+int ipfw_check_frame(void *, struct mbuf **, struct ifnet *, int, int,
struct inpcb *);
#ifdef SYSCTL_NODE
@@ -122,7 +122,7 @@
*/
int
ipfw_check_packet(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
- struct inpcb *inp)
+ int flags, struct inpcb *inp)
{
struct ip_fw_args args;
struct m_tag *tag;
@@ -308,7 +308,7 @@
*/
int
ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
- struct inpcb *inp)
+ int flags, struct inpcb *inp)
{
struct ether_header *eh;
struct ether_header save_eh;
Index: sys/netpfil/pf/pf.h
===================================================================
--- sys/netpfil/pf/pf.h
+++ sys/netpfil/pf/pf.h
@@ -45,7 +45,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,
Index: sys/netpfil/pf/pf.c
===================================================================
--- sys/netpfil/pf/pf.c
+++ sys/netpfil/pf/pf.c
@@ -70,6 +70,7 @@
#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>
@@ -5481,7 +5482,7 @@
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;
@@ -5643,7 +5644,7 @@
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;
@@ -5833,7 +5834,7 @@
#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;
@@ -6220,7 +6221,7 @@
#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;
@@ -6232,28 +6233,9 @@
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);
@@ -6631,7 +6613,7 @@
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);
Index: sys/netpfil/pf/pf_ioctl.c
===================================================================
--- sys/netpfil/pf/pf_ioctl.c
+++ sys/netpfil/pf/pf_ioctl.c
@@ -165,15 +165,15 @@
*/
#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);
@@ -3649,12 +3649,12 @@
#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;
@@ -3666,12 +3666,12 @@
}
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;
@@ -3685,7 +3685,7 @@
#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;
@@ -3696,7 +3696,7 @@
* 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);
@@ -3708,13 +3708,13 @@
}
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);

File Metadata

Mime Type
text/plain
Expires
Sat, Aug 15, 11:17 AM (2 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36780432
Default Alt Text
D13715.id38468.diff (18 KB)

Event Timeline