summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2013-06-03 12:55:13 +0000
committerandre <andre@FreeBSD.org>2013-06-03 12:55:13 +0000
commitb706ceb4abd7f12c0ad38c0da053f4523814bcc4 (patch)
tree1234da94faa0d8e5fb8d693bb7883535361a40a4 /sys/net
parent4cb7f1fd6f7638e16e52678307df1995d28cad40 (diff)
downloadFreeBSD-src-b706ceb4abd7f12c0ad38c0da053f4523814bcc4.zip
FreeBSD-src-b706ceb4abd7f12c0ad38c0da053f4523814bcc4.tar.gz
Allow drivers to specify a maximum TSO length in bytes if they are
limited in the amount of data they can handle at once. Drivers can set ifp->if_hw_tsomax before calling ether_ifattach() to change the limit. The lowest allowable size is IP_MAXPACKET / 8 (8192 bytes) as anything less wouldn't be very useful anymore. The upper limit is still at IP_MAXPACKET (65536 bytes). Raising it requires further auditing of the IPv4/v6 code path's as the length field in the IP header would overflow leading to confusion in firewalls and others packet handler on the real size of the packet. The placement into "struct ifnet" is a bit hackish but the best place that was found. When the stack/driver boundary is updated it should be handled in a better way. Submitted by: cperciva (earlier version) Reviewed by: cperciva Tested by: cperciva MFC after: 1 week (using spare struct members to preserve ABI)
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c19
-rw-r--r--sys/net/if_var.h5
2 files changed, 18 insertions, 6 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index dc5681e..3fd6efb 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -74,18 +74,18 @@
#include <net/vnet.h>
#if defined(INET) || defined(INET6)
-/*XXX*/
#include <netinet/in.h>
#include <netinet/in_var.h>
+#include <netinet/ip.h>
#include <netinet/ip_carp.h>
+#ifdef INET
+#include <netinet/if_ether.h>
+#endif /* INET */
#ifdef INET6
#include <netinet6/in6_var.h>
#include <netinet6/in6_ifattach.h>
-#endif
-#endif
-#ifdef INET
-#include <netinet/if_ether.h>
-#endif
+#endif /* INET6 */
+#endif /* INET || INET6 */
#include <security/mac/mac_framework.h>
@@ -653,6 +653,13 @@ if_attach_internal(struct ifnet *ifp, int vmove)
TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
/* Reliably crash if used uninitialized. */
ifp->if_broadcastaddr = NULL;
+
+ /* Initialize to max value. */
+ if (ifp->if_hw_tsomax == 0)
+ ifp->if_hw_tsomax = IP_MAXPACKET;
+ KASSERT(ifp->if_hw_tsomax <= IP_MAXPACKET &&
+ ifp->if_hw_tsomax >= IP_MAXPACKET / 8,
+ ("%s: tsomax outside of range", __func__));
}
#ifdef VIMAGE
else {
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index ce8f06a..3babc22 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -204,6 +204,11 @@ struct ifnet {
u_int if_fib; /* interface FIB */
u_char if_alloctype; /* if_type at time of allocation */
+ u_int if_hw_tsomax; /* tso burst length limit, the minmum
+ * is (IP_MAXPACKET / 8).
+ * XXXAO: Have to find a better place
+ * for it eventually. */
+
/*
* Spare fields are added so that we can modify sensitive data
* structures without changing the kernel binary interface, and must
OpenPOWER on IntegriCloud