]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ipv6: lockless IPV6_AUTOFLOWLABEL implementation
authorEric Dumazet <edumazet@google.com>
Tue, 12 Sep 2023 16:02:06 +0000 (16:02 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Sep 2023 09:33:47 +0000 (10:33 +0100)
Move np->autoflowlabel and np->autoflowlabel_set in inet->inet_flags,
to fix data-races.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/ipv6.h
include/net/inet_sock.h
include/net/ipv6.h
net/ipv6/ip6_output.c
net/ipv6/ipv6_sockglue.c

index d88e91b7f0a319a816488025ef213c4fb90ed359..e3be5dc21b7d27080b398f1425bf11145896a4f3 100644 (file)
@@ -253,8 +253,6 @@ struct ipv6_pinfo {
                                                 * 100: prefer care-of address
                                                 */
                                dontfrag:1,
-                               autoflowlabel:1,
-                               autoflowlabel_set:1,
                                rtalert_isolate:1;
        __u8                    min_hopcount;
        __u8                    tclass;
index 97e70a97dae888e6ab93c6446f4f3ba58cd8583e..f1af64a4067310258a3bc45b84ad3fd093bddbab 100644 (file)
@@ -271,6 +271,8 @@ enum {
        INET_FLAGS_MC6_LOOP     = 20,
        INET_FLAGS_RECVERR6_RFC4884 = 21,
        INET_FLAGS_MC6_ALL      = 22,
+       INET_FLAGS_AUTOFLOWLABEL_SET = 23,
+       INET_FLAGS_AUTOFLOWLABEL = 24,
 };
 
 /* cmsg flags for inet */
index 8a04a89853367a6c99d06da220a4ca6a319173bf..4b6cbec059e25ea2e810b47eeace56b041e3efef 100644 (file)
@@ -428,7 +428,7 @@ int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq,
                           int flags);
 int ip6_flowlabel_init(void);
 void ip6_flowlabel_cleanup(void);
-bool ip6_autoflowlabel(struct net *net, const struct ipv6_pinfo *np);
+bool ip6_autoflowlabel(struct net *net, const struct sock *sk);
 
 static inline void fl6_sock_release(struct ip6_flowlabel *fl)
 {
index ab7ede4a731a96fe6dce3205df29b298c923acc7..47aa42f93ccda8b49ed6ecd7a7a07703ae147928 100644 (file)
@@ -232,12 +232,11 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(ip6_output);
 
-bool ip6_autoflowlabel(struct net *net, const struct ipv6_pinfo *np)
+bool ip6_autoflowlabel(struct net *net, const struct sock *sk)
 {
-       if (!np->autoflowlabel_set)
+       if (!inet6_test_bit(AUTOFLOWLABEL_SET, sk))
                return ip6_default_np_autolabel(net);
-       else
-               return np->autoflowlabel;
+       return inet6_test_bit(AUTOFLOWLABEL, sk);
 }
 
 /*
@@ -314,7 +313,7 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
                hlimit = ip6_dst_hoplimit(dst);
 
        ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel,
-                               ip6_autoflowlabel(net, np), fl6));
+                               ip6_autoflowlabel(net, sk), fl6));
 
        hdr->payload_len = htons(seg_len);
        hdr->nexthdr = proto;
@@ -1938,7 +1937,6 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
        struct sk_buff *skb, *tmp_skb;
        struct sk_buff **tail_skb;
        struct in6_addr *final_dst;
-       struct ipv6_pinfo *np = inet6_sk(sk);
        struct net *net = sock_net(sk);
        struct ipv6hdr *hdr;
        struct ipv6_txoptions *opt = v6_cork->opt;
@@ -1981,7 +1979,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
 
        ip6_flow_hdr(hdr, v6_cork->tclass,
                     ip6_make_flowlabel(net, skb, fl6->flowlabel,
-                                       ip6_autoflowlabel(net, np), fl6));
+                                       ip6_autoflowlabel(net, sk), fl6));
        hdr->hop_limit = v6_cork->hop_limit;
        hdr->nexthdr = proto;
        hdr->saddr = fl6->saddr;
index 7a181831f226c67813446145f8f58fa58908e3ae..d5d428a695f728d96a7d075d86f806cc3f926e0a 100644 (file)
@@ -474,6 +474,10 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                        return -EINVAL;
                inet6_assign_bit(MC6_ALL, sk, valbool);
                return 0;
+       case IPV6_AUTOFLOWLABEL:
+               inet6_assign_bit(AUTOFLOWLABEL, sk, valbool);
+               inet6_set_bit(AUTOFLOWLABEL_SET, sk);
+               return 0;
        }
        if (needs_rtnl)
                rtnl_lock();
@@ -970,11 +974,6 @@ done:
                np->dontfrag = valbool;
                retv = 0;
                break;
-       case IPV6_AUTOFLOWLABEL:
-               np->autoflowlabel = valbool;
-               np->autoflowlabel_set = 1;
-               retv = 0;
-               break;
        case IPV6_RECVFRAGSIZE:
                np->rxopt.bits.recvfragsize = valbool;
                retv = 0;
@@ -1447,7 +1446,7 @@ int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                break;
 
        case IPV6_AUTOFLOWLABEL:
-               val = ip6_autoflowlabel(sock_net(sk), np);
+               val = ip6_autoflowlabel(sock_net(sk), sk);
                break;
 
        case IPV6_RECVFRAGSIZE: