Commit a346abe0 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

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: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 954a5a02
...@@ -1452,7 +1452,7 @@ flowlabel_reflect - INTEGER ...@@ -1452,7 +1452,7 @@ flowlabel_reflect - INTEGER
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
This is a mask of two bits. This is a bitmask.
1: enabled for established flows 1: enabled for established flows
Note that this prevents automatic flowlabel changes, as done Note that this prevents automatic flowlabel changes, as done
...@@ -1463,6 +1463,8 @@ flowlabel_reflect - INTEGER ...@@ -1463,6 +1463,8 @@ flowlabel_reflect - INTEGER
If set, a RST packet sent in response to a SYN packet on a closed If set, a RST packet sent in response to a SYN packet on a closed
port will reflect the incoming flow label. port will reflect the incoming flow label.
4: enabled for ICMPv6 echo reply messages.
Default: 0 Default: 0
fib_multipath_hash_policy - INTEGER fib_multipath_hash_policy - INTEGER
......
...@@ -301,6 +301,13 @@ struct ipv6_txoptions { ...@@ -301,6 +301,13 @@ struct ipv6_txoptions {
/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
}; };
/* flowlabel_reflect sysctl values */
enum flowlabel_reflect {
FLOWLABEL_REFLECT_ESTABLISHED = 1,
FLOWLABEL_REFLECT_TCP_RESET = 2,
FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES = 4,
};
struct ip6_flowlabel { struct ip6_flowlabel {
struct ip6_flowlabel __rcu *next; struct ip6_flowlabel __rcu *next;
__be32 label; __be32 label;
......
...@@ -208,7 +208,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol, ...@@ -208,7 +208,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 & 1; np->repflow = net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ESTABLISHED;
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
......
...@@ -703,6 +703,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -703,6 +703,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY; tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
memset(&fl6, 0, sizeof(fl6)); memset(&fl6, 0, sizeof(fl6));
if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_ICMPV6_ECHO_REPLIES)
fl6.flowlabel = ip6_flowlabel(ipv6_hdr(skb));
fl6.flowi6_proto = IPPROTO_ICMPV6; fl6.flowi6_proto = IPPROTO_ICMPV6;
fl6.daddr = ipv6_hdr(skb)->saddr; fl6.daddr = ipv6_hdr(skb)->saddr;
if (saddr) if (saddr)
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
static int zero; static int zero;
static int one = 1; static int one = 1;
static int three = 3; static int flowlabel_reflect_max = 0x7;
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;
...@@ -116,7 +116,7 @@ static struct ctl_table ipv6_table_template[] = { ...@@ -116,7 +116,7 @@ static struct ctl_table ipv6_table_template[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec,
.extra1 = &zero, .extra1 = &zero,
.extra2 = &three, .extra2 = &flowlabel_reflect_max,
}, },
{ {
.procname = "max_dst_opts_number", .procname = "max_dst_opts_number",
......
...@@ -989,7 +989,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) ...@@ -989,7 +989,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
if (sk->sk_state == TCP_TIME_WAIT) if (sk->sk_state == TCP_TIME_WAIT)
label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel); label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel);
} else { } else {
if (net->ipv6.sysctl.flowlabel_reflect & 2) if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_TCP_RESET)
label = ip6_flowlabel(ipv6h); label = ip6_flowlabel(ipv6h);
} }
......
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