]> Pileus Git - ~andy/linux/blobdiff - net/bridge/br_input.c
bridge: Implement vlan ingress/egress policy with PVID.
[~andy/linux] / net / bridge / br_input.c
index 4b34207419b1cfbe39ca54321cf9087101bab155..a63f227ad963890d1fe88e0ff0918f15d237e6de 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/etherdevice.h>
 #include <linux/netfilter_bridge.h>
 #include <linux/export.h>
+#include <linux/rculist.h>
 #include "br_private.h"
 
 /* Hook for brouter */
@@ -34,6 +35,20 @@ static int br_pass_frame_up(struct sk_buff *skb)
        brstats->rx_bytes += skb->len;
        u64_stats_update_end(&brstats->syncp);
 
+       /* Bridge is just like any other port.  Make sure the
+        * packet is allowed except in promisc modue when someone
+        * may be running packet capture.
+        */
+       if (!(brdev->flags & IFF_PROMISC) &&
+           !br_allowed_egress(br, br_get_vlan_info(br), skb)) {
+               kfree_skb(skb);
+               return NET_RX_DROP;
+       }
+
+       skb = br_handle_vlan(br, br_get_vlan_info(br), skb);
+       if (!skb)
+               return NET_RX_DROP;
+
        indev = skb->dev;
        skb->dev = brdev;
 
@@ -50,10 +65,14 @@ int br_handle_frame_finish(struct sk_buff *skb)
        struct net_bridge_fdb_entry *dst;
        struct net_bridge_mdb_entry *mdst;
        struct sk_buff *skb2;
+       u16 vid = 0;
 
        if (!p || p->state == BR_STATE_DISABLED)
                goto drop;
 
+       if (!br_allowed_ingress(p->br, nbp_get_vlan_info(p), skb, &vid))
+               goto drop;
+
        /* insert into forwarding database after filtering to avoid spoofing */
        br = p->br;
        br_fdb_update(br, p, eth_hdr(skb)->h_source);