Re: linux kernel 2.6.9-rc4, skb->mac.ethernet => eth_hdr(skb) issues.

Joerg Albert <[email protected]> Thu, 14 Oct 2004 05:51:22 +0200 (CEST)
Newsgroups gmane.linux.drivers.at76c503a.user
Message-ID <[email protected]>
Hi,

On Wed, 13 Oct 2004, Emil wrote:

> Hello, you who this might concern.
>
> I have been trying to compile with the following results:
>
> --snip--
> /usr/src/atm/at76c503a/at76c503.c: In function `ieee80211_to_eth':
> /usr/src/atm/at76c503a/at76c503.c:3903: error: union has no member named
> `ethernet'
> --snip--
>
> at76c503.c - 3902-3903:
>   eth_hdr = (struct ethhdr *)(skb->data-sizeof(struct ethhdr));
> 	  skb->mac.ethernet = eth_hdr;
>
> Related changes to the kernel i found in this file:
> /usr/src/linux/include/linux/if_ether.h
>
> Found on google; This error and sollution is most likely because
> of the same changes in the linux kernel, need different sollution
> though:
> http://pvrguide.no-ip.com/bbs-old/viewtopic/9079.html
>
> If I was abit better at this level of network-coding I could have made
> a patch, but I failed at that. My patched driver never returned any pings.
> And my conclusion to that is that I screwed up the ethernet-header. :-(
>
> Hopefully this is no match for the maintainers of this driver and they
> can fix this so that the forthcoming kernel 2.6.9 will work as a charm.

Could you please try the attached patch against 0.12beta21 (might work
against former versions as well) - I don't have a 2.6.9-rc4 here at the
moment.

Thanks!

/Jörg.
eth_hdr.patch (text/plain, 3.9 KB)
Index: at76c503.c
===================================================================
RCS file: /cvsroot/at76c503a/at76c503a/at76c503.c,v
retrieving revision 1.71
diff -u -r1.71 at76c503.c
--- at76c503.c	14 Oct 2004 01:21:21 -0000	1.71
+++ at76c503.c	14 Oct 2004 01:42:24 -0000
@@ -178,6 +178,10 @@
 
 #endif //#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9)
+# define eth_hdr(s) (s)->mac.ethernet
+#endif
+
 /* wireless extension level this source currently supports */
 #define WIRELESS_EXT_SUPPORTED	16
 
@@ -3855,7 +3859,7 @@
 static void ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
 {
 	struct ieee802_11_hdr *i802_11_hdr;
-	struct ethhdr *eth_hdr;
+	struct ethhdr *eth_hdr_p;
 	u8 *src_addr;
 	u8 *dest_addr;
 	unsigned short proto = 0;
@@ -3878,9 +3882,9 @@
 	       				    : i802_11_hdr->addr3;
 	dest_addr = i802_11_hdr->addr1;
 
-	eth_hdr = (struct ethhdr *)skb->data;
-	if (!memcmp(eth_hdr->h_source, src_addr, ETH_ALEN) &&
-	    !memcmp(eth_hdr->h_dest, dest_addr, ETH_ALEN)) {
+	eth_hdr_p = (struct ethhdr *)skb->data;
+	if (!memcmp(eth_hdr_p->h_source, src_addr, ETH_ALEN) &&
+	    !memcmp(eth_hdr_p->h_dest, dest_addr, ETH_ALEN)) {
 		/* An ethernet frame is encapsulated within the data portion.
 		 * Just use its header instead. */
 		skb_pull(skb, sizeof(struct ethhdr));
@@ -3911,19 +3915,19 @@
 #endif /* IEEE_STANDARD */
 	}
 
-	eth_hdr = (struct ethhdr *)(skb->data-sizeof(struct ethhdr));
-	skb->mac.ethernet = eth_hdr;
+	eth_hdr_p = (struct ethhdr *)(skb->data-sizeof(struct ethhdr));
+	eth_hdr(skb) = eth_hdr_p;
 	if (build_ethhdr) {
-		/* This needs to be done in this order (eth_hdr->h_dest may
+		/* This needs to be done in this order (eth_hdr_p->h_dest may
 		 * overlap src_addr) */
-		memcpy(eth_hdr->h_source, src_addr, ETH_ALEN);
-		memcpy(eth_hdr->h_dest, dest_addr, ETH_ALEN);
+		memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
+		memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
 		/* make an 802.3 header (proto = length) */
-		eth_hdr->h_proto = proto;
+		eth_hdr_p->h_proto = proto;
 	}
 
-	if (ntohs(eth_hdr->h_proto) > 1518) {
-		skb->protocol = eth_hdr->h_proto;
+	if (ntohs(eth_hdr_p->h_proto) > 1518) {
+		skb->protocol = eth_hdr_p->h_proto;
 	} else if (*(unsigned short *)skb->data == 0xFFFF) {
 		/* Magic hack for Novell IPX-in-802.3 packets */
 		skb->protocol = htons(ETH_P_802_3);
@@ -3937,8 +3941,8 @@
 	{
 		char da[3*ETH_ALEN], sa[3*ETH_ALEN];
 		dbg_uc("%s: EXIT skb da %s sa %s proto x%04x len %d data %s", __FUNCTION__,
-		       hex2str(da, skb->mac.ethernet->h_dest, ETH_ALEN, ':'),
-		       hex2str(sa, skb->mac.ethernet->h_source, ETH_ALEN, ':'),
+		       hex2str(da, eth_hdr(skb)->h_dest, ETH_ALEN, ':'),
+		       hex2str(sa, eth_hdr(skb)->h_source, ETH_ALEN, ':'),
 		       ntohs(skb->protocol), skb->len,
 		       hex2str(dev->obuf, skb->data, 
 			       min((int)sizeof(dev->obuf)/3,64), ' '));
@@ -3953,7 +3957,7 @@
 static void ieee80211_fixup(struct sk_buff *skb, int iw_mode)
 {
 	struct ieee802_11_hdr *i802_11_hdr;
-	struct ethhdr *eth_hdr;
+	struct ethhdr *eth_hdr_p;
 	u8 *src_addr;
 	u8 *dest_addr;
 	unsigned short proto = 0;
@@ -3968,13 +3972,13 @@
 
 	skb->mac.raw = (unsigned char *)i802_11_hdr;
 
-	eth_hdr = (struct ethhdr *)skb->data;
-	if (!memcmp(eth_hdr->h_source, src_addr, ETH_ALEN) &&
-	    !memcmp(eth_hdr->h_dest, dest_addr, ETH_ALEN)) {
+	eth_hdr_p = (struct ethhdr *)skb->data;
+	if (!memcmp(eth_hdr_p->h_source, src_addr, ETH_ALEN) &&
+	    !memcmp(eth_hdr_p->h_dest, dest_addr, ETH_ALEN)) {
 		/* There's an ethernet header encapsulated within the data
 		 * portion, count it as part of the hardware header */
 		skb_pull(skb, sizeof(struct ethhdr));
-		proto = eth_hdr->h_proto;
+		proto = eth_hdr_p->h_proto;
 	} else if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
 		/* SNAP frame - collapse it */
 		/* RFC1042/802.1h encapsulated packet.  Treat the SNAP header