diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c index 09458935a49e..9ce8f440e38f 100644 --- a/net/bridge/br_arp_nd_proxy.c +++ b/net/bridge/br_arp_nd_proxy.c @@ -521,7 +521,8 @@ bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid) v = br_vlan_find(vg, vid); if (!v) return false; - return !!(v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED); + return !!(READ_ONCE(v->priv_flags) & + BR_VLFLAG_NEIGH_SUPPRESS_ENABLED); } return test_bit(BR_NEIGH_SUPPRESS_BIT, &p->flags); } @@ -535,7 +536,8 @@ bool br_is_neigh_forward_grat_enabled(const struct net_bridge_port *p, u16 vid) v = br_vlan_find(vg, vid); if (!v) return false; - return !!(v->priv_flags & BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED); + return !!(READ_ONCE(v->priv_flags) & + BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED); } return test_bit(BR_NEIGH_FORWARD_GRAT_BIT, &p->flags); } diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c index 43a300ae6bfa..ecd8bba7430e 100644 --- a/net/bridge/br_mst.c +++ b/net/bridge/br_mst.c @@ -70,7 +70,7 @@ int br_mst_get_state(const struct net_device *dev, u16 msti, u8 *state) list_for_each_entry(v, &vg->vlan_list, vlist) { if (v->brvlan->msti == msti) { - *state = v->state; + *state = br_vlan_get_state(v); return 0; } } @@ -86,7 +86,7 @@ static void br_mst_vlan_set_state(struct net_bridge_vlan_group *vg, if (br_vlan_get_state(v) == state) return; - if (v->vid == vg->pvid) + if (v->vid == br_get_pvid(vg)) br_vlan_set_pvid_state(vg, state); br_vlan_set_state(v, state); @@ -123,7 +123,7 @@ int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state, err = 0; list_for_each_entry_rcu(v, &vg->vlan_list, vlist) { - if (v->brvlan->msti != msti) + if (READ_ONCE(v->brvlan->msti) != msti) continue; br_mst_vlan_set_state(vg, v, state); @@ -145,7 +145,7 @@ static void br_mst_vlan_sync_state(struct net_bridge_vlan *pv, u16 msti) * it. */ if (v != pv && v->brvlan->msti == msti) { - br_mst_vlan_set_state(vg, pv, v->state); + br_mst_vlan_set_state(vg, pv, br_vlan_get_state(v)); return; } } @@ -176,7 +176,7 @@ int br_mst_vlan_set_msti(struct net_bridge_vlan *mv, u16 msti) if (err && err != -EOPNOTSUPP) return err; - mv->msti = msti; + WRITE_ONCE(mv->msti, msti); list_for_each_entry(p, &mv->br->port_list, list) { vg = nbp_vlan_group(p); @@ -249,7 +249,9 @@ size_t br_mst_info_size(const struct net_bridge_vlan_group *vg) sz = nla_total_size(0); list_for_each_entry_rcu(v, &vg->vlan_list, vlist) { - if (test_bit(v->brvlan->msti, seen)) + u16 msti = READ_ONCE(v->brvlan->msti); + + if (test_bit(msti, seen)) continue; /* IFLA_BRIDGE_MST_ENTRY */ @@ -259,7 +261,7 @@ size_t br_mst_info_size(const struct net_bridge_vlan_group *vg) /* IFLA_BRIDGE_MST_ENTRY_STATE */ nla_total_size(sizeof(u8)); - __set_bit(v->brvlan->msti, seen); + __set_bit(msti, seen); } return sz; @@ -280,7 +282,8 @@ int br_mst_fill_info(struct sk_buff *skb, nest = nla_nest_start_noflag(skb, IFLA_BRIDGE_MST_ENTRY); if (!nest || nla_put_u16(skb, IFLA_BRIDGE_MST_ENTRY_MSTI, v->brvlan->msti) || - nla_put_u8(skb, IFLA_BRIDGE_MST_ENTRY_STATE, v->state)) { + nla_put_u8(skb, IFLA_BRIDGE_MST_ENTRY_STATE, + br_vlan_get_state(v))) { err = -EMSGSIZE; break; } diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 3e9b10f8abf1..d9ff0f7318e5 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -923,7 +923,7 @@ static void __br_multicast_query_handle_vlan(struct net_bridge_mcast *brmctx, else if (br_multicast_ctx_is_vlan(brmctx)) vlan = brmctx->vlan; - if (vlan && !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) { + if (vlan && !(READ_ONCE(vlan->flags) & BRIDGE_VLAN_INFO_UNTAGGED)) { u16 vlan_proto; if (br_vlan_get_proto(brmctx->br->dev, &vlan_proto) != 0) @@ -2183,7 +2183,7 @@ static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) spin_lock_bh(&br->multicast_lock); if (br_multicast_port_ctx_is_vlan(pmctx) && - !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) { + !(READ_ONCE(pmctx->vlan->priv_flags) & BR_VLFLAG_MCAST_ENABLED)) { spin_unlock_bh(&br->multicast_lock); return; } @@ -2220,7 +2220,7 @@ static void br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx) spin_lock_bh(&br->multicast_lock); if (br_multicast_port_ctx_is_vlan(pmctx) && - !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) { + !(READ_ONCE(pmctx->vlan->priv_flags) & BR_VLFLAG_MCAST_ENABLED)) { spin_unlock_bh(&br->multicast_lock); return; } @@ -4094,7 +4094,8 @@ int br_multicast_rcv(struct net_bridge_mcast **brmctx, *pmctx = &vlan->port_mcast_ctx; } - if (!(masterv->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)) + if (!(READ_ONCE(masterv->priv_flags) & + BR_VLFLAG_GLOBAL_MCAST_ENABLED)) return 0; } @@ -4394,7 +4395,8 @@ void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on) return; spin_lock_bh(&br->multicast_lock); - vlan->priv_flags ^= BR_VLFLAG_MCAST_ENABLED; + WRITE_ONCE(vlan->priv_flags, vlan->priv_flags ^ + BR_VLFLAG_MCAST_ENABLED); spin_unlock_bh(&br->multicast_lock); if (on) @@ -4410,7 +4412,8 @@ void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on) br = vlan->port->br; spin_lock_bh(&br->multicast_lock); - vlan->priv_flags ^= BR_VLFLAG_MCAST_ENABLED; + WRITE_ONCE(vlan->priv_flags, vlan->priv_flags ^ + BR_VLFLAG_MCAST_ENABLED); if (on) __br_multicast_enable_port_ctx(&vlan->port_mcast_ctx); else @@ -4488,7 +4491,8 @@ bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on) if (on == !!(vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)) return false; - vlan->priv_flags ^= BR_VLFLAG_GLOBAL_MCAST_ENABLED; + WRITE_ONCE(vlan->priv_flags, vlan->priv_flags ^ + BR_VLFLAG_GLOBAL_MCAST_ENABLED); br_multicast_toggle_vlan(vlan, on); return true; diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index b2cd4e39326d..ae76df0de05a 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -41,7 +41,7 @@ static int __get_num_vlan_infos(struct net_bridge_vlan_group *vg, if (v->vid == pvid) flags |= BRIDGE_VLAN_INFO_PVID; - if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED) + if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED) flags |= BRIDGE_VLAN_INFO_UNTAGGED; if (vid_range_start == 0) { @@ -81,7 +81,7 @@ static int br_get_num_vlan_infos(struct net_bridge_vlan_group *vg, return 0; if (filter_mask & RTEXT_FILTER_BRVLAN) - return vg->num_vlans; + return READ_ONCE(vg->num_vlans); rcu_read_lock(); num_vlans = __get_num_vlan_infos(vg, filter_mask); @@ -385,7 +385,7 @@ static int br_fill_ifvlaninfo_compressed(struct sk_buff *skb, if (v->vid == pvid) flags |= BRIDGE_VLAN_INFO_PVID; - if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED) + if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED) flags |= BRIDGE_VLAN_INFO_UNTAGGED; if (vid_range_start == 0) { @@ -437,7 +437,7 @@ static int br_fill_ifvlaninfo(struct sk_buff *skb, if (v->vid == pvid) vinfo.flags |= BRIDGE_VLAN_INFO_PVID; - if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED) + if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED) vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO, @@ -531,7 +531,7 @@ static int br_fill_ifinfo(struct sk_buff *skb, else vg = br_vlan_group_rcu(br); - if (!vg || !vg->num_vlans) { + if (!vg || !READ_ONCE(vg->num_vlans)) { rcu_read_unlock(); goto done; } diff --git a/net/bridge/br_netlink_tunnel.c b/net/bridge/br_netlink_tunnel.c index e7eceab5b515..e64054628ac9 100644 --- a/net/bridge/br_netlink_tunnel.c +++ b/net/bridge/br_netlink_tunnel.c @@ -29,8 +29,10 @@ static size_t __get_vlan_tinfo_size(void) bool vlan_tunid_inrange(const struct net_bridge_vlan *v_curr, const struct net_bridge_vlan *v_last) { - __be32 tunid_curr = tunnel_id_to_key32(v_curr->tinfo.tunnel_id); - __be32 tunid_last = tunnel_id_to_key32(v_last->tinfo.tunnel_id); + __be32 tunid_curr, tunid_last; + + tunid_curr = tunnel_id_to_key32(READ_ONCE(v_curr->tinfo.tunnel_id)); + tunid_last = tunnel_id_to_key32(READ_ONCE(v_last->tinfo.tunnel_id)); return (be32_to_cpu(tunid_curr) - be32_to_cpu(tunid_last)) == 1; } @@ -43,7 +45,7 @@ static int __get_num_vlan_tunnel_infos(struct net_bridge_vlan_group *vg) /* Count number of vlan infos */ list_for_each_entry_rcu(v, &vg->vlan_list, vlist) { /* only a context, bridge vlan not activated */ - if (!br_vlan_should_use(v) || !v->tinfo.tunnel_id) + if (!br_vlan_should_use(v) || !READ_ONCE(v->tinfo.tunnel_id)) continue; if (!vtbegin) { @@ -124,19 +126,19 @@ static int br_fill_vlan_tinfo_range(struct sk_buff *skb, if (vtend && (vtend->vid - vtbegin->vid) > 0) { /* add range to skb */ err = br_fill_vlan_tinfo(skb, vtbegin->vid, - vtbegin->tinfo.tunnel_id, + READ_ONCE(vtbegin->tinfo.tunnel_id), BRIDGE_VLAN_INFO_RANGE_BEGIN); if (err) return err; err = br_fill_vlan_tinfo(skb, vtend->vid, - vtend->tinfo.tunnel_id, + READ_ONCE(vtend->tinfo.tunnel_id), BRIDGE_VLAN_INFO_RANGE_END); if (err) return err; } else { err = br_fill_vlan_tinfo(skb, vtbegin->vid, - vtbegin->tinfo.tunnel_id, + READ_ONCE(vtbegin->tinfo.tunnel_id), 0); if (err) return err; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index d337b1cfb980..df1500391f1d 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -665,13 +665,13 @@ static inline int br_is_root_bridge(const struct net_bridge *br) /* check if a VLAN entry is global */ static inline bool br_vlan_is_master(const struct net_bridge_vlan *v) { - return v->flags & BRIDGE_VLAN_INFO_MASTER; + return READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_MASTER; } /* check if a VLAN entry is used by the bridge */ static inline bool br_vlan_is_brentry(const struct net_bridge_vlan *v) { - return v->flags & BRIDGE_VLAN_INFO_BRENTRY; + return READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_BRENTRY; } /* check if we should use the vlan entry, returns false if it's only context */ @@ -687,6 +687,15 @@ static inline bool br_vlan_should_use(const struct net_bridge_vlan *v) return true; } +/* The vlan state can be changed with only rcu held by the mst code so + * annotate the lock-free read. br_vlan_set_state() is kept further down + * because it needs br_multicast_update_vlan_mcast_ctx(). + */ +static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v) +{ + return READ_ONCE(v->state); +} + static inline bool nbp_state_should_learn(const struct net_bridge_port *p) { return p->state == BR_STATE_LEARNING || p->state == BR_STATE_FORWARDING; @@ -1273,21 +1282,24 @@ br_multicast_ctx_vlan_global_disabled(const struct net_bridge_mcast *brmctx) { return br_multicast_ctx_is_vlan(brmctx) && (!br_opt_get(brmctx->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED) || - !(brmctx->vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)); + !(READ_ONCE(brmctx->vlan->priv_flags) & + BR_VLFLAG_GLOBAL_MCAST_ENABLED)); } static inline bool br_multicast_ctx_vlan_disabled(const struct net_bridge_mcast *brmctx) { return br_multicast_ctx_is_vlan(brmctx) && - !(brmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED); + !(READ_ONCE(brmctx->vlan->priv_flags) & + BR_VLFLAG_MCAST_ENABLED); } static inline bool br_multicast_port_ctx_vlan_disabled(const struct net_bridge_mcast_port *pmctx) { return br_multicast_port_ctx_is_vlan(pmctx) && - !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED); + !(READ_ONCE(pmctx->vlan->priv_flags) & + BR_VLFLAG_MCAST_ENABLED); } static inline bool @@ -1296,7 +1308,7 @@ br_multicast_port_ctx_state_disabled(const struct net_bridge_mcast_port *pmctx) return pmctx->port->state == BR_STATE_DISABLED || (br_multicast_port_ctx_is_vlan(pmctx) && (br_multicast_port_ctx_vlan_disabled(pmctx) || - pmctx->vlan->state == BR_STATE_DISABLED)); + br_vlan_get_state(pmctx->vlan) == BR_STATE_DISABLED)); } static inline bool @@ -1305,7 +1317,7 @@ br_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx) return br_multicast_port_ctx_state_disabled(pmctx) || pmctx->port->state == BR_STATE_BLOCKING || (br_multicast_port_ctx_is_vlan(pmctx) && - pmctx->vlan->state == BR_STATE_BLOCKING); + br_vlan_get_state(pmctx->vlan) == BR_STATE_BLOCKING); } static inline bool @@ -1687,8 +1699,7 @@ static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg) if (!vg) return 0; - smp_rmb(); - return vg->pvid; + return READ_ONCE(vg->pvid); } static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid) @@ -1914,14 +1925,6 @@ bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr, bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range, const struct net_bridge_vlan *v_opts); -/* vlan state manipulation helpers using *_ONCE to annotate lock-free access, - * while br_vlan_set_state() may access data protected by multicast_lock. - */ -static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v) -{ - return READ_ONCE(v->state); -} - static inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state) { WRITE_ONCE(v->state, state); diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 1e0e436629ec..72b75757ac85 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -40,9 +40,8 @@ static void __vlan_add_pvid(struct net_bridge_vlan_group *vg, if (vg->pvid == v->vid) return; - smp_wmb(); - br_vlan_set_pvid_state(vg, v->state); - vg->pvid = v->vid; + br_vlan_set_pvid_state(vg, br_vlan_get_state(v)); + WRITE_ONCE(vg->pvid, v->vid); } static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid) @@ -50,8 +49,7 @@ static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid) if (vg->pvid != vid) return; - smp_wmb(); - vg->pvid = 0; + WRITE_ONCE(vg->pvid, 0); } /* Update the BRIDGE_VLAN_INFO_PVID and BRIDGE_VLAN_INFO_UNTAGGED flags of @v. @@ -62,6 +60,7 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, bool commit) { struct net_bridge_vlan_group *vg; + u16 vlan_flags; bool change; if (br_vlan_is_master(v)) @@ -70,8 +69,9 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, vg = nbp_vlan_group(v->port); /* check if anything would be changed on commit */ + vlan_flags = v->flags; change = !!(flags & BRIDGE_VLAN_INFO_PVID) == !!(vg->pvid != v->vid) || - ((flags ^ v->flags) & BRIDGE_VLAN_INFO_UNTAGGED); + ((flags ^ vlan_flags) & BRIDGE_VLAN_INFO_UNTAGGED); if (!commit) goto out; @@ -82,9 +82,10 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, __vlan_delete_pvid(vg, v->vid); if (flags & BRIDGE_VLAN_INFO_UNTAGGED) - v->flags |= BRIDGE_VLAN_INFO_UNTAGGED; + vlan_flags |= BRIDGE_VLAN_INFO_UNTAGGED; else - v->flags &= ~BRIDGE_VLAN_INFO_UNTAGGED; + vlan_flags &= ~BRIDGE_VLAN_INFO_UNTAGGED; + WRITE_ONCE(v->flags, vlan_flags); out: return change; @@ -343,7 +344,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, goto out_filt; } } - vg->num_vlans++; + WRITE_ONCE(vg->num_vlans, vg->num_vlans + 1); } /* set the state before publishing */ @@ -366,7 +367,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, out_fdb_insert: if (br_vlan_should_use(v)) { br_fdb_find_delete_local(br, p, dev->dev_addr, v->vid); - vg->num_vlans--; + WRITE_ONCE(vg->num_vlans, vg->num_vlans - 1); } out_filt: @@ -415,8 +416,8 @@ static int __vlan_del(struct net_bridge_vlan *v) } if (br_vlan_should_use(v)) { - v->flags &= ~BRIDGE_VLAN_INFO_BRENTRY; - vg->num_vlans--; + WRITE_ONCE(v->flags, v->flags & ~BRIDGE_VLAN_INFO_BRENTRY); + WRITE_ONCE(vg->num_vlans, vg->num_vlans - 1); } if (masterv != v) { @@ -524,7 +525,7 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, * hardware on each egress port as appropriate. So only strip the VLAN * header if forwarding offload is not being used. */ - if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED && + if (READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED && !br_switchdev_frame_uses_tx_fwd_offload(skb)) __vlan_hwaccel_clear_tag(skb); @@ -694,7 +695,7 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) return true; vg = nbp_vlan_group_rcu(p); - if (!vg || !vg->num_vlans) + if (!vg || !READ_ONCE(vg->num_vlans)) return false; if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto) @@ -755,8 +756,8 @@ static int br_vlan_add_existing(struct net_bridge *br, } refcount_inc(&vlan->refcnt); - vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY; - vg->num_vlans++; + WRITE_ONCE(vlan->flags, vlan->flags | BRIDGE_VLAN_INFO_BRENTRY); + WRITE_ONCE(vg->num_vlans, vg->num_vlans + 1); *changed = true; br_multicast_toggle_one_vlan(vlan, true); } @@ -1491,12 +1492,12 @@ int br_vlan_fill_forward_path_mode(struct net_bridge *br, if (!v || !br_vlan_should_use(v)) return -EINVAL; - if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED)) + if (!(READ_ONCE(v->flags) & BRIDGE_VLAN_INFO_UNTAGGED)) return 0; if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG) path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; - else if (v->priv_flags & BR_VLFLAG_TAGGING_BY_SWITCHDEV) + else if (READ_ONCE(v->priv_flags) & BR_VLFLAG_TAGGING_BY_SWITCHDEV) path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW; else path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG; @@ -1552,7 +1553,7 @@ int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid, return -ENOENT; p_vinfo->vid = vid; - p_vinfo->flags = v->flags; + p_vinfo->flags = READ_ONCE(v->flags); if (vid == br_get_pvid(vg)) p_vinfo->flags |= BRIDGE_VLAN_INFO_PVID; return 0; diff --git a/net/bridge/br_vlan_options.c b/net/bridge/br_vlan_options.c index cb0f556ff40d..506668fc31d9 100644 --- a/net/bridge/br_vlan_options.c +++ b/net/bridge/br_vlan_options.c @@ -43,7 +43,7 @@ bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr, u8 range_mc_rtr = br_vlan_multicast_router(range_end); u8 curr_mc_rtr = br_vlan_multicast_router(v_curr); - if (v_curr->state != range_end->state) + if (br_vlan_get_state(v_curr) != br_vlan_get_state(range_end)) return false; if (!__vlan_tun_can_enter_range(v_curr, range_end)) @@ -276,7 +276,8 @@ static int br_vlan_process_one_opts(const struct net_bridge *br, } if (val != enabled) { - v->priv_flags ^= BR_VLFLAG_NEIGH_SUPPRESS_ENABLED; + WRITE_ONCE(v->priv_flags, v->priv_flags ^ + BR_VLFLAG_NEIGH_SUPPRESS_ENABLED); *changed = true; } } @@ -292,7 +293,8 @@ static int br_vlan_process_one_opts(const struct net_bridge *br, } if (val != enabled) { - v->priv_flags ^= BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED; + WRITE_ONCE(v->priv_flags, v->priv_flags ^ + BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED); *changed = true; } } diff --git a/net/bridge/br_vlan_tunnel.c b/net/bridge/br_vlan_tunnel.c index 257cae9f1569..04751f15d708 100644 --- a/net/bridge/br_vlan_tunnel.c +++ b/net/bridge/br_vlan_tunnel.c @@ -22,7 +22,7 @@ static inline int br_vlan_tunid_cmp(struct rhashtable_compare_arg *arg, const struct net_bridge_vlan *vle = ptr; __be64 tunid = *(__be64 *)arg->key; - return vle->tinfo.tunnel_id != tunid; + return READ_ONCE(vle->tinfo.tunnel_id) != tunid; } static const struct rhashtable_params br_vlan_tunnel_rht_params = {