diff options
author | Eric Dumazet <edumazet@google.com> | 2019-07-01 09:39:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-01 13:54:51 -0400 |
commit | a346abe051bd2bd0d5d0140b2da9ec95639acad7 (patch) | |
tree | 1e03874ac049b3d298d382e678a84b68f7ce5f12 | |
parent | 954a5a029472568845a25cd1c59e02e09db3316c (diff) |
ipv6: icmp: allow flowlabel reflection in echo replies
Extend flowlabel_reflect bitmask to allow conditional
reflection of incoming flowlabels in echo replies.
Note this has precedence against auto flowlabels.
Add flowlabel_reflect enum to replace hard coded
values.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 4 | ||||
-rw-r--r-- | include/net/ipv6.h | 7 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 3 | ||||
-rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 4 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 2 |
6 files changed, 17 insertions, 5 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index e0d8a96e2c67..f0e6d1f53485 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -1452,7 +1452,7 @@ flowlabel_reflect - INTEGER | |||
1452 | environments. See RFC 7690 and: | 1452 | environments. See RFC 7690 and: |
1453 | https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01 | 1453 | https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01 |
1454 | 1454 | ||
1455 | This is a mask of two bits. | 1455 | This is a bitmask. |
1456 | 1: enabled for established flows | 1456 | 1: enabled for established flows |
1457 | 1457 | ||
1458 | Note that this prevents automatic flowlabel changes, as done | 1458 | Note that this prevents automatic flowlabel changes, as done |
@@ -1463,6 +1463,8 @@ flowlabel_reflect - INTEGER | |||
1463 | If set, a RST packet sent in response to a SYN packet on a closed | 1463 | If set, a RST packet sent in response to a SYN packet on a closed |
1464 | port will reflect the incoming flow label. | 1464 | port will reflect the incoming flow label. |
1465 | 1465 | ||
1466 | 4: enabled for ICMPv6 echo reply messages. | ||
1467 | |||
1466 | Default: 0 | 1468 | Default: 0 |
1467 | 1469 | ||
1468 | fib_multipath_hash_policy - INTEGER | 1470 | fib_multipath_hash_policy - INTEGER |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index b41f6a0fa903..8eca5fb30376 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -301,6 +301,13 @@ struct ipv6_txoptions { | |||
301 | /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ | 301 | /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ |
302 | }; | 302 | }; |
303 | 303 | ||
304 | /* flowlabel_reflect sysctl values */ | ||
305 | enum flowlabel_reflect { | ||
306 | FLOWLABEL_REFLECT_ESTABLISHED = 1, | ||
307 | FLOWLABEL_REFLECT_TCP_RESET = 2, | ||
308 | FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES = 4, | ||
309 | }; | ||
310 | |||
304 | struct ip6_flowlabel { | 311 | struct ip6_flowlabel { |
305 | struct ip6_flowlabel __rcu *next; | 312 | struct ip6_flowlabel __rcu *next; |
306 | __be32 label; | 313 | __be32 label; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 7382a927d1eb..8369af32cef6 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -208,7 +208,7 @@ lookup_protocol: | |||
208 | np->mc_loop = 1; | 208 | np->mc_loop = 1; |
209 | np->mc_all = 1; | 209 | np->mc_all = 1; |
210 | np->pmtudisc = IPV6_PMTUDISC_WANT; | 210 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
211 | np->repflow = net->ipv6.sysctl.flowlabel_reflect & 1; | 211 | np->repflow = net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ESTABLISHED; |
212 | sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; | 212 | sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; |
213 | 213 | ||
214 | /* Init the ipv4 part of the socket since we can have sockets | 214 | /* Init the ipv4 part of the socket since we can have sockets |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 12906301ec7b..62c997201970 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -703,6 +703,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
703 | tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY; | 703 | tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY; |
704 | 704 | ||
705 | memset(&fl6, 0, sizeof(fl6)); | 705 | memset(&fl6, 0, sizeof(fl6)); |
706 | if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES) | ||
707 | fl6.flowlabel = ip6_flowlabel(ipv6_hdr(skb)); | ||
708 | |||
706 | fl6.flowi6_proto = IPPROTO_ICMPV6; | 709 | fl6.flowi6_proto = IPPROTO_ICMPV6; |
707 | fl6.daddr = ipv6_hdr(skb)->saddr; | 710 | fl6.daddr = ipv6_hdr(skb)->saddr; |
708 | if (saddr) | 711 | if (saddr) |
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 6d86fac472e7..8b3fe81783ed 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | static int zero; | 24 | static int zero; |
25 | static int one = 1; | 25 | static int one = 1; |
26 | static int three = 3; | 26 | static int flowlabel_reflect_max = 0x7; |
27 | static int auto_flowlabels_min; | 27 | static int auto_flowlabels_min; |
28 | static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX; | 28 | static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX; |
29 | 29 | ||
@@ -116,7 +116,7 @@ static struct ctl_table ipv6_table_template[] = { | |||
116 | .mode = 0644, | 116 | .mode = 0644, |
117 | .proc_handler = proc_dointvec, | 117 | .proc_handler = proc_dointvec, |
118 | .extra1 = &zero, | 118 | .extra1 = &zero, |
119 | .extra2 = &three, | 119 | .extra2 = &flowlabel_reflect_max, |
120 | }, | 120 | }, |
121 | { | 121 | { |
122 | .procname = "max_dst_opts_number", | 122 | .procname = "max_dst_opts_number", |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 408d9ec26971..4f3f99b39820 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -989,7 +989,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) | |||
989 | if (sk->sk_state == TCP_TIME_WAIT) | 989 | if (sk->sk_state == TCP_TIME_WAIT) |
990 | label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel); | 990 | label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel); |
991 | } else { | 991 | } else { |
992 | if (net->ipv6.sysctl.flowlabel_reflect & 2) | 992 | if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_TCP_RESET) |
993 | label = ip6_flowlabel(ipv6h); | 993 | label = ip6_flowlabel(ipv6h); |
994 | } | 994 | } |
995 | 995 | ||