Subject: Re: Allowing large PPPoE frames
To: None <tech-net@netbsd.org>
From: Quentin Garnier <netbsd@quatriemek.com>
List: tech-net
Date: 08/15/2003 16:13:14
This is a multi-part message in MIME format.

--Multipart_Fri__15_Aug_2003_16:13:14_+0200_08eb4a00
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Le Sat, 2 Aug 2003 23:27:55 +0200
Quentin Garnier a ecrit :
[...]

Attached is the updated version of the patch. sip(4) works of course, I
could test tlp(4) (on my variant, DECchip 21140A Ethernet pass 2.0), and
the ne(4) realtek 8029 variant I have works too.

-- 
Quentin Garnier - cube@cubidou.net
"Feels like I'm fiddling while Rome is burning down.
Should I lay my fiddle down and take a rifle from the ground ?"
Leigh Nash/Sixpence None The Richer, Paralyzed, Divine Discontents, 2002.

--Multipart_Fri__15_Aug_2003_16:13:14_+0200_08eb4a00
Content-Type: text/plain;
 name="pppoe_large_frames.diff"
Content-Disposition: attachment;
 filename="pppoe_large_frames.diff"
Content-Transfer-Encoding: 7bit

Index: net/if_pppoe.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_pppoe.c,v
retrieving revision 1.44
diff -u -r1.44 if_pppoe.c
--- net/if_pppoe.c	2003/06/27 16:24:32	1.44
+++ net/if_pppoe.c	2003/08/15 13:56:47
@@ -830,6 +830,14 @@
 			sc->sc_eth_if = ifunit(parms->eth_ifname);
 			if (sc->sc_eth_if == NULL)
 				return ENXIO;
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+			if (sc->sc_eth_if->if_type == IFT_ETHER) {
+				/* It shouldn't be anything else anyway */
+				struct ethercom *ec = (struct ethercom *)sc->sc_eth_if;
+				if ((ec->ec_capabilities & ETHERCAP_PPPOE_MRU))
+					ec->ec_capenable |= ETHERCAP_PPPOE_MRU;
+			}
+#endif
 		}
 		if (parms->ac_name) {
 			size_t s;
Index: net/if_ether.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_ether.h,v
retrieving revision 1.34
diff -u -r1.34 if_ether.h
--- net/if_ether.h	2003/08/07 16:32:51	1.34
+++ net/if_ether.h	2003/08/15 13:56:47
@@ -56,6 +56,9 @@
  * Some Ethernet extensions.
  */
 #define	ETHER_VLAN_ENCAP_LEN 4	/* length of 802.1Q VLAN encapsulation */
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+#define	ETHER_PPPOE_ENCAP_LEN 8
+#endif
 
 /*
  * Ethernet address - 6 octets
@@ -86,10 +89,18 @@
  * Compute the maximum frame size based on ethertype (i.e. possible
  * encapsulation) and whether or not an FCS is present.
  */
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
 #define	ETHER_MAX_FRAME(ifp, etype, hasfcs)				\
 	((ifp)->if_mtu + ETHER_HDR_LEN +				\
 	 ((hasfcs) ? ETHER_CRC_LEN : 0) +				\
+	 (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0) +	\
+	 (((etype) == ETHERTYPE_PPPOE) ? ETHER_PPPOE_ENCAP_LEN : 0))
+#else
+#define ETHER_MAX_FRAME(ifp, etype, hasfcs)				\
+	((ifp)->if_mtu + ETHER_HDR_LEN +				\
+	 ((hasfcs) ? ETHER_CRC_LEN : 0) +				\
 	 (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))
+#endif
 
 /*
  * Ethernet CRC32 polynomials (big- and little-endian verions).
@@ -166,6 +177,9 @@
 #define	ETHERCAP_VLAN_MTU	0x00000001	/* VLAN-compatible MTU */
 #define	ETHERCAP_VLAN_HWTAGGING	0x00000002	/* hardware VLAN tag support */
 #define	ETHERCAP_JUMBO_MTU	0x00000004	/* 9000 byte MTU supported */
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+#define	ETHERCAP_PPPOE_MRU	0x00000008	/* 1508 byte MTU supported */
+#endif
 
 #ifdef	_KERNEL
 extern u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN];
Index: dev/ic/tulip.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/tulip.c,v
retrieving revision 1.122
diff -u -r1.122 tulip.c
--- dev/ic/tulip.c	2003/02/26 06:31:10	1.122
+++ dev/ic/tulip.c	2003/08/15 13:56:56
@@ -501,6 +501,9 @@
 	 * We can support 802.1Q VLAN-sized frames.
 	 */
 	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+	sc->sc_ethercom.ec_capabilities |= ETHERCAP_PPPOE_MRU;
+#endif
 
 	/*
 	 * Attach the interface.
@@ -1267,7 +1270,12 @@
 		 * error.
 		 */
 		if (rxstat & TDSTAT_ES &&
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+		    ((sc->sc_ethercom.ec_capenable &
+		      (ETHERCAP_PPPOE_MRU | ETHERCAP_VLAN_MTU)) == 0 ||
+#else
 		    ((sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) == 0 ||
+#endif
 		     (rxstat & (TDSTAT_Rx_DE | TDSTAT_Rx_RF |
 				TDSTAT_Rx_DB | TDSTAT_Rx_CE)) != 0)) {
 #define	PRINTERR(bit, str)						\
Index: dev/ic/dp8390.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/dp8390.c,v
retrieving revision 1.52
diff -u -r1.52 dp8390.c
--- dev/ic/dp8390.c	2003/01/15 22:20:05	1.52
+++ dev/ic/dp8390.c	2003/08/15 13:56:59
@@ -156,6 +156,11 @@
 	 */
 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
 
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+	/* At least the RealTek 8029 supports this out of the box */
+	sc->sc_ec.ec_capabilities |= ETHERCAP_PPPOE_MRU;
+#endif
+
 	/* Attach the interface. */
 	if_attach(ifp);
 	ether_ifattach(ifp, sc->sc_enaddr);
Index: dev/pci/if_sip.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_sip.c,v
retrieving revision 1.79
diff -u -r1.79 if_sip.c
--- dev/pci/if_sip.c	2003/08/15 07:29:34	1.79
+++ dev/pci/if_sip.c	2003/08/15 13:57:05
@@ -968,6 +968,13 @@
 	 * We can support 802.1Q VLAN-sized frames.
 	 */
 	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+	/*
+	 * We can support very long frames for broken PPPoE
+	 * implementations.
+	 */
+	sc->sc_ethercom.ec_capabilities |= ETHERCAP_PPPOE_MRU;
+#endif
 
 #ifdef DP83820
 	/*
@@ -2319,8 +2326,14 @@
 	* Accept packets >1518 bytes (including FCS) so we can handle
 	* 802.1q-tagged frames properly.
 	*/
+#ifdef PPPOE_ACCEPT_LARGE_FRAMES
+	/* It is also true for PPPOE frames */
+	if (sc->sc_ethercom.ec_capenable &
+	    (ETHERCAP_VLAN_MTU | ETHERCAP_PPPOE_MRU))
+#else
 	if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU)
 		sc->sc_rxcfg |= RXCFG_ALP;
+#endif
 #endif
 	bus_space_write_4(st, sh, SIP_RXCFG, sc->sc_rxcfg);
 

--Multipart_Fri__15_Aug_2003_16:13:14_+0200_08eb4a00--