[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <010ede54-eb81-73ed-53a4-2f8e762984b1@gmail.com>
Date: Fri, 4 Mar 2022 15:11:21 -0800
From: Dimitrios Bouras <dimitrios.bouras@...il.com>
To: "David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>
Cc: netdev@...r.kernel.org
Subject: Transparently receive IP over LLC/SNAP
Hello everyone,
I hope I've addressed this properly - please be gentle in guiding me if otherwise (it's my first).
Many thanks,
Dimitri
From my commit message for the branch on GitHub:
------------------8<------------------8<------------------8<------------------8<------------------
Add Ethernet over LLC SNAP RX capability to eth.c
Practical use cases exist where being able to receive Ethernet packets encapsulated in LLC SNAP is
useful, while at the same time encapsulating replies (transmitting back) in LLC SNAP is not
required. Accordingly, this is not an attempt to add full-blown support for IP over LLC SNAP, only a
"hack" that "just works" -- see Alan's comment on the the Linux-kernel list on this subject ("Linux
supports LLC/SNAP and various things over it (IPX/Appletalk DDP etc) but not IP over it, as it's one
of those standards bodies driven bogosities which nobody ever actually deployed" --
http://lkml.iu.edu/hypermail/linux/kernel/1107.3/01249.html). It is worth noting, however, that the
networking stack in all recent versions of MS Windows behaves in the exact same way (receives
LLC/SNAP-encapsulated IP just fine but replies in plain IP), even though this doesn't appear to be
documented anywhere.
------------------8<------------------8<------------------8<------------------8<------------------
The unified patch follows:
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index ebcc812735a4..1df5446af922 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -15,23 +15,24 @@
* Alan Cox, <gw4pts@...pts.ampr.org>
*
* Fixes:
- * Mr Linux : Arp problems
- * Alan Cox : Generic queue tidyup (very tiny here)
- * Alan Cox : eth_header ntohs should be htons
- * Alan Cox : eth_rebuild_header missing an htons and
- * minor other things.
- * Tegge : Arp bug fixes.
- * Florian : Removed many unnecessary functions, code cleanup
- * and changes for new arp and skbuff.
- * Alan Cox : Redid header building to reflect new format.
- * Alan Cox : ARP only when compiled with CONFIG_INET
- * Greg Page : 802.2 and SNAP stuff.
- * Alan Cox : MAC layer pointers/new format.
- * Paul Gortmaker : eth_copy_and_sum shouldn't csum padding.
- * Alan Cox : Protect against forwarding explosions with
- * older network drivers and IFF_ALLMULTI.
- * Christer Weinigel : Better rebuild header message.
- * Andrew Morton : 26Feb01: kill ether_setup() - use netdev_boot_setup().
+ * Mr Linux : Arp problems
+ * Alan Cox : Generic queue tidyup (very tiny here)
+ * Alan Cox : eth_header ntohs should be htons
+ * Alan Cox : eth_rebuild_header missing an htons and
+ * minor other things.
+ * Tegge : Arp bug fixes.
+ * Florian : Removed many unnecessary functions, code cleanup
+ * and changes for new arp and skbuff.
+ * Alan Cox : Redid header building to reflect new format.
+ * Alan Cox : ARP only when compiled with CONFIG_INET
+ * Greg Page : 802.2 and SNAP stuff.
+ * Alan Cox : MAC layer pointers/new format.
+ * Paul Gortmaker : eth_copy_and_sum shouldn't csum padding.
+ * Alan Cox : Protect against forwarding explosions with
+ * older network drivers and IFF_ALLMULTI.
+ * Christer Weinigel : Better rebuild header message.
+ * Andrew Morton : 26Feb01: kill ether_setup() - use netdev_boot_setup().
+ * Dimitrios Bouras : May 2021: transparently receive Ethernet over LLC/SNAP.
*/
#include <linux/module.h>
#include <linux/types.h>
@@ -157,6 +158,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
unsigned short _service_access_point;
const unsigned short *sap;
const struct ethhdr *eth;
+ const unsigned char *esn;
skb->dev = dev;
skb_reset_mac_header(skb);
@@ -185,9 +187,32 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
if (unlikely(netdev_uses_dsa(dev)))
return htons(ETH_P_XDSA);
+ /* The protocol field is > 0x0600 so this is an Ethernet frame */
if (likely(eth_proto_is_802_3(eth->h_proto)))
return eth->h_proto;
+ /* Check for Ethernet protocol packets encapsulated in LCC SNAP.
+ * If found, de-encapsulate transparently and feed them upwards
+ * as if they were received inside normal Ethernet frames.
+ *
+ * 6 6 2 1 1 1 5 0-1492 0-38 4
+ * +------+-----+-----+------+------+-----+-------+------+-----+-----+
+ * | Dest | Src | Len | DSAP | SSAP | CTL | Proto | Data | Pad | FCS |
+ * | | | | xAA | xAA | x03 | | | | |
+ * +------+-----+-----+------+------+-----+-------+------+-----+-----+
+ */
+ esn = skb->data;
+ if (esn[0] == 0xAA && esn[1] == 0xAA && esn[2] == 0x03 &&
+ esn[3] == 0x00 && esn[4] == 0x00 && esn[5] == 0x00) {
+ /* pull LLC header (3 bytes) and protocol ID (5 bytes) */
+ /* then recalculate the FCS checksum. After the call, */
+ /* skb->data will be pointing to the IP protocol payload */
+ skb_pull_rcsum(skb, 8);
+ /* pretend that this is an Ethernet frame by returning */
+ /* the encapsulated prototol code (2 LSBytes of Proto) */
+ return *(__be16 *)(esn + 6);
+ }
+
/*
* This is a magic hack to spot IPX packets. Older Novell breaks
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
Powered by blists - more mailing lists