Page MenuHomeFreeBSD

D30831.id91203.diff
No OneTemporary

D30831.id91203.diff

Index: sys/arm64/broadcom/genet/if_genet.c
===================================================================
--- sys/arm64/broadcom/genet/if_genet.c
+++ sys/arm64/broadcom/genet/if_genet.c
@@ -49,6 +49,7 @@
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
+#include <sys/sysctl.h>
#include <sys/module.h>
#include <sys/taskqueue.h>
#include <sys/gpio.h>
@@ -97,9 +98,27 @@
#define TX_MAX_SEGS 20
-/* Maximum number of mbufs to send to if_input */
+static SYSCTL_NODE(_hw, OID_AUTO, genet, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
+ "genet driver parameters");
+
+/* Maximum number of mbufs to pass per call to if_input */
static int gen_rx_batch = 16 /* RX_BATCH_DEFAULT */;
-TUNABLE_INT("hw.gen.rx_batch", &gen_rx_batch);
+SYSCTL_INT(_hw_genet, OID_AUTO, rx_batch, CTLFLAG_RDTUN,
+ &gen_rx_batch, 0, "max mbufs per call to if_input");
+
+TUNABLE_INT("hw.gen.rx_batch", &gen_rx_batch); /* old name/interface */
+
+/*
+ * Transmitting packets with only an Ethernet header in the first mbuf
+ * fails. Examples include reflected ICMPv6 packets, e.g. echo replies;
+ * forwarded IPv6/TCP packets; and forwarded IPv4/TCP packets that use NAT
+ * with IPFW. Pulling up the sizes of ether_header + ip6_hdr + icmp6_hdr
+ * seems to work for both ICMPv6 and TCP over IPv6, as well as the IPv4/TCP
+ * case.
+ */
+static int gen_tx_hdr_min = 56; /* ether_header + ip6_hdr + icmp6_hdr */
+SYSCTL_INT(_hw_genet, OID_AUTO, tx_hdr_min, CTLFLAG_RW,
+ &gen_tx_hdr_min, 0, "header to add to packets with ether header only");
static struct ofw_compat_data compat_data[] = {
{ "brcm,genet-v1", 1 },
@@ -995,31 +1014,19 @@
m = *mp;
/*
- * Reflected ICMPv6 packets, e.g. echo replies, tend to get laid
- * out with only the Ethernet header in the first mbuf, and this
- * doesn't seem to work. Forwarded TCP packets over IPv6 also
- * fail if laid out with only the Ethernet header in the first mbuf.
- * For now, pull up any IPv6 packet with that layout. Maybe IPv4
- * needs it but we haven't run into it. Pulling up the sizes of
- * ether_header + ip6_header + icmp6_hdr seems to work for both
- * ICMPv6 and TCP over IPv6.
+ * Don't attempt to send packets with only an Ethernet header in
+ * first mbuf; see comment above with gen_tx_hdr_min.
*/
-#define IP6_PULLUP_LEN (sizeof(struct ether_header) + \
- sizeof(struct ip6_hdr) + 8)
if (m->m_len == sizeof(struct ether_header)) {
- int ether_type = mtod(m, struct ether_header *)->ether_type;
- if (ntohs(ether_type) == ETHERTYPE_IPV6) {
- m = m_pullup(m, MIN(m->m_pkthdr.len, IP6_PULLUP_LEN));
- if (m == NULL) {
- if (sc->ifp->if_flags & IFF_DEBUG)
- device_printf(sc->dev,
- "IPV6 pullup fail\n");
- *mp = NULL;
- return (ENOMEM);
- }
+ m = m_pullup(m, MIN(m->m_pkthdr.len, gen_tx_hdr_min));
+ if (m == NULL) {
+ if (sc->ifp->if_flags & IFF_DEBUG)
+ device_printf(sc->dev,
+ "header pullup fail\n");
+ *mp = NULL;
+ return (ENOMEM);
}
}
-#undef IP6_PULLUP_LEN
if ((if_getcapenable(sc->ifp) & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) !=
0) {

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 8:37 AM (9 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31965486
Default Alt Text
D30831.id91203.diff (3 KB)

Event Timeline