Move np->dontfrag flag to 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>
                                                 * 010: prefer public address
                                                 * 100: prefer care-of address
                                                 */
-                               dontfrag:1,
                                rtalert_isolate:1;
        __u8                    min_hopcount;
        __u8                    tclass;
 
        INET_FLAGS_MC6_ALL      = 22,
        INET_FLAGS_AUTOFLOWLABEL_SET = 23,
        INET_FLAGS_AUTOFLOWLABEL = 24,
+       INET_FLAGS_DONTFRAG     = 25,
 };
 
 /* cmsg flags for inet */
 
 }
 
 static inline void ipcm6_init_sk(struct ipcm6_cookie *ipc6,
-                                const struct ipv6_pinfo *np)
+                                const struct sock *sk)
 {
        *ipc6 = (struct ipcm6_cookie) {
                .hlimit = -1,
-               .tclass = np->tclass,
-               .dontfrag = np->dontfrag,
+               .tclass = inet6_sk(sk)->tclass,
+               .dontfrag = inet6_test_bit(DONTFRAG, sk),
        };
 }
 
 
 
        proto = sk->sk_protocol;
        if (proto == IPPROTO_UDP || proto == IPPROTO_RAW)
-               return inet6_sk(sk)->dontfrag;
+               return inet6_test_bit(DONTFRAG, sk);
 
        return false;
 }
 
        else if (!fl6.flowi6_oif)
                fl6.flowi6_oif = np->ucast_oif;
 
-       ipcm6_init_sk(&ipc6, np);
+       ipcm6_init_sk(&ipc6, sk);
        ipc6.sockc.mark = mark;
        fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
 
        msg.offset = 0;
        msg.type = type;
 
-       ipcm6_init_sk(&ipc6, np);
+       ipcm6_init_sk(&ipc6, sk);
        ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
        ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb));
        ipc6.sockc.mark = mark;
 
                return ERR_PTR(err);
        }
        if (ipc6->dontfrag < 0)
-               ipc6->dontfrag = inet6_sk(sk)->dontfrag;
+               ipc6->dontfrag = inet6_test_bit(DONTFRAG, sk);
 
        err = __ip6_append_data(sk, &queue, cork, &v6_cork,
                                ¤t->task_frag, getfrag, from,
 
                inet6_assign_bit(AUTOFLOWLABEL, sk, valbool);
                inet6_set_bit(AUTOFLOWLABEL_SET, sk);
                return 0;
+       case IPV6_DONTFRAG:
+               inet6_assign_bit(DONTFRAG, sk, valbool);
+               return 0;
        }
        if (needs_rtnl)
                rtnl_lock();
                        goto e_inval;
                retv = __ip6_sock_set_addr_preferences(sk, val);
                break;
-       case IPV6_DONTFRAG:
-               np->dontfrag = valbool;
-               retv = 0;
-               break;
        case IPV6_RECVFRAGSIZE:
                np->rxopt.bits.recvfragsize = valbool;
                retv = 0;
                break;
 
        case IPV6_DONTFRAG:
-               val = np->dontfrag;
+               val = inet6_test_bit(DONTFRAG, sk);
                break;
 
        case IPV6_AUTOFLOWLABEL:
 
             l3mdev_master_ifindex_by_index(sock_net(sk), oif) != sk->sk_bound_dev_if))
                return -EINVAL;
 
-       ipcm6_init_sk(&ipc6, np);
+       ipcm6_init_sk(&ipc6, sk);
        ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags);
        ipc6.sockc.mark = READ_ONCE(sk->sk_mark);
 
 
                ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
        if (ipc6.dontfrag < 0)
-               ipc6.dontfrag = np->dontfrag;
+               ipc6.dontfrag = inet6_test_bit(DONTFRAG, sk);
 
        if (msg->msg_flags&MSG_CONFIRM)
                goto do_confirm;
 
 
 do_append_data:
        if (ipc6.dontfrag < 0)
-               ipc6.dontfrag = np->dontfrag;
+               ipc6.dontfrag = inet6_test_bit(DONTFRAG, sk);
        up->len += ulen;
        err = ip6_append_data(sk, getfrag, msg, ulen, sizeof(struct udphdr),
                              &ipc6, fl6, (struct rt6_info *)dst,
 
                ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
        if (ipc6.dontfrag < 0)
-               ipc6.dontfrag = np->dontfrag;
+               ipc6.dontfrag = inet6_test_bit(DONTFRAG, sk);
 
        if (msg->msg_flags & MSG_CONFIRM)
                goto do_confirm;