tcp: reflect tos value received in SYN to the socket
This commit adds a new TCP feature to reflect the tos value received in SYN, and send it out on the SYN-ACK, and eventually set the tos value of the established socket with this reflected tos value. This provides a way to set the traffic class/QoS level for all traffic in the same connection to be the same as the incoming SYN request. It could be useful in data centers to provide equivalent QoS according to the incoming request. This feature is guarded by /proc/sys/net/ipv4/tcp_reflect_tos, and is by default turned off. Signed-off-by: Wei Wang <weiwan@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
de033b7d15
commit
ac8f1710c1
@@ -510,6 +510,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
|
||||
struct flowi6 *fl6 = &fl->u.ip6;
|
||||
struct sk_buff *skb;
|
||||
int err = -ENOMEM;
|
||||
u8 tclass;
|
||||
|
||||
/* First, grab a route. */
|
||||
if (!dst && (dst = inet6_csk_route_req(sk, fl6, req,
|
||||
@@ -528,9 +529,12 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
|
||||
|
||||
rcu_read_lock();
|
||||
opt = ireq->ipv6_opt;
|
||||
tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ?
|
||||
tcp_rsk(req)->syn_tos : np->tclass;
|
||||
if (!opt)
|
||||
opt = rcu_dereference(np->opt);
|
||||
err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt, np->tclass,
|
||||
err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt,
|
||||
tclass & ~INET_ECN_MASK,
|
||||
sk->sk_priority);
|
||||
rcu_read_unlock();
|
||||
err = net_xmit_eval(err);
|
||||
@@ -1310,6 +1314,10 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
||||
if (np->repflow)
|
||||
newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb));
|
||||
|
||||
/* Set ToS of the new socket based upon the value of incoming SYN. */
|
||||
if (sock_net(sk)->ipv4.sysctl_tcp_reflect_tos)
|
||||
newnp->tclass = tcp_rsk(req)->syn_tos & ~INET_ECN_MASK;
|
||||
|
||||
/* Clone native IPv6 options from listening socket (if any)
|
||||
|
||||
Yes, keeping reference count would be much more clever,
|
||||
|
Reference in New Issue
Block a user