From owner-svn-src-stable@freebsd.org Sun Apr 15 15:22:31 2018 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E0E7BF9B5F1; Sun, 15 Apr 2018 15:22:30 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 89E7C83D1C; Sun, 15 Apr 2018 15:22:30 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8302C10AD4; Sun, 15 Apr 2018 15:22:30 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3FFMUTH042627; Sun, 15 Apr 2018 15:22:30 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3FFMSft042609; Sun, 15 Apr 2018 15:22:28 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201804151522.w3FFMSft042609@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Sun, 15 Apr 2018 15:22:28 +0000 (UTC) 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 X-SVN-Group: stable-11 X-SVN-Commit-Author: kp X-SVN-Commit-Paths: in stable/11: share/man/man9 sys/net sys/netinet sys/netinet6 sys/netpfil/pf X-SVN-Commit-Revision: 332513 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Apr 2018 15:22:31 -0000 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 #include +#include #include #include #include @@ -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