ipv6: add flowlabel_consistency sysctl
authorFlorent Fourcot <florent.fourcot@enst-bretagne.fr>
Fri, 17 Jan 2014 16:15:05 +0000 (17:15 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Jan 2014 01:12:31 +0000 (17:12 -0800)
With the introduction of IPV6_FL_F_REFLECT, there is no guarantee of
flow label unicity. This patch introduces a new sysctl to protect the old
behaviour, enable by default.

Changelog of V3:
 * rename ip6_flowlabel_consistency to flowlabel_consistency
 * use net_info_ratelimited()
 * checkpatch cleanups

Signed-off-by: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
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/ip6_flowlabel.c
net/ipv6/sysctl_net_ipv6.c

index c97932c88ea3a39b8547d67df667061c9b677a30..5de03740cdd50c4177d649bc1675c7e412526651 100644 (file)
@@ -1118,6 +1118,14 @@ bindv6only - BOOLEAN
 
        Default: FALSE (as specified in RFC3493)
 
+flowlabel_consistency - BOOLEAN
+       Protect the consistency (and unicity) of flow label.
+       You have to disable it to use IPV6_FL_F_REFLECT flag on the
+       flow label manager.
+       TRUE: enabled
+       FALSE: disabled
+       Default: TRUE
+
 anycast_src_echo_reply - BOOLEAN
        Controls the use of anycast addresses as source addresses for ICMPv6
        echo reply
index 592fecd2e59efa19b1d91db88f6ba99865c03633..21edaf1f79161535af7ae1ae3ae7535ff1a236e3 100644 (file)
@@ -27,6 +27,7 @@ struct netns_sysctl_ipv6 {
        int ip6_rt_gc_elasticity;
        int ip6_rt_mtu_expires;
        int ip6_rt_min_advmss;
+       int flowlabel_consistency;
        int icmpv6_time;
        int anycast_src_echo_reply;
 };
index c921d5d388313876ff497bccd7ad44ee4e48453f..d935889f1008ae93ff1efe52badeedf41352f257 100644 (file)
@@ -775,6 +775,7 @@ static int __net_init inet6_net_init(struct net *net)
 
        net->ipv6.sysctl.bindv6only = 0;
        net->ipv6.sysctl.icmpv6_time = 1*HZ;
+       net->ipv6.sysctl.flowlabel_consistency = 1;
        atomic_set(&net->ipv6.rt_genid, 0);
 
        err = ipv6_init_mibs(net);
index 01bf2524c72aeef5cd104f2074f140c2972ef20a..dfa41bb4e0dc0a97a9de933716ef9dbbabe5475d 100644 (file)
@@ -588,8 +588,15 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
 
        case IPV6_FL_A_GET:
                if (freq.flr_flags & IPV6_FL_F_REFLECT) {
+                       struct net *net = sock_net(sk);
+                       if (net->ipv6.sysctl.flowlabel_consistency) {
+                               net_info_ratelimited("Can not set IPV6_FL_F_REFLECT if flowlabel_consistency sysctl is enable\n");
+                               return -EPERM;
+                       }
+
                        if (sk->sk_protocol != IPPROTO_TCP)
                                return -ENOPROTOOPT;
+
                        np->repflow = 1;
                        return 0;
                }
index b51b2688102cf025ae98c314eb605dd7cd3000f9..7f405a168822afab4fa5349317ef43f2ed8e3a0f 100644 (file)
@@ -31,6 +31,13 @@ static struct ctl_table ipv6_table_template[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec
        },
+       {
+               .procname       = "flowlabel_consistency",
+               .data           = &init_net.ipv6.sysctl.flowlabel_consistency,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
        { }
 };
 
@@ -59,6 +66,7 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
                goto out;
        ipv6_table[0].data = &net->ipv6.sysctl.bindv6only;
        ipv6_table[1].data = &net->ipv6.sysctl.anycast_src_echo_reply;
+       ipv6_table[2].data = &net->ipv6.sysctl.flowlabel_consistency;
 
        ipv6_route_table = ipv6_route_sysctl_init(net);
        if (!ipv6_route_table)