Correct .gbs.conf settings
[platform/adaptation/renesas_rcar/renesas_kernel.git] / net / bridge / br_vlan.c
index 8249ca7..e1bd253 100644 (file)
@@ -119,38 +119,37 @@ static void __vlan_flush(struct net_port_vlans *v)
        kfree_rcu(v, rcu);
 }
 
-/* Strip the tag from the packet.  Will return skb with tci set 0.  */
-static struct sk_buff *br_vlan_untag(struct sk_buff *skb)
-{
-       if (skb->protocol != htons(ETH_P_8021Q)) {
-               skb->vlan_tci = 0;
-               return skb;
-       }
-
-       skb->vlan_tci = 0;
-       skb = vlan_untag(skb);
-       if (skb)
-               skb->vlan_tci = 0;
-
-       return skb;
-}
-
 struct sk_buff *br_handle_vlan(struct net_bridge *br,
                               const struct net_port_vlans *pv,
                               struct sk_buff *skb)
 {
        u16 vid;
 
-       if (!br->vlan_enabled)
+       /* If this packet was not filtered at input, let it pass */
+       if (!BR_INPUT_SKB_CB(skb)->vlan_filtered)
                goto out;
 
+       /* Vlan filter table must be configured at this point.  The
+        * only exception is the bridge is set in promisc mode and the
+        * packet is destined for the bridge device.  In this case
+        * pass the packet as is.
+        */
+       if (!pv) {
+               if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) {
+                       goto out;
+               } else {
+                       kfree_skb(skb);
+                       return NULL;
+               }
+       }
+
        /* At this point, we know that the frame was filtered and contains
         * a valid vlan id.  If the vlan id is set in the untagged bitmap,
         * send untagged; otherwise, send tagged.
         */
        br_vlan_get_tag(skb, &vid);
        if (test_bit(vid, pv->untagged_bitmap))
-               skb = br_vlan_untag(skb);
+               skb->vlan_tci = 0;
 
 out:
        return skb;
@@ -165,14 +164,30 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
        /* If VLAN filtering is disabled on the bridge, all packets are
         * permitted.
         */
-       if (!br->vlan_enabled)
+       if (!br->vlan_enabled) {
+               BR_INPUT_SKB_CB(skb)->vlan_filtered = false;
                return true;
+       }
 
        /* If there are no vlan in the permitted list, all packets are
         * rejected.
         */
        if (!v)
-               return false;
+               goto drop;
+
+       BR_INPUT_SKB_CB(skb)->vlan_filtered = true;
+
+       /* If vlan tx offload is disabled on bridge device and frame was
+        * sent from vlan device on the bridge device, it does not have
+        * HW accelerated vlan tag.
+        */
+       if (unlikely(!vlan_tx_tag_present(skb) &&
+                    (skb->protocol == htons(ETH_P_8021Q) ||
+                     skb->protocol == htons(ETH_P_8021AD)))) {
+               skb = skb_vlan_untag(skb);
+               if (unlikely(!skb))
+                       return false;
+       }
 
        err = br_vlan_get_tag(skb, vid);
        if (!*vid) {
@@ -183,7 +198,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
                 * vlan untagged or priority-tagged traffic belongs to.
                 */
                if (pvid == VLAN_N_VID)
-                       return false;
+                       goto drop;
 
                /* PVID is set on this port.  Any untagged or priority-tagged
                 * ingress frame is considered to belong to this vlan.
@@ -206,7 +221,8 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
        /* Frame had a valid vlan tag.  See if vlan is allowed */
        if (test_bit(*vid, v->vlan_bitmap))
                return true;
-
+drop:
+       kfree_skb(skb);
        return false;
 }
 
@@ -217,7 +233,8 @@ bool br_allowed_egress(struct net_bridge *br,
 {
        u16 vid;
 
-       if (!br->vlan_enabled)
+       /* If this packet was not filtered at input, let it pass */
+       if (!BR_INPUT_SKB_CB(skb)->vlan_filtered)
                return true;
 
        if (!v)
@@ -230,6 +247,35 @@ bool br_allowed_egress(struct net_bridge *br,
        return false;
 }
 
+/* Called under RCU */
+bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
+{
+       struct net_bridge *br = p->br;
+       struct net_port_vlans *v;
+
+       /* If filtering was disabled at input, let it pass. */
+       if (!br->vlan_enabled)
+               return true;
+
+       v = rcu_dereference(p->vlan_info);
+       if (!v)
+               return false;
+
+       br_vlan_get_tag(skb, vid);
+       if (!*vid) {
+               *vid = br_get_pvid(v);
+               if (*vid == VLAN_N_VID)
+                       return false;
+
+               return true;
+       }
+
+       if (test_bit(*vid, v->vlan_bitmap))
+               return true;
+
+       return false;
+}
+
 /* Must be protected by RTNL.
  * Must be called with vid in range from 1 to 4094 inclusive.
  */