summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/ip_fastfwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/ip_fastfwd.c')
-rw-r--r--freebsd/sys/netinet/ip_fastfwd.c181
1 files changed, 27 insertions, 154 deletions
diff --git a/freebsd/sys/netinet/ip_fastfwd.c b/freebsd/sys/netinet/ip_fastfwd.c
index 863b9a16..19dfb1ab 100644
--- a/freebsd/sys/netinet/ip_fastfwd.c
+++ b/freebsd/sys/netinet/ip_fastfwd.c
@@ -78,7 +78,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <rtems/bsd/local/opt_ipfw.h>
#include <rtems/bsd/local/opt_ipstealth.h>
#include <rtems/bsd/sys/param.h>
@@ -87,6 +86,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
+#include <sys/sdt.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
@@ -99,6 +99,7 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
@@ -108,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)
{
@@ -158,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;
@@ -166,119 +161,20 @@ ip_fastforward(struct mbuf *m)
struct sockaddr_in *dst = NULL;
struct ifnet *ifp;
struct in_addr odest, dest;
- u_short sum, ip_len;
+ 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
/*
@@ -289,16 +185,14 @@ 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 (ip_doopts == 1)
+ if (V_ip_doopts == 1)
return m;
- else if (ip_doopts == 2) {
+ else if (V_ip_doopts == 2) {
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_FILTER_PROHIB,
0, 0);
return NULL; /* mbuf already free'd */
@@ -312,7 +206,7 @@ ip_fastforward(struct mbuf *m)
*
* XXX: Probably some of these checks could be direct drop
* conditions. However it is not clear whether there are some
- * hacks or obscure behaviours which make it neccessary to
+ * hacks or obscure behaviours which make it necessary to
* let ip_input handle it. We play safe here and let ip_input
* deal with it until it is proven that we can directly drop it.
*/
@@ -340,12 +234,6 @@ ip_fastforward(struct mbuf *m)
* Step 3: incoming packet firewall processing
*/
- /*
- * Convert to host representation
- */
- ip->ip_len = ntohs(ip->ip_len);
- ip->ip_off = ntohs(ip->ip_off);
-
odest.s_addr = dest.s_addr = ip->ip_dst.s_addr;
/*
@@ -464,8 +352,6 @@ passin:
forwardlocal:
/*
* Return packet for processing by ip_input().
- * Keep host byte order as expected at ip_input's
- * "ours"-label.
*/
m->m_flags |= M_FASTFWD_OURS;
if (ro.ro_rt)
@@ -491,29 +377,18 @@ passout:
/*
* Step 6: send off the packet
*/
+ ip_len = ntohs(ip->ip_len);
+ ip_off = ntohs(ip->ip_off);
/*
* Check if route is dampned (when ARP is unable to resolve)
*/
if ((ro.ro_rt->rt_flags & RTF_REJECT) &&
- (ro.ro_rt->rt_rmx.rmx_expire == 0 ||
- time_uptime < ro.ro_rt->rt_rmx.rmx_expire)) {
+ (ro.ro_rt->rt_expire == 0 || time_uptime < ro.ro_rt->rt_expire)) {
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
goto consumed;
}
-#ifndef ALTQ
- /*
- * Check if there is enough space in the interface queue
- */
- if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >=
- ifp->if_snd.ifq_maxlen) {
- IPSTAT_INC(ips_odropped);
- /* would send source quench here but that is depreciated */
- goto drop;
- }
-#endif
-
/*
* Check if media link state of interface is not down
*/
@@ -525,28 +400,27 @@ passout:
/*
* Check if packet fits MTU or if hardware will fragment for us
*/
- if (ro.ro_rt->rt_rmx.rmx_mtu)
- mtu = min(ro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu);
+ if (ro.ro_rt->rt_mtu)
+ mtu = min(ro.ro_rt->rt_mtu, ifp->if_mtu);
else
mtu = ifp->if_mtu;
- if (ip->ip_len <= mtu ||
- (ifp->if_hwassist & CSUM_FRAGMENT && (ip->ip_off & IP_DF) == 0)) {
+ if (ip_len <= mtu) {
/*
- * Restore packet header fields to original values
+ * Avoid confusing lower layers.
*/
- ip->ip_len = htons(ip->ip_len);
- ip->ip_off = htons(ip->ip_off);
+ m_clrprotoflags(m);
/*
* Send off the packet via outgoing interface
*/
+ IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, &ro);
} else {
/*
* Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery
*/
- if (ip->ip_off & IP_DF) {
+ if (ip_off & IP_DF) {
IPSTAT_INC(ips_cantfrag);
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
0, mtu);
@@ -556,14 +430,8 @@ passout:
* We have to fragment the packet
*/
m->m_pkthdr.csum_flags |= CSUM_IP;
- /*
- * ip_fragment expects ip_len and ip_off in host byte
- * order but returns all packets in network byte order
- */
- if (ip_fragment(ip, &m, mtu, ifp->if_hwassist,
- (~ifp->if_hwassist & CSUM_DELAY_IP))) {
+ if (ip_fragment(ip, &m, mtu, ifp->if_hwassist))
goto drop;
- }
KASSERT(m != NULL, ("null mbuf and no error"));
/*
* Send off the fragments via outgoing interface
@@ -572,7 +440,12 @@ passout:
do {
m0 = m->m_nextpkt;
m->m_nextpkt = NULL;
+ /*
+ * Avoid confusing lower layers.
+ */
+ m_clrprotoflags(m);
+ IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, &ro);
if (error)
@@ -592,7 +465,7 @@ passout:
if (error != 0)
IPSTAT_INC(ips_odropped);
else {
- ro.ro_rt->rt_rmx.rmx_pksent++;
+ counter_u64_add(ro.ro_rt->rt_pksent, 1);
IPSTAT_INC(ips_forward);
IPSTAT_INC(ips_fastforward);
}