Subject: Re: ECN and the DSCP field
To: None <tech-net@NetBSD.org>
From: David Young <dyoung@pobox.com>
List: tech-net
Date: 06/06/2006 12:13:11
On Tue, Jun 06, 2006 at 05:49:39PM +0100, Rui Paulo wrote:
> Hi,
> As you might know, RFC 2474 introduces a new field called
> "Differentiated Services".
>
> Quoting the RFC:
>
> The DS field structure is presented below:
>
>
> 0 1 2 3 4 5 6 7
> +---+---+---+---+---+---+---+---+
> | DSCP | CU |
> +---+---+---+---+---+---+---+---+
>
> DSCP: differentiated services codepoint
> CU: currently unused
>
> This replaces the ip_tos field with a more fine grained type of
> service control.
> DSCP can have serveral values, assigned from IANA and available from:
> http://www.iana.org/assignments/dscp-registry.
>
> The CU bits are now used by ECN indicating (from RFC 3168):
>
> Bits 6-7, ECN Field:
>
> Binary Keyword References
> ------ ------- ----------
> 00 Not-ECT (Not ECN-Capable Transport) [RFC 3168]
> 01 ECT(1) (ECN-Capable Transport(1)) [RFC 3168]
> 10 ECT(0) (ECN-Capable Transport(0)) [RFC 3168]
> 11 CE (Congestion Experienced) [RFC 3168]
>
> So, what I was thinking was replacing our ip_tos field in 'struct ip'
> by something like:
>
> struct ip {
>
> [...]
>
> union {
> struct ip_ds { /* differentiated services */
> #if BYTE_ORDER == LITTLE_ENDIAN
> u_int8_t ds_ecn:2; /* ecn field */
> u_int8_t ds_cp:6; /* diffserv codepoint */
> #endif
> #if BYTE_ORDER == BIG_ENDIAN
> u_int8_t ds_cp:6; /* diffserv codepoint */
> u_int8_t ds_ecn:2; /* ecn field */
> #endif
> } ip_ds __attribute__((__packed__));
I think bitfields are just fine for flags and other tiny fields, but
I object to the use of bitfields to define any binary format. I don't
think the C standard guarantees any particular bit order, and I would
have to pull out GCC's manual to interpret your ip_ds definition, above.
At a glance, the LITTLE_ENDIAN definition looks backwards.
For defining bitfields, I prefer to use the __BITS() and __BIT() macros.
The resulting definitions are easy to read, to write, and to cross-check
with an RFC or a datasheet:
> 0 1 2 3 4 5 6 7
> +---+---+---+---+---+---+---+---+
> | DSCP | CU |
> +---+---+---+---+---+---+---+---+
struct ip {
[...]
union {
uint8_t ip_ds; /* differentiated services */
#define IP_DS_ECN_MASK __BITS(7,6) /* ecn field */
#define IP_DS_CP_MASK __BITS(5,0) /* diffserv codepoint */
uint8_t ip_tos; /* type of service */
} ip_dsf __attribute__((__packed__));
}
Reading/writing the fields is easy with SHIFTIN()/SHIFTOUT().
(I still owe NetBSD a manual page on these macros....)
Dave
--
David Young OJC Technologies
dyoung@ojctech.com Urbana, IL * (217) 278-3933