pf: distinguish forwarding and output cases for pf_refragment6()
Re-introduce PFIL_FWD, because pf's pf_refragment6() needs to know if we're ip6_forward()-ing or ip6_output()-ing. ip6_forward() relies on m->m_pkthdr.rcvif, at least for link-local traffic (for in6_get_unicast_scopeid()). rcvif is not set for locally generated traffic (e.g. from icmp6_reflect()), so we need to call the correct output function. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revisi: https://reviews.freebsd.org/D39061
This commit is contained in:
parent
c91ae48a25
commit
b52b61c0b6
@ -202,8 +202,11 @@ pfil_mbuf_common(pfil_chain_t *pch, struct mbuf **m, struct ifnet *ifp,
|
||||
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 @@ pfil_mbuf_out(struct pfil_head *head, struct mbuf **m, struct ifnet *ifp,
|
||||
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.
|
||||
|
@ -80,7 +80,7 @@ struct pfilioc_link {
|
||||
|
||||
#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 @@ int pfil_mbuf_in(struct pfil_head *, struct mbuf **, struct ifnet *,
|
||||
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
|
||||
|
@ -2135,7 +2135,7 @@ int pf_normalize_ip6(struct mbuf **, int, struct pfi_kkif *, u_short *,
|
||||
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 *);
|
||||
|
@ -321,7 +321,7 @@ ip6_forward(struct mbuf *m, int srcrt)
|
||||
|
||||
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 *);
|
||||
|
@ -7953,7 +7953,7 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
|
||||
/* 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);
|
||||
|
||||
|
@ -942,7 +942,8 @@ pf_reassemble6(struct mbuf **m0, struct ip6_hdr *ip6, struct ip6_frag *fraghdr,
|
||||
|
||||
#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 @@ pf_refragment6(struct ifnet *ifp, struct mbuf **m0, struct m_tag *mtag)
|
||||
memset(&pd, 0, sizeof(pd));
|
||||
pd.pf_mtag = pf_find_mtag(m);
|
||||
if (error == 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user