]> Pileus Git - ~andy/linux/blobdiff - net/bridge/br_device.c
bridge: Implement vlan ingress/egress policy with PVID.
[~andy/linux] / net / bridge / br_device.c
index 7c78e264019000fe48d4bed8c22a86f6b7b4131d..9509139da49c4d65942000ff7af7724530ef9027 100644 (file)
@@ -30,6 +30,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        struct net_bridge_fdb_entry *dst;
        struct net_bridge_mdb_entry *mdst;
        struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
+       u16 vid = 0;
 
        rcu_read_lock();
 #ifdef CONFIG_BRIDGE_NETFILTER
@@ -45,6 +46,9 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        brstats->tx_bytes += skb->len;
        u64_stats_update_end(&brstats->syncp);
 
+       if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid))
+               goto out;
+
        BR_INPUT_SKB_CB(skb)->brdev = dev;
 
        skb_reset_mac_header(skb);
@@ -172,12 +176,10 @@ static int br_set_mac_address(struct net_device *dev, void *p)
 
        spin_lock_bh(&br->lock);
        if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) {
-               dev->addr_assign_type &= ~NET_ADDR_RANDOM;
                memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
                br_fdb_change_mac_address(br, addr->sa_data);
                br_stp_change_bridge_id(br, addr->sa_data);
        }
-       br->flags |= BR_SET_MAC_ADDR;
        spin_unlock_bh(&br->lock);
 
        return 0;
@@ -185,10 +187,10 @@ static int br_set_mac_address(struct net_device *dev, void *p)
 
 static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       strcpy(info->driver, "bridge");
-       strcpy(info->version, BR_VERSION);
-       strcpy(info->fw_version, "N/A");
-       strcpy(info->bus_info, "N/A");
+       strlcpy(info->driver, "bridge", sizeof(info->driver));
+       strlcpy(info->version, BR_VERSION, sizeof(info->version));
+       strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
+       strlcpy(info->bus_info, "N/A", sizeof(info->bus_info));
 }
 
 static netdev_features_t br_fix_features(struct net_device *dev,
@@ -267,7 +269,7 @@ void br_netpoll_disable(struct net_bridge_port *p)
 
        p->np = NULL;
 
-       __netpoll_free_rcu(np);
+       __netpoll_free_async(np);
 }
 
 #endif
@@ -315,6 +317,7 @@ static const struct net_device_ops br_netdev_ops = {
        .ndo_fdb_dump            = br_fdb_dump,
        .ndo_bridge_getlink      = br_getlink,
        .ndo_bridge_setlink      = br_setlink,
+       .ndo_bridge_dellink      = br_dellink,
 };
 
 static void br_dev_free(struct net_device *dev)