summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/ip6_forward.c
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2014-11-05 09:23:29 +0000
committerae <ae@FreeBSD.org>2014-11-05 09:23:29 +0000
commit6933957ccb7c9d3685e51d3aae7e3a8ab8d91c8f (patch)
tree4c59a543f83db7eb244721ea9d542127873cf105 /sys/netinet6/ip6_forward.c
parentf5ef39c5536cbd1ec407ea4507e695db17fe32c1 (diff)
downloadFreeBSD-src-6933957ccb7c9d3685e51d3aae7e3a8ab8d91c8f.zip
FreeBSD-src-6933957ccb7c9d3685e51d3aae7e3a8ab8d91c8f.tar.gz
MFC r266800 by vanhu:
IPv4-in-IPv6 and IPv6-in-IPv4 IPsec tunnels. For IPv6-in-IPv4, you may need to do the following command on the tunnel interface if it is configured as IPv4 only: ifconfig <interface> inet6 -ifdisabled Code logic inspired from NetBSD. PR: kern/169438 MC r266822 by bz: Use IPv4 statistics in ipsec4_process_packet() rather than the IPv6 version. This also unbreaks the NOINET6 builds after r266800. MFC r268083 by zec: The assumption in ipsec4_process_packet() that the payload may be only IPv4 is wrong, so check the IP version before mangling the payload header. MFC r272394: Do not strip outer header when operating in transport mode. Instead requeue mbuf back to IPv4 protocol handler. If there is one extra IP-IP encapsulation, it will be handled with tunneling interface. And thus proper interface will be exposed into mbuf's rcvif. Also, tcpdump that listens on tunneling interface will see packets in both directions. PR: 194761
Diffstat (limited to 'sys/netinet6/ip6_forward.c')
-rw-r--r--sys/netinet6/ip6_forward.c46
1 files changed, 16 insertions, 30 deletions
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index 95aba93..6e2bec9 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -251,7 +251,6 @@ ip6_forward(struct mbuf *m, int srcrt)
{
struct ipsecrequest *isr = NULL;
- struct ipsec_output_state state;
/*
* when the kernel forwards a packet, it is not proper to apply
@@ -284,18 +283,27 @@ ip6_forward(struct mbuf *m, int srcrt)
*
* IPv6 [ESP|AH] IPv6 [extension headers] payload
*/
- bzero(&state, sizeof(state));
- state.m = m;
- state.ro = NULL; /* update at ipsec6_output_tunnel() */
- state.dst = NULL; /* update at ipsec6_output_tunnel() */
- error = ipsec6_output_tunnel(&state, sp, 0);
+ /*
+ * If we need to encapsulate the packet, do it here
+ * ipsec6_proces_packet will send the packet using ip6_output
+ */
+ error = ipsec6_process_packet(m, sp->req);
- m = state.m;
KEY_FREESP(&sp);
+ 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.
+ */
+ error = 0;
+ goto skip_ipsec;
+ }
+
if (error) {
- /* mbuf is already reclaimed in ipsec6_output_tunnel. */
+ /* mbuf is already reclaimed in ipsec6_process_packet. */
switch (error) {
case EHOSTUNREACH:
case ENETUNREACH:
@@ -318,7 +326,6 @@ ip6_forward(struct mbuf *m, int srcrt)
m_freem(mcopy);
#endif
}
- m_freem(m);
return;
} else {
/*
@@ -330,25 +337,7 @@ ip6_forward(struct mbuf *m, int srcrt)
m = NULL;
goto freecopy;
}
-
- if ((m != NULL) && (ip6 != mtod(m, struct ip6_hdr *)) ){
- /*
- * now tunnel mode headers are added. we are originating
- * packet instead of forwarding the packet.
- */
- ip6_output(m, NULL, NULL, IPV6_FORWARDING/*XXX*/, NULL, NULL,
- NULL);
- goto freecopy;
- }
-
- /* adjust pointer */
- dst = (struct sockaddr_in6 *)state.dst;
- rt = state.ro ? state.ro->ro_rt : NULL;
- if (dst != NULL && rt != NULL)
- ipsecrt = 1;
}
- if (ipsecrt)
- goto skip_routing;
skip_ipsec:
#endif
again:
@@ -371,9 +360,6 @@ again2:
goto bad;
}
rt = rin6.ro_rt;
-#ifdef IPSEC
-skip_routing:
-#endif
/*
* Source scope check: if a packet can't be delivered to its
OpenPOWER on IntegriCloud