0

While I was looking into the source code of linux, I came across the following definition about IPv6 header format and got confused with the order of "priority" and "version" field according to enndianness. I think both fields are 4 bits(nibble) and they are not related to endianness. I don't understand why linux kernel defined ipv6 header like this.

And there is another question about this structure. Accordinig to https://en.wikipedia.org/wiki/IPv6_packet, traffic class is 8 bits and flow lable field is 20 bit but this structure defined them with 4 bits and 24 bits repectively.

struct ipv6hdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8            priority:4,
                version:4;
#elif defined(__BIG_ENDIAN_BITFIELD)
    __u8            version:4,
                priority:4;
#else
#error  "Please fix <asm/byteorder.h>"
#endif
    __u8            flow_lbl[3];

    __be16          payload_len;
    __u8            nexthdr;
    __u8            hop_limit;

    struct  in6_addr    saddr;
    struct  in6_addr    daddr;
};
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
mjshin
  • 1
  • 1
  • Macros `__LITTLE_ENDIAN_BITFIELD` and `__BIG_ENDIAN_BITFIELD` are not about common endianness of bytes. It is "endianess of bits" - internal property of the some compilers. – Tsyvarev Oct 07 '21 at 07:05

1 Answers1

0

While I was looking into the source code of linux, I came across the following definition about IPv6 header format and got confused with the order of "priority" and "version" field according to enndianness. I think both fields are 4 bits(nibble) and they are not related to endianness. I don't understand why linux kernel defined ipv6 header like this.

The fields are, as you say, not related to endianness, but how your platform (your architecture) saves them in memory actually does. Nobody is considering the endianness of TCP/IP in the wire, which is well defined, uniform and unambiguous, but the endianness of your computer, and the #ifs controlling that are for the same source to be compiled without change on both kinds of machines. In order for the source code to be compilable in a {big/low}endian architecture, some measures have to be made for the fields to end in the precise same position in the packet, independent if you encode them in a sun sparcstation, or an intel laptop.

The way normally the encoding is done is to make an exact byte image, byte by byte, of how the packet will be serialized on the wire. This means that if you are little endian machine, the bytes of a 32bit integer have to be exchanged order to appear in the wire always the most signifiant bye first. There are portable ways of doing this, but they normally require more work to be done in the cpu than just to exchange the bytes two by two.

I cannot say if the order of assignment of bits to a bitfield in a word depends on the order of the bitfields itself and this is done differently in {big/low}endian machines, but as you state, if it is done so in the linux kernel, then the answer will be that it probably does. (the main reason being that it works correctly since a lot of time ago, and such an issue would have interrupted tcp/ip communications from the beginning)

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31