ip[6]_tryforward does inbound and outbound packet firewall processing.
This can lead to change of mbuf pointer (packet filter could do m_pullup(), NAT, etc). Also in case of change of destination address, tryforward can decide that packet should be handled by local system. In this case modified mbuf can be returned to the ip[6]_input(). To handle this correctly, check M_FASTFWD_OURS flag after return from ip[6]_tryforward. And if it is present, update variables that depend from mbuf pointer and skip another inbound firewall processing. No objection from: #network MFC after: 3 weeks Sponsored by: Yandex LLC Differential Revision: https://reviews.freebsd.org/D8764
This commit is contained in:
parent
d9ba4eefdc
commit
ad9f4d6ab6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=310258
@ -550,24 +550,35 @@ ip_input(struct mbuf *m)
|
||||
m_adj(m, ip_len - m->m_pkthdr.len);
|
||||
}
|
||||
|
||||
/* Try to forward the packet, but if we fail continue */
|
||||
/*
|
||||
* Try to forward the packet, but if we fail continue.
|
||||
* ip_tryforward() does inbound and outbound packet firewall
|
||||
* processing. If firewall has decided that destination becomes
|
||||
* our local address, it sets M_FASTFWD_OURS flag. In this
|
||||
* case skip another inbound firewall processing and update
|
||||
* ip pointer.
|
||||
*/
|
||||
if (V_ipforwarding != 0
|
||||
#ifdef IPSEC
|
||||
/* For now we do not handle IPSEC in tryforward. */
|
||||
if (!key_havesp(IPSEC_DIR_INBOUND) && !key_havesp(IPSEC_DIR_OUTBOUND) &&
|
||||
(V_ipforwarding == 1))
|
||||
if (ip_tryforward(m) == NULL)
|
||||
&& !key_havesp(IPSEC_DIR_INBOUND)
|
||||
&& !key_havesp(IPSEC_DIR_OUTBOUND)
|
||||
#endif
|
||||
) {
|
||||
if ((m = ip_tryforward(m)) == NULL)
|
||||
return;
|
||||
if (m->m_flags & M_FASTFWD_OURS) {
|
||||
m->m_flags &= ~M_FASTFWD_OURS;
|
||||
ip = mtod(m, struct ip *);
|
||||
goto ours;
|
||||
}
|
||||
}
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
* Bypass packet filtering for packets previously handled by IPsec.
|
||||
*/
|
||||
if (ip_ipsec_filtertunnel(m))
|
||||
goto passin;
|
||||
#else
|
||||
if (V_ipforwarding == 1)
|
||||
if (ip_tryforward(m) == NULL)
|
||||
return;
|
||||
#endif /* IPSEC */
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Run through list of hooks for input packets.
|
||||
*
|
||||
|
@ -726,23 +726,36 @@ ip6_input(struct mbuf *m)
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
/* Try to forward the packet, but if we fail continue */
|
||||
/*
|
||||
* Try to forward the packet, but if we fail continue.
|
||||
* ip6_tryforward() does inbound and outbound packet firewall
|
||||
* processing. If firewall has decided that destination becomes
|
||||
* our local address, it sets M_FASTFWD_OURS flag. In this
|
||||
* case skip another inbound firewall processing and update
|
||||
* ip6 pointer.
|
||||
*/
|
||||
if (V_ip6_forwarding != 0
|
||||
#ifdef IPSEC
|
||||
if (V_ip6_forwarding != 0 && !key_havesp(IPSEC_DIR_INBOUND) &&
|
||||
!key_havesp(IPSEC_DIR_OUTBOUND))
|
||||
if (ip6_tryforward(m) == NULL)
|
||||
&& !key_havesp(IPSEC_DIR_INBOUND)
|
||||
&& !key_havesp(IPSEC_DIR_OUTBOUND)
|
||||
#endif
|
||||
) {
|
||||
if ((m = ip6_tryforward(m)) == NULL)
|
||||
return;
|
||||
if (m->m_flags & M_FASTFWD_OURS) {
|
||||
m->m_flags &= ~M_FASTFWD_OURS;
|
||||
ours = 1;
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
goto hbhcheck;
|
||||
}
|
||||
}
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
* Bypass packet filtering for packets previously handled by IPsec.
|
||||
*/
|
||||
if (ip6_ipsec_filtertunnel(m))
|
||||
goto passin;
|
||||
#else
|
||||
if (V_ip6_forwarding != 0)
|
||||
if (ip6_tryforward(m) == NULL)
|
||||
return;
|
||||
#endif /* IPSEC */
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Run through list of hooks for input packets.
|
||||
*
|
||||
@ -750,12 +763,12 @@ ip6_input(struct mbuf *m)
|
||||
* (e.g. by NAT rewriting). When this happens,
|
||||
* tell ip6_forward to do the right thing.
|
||||
*/
|
||||
odst = ip6->ip6_dst;
|
||||
|
||||
/* Jump over all PFIL processing if hooks are not active. */
|
||||
if (!PFIL_HOOKED(&V_inet6_pfil_hook))
|
||||
goto passin;
|
||||
|
||||
odst = ip6->ip6_dst;
|
||||
if (pfil_run_hooks(&V_inet6_pfil_hook, &m,
|
||||
m->m_pkthdr.rcvif, PFIL_IN, NULL))
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user