in6_dev = in6_dev_get(netdev);
        if (!in6_dev)
                goto out;
-       is_router = !!in6_dev->cnf.forwarding;
+       is_router = !!READ_ONCE(in6_dev->cnf.forwarding);
        in6_dev_put(in6_dev);
 
        /* ipv6_stub != NULL if in6_dev_get returned an inet6_dev */
 
        return 0;
 }
 
-static inline bool ipv6_accept_ra(struct inet6_dev *idev)
+static inline bool ipv6_accept_ra(const struct inet6_dev *idev)
 {
+       s32 accept_ra = READ_ONCE(idev->cnf.accept_ra);
+
        /* If forwarding is enabled, RA are not accepted unless the special
         * hybrid mode (accept_ra=2) is enabled.
         */
-       return idev->cnf.forwarding ? idev->cnf.accept_ra == 2 :
-           idev->cnf.accept_ra;
+       return READ_ONCE(idev->cnf.forwarding) ? accept_ra == 2 :
+               accept_ra;
 }
 
 #define IPV6_FRAG_HIGH_THRESH  (4 * 1024*1024) /* 4194304 */
 
                return -ENODEV;
 
        idev = __in6_dev_get_safely(dev);
-       if (unlikely(!idev || !idev->cnf.forwarding))
+       if (unlikely(!idev || !READ_ONCE(idev->cnf.forwarding)))
                return BPF_FIB_LKUP_RET_FWD_DISABLED;
 
        if (flags & BPF_FIB_LOOKUP_OUTPUT) {
 
                goto out;
 
        if ((all || type == NETCONFA_FORWARDING) &&
-           nla_put_s32(skb, NETCONFA_FORWARDING, devconf->forwarding) < 0)
+           nla_put_s32(skb, NETCONFA_FORWARDING,
+                       READ_ONCE(devconf->forwarding)) < 0)
                goto nla_put_failure;
 #ifdef CONFIG_IPV6_MROUTE
        if ((all || type == NETCONFA_MC_FORWARDING) &&
                idev = __in6_dev_get(dev);
                if (idev) {
                        int changed = (!idev->cnf.forwarding) ^ (!newf);
-                       idev->cnf.forwarding = newf;
+
+                       WRITE_ONCE(idev->cnf.forwarding, newf);
                        if (changed)
                                dev_forward_change(idev);
                }
 
        net = (struct net *)table->extra2;
        old = *p;
-       *p = newf;
+       WRITE_ONCE(*p, newf);
 
        if (p == &net->ipv6.devconf_dflt->forwarding) {
                if ((!newf) ^ (!old))
        if (p == &net->ipv6.devconf_all->forwarding) {
                int old_dflt = net->ipv6.devconf_dflt->forwarding;
 
-               net->ipv6.devconf_dflt->forwarding = newf;
+               WRITE_ONCE(net->ipv6.devconf_dflt->forwarding, newf);
                if ((!newf) ^ (!old_dflt))
                        inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
                                                     NETCONFA_FORWARDING,
 
        u32 mtu;
 
        idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif));
-       if (net->ipv6.devconf_all->forwarding == 0)
+       if (READ_ONCE(net->ipv6.devconf_all->forwarding) == 0)
                goto error;
 
        if (skb->pkt_type != PACKET_HOST)
 
                }
 
                if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
-                   (idev->cnf.forwarding &&
+                   (READ_ONCE(idev->cnf.forwarding) &&
                     (net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
                     (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
                        if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
        }
 
        if (is_router < 0)
-               is_router = idev->cnf.forwarding;
+               is_router = READ_ONCE(idev->cnf.forwarding);
 
        if (dad) {
                ndisc_send_na(dev, &in6addr_linklocal_allnodes, &msg->target,
         * Note that we don't do a (daddr == all-routers-mcast) check.
         */
        new_state = msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE;
-       if (!neigh && lladdr && idev && idev->cnf.forwarding) {
+       if (!neigh && lladdr && idev && READ_ONCE(idev->cnf.forwarding)) {
                if (accept_untracked_na(dev, saddr)) {
                        neigh = neigh_create(&nd_tbl, &msg->target, dev);
                        new_state = NUD_STALE;
                 * has already sent a NA to us.
                 */
                if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
-                   net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
+                   READ_ONCE(net->ipv6.devconf_all->forwarding) &&
+                   net->ipv6.devconf_all->proxy_ndp &&
                    pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
                        /* XXX: idev->cnf.proxy_ndp */
                        goto out;
        }
 
        /* Don't accept RS if we're not in router mode */
-       if (!idev->cnf.forwarding)
+       if (!READ_ONCE(idev->cnf.forwarding))
                goto out;
 
        /*
 
 
        strict |= flags & RT6_LOOKUP_F_IFACE;
        strict |= flags & RT6_LOOKUP_F_IGNORE_LINKSTATE;
-       if (net->ipv6.devconf_all->forwarding == 0)
+       if (READ_ONCE(net->ipv6.devconf_all->forwarding) == 0)
                strict |= RT6_LOOKUP_F_REACHABLE;
 
        rcu_read_lock();
        in6_dev = __in6_dev_get(skb->dev);
        if (!in6_dev)
                return;
-       if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_redirects)
+       if (READ_ONCE(in6_dev->cnf.forwarding) || !in6_dev->cnf.accept_redirects)
                return;
 
        /* RFC2461 8.1: