summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-05-11 08:59:58 -0300
committerRenato Botelho <renato@netgate.com>2017-05-11 08:59:58 -0300
commit5fa580e9c45b6668f134701651fa17cad722750e (patch)
tree8c4a473887fb8b23533d37cf95c1a33a406d1fe8 /sys/netinet/ip_input.c
parent4a3427ce64e27e7bac30020eb566d3b6a9072d12 (diff)
parentdad5ccf4808854af8f6af32ab4f15dca00dae42b (diff)
downloadFreeBSD-src-5fa580e9c45b6668f134701651fa17cad722750e.zip
FreeBSD-src-5fa580e9c45b6668f134701651fa17cad722750e.tar.gz
Merge remote-tracking branch 'origin/stable/11' into devel-11
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r--sys/netinet/ip_input.c109
1 files changed, 44 insertions, 65 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 7023fe1..c7e586e 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -77,13 +77,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_options.h>
#include <machine/in_cksum.h>
#include <netinet/ip_carp.h>
-#ifdef IPSEC
-#include <netinet/ip_ipsec.h>
-#include <netipsec/ipsec.h>
-#include <netipsec/key.h>
-#endif /* IPSEC */
#include <netinet/in_rss.h>
+#include <netipsec/ipsec_support.h>
+
#include <sys/socketvar.h>
#include <security/mac/mac_framework.h>
@@ -269,9 +266,9 @@ sysctl_netinet_intr_direct_queue_maxlen(SYSCTL_HANDLER_ARGS)
return (EINVAL);
return (netisr_setqlimit(&ip_direct_nh, qlimit));
}
-SYSCTL_PROC(_net_inet_ip, IPCTL_INTRQMAXLEN, intr_direct_queue_maxlen,
- CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_netinet_intr_direct_queue_maxlen, "I",
- "Maximum size of the IP direct input queue");
+SYSCTL_PROC(_net_inet_ip, IPCTL_INTRDQMAXLEN, intr_direct_queue_maxlen,
+ CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_netinet_intr_direct_queue_maxlen,
+ "I", "Maximum size of the IP direct input queue");
static int
sysctl_netinet_intr_direct_queue_drops(SYSCTL_HANDLER_ARGS)
@@ -290,7 +287,7 @@ sysctl_netinet_intr_direct_queue_drops(SYSCTL_HANDLER_ARGS)
return (0);
}
-SYSCTL_PROC(_net_inet_ip, IPCTL_INTRQDROPS, intr_direct_queue_drops,
+SYSCTL_PROC(_net_inet_ip, IPCTL_INTRDQDROPS, intr_direct_queue_drops,
CTLTYPE_INT|CTLFLAG_RD, 0, 0, sysctl_netinet_intr_direct_queue_drops, "I",
"Number of packets dropped from the IP direct input queue");
#endif /* RSS */
@@ -433,6 +430,12 @@ ip_direct_input(struct mbuf *m)
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv4)) {
+ if (IPSEC_INPUT(ipv4, m, hlen, ip->ip_p) != 0)
+ return;
+ }
+#endif /* IPSEC */
IPSTAT_INC(ips_delivered);
(*inetsw[ip_protox[ip->ip_p]].pr_input)(&m, &hlen, ip->ip_p);
return;
@@ -562,11 +565,11 @@ tooshort:
* ip pointer.
*/
if (V_ipforwarding != 0
-#ifdef IPSEC
- && !key_havesp(IPSEC_DIR_INBOUND)
- && !key_havesp(IPSEC_DIR_OUTBOUND)
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ && (!IPSEC_ENABLED(ipv4) ||
+ IPSEC_CAPS(ipv4, m, IPSEC_CAP_OPERABLE) == 0)
#endif
- ) {
+ ) {
if ((m = ip_tryforward(m)) == NULL)
return;
if (m->m_flags & M_FASTFWD_OURS) {
@@ -575,13 +578,16 @@ tooshort:
goto ours;
}
}
-#ifdef IPSEC
+
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* Bypass packet filtering for packets previously handled by IPsec.
*/
- if (ip_ipsec_filtertunnel(m))
- goto passin;
+ if (IPSEC_ENABLED(ipv4) &&
+ IPSEC_CAPS(ipv4, m, IPSEC_CAP_BYPASS_FILTER) != 0)
+ goto passin;
#endif
+
/*
* Run through list of hooks for input packets.
*
@@ -805,14 +811,11 @@ ours:
hlen = ip->ip_hl << 2;
}
-#ifdef IPSEC
- /*
- * enforce IPsec policy checking if we are seeing last header.
- * note that we do not visit this with protocols with pcb layer
- * code - like udp/tcp/raw ip.
- */
- if (ip_ipsec_input(m, ip->ip_p) != 0)
- goto bad;
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv4)) {
+ if (IPSEC_INPUT(ipv4, m, hlen, ip->ip_p) != 0)
+ return;
+ }
#endif /* IPSEC */
/*
@@ -954,24 +957,14 @@ ip_forward(struct mbuf *m, int srcrt)
m_freem(m);
return;
}
-#ifdef IPSEC
- if (ip_ipsec_fwd(m) != 0) {
- IPSTAT_INC(ips_cantforward);
- m_freem(m);
- return;
- }
-#endif /* IPSEC */
+ if (
#ifdef IPSTEALTH
- if (!V_ipstealth) {
+ V_ipstealth == 0 &&
#endif
- if (ip->ip_ttl <= IPTTLDEC) {
- icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS,
- 0, 0);
- return;
- }
-#ifdef IPSTEALTH
+ ip->ip_ttl <= IPTTLDEC) {
+ icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, 0);
+ return;
}
-#endif
bzero(&ro, sizeof(ro));
sin = (struct sockaddr_in *)&ro.ro_dst;
@@ -990,19 +983,6 @@ ip_forward(struct mbuf *m, int srcrt)
ifa_ref(&ia->ia_ifa);
} else
ia = NULL;
-#ifndef IPSEC
- /*
- * 'ia' may be NULL if there is no route for this destination.
- * In case of IPsec, Don't discard it just yet, but pass it to
- * ip_output in case of outgoing IPsec policy.
- */
- if (!srcrt && ia == NULL) {
- icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
- RO_RTFREE(&ro);
- return;
- }
-#endif
-
/*
* Save the IP header and at most 8 bytes of the payload,
* in case we need to generate an ICMP message to the src.
@@ -1035,15 +1015,22 @@ ip_forward(struct mbuf *m, int srcrt)
mcopy->m_pkthdr.len = mcopy->m_len;
m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
}
-
#ifdef IPSTEALTH
- if (!V_ipstealth) {
+ if (V_ipstealth == 0)
#endif
ip->ip_ttl -= IPTTLDEC;
-#ifdef IPSTEALTH
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv4)) {
+ if ((error = IPSEC_FORWARD(ipv4, m)) != 0) {
+ /* mbuf consumed by IPsec */
+ m_freem(mcopy);
+ if (error != EINPROGRESS)
+ IPSTAT_INC(ips_cantforward);
+ return;
+ }
+ /* No IPsec processing required */
}
-#endif
-
+#endif /* IPSEC */
/*
* If forwarding packet using same interface that it came in on,
* perhaps should send a redirect to sender to shortcut a hop.
@@ -1121,14 +1108,6 @@ ip_forward(struct mbuf *m, int srcrt)
case EMSGSIZE:
type = ICMP_UNREACH;
code = ICMP_UNREACH_NEEDFRAG;
-
-#ifdef IPSEC
- /*
- * If IPsec is configured for this path,
- * override any possibly mtu value set by ip_output.
- */
- mtu = ip_ipsec_mtu(mcopy, mtu);
-#endif /* IPSEC */
/*
* If the MTU was set before make sure we are below the
* interface MTU.
OpenPOWER on IntegriCloud