Commit ec01147a authored by David S. Miller's avatar David S. Miller

Merge branch 'tcp-flowlabel'

Eric Dumazet says:

====================
ipv6: tcp: more control on RST flowlabels

First patch allows to reflect incoming IPv6 flowlabel
on RST packets sent when no socket could handle the packet.

Second patch makes sure we send the same flowlabel
for RST or ACK packets on behalf of TIME_WAIT sockets.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e736bf72 50a8accf
...@@ -1429,14 +1429,24 @@ flowlabel_state_ranges - BOOLEAN ...@@ -1429,14 +1429,24 @@ flowlabel_state_ranges - BOOLEAN
FALSE: disabled FALSE: disabled
Default: true Default: true
flowlabel_reflect - BOOLEAN flowlabel_reflect - INTEGER
Automatically reflect the flow label. Needed for Path MTU Control flow label reflection. Needed for Path MTU
Discovery to work with Equal Cost Multipath Routing in anycast Discovery to work with Equal Cost Multipath Routing in anycast
environments. See RFC 7690 and: environments. See RFC 7690 and:
https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01 https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01
TRUE: enabled
FALSE: disabled This is a mask of two bits.
Default: FALSE 1: enabled for established flows
Note that this prevents automatic flowlabel changes, as done
in "tcp: change IPv6 flow-label upon receiving spurious retransmission"
and "tcp: Change txhash on every SYN and RTO retransmit"
2: enabled for TCP RESET packets (no active listener)
If set, a RST packet sent in response to a SYN packet on a closed
port will reflect the incoming flow label.
Default: 0
fib_multipath_hash_policy - INTEGER fib_multipath_hash_policy - INTEGER
Controls which hash policy to use for multipath routes. Controls which hash policy to use for multipath routes.
......
...@@ -212,7 +212,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, ...@@ -212,7 +212,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
np->mc_loop = 1; np->mc_loop = 1;
np->mc_all = 1; np->mc_all = 1;
np->pmtudisc = IPV6_PMTUDISC_WANT; np->pmtudisc = IPV6_PMTUDISC_WANT;
np->repflow = net->ipv6.sysctl.flowlabel_reflect; np->repflow = net->ipv6.sysctl.flowlabel_reflect & 1;
sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; sk->sk_ipv6only = net->ipv6.sysctl.bindv6only;
/* Init the ipv4 part of the socket since we can have sockets /* Init the ipv4 part of the socket since we can have sockets
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
static int zero; static int zero;
static int one = 1; static int one = 1;
static int three = 3;
static int auto_flowlabels_min; static int auto_flowlabels_min;
static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX; static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX;
...@@ -114,6 +115,8 @@ static struct ctl_table ipv6_table_template[] = { ...@@ -114,6 +115,8 @@ static struct ctl_table ipv6_table_template[] = {
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec,
.extra1 = &zero,
.extra2 = &three,
}, },
{ {
.procname = "max_dst_opts_number", .procname = "max_dst_opts_number",
......
...@@ -916,15 +916,17 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 ...@@ -916,15 +916,17 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
{ {
const struct tcphdr *th = tcp_hdr(skb); const struct tcphdr *th = tcp_hdr(skb);
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
u32 seq = 0, ack_seq = 0; u32 seq = 0, ack_seq = 0;
struct tcp_md5sig_key *key = NULL; struct tcp_md5sig_key *key = NULL;
#ifdef CONFIG_TCP_MD5SIG #ifdef CONFIG_TCP_MD5SIG
const __u8 *hash_location = NULL; const __u8 *hash_location = NULL;
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
unsigned char newhash[16]; unsigned char newhash[16];
int genhash; int genhash;
struct sock *sk1 = NULL; struct sock *sk1 = NULL;
#endif #endif
__be32 label = 0;
struct net *net;
int oif = 0; int oif = 0;
if (th->rst) if (th->rst)
...@@ -936,6 +938,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) ...@@ -936,6 +938,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
if (!sk && !ipv6_unicast_destination(skb)) if (!sk && !ipv6_unicast_destination(skb))
return; return;
net = dev_net(skb_dst(skb)->dev);
#ifdef CONFIG_TCP_MD5SIG #ifdef CONFIG_TCP_MD5SIG
rcu_read_lock(); rcu_read_lock();
hash_location = tcp_parse_md5sig_option(th); hash_location = tcp_parse_md5sig_option(th);
...@@ -949,7 +952,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) ...@@ -949,7 +952,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
* Incoming packet is checked with md5 hash with finding key, * Incoming packet is checked with md5 hash with finding key,
* no RST generated if md5 hash doesn't match. * no RST generated if md5 hash doesn't match.
*/ */
sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), sk1 = inet6_lookup_listener(net,
&tcp_hashinfo, NULL, 0, &tcp_hashinfo, NULL, 0,
&ipv6h->saddr, &ipv6h->saddr,
th->source, &ipv6h->daddr, th->source, &ipv6h->daddr,
...@@ -979,9 +982,15 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) ...@@ -979,9 +982,15 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
oif = sk->sk_bound_dev_if; oif = sk->sk_bound_dev_if;
if (sk_fullsock(sk)) if (sk_fullsock(sk))
trace_tcp_send_reset(sk, skb); trace_tcp_send_reset(sk, skb);
if (sk->sk_state == TCP_TIME_WAIT)
label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel);
} else {
if (net->ipv6.sysctl.flowlabel_reflect & 2)
label = ip6_flowlabel(ipv6h);
} }
tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0); tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0,
label);
#ifdef CONFIG_TCP_MD5SIG #ifdef CONFIG_TCP_MD5SIG
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment