diff -Nur linux-2.6.11.10/include/linux/ip.h linux-2.6.11.10-zph/include/linux/ip.h --- linux-2.6.11.10/include/linux/ip.h 2005-05-16 20:51:43.000000000 +0300 +++ linux-2.6.11.10-zph/include/linux/ip.h 2005-05-26 18:21:43.000000000 +0300 @@ -136,6 +136,7 @@ int mc_index; /* Multicast device index */ __u32 mc_addr; struct ip_mc_socklist *mc_list; /* Group array */ + /* * Following members are used to retain the infomation to build * an ip header on each ip fragmentation while the socket is corked. @@ -149,6 +150,7 @@ u32 addr; struct flowi fl; } cork; + __u8 zph_tos; /* ZPH TOS received on connect */ }; #define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */ diff -Nur linux-2.6.11.10/net/ipv4/ip_sockglue.c linux-2.6.11.10-zph/net/ipv4/ip_sockglue.c --- linux-2.6.11.10/net/ipv4/ip_sockglue.c 2005-05-16 20:51:58.000000000 +0300 +++ linux-2.6.11.10-zph/net/ipv4/ip_sockglue.c 2005-05-26 18:21:55.000000000 +0300 @@ -1047,6 +1047,12 @@ int hlim = inet->mc_ttl; put_cmsg(&msg, SOL_IP, IP_TTL, sizeof(hlim), &hlim); } + + if (inet->cmsg_flags&IP_CMSG_TOS) { + int hlim = inet->zph_tos; + put_cmsg(&msg, SOL_IP, IP_TOS, sizeof(hlim), &hlim); + } + len -= msg.msg_controllen; return put_user(len, optlen); } diff -Nur linux-2.6.11.10/net/ipv4/tcp_input.c linux-2.6.11.10-zph/net/ipv4/tcp_input.c --- linux-2.6.11.10/net/ipv4/tcp_input.c 2005-05-16 20:52:00.000000000 +0300 +++ linux-2.6.11.10-zph/net/ipv4/tcp_input.c 2005-05-26 18:22:04.000000000 +0300 @@ -4452,6 +4452,7 @@ struct tcphdr *th, unsigned len) { struct tcp_sock *tp = tcp_sk(sk); + struct inet_sock *inet = inet_sk(sk); int saved_clamp = tp->rx_opt.mss_clamp; tcp_parse_options(skb, &tp->rx_opt, 0); @@ -4508,10 +4509,15 @@ * state to ESTABLISHED..." */ + TCP_ECN_rcv_synack(tp, th); if (tp->ecn_flags&TCP_ECN_OK) sk->sk_no_largesend = 1; + /* ZPH, copy TOS field from the SYNACK packet to zph_tos field + * of the af_inet member of sock structure */ + inet->zph_tos = skb->nh.iph->tos; + tp->snd_wl1 = TCP_SKB_CB(skb)->seq; tcp_ack(sk, skb, FLAG_SLOWPATH);