diff options
| author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2008-03-14 16:38:11 +0000 |
|---|---|---|
| committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2008-03-14 16:38:11 +0000 |
| commit | 9e3bdede0f3df75b406a354c65350cb976a3f1df (patch) | |
| tree | c38b7d05bd49b6aa0f1e85463850a23ad784aabd /sys | |
| parent | a09e09654c8c5118c8fb288d88f749e14a840b9c (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/netinet/ip_ipsec.c | 12 | ||||
| -rw-r--r-- | sys/netinet6/ip6_output.c | 18 | ||||
| -rw-r--r-- | sys/netipsec/ipsec_output.c | 55 |
3 files changed, 61 insertions, 24 deletions
diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index b15a6dca5712..53311d0de378 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> +#include <sys/errno.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mbuf.h> @@ -329,6 +330,17 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error, /* NB: callee frees mbuf */ *error = ipsec4_process_packet(*m, sp->req, *flags, 0); + if (*error == EJUSTRETURN) { + /* + * We had a SP with a level of 'use' and no SA. We + * will just continue to process the packet without + * IPsec processing and return without error. + */ + *error = 0; + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + goto done; + } /* * Preserve KAME behaviour: ENOENT can be returned * when an SA acquire is in progress. Don't propagate diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 2336e41e0b70..c0b2bd7d8c92 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -384,7 +384,14 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags, &needipsectun); m = state.m; - if (error) { + if (error == EJUSTRETURN) { + /* + * We had a SP with a level of 'use' and no SA. We + * will just continue to process the packet without + * IPsec processing. + */ + ; + } else if (error) { /* mbuf is already reclaimed in ipsec6_output_trans. */ m = NULL; switch (error) { @@ -551,7 +558,14 @@ again: m = state.m; ro = (struct route_in6 *)state.ro; dst = (struct sockaddr_in6 *)state.dst; - if (error) { + if (error == EJUSTRETURN) { + /* + * We had a SP with a level of 'use' and no SA. We + * will just continue to process the packet without + * IPsec processing. + */ + ; + } else if (error) { /* mbuf is already reclaimed in ipsec6_output_tunnel. */ m0 = m = NULL; m = NULL; diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c index ae7c08b423a6..a8656eff1cbf 100644 --- a/sys/netipsec/ipsec_output.c +++ b/sys/netipsec/ipsec_output.c @@ -286,17 +286,19 @@ again: goto bad; } sav = isr->sav; - if (sav == NULL) { /* XXX valid return */ + if (sav == NULL) { IPSEC_ASSERT(ipsec_get_reqlevel(isr) == IPSEC_LEVEL_USE, ("no SA found, but required; level %u", ipsec_get_reqlevel(isr))); IPSECREQUEST_UNLOCK(isr); isr = isr->next; - if (isr == NULL) { - /*XXXstatistic??*/ - *error = EINVAL; /*XXX*/ + /* + * If isr is NULL, we found a 'use' policy w/o SA. + * Return w/o error and w/o isr so we can drop out + * and continue w/o IPsec processing. + */ + if (isr == NULL) return isr; - } IPSECREQUEST_LOCK(isr); goto again; } @@ -356,8 +358,11 @@ ipsec4_process_packet( IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ isr = ipsec_nextisr(m, isr, AF_INET, &saidx, &error); - if (isr == NULL) - goto bad; + if (isr == NULL) { + if (error != 0) + goto bad; + return EJUSTRETURN; + } sav = isr->sav; @@ -581,21 +586,24 @@ ipsec6_output_trans( IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ isr = ipsec_nextisr(m, isr, AF_INET6, &saidx, &error); if (isr == NULL) { + if (error != 0) { #ifdef notdef - /* XXX should notification be done for all errors ? */ - /* - * Notify the fact that the packet is discarded - * to ourselves. I believe this is better than - * just silently discarding. (jinmei@kame.net) - * XXX: should we restrict the error to TCP packets? - * XXX: should we directly notify sockets via - * pfctlinputs? - */ - icmp6_error(m, ICMP6_DST_UNREACH, - ICMP6_DST_UNREACH_ADMIN, 0); - m = NULL; /* NB: icmp6_error frees mbuf */ + /* XXX should notification be done for all errors ? */ + /* + * Notify the fact that the packet is discarded + * to ourselves. I believe this is better than + * just silently discarding. (jinmei@kame.net) + * XXX: should we restrict the error to TCP packets? + * XXX: should we directly notify sockets via + * pfctlinputs? + */ + icmp6_error(m, ICMP6_DST_UNREACH, + ICMP6_DST_UNREACH_ADMIN, 0); + m = NULL; /* NB: icmp6_error frees mbuf */ #endif - goto bad; + goto bad; + } + return EJUSTRETURN; } error = (*isr->sav->tdb_xform->xf_output)(m, isr, NULL, @@ -712,8 +720,11 @@ ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp, int IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */ isr = ipsec_nextisr(m, isr, AF_INET6, &saidx, &error); - if (isr == NULL) - goto bad; + if (isr == NULL) { + if (error != 0) + goto bad; + return EJUSTRETURN; + } #ifdef DEV_ENC /* pass the mbuf to enc0 for bpf processing */ |
