diff options
Diffstat (limited to 'sys/netinet6/ip6_forward.c')
-rw-r--r-- | sys/netinet6/ip6_forward.c | 54 |
1 files changed, 21 insertions, 33 deletions
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index caa58e6..053864a 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_pcb.h> #ifdef IPSEC +#include <netinet6/ip6_ipsec.h> #include <netipsec/ipsec.h> #include <netipsec/ipsec6.h> #include <netipsec/key.h> @@ -111,21 +112,6 @@ ip6_forward(struct mbuf *m, int srcrt) struct m_tag *fwd_tag; char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; -#ifdef IPSEC - /* - * Check AH/ESP integrity. - */ - /* - * Don't increment ip6s_cantforward because this is the check - * before forwarding packet actually. - */ - if (ipsec6_in_reject(m, NULL)) { - IPSEC6STAT_INC(ips_in_polvio); - m_freem(m); - return; - } -#endif /* IPSEC */ - /* * Do not forward packets to multicast destination (should be handled * by ip6_mforward(). @@ -150,6 +136,17 @@ ip6_forward(struct mbuf *m, int srcrt) m_freem(m); return; } +#ifdef IPSEC + /* + * Check if this packet has an active SA and needs to be dropped + * instead of forwarded. + */ + if (ip6_ipsec_fwd(m) != 0) { + IP6STAT_INC(ip6s_cantforward); + m_freem(m); + return; + } +#endif /* IPSEC */ #ifdef IPSTEALTH if (!V_ip6stealth) { @@ -179,8 +176,7 @@ ip6_forward(struct mbuf *m, int srcrt) #ifdef IPSEC /* get a security policy for this packet */ - sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, - IP_FORWARDING, &error); + sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, &error); if (sp == NULL) { IPSEC6STAT_INC(ips_out_inval); IP6STAT_INC(ip6s_cantforward); @@ -254,8 +250,7 @@ ip6_forward(struct mbuf *m, int srcrt) /* * when the kernel forwards a packet, it is not proper to apply - * IPsec transport mode to the packet is not proper. this check - * avoid from this. + * IPsec transport mode to the packet. This check avoid from this. * at present, if there is even a transport mode SA request in the * security policy, the kernel does not apply IPsec to the packet. * this check is not enough because the following case is valid. @@ -289,9 +284,9 @@ ip6_forward(struct mbuf *m, int srcrt) * ipsec6_proces_packet will send the packet using ip6_output */ error = ipsec6_process_packet(m, sp->req); - - KEY_FREESP(&sp); - + /* Release SP if an error occured */ + if (error != 0) + KEY_FREESP(&sp); if (error == EJUSTRETURN) { /* * We had a SP with a level of 'use' and no SA. We @@ -557,8 +552,6 @@ pass: if (mcopy) { u_long mtu; #ifdef IPSEC - struct secpolicy *sp; - int ipsecerror; size_t ipsechdrsiz; #endif /* IPSEC */ @@ -571,15 +564,10 @@ pass: * case, as we have the outgoing interface for * encapsulated packet as "rt->rt_ifp". */ - sp = ipsec_getpolicybyaddr(mcopy, IPSEC_DIR_OUTBOUND, - IP_FORWARDING, &ipsecerror); - if (sp) { - ipsechdrsiz = ipsec_hdrsiz(mcopy, - IPSEC_DIR_OUTBOUND, NULL); - if (ipsechdrsiz < mtu) - mtu -= ipsechdrsiz; - } - + ipsechdrsiz = ipsec_hdrsiz(mcopy, IPSEC_DIR_OUTBOUND, + NULL); + if (ipsechdrsiz < mtu) + mtu -= ipsechdrsiz; /* * if mtu becomes less than minimum MTU, * tell minimum MTU (and I'll need to fragment it). |