summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet6/ip6_forward.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 09:36:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 14:46:23 +0200
commitde8a76da2f374792594ce03a203b3f30e4889f6f (patch)
tree12b5e1e59358005c3c522955c08aee4795e4829c /freebsd/sys/netinet6/ip6_forward.c
parentEnable bridging by default (diff)
downloadrtems-libbsd-de8a76da2f374792594ce03a203b3f30e4889f6f.tar.bz2
Update to FreeBSD head 2017-04-04
Git mirror commit 642b174daddbd0efd9bb5f242c43f4ab4db6869f.
Diffstat (limited to 'freebsd/sys/netinet6/ip6_forward.c')
-rw-r--r--freebsd/sys/netinet6/ip6_forward.c229
1 files changed, 18 insertions, 211 deletions
diff --git a/freebsd/sys/netinet6/ip6_forward.c b/freebsd/sys/netinet6/ip6_forward.c
index b57d31fa..f3e6c11c 100644
--- a/freebsd/sys/netinet6/ip6_forward.c
+++ b/freebsd/sys/netinet6/ip6_forward.c
@@ -71,12 +71,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>
-#endif /* IPSEC */
+#include <netipsec/ipsec_support.h>
/*
* Forward a packet. If some error occurs return the sender
@@ -102,9 +97,6 @@ ip6_forward(struct mbuf *m, int srcrt)
struct ifnet *origifp; /* maybe unnecessary */
u_int32_t inzone, outzone;
struct in6_addr src_in6, dst_in6, odst;
-#ifdef IPSEC
- struct secpolicy *sp = NULL;
-#endif
struct m_tag *fwd_tag;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
@@ -132,32 +124,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 */
+ if (
#ifdef IPSTEALTH
- if (!V_ip6stealth) {
+ V_ip6stealth == 0 &&
#endif
- if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
+ ip6->ip6_hlim <= IPV6_HLIMDEC) {
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
icmp6_error(m, ICMP6_TIME_EXCEEDED,
- ICMP6_TIME_EXCEED_TRANSIT, 0);
+ ICMP6_TIME_EXCEED_TRANSIT, 0);
return;
}
- ip6->ip6_hlim -= IPV6_HLIMDEC;
-
-#ifdef IPSTEALTH
- }
-#endif
/*
* Save at most ICMPV6_PLD_MAXLEN (= the min IPv6 MTU -
@@ -170,167 +147,22 @@ ip6_forward(struct mbuf *m, int srcrt)
*/
mcopy = m_copym(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN),
M_NOWAIT);
-
-#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);
+#ifdef IPSTEALTH
+ if (V_ip6stealth == 0)
#endif
- }
- m_freem(m);
- return;
- }
-
- error = 0;
+ ip6->ip6_hlim -= IPV6_HLIMDEC;
- /* 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
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv6)) {
+ if ((error = IPSEC_FORWARD(ipv6, m)) != 0) {
+ /* mbuf consumed by IPsec */
m_freem(mcopy);
-#endif
- }
- m_freem(m);
- return;
-
- case IPSEC_POLICY_BYPASS:
- case IPSEC_POLICY_NONE:
- /* no need to do IPsec. */
- KEY_FREESP(&sp);
- goto skip_ipsec;
-
- case IPSEC_POLICY_IPSEC:
- if (sp->req == NULL) {
- /* XXX should be panic ? */
- printf("ip6_forward: No IPsec request specified.\n");
- IP6STAT_INC(ip6s_cantforward);
- KEY_FREESP(&sp);
- if (mcopy) {
-#if 0
- /* XXX: what icmp ? */
-#else
- m_freem(mcopy);
-#endif
- }
- m_freem(m);
+ if (error != EINPROGRESS)
+ IP6STAT_INC(ip6s_cantforward);
return;
}
- /* do IPsec */
- break;
-
- case IPSEC_POLICY_ENTRUST:
- default:
- /* should be panic ?? */
- printf("ip6_forward: Invalid policy found. %d\n", sp->policy);
- KEY_FREESP(&sp);
- goto skip_ipsec;
+ /* No IPsec processing required */
}
-
- {
- struct ipsecrequest *isr = NULL;
-
- /*
- * when the kernel forwards a packet, it is not proper to apply
- * 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.
- * ipsec esp/tunnel/xxx-xxx/require esp/transport//require;
- */
- for (isr = sp->req; isr; isr = isr->next) {
- if (isr->saidx.mode == IPSEC_MODE_ANY)
- goto doipsectunnel;
- if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
- goto doipsectunnel;
- }
-
- /*
- * if there's no need for tunnel mode IPsec, skip.
- */
- if (!isr)
- goto skip_ipsec;
-
- doipsectunnel:
- /*
- * All the extension headers will become inaccessible
- * (since they can be encrypted).
- * Don't panic, we need no more updates to extension headers
- * on inner IPv6 packet (since they are now encapsulated).
- *
- * IPv6 [ESP|AH] IPv6 [extension headers] payload
- */
-
- /*
- * 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);
- /* Release SP if an error occurred */
- if (error != 0)
- 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_process_packet. */
- switch (error) {
- case EHOSTUNREACH:
- case ENETUNREACH:
- case EMSGSIZE:
- case ENOBUFS:
- case ENOMEM:
- break;
- default:
- printf("ip6_output (ipsec): error code %d\n", error);
- /* FALLTHROUGH */
- case ENOENT:
- /* don't show these error codes to the user */
- break;
- }
- IP6STAT_INC(ip6s_cantforward);
- if (mcopy) {
-#if 0
- /* XXX: what icmp ? */
-#else
- m_freem(mcopy);
-#endif
- }
- return;
- } else {
- /*
- * In the FAST IPSec case we have already
- * re-injected the packet and it has been freed
- * by the ipsec_done() function. So, just clean
- * up after ourselves.
- */
- m = NULL;
- goto freecopy;
- }
- }
-skip_ipsec:
#endif
again:
bzero(&rin6, sizeof(struct route_in6));
@@ -542,34 +374,9 @@ pass:
/* See if the size was changed by the packet filter. */
if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
- if (mcopy) {
- u_long mtu;
-#ifdef IPSEC
- size_t ipsechdrsiz;
-#endif /* IPSEC */
-
- mtu = IN6_LINKMTU(rt->rt_ifp);
-#ifdef IPSEC
- /*
- * When we do IPsec tunnel ingress, we need to play
- * with the link value (decrement IPsec header size
- * from mtu value). The code is much simpler than v4
- * case, as we have the outgoing interface for
- * encapsulated packet as "rt->rt_ifp".
- */
- 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).
- */
- if (mtu < IPV6_MMTU)
- mtu = IPV6_MMTU;
-#endif /* IPSEC */
- icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
- }
+ if (mcopy)
+ icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0,
+ IN6_LINKMTU(rt->rt_ifp));
goto bad;
}