@@ -89,6 +89,21 @@ void br_port_carrier_check(struct net_bridge_port *p, bool *notified)
spin_unlock_bh(&br->lock);
}
+int nbp_flags_change(struct net_bridge_port *p, unsigned long flags,
+ unsigned long mask, struct netlink_ext_ack *extack)
+{
+ int err;
+
+ err = br_switchdev_set_port_flag(p, flags, mask, extack);
+ if (err)
+ return err;
+
+ p->flags &= ~mask;
+ p->flags |= flags;
+
+ return 0;
+}
+
static void br_port_set_promisc(struct net_bridge_port *p)
{
int err = 0;
@@ -343,6 +358,10 @@ static void del_nbp(struct net_bridge_port *p)
update_headroom(br, get_max_headroom(br));
netdev_reset_rx_headroom(dev);
+ nbp_flags_change(p, 0, BR_LEARNING, NULL);
+ nbp_flags_change(p, BR_FLOOD, BR_FLOOD, NULL);
+ nbp_flags_change(p, BR_MCAST_FLOOD, BR_MCAST_FLOOD, NULL);
+ nbp_flags_change(p, BR_BCAST_FLOOD, BR_BCAST_FLOOD, NULL);
nbp_vlan_flush(p);
br_fdb_delete_by_port(br, p, 0, 1);
switchdev_deferred_process();
@@ -428,7 +447,10 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
p->path_cost = port_cost(dev);
p->priority = 0x8000 >> BR_PORT_BITS;
p->port_no = index;
- p->flags = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
+ nbp_flags_change(p, BR_LEARNING, BR_LEARNING, NULL);
+ nbp_flags_change(p, BR_FLOOD, BR_FLOOD, NULL);
+ nbp_flags_change(p, BR_MCAST_FLOOD, BR_MCAST_FLOOD, NULL);
+ nbp_flags_change(p, BR_BCAST_FLOOD, BR_BCAST_FLOOD, NULL);
br_init_port(p);
br_set_state(p, BR_STATE_DISABLED);
br_stp_port_timer_init(p);
@@ -852,28 +852,20 @@ static int br_set_port_state(struct net_bridge_port *p, u8 state)
return 0;
}
-/* Set/clear or port flags based on attribute */
+/* Set/clear or port flags based on netlink attribute */
static int br_set_port_flag(struct net_bridge_port *p, struct nlattr *tb[],
int attrtype, unsigned long mask,
struct netlink_ext_ack *extack)
{
- unsigned long flags;
- int err;
+ unsigned long flags = 0;
if (!tb[attrtype])
return 0;
if (nla_get_u8(tb[attrtype]))
- flags = p->flags | mask;
- else
- flags = p->flags & ~mask;
-
- err = br_switchdev_set_port_flag(p, flags, mask, extack);
- if (err)
- return err;
+ flags = mask;
- p->flags = flags;
- return 0;
+ return nbp_flags_change(p, flags, mask, extack);
}
/* Process bridge protocol info on port */
@@ -749,6 +749,8 @@ netdev_features_t br_features_recompute(struct net_bridge *br,
void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
void br_manage_promisc(struct net_bridge *br);
int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev);
+int nbp_flags_change(struct net_bridge_port *p, unsigned long flags,
+ unsigned long mask, struct netlink_ext_ack *extack);
/* br_input.c */
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);