Page MenuHomeFreeBSD

D13715.id37313.diff
No OneTemporary

D13715.id37313.diff

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
@@ -149,6 +149,9 @@
struct ip *ip = mtod(*mp, struct ip *);
int rv;
+ if (dir == PFIL_FWD)
+ dir = PFIL_OUT;
+
/*
* IPFilter expects evreything in network byte order
*/
@@ -178,6 +181,9 @@
{
int error;
+ if (dir == PFIL_FWD)
+ dir = PFIL_OUT;
+
CURVNET_SET(ifp->if_vnet);
error = ipf_check(&V_ipfmain, mtod(*mp, struct ip *),
sizeof(struct ip6_hdr), ifp, (dir == PFIL_OUT), mp);
@@ -1371,12 +1377,12 @@
ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
if (ph_inet != NULL)
pfil_remove_hook((void *)ipf_check_wrapper, NULL,
- PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet);
+ PFIL_IN|PFIL_OUT|PFIL_FWD|PFIL_WAITOK, ph_inet);
# ifdef USE_INET6
ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (ph_inet6 != NULL)
pfil_remove_hook((void *)ipf_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6);
+ PFIL_IN|PFIL_OUT|PFIL_FWD|PFIL_WAITOK, ph_inet6);
# endif
#endif
@@ -1406,11 +1412,11 @@
if (ph_inet != NULL)
pfil_add_hook((void *)ipf_check_wrapper, NULL,
- PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet);
+ PFIL_IN|PFIL_OUT|PFIL_FWD|PFIL_WAITOK, ph_inet);
# ifdef USE_INET6
if (ph_inet6 != NULL)
pfil_add_hook((void *)ipf_check_wrapper6, NULL,
- PFIL_IN|PFIL_OUT|PFIL_WAITOK, ph_inet6);
+ PFIL_IN|PFIL_OUT|PFIL_FWD|PFIL_WAITOK, ph_inet6);
# endif
# endif
return (0);
Index: sys/net/pfil.h
===================================================================
--- sys/net/pfil.h
+++ sys/net/pfil.h
@@ -62,8 +62,9 @@
#define PFIL_IN 0x00000001
#define PFIL_OUT 0x00000002
-#define PFIL_WAITOK 0x00000004
-#define PFIL_ALL (PFIL_IN|PFIL_OUT)
+#define PFIL_FWD 0x00000004
+#define PFIL_WAITOK 0x00000008
+#define PFIL_ALL (PFIL_IN|PFIL_OUT|PFIL_FWD)
typedef TAILQ_HEAD(pfil_chain, packet_filter_hook) pfil_chain_t;
@@ -79,6 +80,7 @@
struct pfil_head {
pfil_chain_t ph_in;
pfil_chain_t ph_out;
+ pfil_chain_t ph_fwd;
int ph_type;
int ph_nhooks;
#if defined( __linux__ ) || defined( _WIN32 )
Index: sys/net/pfil.c
===================================================================
--- sys/net/pfil.c
+++ sys/net/pfil.c
@@ -126,6 +126,8 @@
return (TAILQ_FIRST(&ph->ph_in));
else if (dir == PFIL_OUT)
return (TAILQ_FIRST(&ph->ph_out));
+ else if (dir == PFIL_FWD)
+ return (TAILQ_FIRST(&ph->ph_fwd));
else
return (NULL);
}
@@ -213,6 +215,7 @@
ph->ph_nhooks = 0;
TAILQ_INIT(&ph->ph_in);
TAILQ_INIT(&ph->ph_out);
+ TAILQ_INIT(&ph->ph_fwd);
LIST_INSERT_HEAD(&V_pfil_head_list, ph, ph_list);
PFIL_HEADLIST_UNLOCK();
return (0);
@@ -235,6 +238,8 @@
free(pfh, M_IFADDR);
TAILQ_FOREACH_SAFE(pfh, &ph->ph_out, pfil_chain, pfnext)
free(pfh, M_IFADDR);
+ TAILQ_FOREACH_SAFE(pfh, &ph->ph_fwd, pfil_chain, pfnext)
+ free(pfh, M_IFADDR);
PFIL_LOCK_DESTROY(ph);
return (0);
}
@@ -260,6 +265,7 @@
* flags are:
* PFIL_IN call me on incoming packets
* PFIL_OUT call me on outgoing packets
+ * PFIL_FWD call me in the forwarding path
* PFIL_ALL call me on all of the above
* PFIL_WAITOK OK to call malloc with M_WAITOK.
*/
@@ -268,6 +274,7 @@
{
struct packet_filter_hook *pfh1 = NULL;
struct packet_filter_hook *pfh2 = NULL;
+ struct packet_filter_hook *pfh3 = NULL;
int err;
if (flags & PFIL_IN) {
@@ -286,11 +293,19 @@
goto error;
}
}
+ if (flags & PFIL_FWD) {
+ pfh3 = (struct packet_filter_hook *)malloc(sizeof(*pfh1),
+ M_IFADDR, (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
+ if (pfh3 == NULL) {
+ err = ENOMEM;
+ goto error;
+ }
+ }
PFIL_WLOCK(ph);
if (flags & PFIL_IN) {
pfh1->pfil_func = func;
pfh1->pfil_arg = arg;
- err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT);
+ err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~(PFIL_OUT | PFIL_FWD));
if (err)
goto locked_error;
ph->ph_nhooks++;
@@ -298,10 +313,23 @@
if (flags & PFIL_OUT) {
pfh2->pfil_func = func;
pfh2->pfil_arg = arg;
- err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN);
+ err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~(PFIL_IN | PFIL_FWD));
+ if (err) {
+ if (flags & PFIL_IN)
+ pfil_chain_remove(&ph->ph_in, func, arg);
+ goto locked_error;
+ }
+ ph->ph_nhooks++;
+ }
+ if (flags & PFIL_FWD) {
+ pfh3->pfil_func = func;
+ pfh3->pfil_arg = arg;
+ err = pfil_chain_add(&ph->ph_fwd, pfh3, flags & ~(PFIL_IN | PFIL_OUT));
if (err) {
if (flags & PFIL_IN)
pfil_chain_remove(&ph->ph_in, func, arg);
+ if (flags & PFIL_OUT)
+ pfil_chain_remove(&ph->ph_out, func, arg);
goto locked_error;
}
ph->ph_nhooks++;
@@ -315,6 +343,8 @@
free(pfh1, M_IFADDR);
if (pfh2 != NULL)
free(pfh2, M_IFADDR);
+ if (pfh3 != NULL)
+ free(pfh3, M_IFADDR);
return (err);
}
@@ -338,6 +368,11 @@
if (err == 0)
ph->ph_nhooks--;
}
+ if ((err == 0) && (flags & PFIL_FWD)) {
+ err = pfil_chain_remove(&ph->ph_fwd, func, arg);
+ if (err == 0)
+ ph->ph_nhooks--;
+ }
PFIL_WUNLOCK(ph);
return (err);
}
Index: sys/netinet/ip_fastfwd.c
===================================================================
--- sys/netinet/ip_fastfwd.c
+++ sys/netinet/ip_fastfwd.c
@@ -300,12 +300,12 @@
return (NULL); /* icmp unreach already sent */
/*
- * Step 5: outgoing firewall packet processing
+ * Step 5: forwarding firewall packet processing
*/
if (!PFIL_HOOKED(&V_inet_pfil_hook))
goto passout;
- if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, NULL) ||
+ if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_FWD, NULL) ||
m == NULL) {
goto drop;
}
Index: sys/netinet/siftr.c
===================================================================
--- sys/netinet/siftr.c
+++ sys/netinet/siftr.c
@@ -843,6 +843,9 @@
inp_locally_locked = 0;
ss = DPCPU_PTR(ss);
+ if (dir == PFIL_FWD)
+ dir = PFIL_OUT;
+
/*
* m_pullup is not required here because ip_{input|output}
* already do the heavy lifting for us.
@@ -1135,17 +1138,21 @@
if (action == HOOK) {
pfil_add_hook(siftr_chkpkt, NULL,
- PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet);
+ PFIL_IN | PFIL_FWD| PFIL_OUT | PFIL_WAITOK,
+ pfh_inet);
#ifdef SIFTR_IPV6
pfil_add_hook(siftr_chkpkt6, NULL,
- PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+ PFIL_IN | PFIL_FWD | PFIL_OUT | PFIL_WAITOK,
+ pfh_inet6);
#endif
} else if (action == UNHOOK) {
pfil_remove_hook(siftr_chkpkt, NULL,
- PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet);
+ PFIL_IN | PFIL_FWD | PFIL_OUT | PFIL_WAITOK,
+ pfh_inet);
#ifdef SIFTR_IPV6
pfil_remove_hook(siftr_chkpkt6, NULL,
- PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+ PFIL_IN | PFIL_FWD | PFIL_OUT | PFIL_WAITOK,
+ pfh_inet6);
#endif
}
CURVNET_RESTORE();
Index: sys/netinet6/ip6_fastfwd.c
===================================================================
--- sys/netinet6/ip6_fastfwd.c
+++ sys/netinet6/ip6_fastfwd.c
@@ -196,11 +196,11 @@
}
/*
- * Outgoing packet firewall processing.
+ * Forwarded packet firewall processing.
*/
if (!PFIL_HOOKED(&V_inet6_pfil_hook))
goto passout;
- if (pfil_run_hooks(&V_inet6_pfil_hook, &m, nh.nh_ifp, PFIL_OUT,
+ if (pfil_run_hooks(&V_inet6_pfil_hook, &m, nh.nh_ifp, 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,8 @@
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_FWD, NULL);
if (error != 0 || m == NULL)
goto freecopy; /* consumed by filter */
ip6 = mtod(m, struct ip6_hdr *);
Index: sys/netpfil/ipfw/ip_fw_pfil.c
===================================================================
--- sys/netpfil/ipfw/ip_fw_pfil.c
+++ sys/netpfil/ipfw/ip_fw_pfil.c
@@ -317,6 +317,9 @@
struct ip_fw_args args;
struct m_tag *mtag;
+ if (dir == PFIL_FWD)
+ dir = PFIL_OUT;
+
/* fetch start point from rule, if any. remove the tag if present. */
mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
if (mtag == NULL) {
@@ -508,7 +511,7 @@
hook_func = (pf == AF_LINK) ? ipfw_check_frame : ipfw_check_packet;
(void) (onoff ? pfil_add_hook : pfil_remove_hook)
- (hook_func, NULL, PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh);
+ (hook_func, NULL, PFIL_IN | PFIL_OUT | PFIL_FWD | PFIL_WAITOK, pfh);
return 0;
}
Index: sys/netpfil/pf/pf.c
===================================================================
--- sys/netpfil/pf/pf.c
+++ sys/netpfil/pf/pf.c
@@ -6246,21 +6246,6 @@
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;
Index: sys/netpfil/pf/pf_ioctl.c
===================================================================
--- sys/netpfil/pf/pf_ioctl.c
+++ sys/netpfil/pf/pf_ioctl.c
@@ -3624,7 +3624,7 @@
int chk;
CURVNET_SET(ifp->if_vnet);
- chk = pf_test6(PF_OUT, ifp, m, inp);
+ chk = pf_test6(dir == PFIL_OUT ? PF_OUT : PF_FWD, ifp, m, inp);
CURVNET_RESTORE();
if (chk && *m) {
m_freem(*m);
@@ -3654,7 +3654,7 @@
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(pf_check_out, NULL, PFIL_OUT | PFIL_FWD | PFIL_WAITOK, pfh_inet);
#endif
#ifdef INET6
pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
@@ -3662,13 +3662,14 @@
#ifdef INET
pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
pfh_inet);
- pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_FWD | 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(pf_check6_out, NULL, PFIL_OUT | PFIL_FWD | PFIL_WAITOK,
+ pfh_inet6);
#endif
V_pf_pfil_hooked = 1;
@@ -3694,7 +3695,7 @@
return (ESRCH); /* XXX */
pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
pfh_inet);
- pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_FWD | PFIL_WAITOK,
pfh_inet);
#endif
#ifdef INET6
@@ -3703,7 +3704,7 @@
return (ESRCH); /* XXX */
pfil_remove_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK,
pfh_inet6);
- pfil_remove_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfil_remove_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_FWD | PFIL_WAITOK,
pfh_inet6);
#endif

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 16, 9:28 PM (20 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27670017
Default Alt Text
D13715.id37313.diff (11 KB)

Event Timeline