Index: sys/netinet/ip_input.c =================================================================== --- sys/netinet/ip_input.c +++ sys/netinet/ip_input.c @@ -907,13 +907,6 @@ m_freem(m); return; } -#ifdef IPSEC - if (ip_ipsec_fwd(m) != 0) { - IPSTAT_INC(ips_cantforward); - m_freem(m); - return; - } -#endif /* IPSEC */ #ifdef IPSTEALTH if (!V_ipstealth) { #endif Index: sys/netinet/ip_ipsec.h =================================================================== --- sys/netinet/ip_ipsec.h +++ sys/netinet/ip_ipsec.h @@ -33,7 +33,6 @@ #define _NETINET_IP_IPSEC_H_ int ip_ipsec_filtertunnel(struct mbuf *); -int ip_ipsec_fwd(struct mbuf *); int ip_ipsec_input(struct mbuf *, int); int ip_ipsec_mtu(struct mbuf *, int); int ip_ipsec_output(struct mbuf **, struct inpcb *, int *); Index: sys/netinet/ip_ipsec.c =================================================================== --- sys/netinet/ip_ipsec.c +++ sys/netinet/ip_ipsec.c @@ -99,19 +99,6 @@ } /* - * Check if this packet has an active SA and needs to be dropped instead - * of forwarded. - * Called from ip_forward(). - * 1 = drop packet, 0 = forward packet. - */ -int -ip_ipsec_fwd(struct mbuf *m) -{ - - return (ipsec4_in_reject(m, NULL)); -} - -/* * Check if protocol type doesn't have a further header and do IPSEC * decryption or reject right now. Protocols with further headers get * their IPSEC treatment within the protocol specific processing. @@ -180,6 +167,12 @@ * sp == NULL, error != 0 discard packet, report error */ if (sp != NULL) { + /* Only for forwarded packets */ + if (inp == NULL && ipsec_in_reject(sp, m)) { + IPSECSTAT_INC(ips_in_polvio); + goto bad; + } + /* * Do delayed checksums now because we send before * this is done in the normal processing path. Index: sys/netinet/ip_output.c =================================================================== --- sys/netinet/ip_output.c +++ sys/netinet/ip_output.c @@ -451,6 +451,7 @@ #ifdef IPSEC switch(ip_ipsec_output(&m, inp, &error)) { case 1: + IPSTAT_INC(ips_cantforward); goto bad; case -1: goto done; Index: sys/netinet6/ip6_forward.c =================================================================== --- sys/netinet6/ip6_forward.c +++ sys/netinet6/ip6_forward.c @@ -134,17 +134,6 @@ 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) { @@ -161,6 +150,33 @@ } #endif +#ifdef IPSEC + /* get a security policy for this packet */ + sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, &error); + if (sp == NULL) { + IPSEC6STAT_INC(ips_out_inval); + IP6STAT_INC(ip6s_cantforward); + + /* XXX: what icmp ? */ + m_freem(m); + return; + } else { + /* + * Check if this packet has an active SA and needs to be dropped + * instead of forwarded. + */ + if (ipsec_in_reject(sp, m)) { + IPSEC6STAT_INC(ips_out_polvio); + IP6STAT_INC(ip6s_cantforward); + KEY_FREESP(&sp); + + /* XXX: what icmp ? */ + m_freem(m); + return; + } + } +#endif + /* * Save at most ICMPV6_PLD_MAXLEN (= the min IPv6 MTU - * size of IPv6 + ICMPv6 headers) bytes of the packet in case @@ -173,42 +189,13 @@ mcopy = m_copy(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN)); #ifdef IPSEC - /* get a security policy for this packet */ - sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, &error); - if (sp == NULL) { - IPSEC6STAT_INC(ips_out_inval); - IP6STAT_INC(ip6s_cantforward); - if (mcopy) { -#if 0 - /* XXX: what icmp ? */ -#else - m_freem(mcopy); -#endif - } - m_freem(m); - return; - } error = 0; /* check policy */ switch (sp->policy) { - case IPSEC_POLICY_DISCARD: - /* - * This packet is just discarded. - */ - IPSEC6STAT_INC(ips_out_polvio); - IP6STAT_INC(ip6s_cantforward); - KEY_FREESP(&sp); - if (mcopy) { -#if 0 - /* XXX: what icmp ? */ -#else - m_freem(mcopy); -#endif - } - m_freem(m); - return; + /* NOTE: _DISCARD is checked above in ipsec_in_reject */ + /* case IPSEC_POLICY_DISCARD: */ case IPSEC_POLICY_BYPASS: case IPSEC_POLICY_NONE: Index: sys/netinet6/ip6_ipsec.h =================================================================== --- sys/netinet6/ip6_ipsec.h +++ sys/netinet6/ip6_ipsec.h @@ -33,7 +33,6 @@ #define _NETINET_IP6_IPSEC_H_ int ip6_ipsec_filtertunnel(struct mbuf *); -int ip6_ipsec_fwd(struct mbuf *); int ip6_ipsec_input(struct mbuf *, int); int ip6_ipsec_output(struct mbuf **, struct inpcb *, int *); #if 0 Index: sys/netinet6/ip6_ipsec.c =================================================================== --- sys/netinet6/ip6_ipsec.c +++ sys/netinet6/ip6_ipsec.c @@ -110,19 +110,6 @@ } /* - * Check if this packet has an active SA and needs to be dropped instead - * of forwarded. - * Called from ip6_forward(). - * 1 = drop packet, 0 = forward packet. - */ -int -ip6_ipsec_fwd(struct mbuf *m) -{ - - return (ipsec6_in_reject(m, NULL)); -} - -/* * Check if protocol type doesn't have a further header and do IPSEC * decryption or reject right now. Protocols with further headers get * their IPSEC treatment within the protocol specific processing. Index: sys/netipsec/ipsec.h =================================================================== --- sys/netipsec/ipsec.h +++ sys/netipsec/ipsec.h @@ -315,6 +315,7 @@ extern int ipsec_get_policy(struct inpcb *inpcb, caddr_t request, size_t len, struct mbuf **mp); extern int ipsec_delete_pcbpolicy(struct inpcb *); +extern int ipsec_in_reject(struct secpolicy *, struct mbuf *); extern int ipsec4_in_reject(struct mbuf *, struct inpcb *); struct secas; Index: sys/netipsec/ipsec.c =================================================================== --- sys/netipsec/ipsec.c +++ sys/netipsec/ipsec.c @@ -238,7 +238,6 @@ struct ipsecstat, ipsec6stat, "IPsec IPv6 statistics."); #endif /* INET6 */ -static int ipsec_in_reject(struct secpolicy *, struct mbuf *); static int ipsec_setspidx_inpcb(struct mbuf *, struct inpcb *); static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int); static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int); @@ -1198,7 +1197,7 @@ * 0: valid * 1: invalid */ -static int +int ipsec_in_reject(struct secpolicy *sp, struct mbuf *m) { struct ipsecrequest *isr;