]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bridge: read p->flags once in br_port_fill_attrs()
authorEric Dumazet <edumazet@google.com>
Thu, 4 Jun 2026 14:13:43 +0000 (14:13 +0000)
committerJakub Kicinski <kuba@kernel.org>
Sat, 6 Jun 2026 00:46:18 +0000 (17:46 -0700)
We might run br_port_fill_attrs() locklessly in the future.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260604141343.2124500-12-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/bridge/br_netlink.c

index ead66dbe1bb7679af18d5f0c2fdea6be2574727d..7cb24de9c77d3d15892723f77288c27a15a6a0ad 100644 (file)
@@ -234,7 +234,8 @@ static inline size_t br_nlmsg_size(struct net_device *dev, u32 filter_mask)
 static int br_port_fill_attrs(struct sk_buff *skb,
                              const struct net_bridge_port *p)
 {
-       u8 mode = !!(p->flags & BR_HAIRPIN_MODE);
+       unsigned long flags = READ_ONCE(p->flags);
+       u8 mode = !!(flags & BR_HAIRPIN_MODE);
        struct net_bridge_port *backup_p;
        u64 timerval;
 
@@ -242,23 +243,23 @@ static int br_port_fill_attrs(struct sk_buff *skb,
            nla_put_u16(skb, IFLA_BRPORT_PRIORITY, READ_ONCE(p->priority)) ||
            nla_put_u32(skb, IFLA_BRPORT_COST, READ_ONCE(p->path_cost)) ||
            nla_put_u8(skb, IFLA_BRPORT_MODE, mode) ||
-           nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD)) ||
+           nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(flags & BR_BPDU_GUARD)) ||
            nla_put_u8(skb, IFLA_BRPORT_PROTECT,
-                      !!(p->flags & BR_ROOT_BLOCK)) ||
+                      !!(flags & BR_ROOT_BLOCK)) ||
            nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE,
-                      !!(p->flags & BR_MULTICAST_FAST_LEAVE)) ||
+                      !!(flags & BR_MULTICAST_FAST_LEAVE)) ||
            nla_put_u8(skb, IFLA_BRPORT_MCAST_TO_UCAST,
-                      !!(p->flags & BR_MULTICAST_TO_UNICAST)) ||
-           nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(p->flags & BR_LEARNING)) ||
+                      !!(flags & BR_MULTICAST_TO_UNICAST)) ||
+           nla_put_u8(skb, IFLA_BRPORT_LEARNING, !!(flags & BR_LEARNING)) ||
            nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD,
-                      !!(p->flags & BR_FLOOD)) ||
+                      !!(flags & BR_FLOOD)) ||
            nla_put_u8(skb, IFLA_BRPORT_MCAST_FLOOD,
-                      !!(p->flags & BR_MCAST_FLOOD)) ||
+                      !!(flags & BR_MCAST_FLOOD)) ||
            nla_put_u8(skb, IFLA_BRPORT_BCAST_FLOOD,
-                      !!(p->flags & BR_BCAST_FLOOD)) ||
-           nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(p->flags & BR_PROXYARP)) ||
+                      !!(flags & BR_BCAST_FLOOD)) ||
+           nla_put_u8(skb, IFLA_BRPORT_PROXYARP, !!(flags & BR_PROXYARP)) ||
            nla_put_u8(skb, IFLA_BRPORT_PROXYARP_WIFI,
-                      !!(p->flags & BR_PROXYARP_WIFI)) ||
+                      !!(flags & BR_PROXYARP_WIFI)) ||
            nla_put(skb, IFLA_BRPORT_ROOT_ID, sizeof(struct ifla_bridge_id),
                    &p->designated_root) ||
            nla_put(skb, IFLA_BRPORT_BRIDGE_ID, sizeof(struct ifla_bridge_id),
@@ -272,22 +273,22 @@ static int br_port_fill_attrs(struct sk_buff *skb,
            nla_put_u8(skb, IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
                       p->topology_change_ack) ||
            nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, READ_ONCE(p->config_pending)) ||
-           nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags &
+           nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(flags &
                                                        BR_VLAN_TUNNEL)) ||
            nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask) ||
            nla_put_u8(skb, IFLA_BRPORT_NEIGH_SUPPRESS,
-                      !!(p->flags & BR_NEIGH_SUPPRESS)) ||
-           nla_put_u8(skb, IFLA_BRPORT_MRP_RING_OPEN, !!(p->flags &
+                      !!(flags & BR_NEIGH_SUPPRESS)) ||
+           nla_put_u8(skb, IFLA_BRPORT_MRP_RING_OPEN, !!(flags &
                                                          BR_MRP_LOST_CONT)) ||
            nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN,
-                      !!(p->flags & BR_MRP_LOST_IN_CONT)) ||
-           nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) ||
-           nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) ||
-           nla_put_u8(skb, IFLA_BRPORT_MAB, !!(p->flags & BR_PORT_MAB)) ||
+                      !!(flags & BR_MRP_LOST_IN_CONT)) ||
+           nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(flags & BR_ISOLATED)) ||
+           nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(flags & BR_PORT_LOCKED)) ||
+           nla_put_u8(skb, IFLA_BRPORT_MAB, !!(flags & BR_PORT_MAB)) ||
            nla_put_u8(skb, IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
-                      !!(p->flags & BR_NEIGH_VLAN_SUPPRESS)) ||
+                      !!(flags & BR_NEIGH_VLAN_SUPPRESS)) ||
            nla_put_u8(skb, IFLA_BRPORT_NEIGH_FORWARD_GRAT,
-                      !!(p->flags & BR_NEIGH_FORWARD_GRAT)))
+                      !!(flags & BR_NEIGH_FORWARD_GRAT)))
                return -EMSGSIZE;
 
        timerval = br_timer_value(&p->message_age_timer);