ipv6: Add sysctl for per namespace flow label reflection
authorJakub Sitnicki <jkbs@redhat.com>
Wed, 23 Aug 2017 07:55:41 +0000 (09:55 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 25 Aug 2017 01:05:43 +0000 (18:05 -0700)
Reflecting IPv6 Flow Label at server nodes is useful in environments
that employ multipath routing to load balance the requests. As "IPv6
Flow Label Reflection" standard draft [1] points out - ICMPv6 PTB error
messages generated in response to a downstream packets from the server
can be routed by a load balancer back to the original server without
looking at transport headers, if the server applies the flow label
reflection. This enables the Path MTU Discovery past the ECMP router in
load-balance or anycast environments where each server node is reachable
by only one path.

Introduce a sysctl to enable flow label reflection per net namespace for
all newly created sockets. Same could be earlier achieved only per
socket by setting the IPV6_FL_F_REFLECT flag for the IPV6_FLOWLABEL_MGR
socket option.

[1] https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01

Signed-off-by: Jakub Sitnicki <jkbs@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/ip-sysctl.txt
include/net/netns/ipv6.h
net/ipv6/af_inet6.c
net/ipv6/sysctl_net_ipv6.c

index 84c9b8cee780bd219d60a4e65b39634a1913f967..6b0bc0f715346a097a6df46e2ba2771359abcd23 100644 (file)
@@ -1350,6 +1350,15 @@ flowlabel_state_ranges - BOOLEAN
        FALSE: disabled
        Default: true
 
+flowlabel_reflect - BOOLEAN
+       Automatically reflect the flow label. Needed for Path MTU
+       Discovery to work with Equal Cost Multipath Routing in anycast
+       environments. See RFC 7690 and:
+       https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01
+       TRUE: enabled
+       FALSE: disabled
+       Default: FALSE
+
 anycast_src_echo_reply - BOOLEAN
        Controls the use of anycast addresses as source addresses for ICMPv6
        echo reply
index 0e50bf3ed0971ccbc06494a7310160a86bec4637..2544f9760a4263b7f1b8d622331ca63038586137 100644 (file)
@@ -36,6 +36,7 @@ struct netns_sysctl_ipv6 {
        int idgen_retries;
        int idgen_delay;
        int flowlabel_state_ranges;
+       int flowlabel_reflect;
 };
 
 struct netns_ipv6 {
index 3b58ee709f3394cdf176269b6330835acb4c4f74..fe5262fd6aa5c2e270f910a8b0231ec3b2929a81 100644 (file)
@@ -211,6 +211,7 @@ lookup_protocol:
        np->mc_loop     = 1;
        np->pmtudisc    = IPV6_PMTUDISC_WANT;
        np->autoflowlabel = ip6_default_np_autolabel(net);
+       np->repflow     = net->ipv6.sysctl.flowlabel_reflect;
        sk->sk_ipv6only = net->ipv6.sysctl.bindv6only;
 
        /* Init the ipv4 part of the socket since we can have sockets
index 69c50e737c5462384a4c6a82b500c96621b53392..6fbf8ae5e52cccd10bca77793a368ee3166bf01e 100644 (file)
@@ -90,6 +90,13 @@ static struct ctl_table ipv6_table_template[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec
        },
+       {
+               .procname       = "flowlabel_reflect",
+               .data           = &init_net.ipv6.sysctl.flowlabel_reflect,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
        { }
 };
 
@@ -149,6 +156,7 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
        ipv6_table[6].data = &net->ipv6.sysctl.idgen_delay;
        ipv6_table[7].data = &net->ipv6.sysctl.flowlabel_state_ranges;
        ipv6_table[8].data = &net->ipv6.sysctl.ip_nonlocal_bind;
+       ipv6_table[9].data = &net->ipv6.sysctl.flowlabel_reflect;
 
        ipv6_route_table = ipv6_route_sysctl_init(net);
        if (!ipv6_route_table)