--- zzzz-none-000/linux-2.4.17/net/ipv4/ip_sockglue.c 2001-10-30 23:08:12.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/net/ipv4/ip_sockglue.c 2004-11-24 13:22:09.000000000 +0000 @@ -5,7 +5,7 @@ * * The IP to API glue. * - * Version: $Id: ip_sockglue.c,v 1.61 2001/10/20 00:00:11 davem Exp $ + * Version: $Id: ip_sockglue.c,v 1.2 2003/12/04 18:28:11 mhassler Exp $ * * Authors: see ip.c * @@ -474,21 +474,47 @@ sk->protinfo.af_inet.cmsg_flags &= ~IP_CMSG_RETOPTS; break; case IP_TOS: /* This sets both TOS and Precedence */ - if (sk->type == SOCK_STREAM) { - val &= ~3; - val |= sk->protinfo.af_inet.tos & 3; - } - if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && - !capable(CAP_NET_ADMIN)) { - err = -EPERM; - break; - } - if (sk->protinfo.af_inet.tos != val) { - sk->protinfo.af_inet.tos=val; - sk->priority = rt_tos2priority(val); - sk_dst_reset(sk); - } + { + int extension_mode = 0; + if (optlen >= sizeof(int)) + { + if (val & 0x8000) + { + extension_mode = 1; + if (val & 0x4000) + sk->priority = 0xFFFF; /* EF1 -- No mapping */ + else + sk->priority = 6; + printk("DEBUG: Extension Mode SKB->Priority=0x%x\n",sk->priority); + + /* Reset the extension bits. */ + val = val & 0xFF; + } + } + + /* If non extension mode or if the MSB of 2nd byte was not set.*/ + if (sk->type == SOCK_STREAM) { + val &= ~3; + val |= sk->protinfo.af_inet.tos & 3; + } + if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && + !capable(CAP_NET_ADMIN)) { + err = -EPERM; + break; + } + if (sk->protinfo.af_inet.tos != val) + { + sk->protinfo.af_inet.tos=val; + + /* Only in non-extension mode set the priority. In extension mode the priority + * has already been set above. */ + if (extension_mode == 0) + sk->priority = rt_tos2priority(val); + sk_dst_reset(sk); + } + printk("DEBUG: SKB->Priority=0x%x\n",sk->priority); break; + } case IP_TTL: if (optlen<1) goto e_inval;