Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142083248
D13715.id37313.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D13715.id37313.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D13715: netpfil: Introduce PFIL_FWD flag
Attached
Detach File
Event Timeline
Log In to Comment