Don't require packet to match a route (any route; this information wasn't

used anyway, so a typical workaround was to add a dummy route) if it's going
to be sent through IPSec tunnel.

Reviewed by:	bz
This commit is contained in:
trasz 2009-04-28 11:10:33 +00:00
parent 5501b55f4f
commit 76f48d741e
2 changed files with 22 additions and 1 deletions

View File

@ -385,7 +385,8 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error,
* the interface supports it.
*/
mtag = m_tag_find(*m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL);
if (mtag != NULL && ((*ifp)->if_capenable & IFCAP_IPSEC) == 0) {
if (mtag != NULL && ifp != NULL &&
((*ifp)->if_capenable & IFCAP_IPSEC) == 0) {
/* notify IPsec to do its own crypto */
ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
*error = EHOSTUNREACH;

View File

@ -144,6 +144,9 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
struct in_addr odst;
#ifdef IPFIREWALL_FORWARD
struct m_tag *fwd_tag = NULL;
#endif
#ifdef IPSEC
int no_route_but_check_spd = 0;
#endif
M_ASSERTPKTHDR(m);
@ -272,6 +275,15 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m));
#endif
if (ro->ro_rt == NULL) {
#ifdef IPSEC
/*
* There is no route for this packet, but it is
* possible that a matching SPD entry exists.
*/
no_route_but_check_spd = 1;
mtu = 0; /* Silence GCC warning. */
goto sendit;
#endif
IPSTAT_INC(ips_noroute);
error = EHOSTUNREACH;
goto bad;
@ -467,6 +479,14 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
default:
break; /* Continue with packet processing. */
}
/*
* Check if there was a route for this packet; return error if not.
*/
if (no_route_but_check_spd) {
IPSTAT_INC(ips_noroute);
error = EHOSTUNREACH;
goto bad;
}
/* Update variables that are affected by ipsec4_output(). */
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;