summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Otavio O Souza <luiz@netgate.com>2015-11-06 07:40:52 -0600
committerLuiz Otavio O Souza <luiz@netgate.com>2015-11-06 07:40:52 -0600
commit5e6268df600406a1570e822ac652576059d820e3 (patch)
tree61042f122e75e98cbca37902fd85ca33a92aae30
parent70c7d0e9cafc983b8ee8fd1b63baa719da18ce1b (diff)
downloadFreeBSD-src-5e6268df600406a1570e822ac652576059d820e3.zip
FreeBSD-src-5e6268df600406a1570e822ac652576059d820e3.tar.gz
MFC r290383:
Replace the fastforward path with tryforward which does not require a sysctl and will always be on. The former split between default and fast forwarding is removed by this commit while preserving the ability to use all network stack features. Differential Revision: https://reviews.freebsd.org/D4042 Reviewed by: ae, melifaro, olivier, rwatson MFC after: 1 month Sponsored by: Rubicon Communications (Netgate) TAG: tryforward
-rw-r--r--sys/net/if_arcsubr.c4
-rw-r--r--sys/net/if_ef.c2
-rw-r--r--sys/net/if_ethersubr.c2
-rw-r--r--sys/net/if_fddisubr.c2
-rw-r--r--sys/net/if_fwsubr.c2
-rw-r--r--sys/net/if_iso88025subr.c2
-rw-r--r--sys/netinet/in_var.h2
-rw-r--r--sys/netinet/ip_fastfwd.c117
-rw-r--r--sys/netinet/ip_input.c13
9 files changed, 19 insertions, 127 deletions
diff --git a/sys/net/if_arcsubr.c b/sys/net/if_arcsubr.c
index 2f94785..1091ae4 100644
--- a/sys/net/if_arcsubr.c
+++ b/sys/net/if_arcsubr.c
@@ -557,15 +557,11 @@ arc_input(struct ifnet *ifp, struct mbuf *m)
#ifdef INET
case ARCTYPE_IP:
m_adj(m, ARC_HDRNEWLEN);
- if ((m = ip_fastforward(m)) == NULL)
- return;
isr = NETISR_IP;
break;
case ARCTYPE_IP_OLD:
m_adj(m, ARC_HDRLEN);
- if ((m = ip_fastforward(m)) == NULL)
- return;
isr = NETISR_IP;
break;
diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c
index fc6402c..478dfb4 100644
--- a/sys/net/if_ef.c
+++ b/sys/net/if_ef.c
@@ -240,8 +240,6 @@ ef_inputEII(struct mbuf *m, struct ether_header *eh, u_short ether_type)
#endif
#ifdef INET
case ETHERTYPE_IP:
- if ((m = ip_fastforward(m)) == NULL)
- return (0);
isr = NETISR_IP;
break;
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 82e140a..773918f 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -796,8 +796,6 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
switch (ether_type) {
#ifdef INET
case ETHERTYPE_IP:
- if ((m = ip_fastforward(m)) == NULL)
- return;
isr = NETISR_IP;
break;
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index 4f54dcb..271f72c 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -501,8 +501,6 @@ fddi_input(ifp, m)
switch (type) {
#ifdef INET
case ETHERTYPE_IP:
- if ((m = ip_fastforward(m)) == NULL)
- return;
isr = NETISR_IP;
break;
diff --git a/sys/net/if_fwsubr.c b/sys/net/if_fwsubr.c
index 31fc2a9..acac423 100644
--- a/sys/net/if_fwsubr.c
+++ b/sys/net/if_fwsubr.c
@@ -595,8 +595,6 @@ firewire_input(struct ifnet *ifp, struct mbuf *m, uint16_t src)
switch (type) {
#ifdef INET
case ETHERTYPE_IP:
- if ((m = ip_fastforward(m)) == NULL)
- return;
isr = NETISR_IP;
break;
diff --git a/sys/net/if_iso88025subr.c b/sys/net/if_iso88025subr.c
index 5975b28..f96df4e 100644
--- a/sys/net/if_iso88025subr.c
+++ b/sys/net/if_iso88025subr.c
@@ -579,8 +579,6 @@ iso88025_input(ifp, m)
#ifdef INET
case ETHERTYPE_IP:
th->iso88025_shost[0] &= ~(TR_RII);
- if ((m = ip_fastforward(m)) == NULL)
- return;
isr = NETISR_IP;
break;
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 8657dbb..511ba26 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -452,7 +452,7 @@ int in_scrubprefix(struct in_ifaddr *, u_int);
void ip_input(struct mbuf *);
int in_ifadown(struct ifaddr *ifa, int);
void in_ifscrub(struct ifnet *, struct in_ifaddr *, u_int);
-struct mbuf *ip_fastforward(struct mbuf *);
+struct mbuf *ip_tryforward(struct mbuf *);
void *in_domifattach(struct ifnet *);
void in_domifdetach(struct ifnet *, void *);
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c
index 3db6311..9c3ea66 100644
--- a/sys/netinet/ip_fastfwd.c
+++ b/sys/netinet/ip_fastfwd.c
@@ -109,12 +109,6 @@ __FBSDID("$FreeBSD$");
#include <machine/in_cksum.h>
-static VNET_DEFINE(int, ipfastforward_active);
-#define V_ipfastforward_active VNET(ipfastforward_active)
-
-SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, fastforwarding, CTLFLAG_RW,
- &VNET_NAME(ipfastforward_active), 0, "Enable fast IP forwarding");
-
static struct sockaddr_in *
ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m)
{
@@ -159,7 +153,7 @@ ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m)
* to ip_input for full processing.
*/
struct mbuf *
-ip_fastforward(struct mbuf *m)
+ip_tryforward(struct mbuf *m)
{
struct ip *ip;
struct mbuf *m0 = NULL;
@@ -167,119 +161,20 @@ ip_fastforward(struct mbuf *m)
struct sockaddr_in *dst = NULL;
struct ifnet *ifp;
struct in_addr odest, dest;
- uint16_t sum, ip_len, ip_off;
+ uint16_t ip_len, ip_off;
int error = 0;
- int hlen, mtu;
+ int mtu;
struct m_tag *fwd_tag = NULL;
/*
* Are we active and forwarding packets?
*/
- if (!V_ipfastforward_active || !V_ipforwarding)
- return m;
M_ASSERTVALID(m);
M_ASSERTPKTHDR(m);
bzero(&ro, sizeof(ro));
- /*
- * Step 1: check for packet drop conditions (and sanity checks)
- */
-
- /*
- * Is entire packet big enough?
- */
- if (m->m_pkthdr.len < sizeof(struct ip)) {
- IPSTAT_INC(ips_tooshort);
- goto drop;
- }
-
- /*
- * Is first mbuf large enough for ip header and is header present?
- */
- if (m->m_len < sizeof (struct ip) &&
- (m = m_pullup(m, sizeof (struct ip))) == NULL) {
- IPSTAT_INC(ips_toosmall);
- return NULL; /* mbuf already free'd */
- }
-
- ip = mtod(m, struct ip *);
-
- /*
- * Is it IPv4?
- */
- if (ip->ip_v != IPVERSION) {
- IPSTAT_INC(ips_badvers);
- goto drop;
- }
-
- /*
- * Is IP header length correct and is it in first mbuf?
- */
- hlen = ip->ip_hl << 2;
- if (hlen < sizeof(struct ip)) { /* minimum header length */
- IPSTAT_INC(ips_badhlen);
- goto drop;
- }
- if (hlen > m->m_len) {
- if ((m = m_pullup(m, hlen)) == NULL) {
- IPSTAT_INC(ips_badhlen);
- return NULL; /* mbuf already free'd */
- }
- ip = mtod(m, struct ip *);
- }
-
- /*
- * Checksum correct?
- */
- if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED)
- sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
- else {
- if (hlen == sizeof(struct ip))
- sum = in_cksum_hdr(ip);
- else
- sum = in_cksum(m, hlen);
- }
- if (sum) {
- IPSTAT_INC(ips_badsum);
- goto drop;
- }
-
- /*
- * Remember that we have checked the IP header and found it valid.
- */
- m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID);
-
- ip_len = ntohs(ip->ip_len);
-
- /*
- * Is IP length longer than packet we have got?
- */
- if (m->m_pkthdr.len < ip_len) {
- IPSTAT_INC(ips_tooshort);
- goto drop;
- }
-
- /*
- * Is packet longer than IP header tells us? If yes, truncate packet.
- */
- if (m->m_pkthdr.len > ip_len) {
- if (m->m_len == m->m_pkthdr.len) {
- m->m_len = ip_len;
- m->m_pkthdr.len = ip_len;
- } else
- m_adj(m, ip_len - m->m_pkthdr.len);
- }
-
- /*
- * Is packet from or to 127/8?
- */
- if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
- (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
- IPSTAT_INC(ips_badaddr);
- goto drop;
- }
#ifdef ALTQ
/*
@@ -290,12 +185,10 @@ ip_fastforward(struct mbuf *m)
#endif
/*
- * Step 2: fallback conditions to normal ip_input path processing
- */
-
- /*
* Only IP packets without options
*/
+ ip = mtod(m, struct ip *);
+
if (ip->ip_hl != (sizeof(struct ip) >> 2)) {
if (V_ip_doopts == 1)
return m;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 287417c..5b2e544 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -77,6 +77,8 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_carp.h>
#ifdef IPSEC
#include <netinet/ip_ipsec.h>
+#include <netipsec/ipsec.h>
+#include <netipsec/key.h>
#endif /* IPSEC */
#include <sys/socketvar.h>
@@ -467,12 +469,23 @@ tooshort:
} else
m_adj(m, ip_len - m->m_pkthdr.len);
}
+
+ /* Try to forward the packet, but if we fail continue */
#ifdef IPSEC
+ /* For now we do not handle IPSEC in tryforward. */
+ if (!key_havesp(IPSEC_DIR_INBOUND) && !key_havesp(IPSEC_DIR_OUTBOUND) &&
+ (V_ipforwarding == 1))
+ if (ip_tryforward(m) == NULL)
+ return;
/*
* Bypass packet filtering for packets previously handled by IPsec.
*/
if (ip_ipsec_filtertunnel(m))
goto passin;
+#else
+ if (V_ipforwarding == 1)
+ if (ip_tryforward(m) == NULL)
+ return;
#endif /* IPSEC */
/*
OpenPOWER on IntegriCloud