diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 1d86242e761d..ba37ab2a0796 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -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. * diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 78dcce73c041..5ccb989246fe 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -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;