]> 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 e1bc090bc00acb160ead451894cf045b59ba386e..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);
@@ -176,7 +180,6 @@ static int br_set_mac_address(struct net_device *dev, void *p)
                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;
@@ -266,7 +269,7 @@ void br_netpoll_disable(struct net_bridge_port *p)
 
        p->np = NULL;
 
-       __netpoll_free_rcu(np);
+       __netpoll_free_async(np);
 }
 
 #endif
@@ -314,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)