Subject: Re: IP Header CRC problems

From: "Pieter Truter" <[email-masked]>
Date: Wed, 10 May 2000 07:46:18 -0700

To clear things up:

I got this explanation from Alexander Shulz: (He had the same problem long
ago)

On the arm, it is important, that the ip header is on a 32 bit boundry.

My problem was a missing skb_reserve(skb, 2); in the receiver code. The skb
is allocated on a 32bit-boundry, the ethernet header is 14 bytes long.
This statement moves the ethernet header to byte 2 of the skb, so that the
ip-header starts at byte 16, thus 32bit alligned. You must create the skb
with 2 bytes more of course.

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]
++        Please use [email-masked] for           ++
++                        kernel-related discussions.                      ++

---

From: Paul Koning <[email-masked]>
Date: Wed, 10 May 2000 11:09:34 -0400 (EDT)

>>>>> "Pieter" == Pieter Truter <[email-masked]> writes:

 Pieter> To clear things up: I got this explanation from Alexander
 Pieter> Shulz: (He had the same problem long ago)

 Pieter> On the arm, it is important, that the ip header is on a 32
 Pieter> bit boundry.

I would call that a bug, if it is true.

 Pieter> My problem was a missing skb_reserve(skb, 2); in the receiver
 Pieter> code. The skb is allocated on a 32bit-boundry, the ethernet
 Pieter> header is 14 bytes long.  This statement moves the ethernet
 Pieter> header to byte 2 of the skb, so that the ip-header starts at
 Pieter> byte 16, thus 32bit alligned. You must create the skb with 2
 Pieter> bytes more of course.

Unfortunately, that solution is not going to work in many cases.

The most obvious reason is that many (probably most) Ethernet DMA
engines require 4-byte aligned receive starting addresses.  If you
offset the receive address by 2 bytes, either they will not work at
all or the offset is simply ignored.

Another reason is that, in a more general protocol stack, you cannot
know ahead of time how many bytes of header there are.  So you may
find that your "plain old" IP traffic is naturally aligned, but some
random tunneled or bridged case then is forced to an odd boundary.

It is just barely possible to build into protocol stacks an assumption
that everything is aligned to even (multiple of 2) boundaries.  That's
about as good as you can do, and to do this you have to refuse PPP
header compression.  (Then again, that's wise anyway, it's an absurd
feature.)  In general, you have *no* chance of forcing 4 byte
alignment on incoming traffic.

	  paul

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Wed, 10 May 2000 21:28:11 +0100 (BST)

> I would call that a bug, if it is true.

True, and its a historic bug of the Linux kernel, not the ARM architecture
in the way it handles the packets.  It is just wrong if you read any C
standard.  (the use of structs to represent external data is fraught
on architecture independent applications).

> Unfortunately, that solution is not going to work in many cases.

This is the exact reason why we have the kernel alignment trap handler.
Ok, so it makes the processing of these packets slow, but at least it
works.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |            http://www.arm.linux.org.uk/            /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |