Page MenuHomeFreeBSD

D39061.diff
No OneTemporary

D39061.diff

diff --git a/sys/net/pfil.h b/sys/net/pfil.h
--- a/sys/net/pfil.h
+++ b/sys/net/pfil.h
@@ -80,7 +80,7 @@
#define PFIL_IN 0x00010000
#define PFIL_OUT 0x00020000
-/* UNUSED 0x00040000 */
+#define PFIL_FWD 0x00040000
#define PFIL_DIR(f) ((f) & (PFIL_IN|PFIL_OUT))
#define PFIL_HEADPTR 0x00100000
#define PFIL_HOOKPTR 0x00200000
@@ -179,6 +179,8 @@
struct inpcb *inp);
int pfil_mbuf_out(struct pfil_head *, struct mbuf **, struct ifnet *,
struct inpcb *inp);
+int pfil_mbuf_fwd(struct pfil_head *, struct mbuf **, struct ifnet *,
+ struct inpcb *);
/*
* Minimally exposed structure to avoid function call in case of absence
diff --git a/sys/net/pfil.c b/sys/net/pfil.c
--- a/sys/net/pfil.c
+++ b/sys/net/pfil.c
@@ -202,8 +202,11 @@
pfil_return_t rv;
NET_EPOCH_ASSERT();
- KASSERT(flags == PFIL_IN || flags == PFIL_OUT,
- ("%s: unsupported flags %d", __func__, flags));
+ KASSERT((flags & ~(PFIL_IN|PFIL_OUT|PFIL_FWD)) == 0,
+ ("%s: unsupported flags %#x", __func__, flags));
+ KASSERT((flags & ~PFIL_FWD) == PFIL_IN ||
+ (flags & ~PFIL_FWD) == PFIL_OUT,
+ ("%s: conflicting directions %#x", __func__, flags));
rv = PFIL_PASS;
CK_STAILQ_FOREACH(link, pch, link_chain) {
@@ -231,6 +234,14 @@
return (pfil_mbuf_common(&head->head_out, m, ifp, PFIL_OUT, inp));
}
+int
+pfil_mbuf_fwd(struct pfil_head *head, struct mbuf **m, struct ifnet *ifp,
+ struct inpcb *inp)
+{
+
+ return (pfil_mbuf_common(&head->head_out, m, ifp, PFIL_OUT | PFIL_FWD, inp));
+}
+
/*
* pfil_head_register() registers a pfil_head with the packet filter hook
* mechanism.
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2135,7 +2135,7 @@
void pf_poolmask(struct pf_addr *, struct pf_addr*,
struct pf_addr *, struct pf_addr *, u_int8_t);
void pf_addr_inc(struct pf_addr *, sa_family_t);
-int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *);
+int pf_refragment6(struct ifnet *, struct mbuf **, struct m_tag *, bool);
#endif /* INET6 */
u_int32_t pf_new_isn(struct pf_kstate *);
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -321,7 +321,7 @@
odst = ip6->ip6_dst;
/* Run through list of hooks for forwarded packets. */
- if (pfil_mbuf_out(V_inet6_pfil_head, &m, nh->nh_ifp,
+ if (pfil_mbuf_fwd(V_inet6_pfil_head, &m, nh->nh_ifp,
NULL) != PFIL_PASS)
goto freecopy;
ip6 = mtod(m, struct ip6_hdr *);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -7953,7 +7953,7 @@
/* If reassembled packet passed, create new fragments. */
if (action == PF_PASS && *m0 && dir == PF_OUT &&
(mtag = m_tag_find(m, PF_REASSEMBLED, NULL)) != NULL)
- action = pf_refragment6(ifp, m0, mtag);
+ action = pf_refragment6(ifp, m0, mtag, pflags & PFIL_FWD);
SDT_PROBE4(pf, ip, test6, done, action, reason, r, s);
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -942,7 +942,8 @@
#ifdef INET6
int
-pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag)
+pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag,
+ bool forward)
{
struct mbuf *m = *m0, *t;
struct pf_fragment_tag *ftag = (struct pf_fragment_tag *)(mtag + 1);
@@ -1009,7 +1010,12 @@
memset(&pd, 0, sizeof(pd));
pd.pf_mtag = pf_find_mtag(m);
if (error == 0)
- ip6_forward(m, 0);
+ if (forward) {
+ MPASS(m->m_pkthdr.rcvif != NULL);
+ ip6_forward(m, 0);
+ } else {
+ ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
+ }
else
m_freem(m);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 17, 10:33 PM (21 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14685600
Default Alt Text
D39061.diff (3 KB)

Event Timeline