aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_device.c')
-rw-r--r--net/bridge/br_device.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 7c78e2640190..d5f1d3fd4b28 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -30,6 +30,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
30 struct net_bridge_fdb_entry *dst; 30 struct net_bridge_fdb_entry *dst;
31 struct net_bridge_mdb_entry *mdst; 31 struct net_bridge_mdb_entry *mdst;
32 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); 32 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
33 u16 vid = 0;
33 34
34 rcu_read_lock(); 35 rcu_read_lock();
35#ifdef CONFIG_BRIDGE_NETFILTER 36#ifdef CONFIG_BRIDGE_NETFILTER
@@ -45,6 +46,9 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
45 brstats->tx_bytes += skb->len; 46 brstats->tx_bytes += skb->len;
46 u64_stats_update_end(&brstats->syncp); 47 u64_stats_update_end(&brstats->syncp);
47 48
49 if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid))
50 goto out;
51
48 BR_INPUT_SKB_CB(skb)->brdev = dev; 52 BR_INPUT_SKB_CB(skb)->brdev = dev;
49 53
50 skb_reset_mac_header(skb); 54 skb_reset_mac_header(skb);
@@ -67,7 +71,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
67 br_multicast_deliver(mdst, skb); 71 br_multicast_deliver(mdst, skb);
68 else 72 else
69 br_flood_deliver(br, skb); 73 br_flood_deliver(br, skb);
70 } else if ((dst = __br_fdb_get(br, dest)) != NULL) 74 } else if ((dst = __br_fdb_get(br, dest, vid)) != NULL)
71 br_deliver(dst->dst, skb); 75 br_deliver(dst->dst, skb);
72 else 76 else
73 br_flood_deliver(br, skb); 77 br_flood_deliver(br, skb);
@@ -172,12 +176,10 @@ static int br_set_mac_address(struct net_device *dev, void *p)
172 176
173 spin_lock_bh(&br->lock); 177 spin_lock_bh(&br->lock);
174 if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { 178 if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) {
175 dev->addr_assign_type &= ~NET_ADDR_RANDOM;
176 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 179 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
177 br_fdb_change_mac_address(br, addr->sa_data); 180 br_fdb_change_mac_address(br, addr->sa_data);
178 br_stp_change_bridge_id(br, addr->sa_data); 181 br_stp_change_bridge_id(br, addr->sa_data);
179 } 182 }
180 br->flags |= BR_SET_MAC_ADDR;
181 spin_unlock_bh(&br->lock); 183 spin_unlock_bh(&br->lock);
182 184
183 return 0; 185 return 0;
@@ -185,10 +187,10 @@ static int br_set_mac_address(struct net_device *dev, void *p)
185 187
186static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info) 188static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
187{ 189{
188 strcpy(info->driver, "bridge"); 190 strlcpy(info->driver, "bridge", sizeof(info->driver));
189 strcpy(info->version, BR_VERSION); 191 strlcpy(info->version, BR_VERSION, sizeof(info->version));
190 strcpy(info->fw_version, "N/A"); 192 strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
191 strcpy(info->bus_info, "N/A"); 193 strlcpy(info->bus_info, "N/A", sizeof(info->bus_info));
192} 194}
193 195
194static netdev_features_t br_fix_features(struct net_device *dev, 196static netdev_features_t br_fix_features(struct net_device *dev,
@@ -267,7 +269,7 @@ void br_netpoll_disable(struct net_bridge_port *p)
267 269
268 p->np = NULL; 270 p->np = NULL;
269 271
270 __netpoll_free_rcu(np); 272 __netpoll_free_async(np);
271} 273}
272 274
273#endif 275#endif
@@ -315,6 +317,7 @@ static const struct net_device_ops br_netdev_ops = {
315 .ndo_fdb_dump = br_fdb_dump, 317 .ndo_fdb_dump = br_fdb_dump,
316 .ndo_bridge_getlink = br_getlink, 318 .ndo_bridge_getlink = br_getlink,
317 .ndo_bridge_setlink = br_setlink, 319 .ndo_bridge_setlink = br_setlink,
320 .ndo_bridge_dellink = br_dellink,
318}; 321};
319 322
320static void br_dev_free(struct net_device *dev) 323static void br_dev_free(struct net_device *dev)