summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-07-01 09:39:36 -0400
committerDavid S. Miller <davem@davemloft.net>2019-07-01 13:54:51 -0400
commita346abe051bd2bd0d5d0140b2da9ec95639acad7 (patch)
tree1e03874ac049b3d298d382e678a84b68f7ce5f12
parent954a5a029472568845a25cd1c59e02e09db3316c (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.txt4
-rw-r--r--include/net/ipv6.h7
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/icmp.c3
-rw-r--r--net/ipv6/sysctl_net_ipv6.c4
-rw-r--r--net/ipv6/tcp_ipv6.c2
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
1468fib_multipath_hash_policy - INTEGER 1470fib_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 */
305enum flowlabel_reflect {
306 FLOWLABEL_REFLECT_ESTABLISHED = 1,
307 FLOWLABEL_REFLECT_TCP_RESET = 2,
308 FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES = 4,
309};
310
304struct ip6_flowlabel { 311struct 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
24static int zero; 24static int zero;
25static int one = 1; 25static int one = 1;
26static int three = 3; 26static int flowlabel_reflect_max = 0x7;
27static int auto_flowlabels_min; 27static int auto_flowlabels_min;
28static int auto_flowlabels_max = IP6_AUTO_FLOW_LABEL_MAX; 28static 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