Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / net / batman-adv / bridge_loop_avoidance.c
index 05f0712be5e7fe3b1fe357d454e6eb9e6c779fc5..a957c8140721def2878b292c2e61e2dd37c36e5c 100644 (file)
@@ -191,7 +191,7 @@ batadv_backbone_hash_find(struct batadv_priv *bat_priv,
        if (!hash)
                return NULL;
 
-       memcpy(search_entry.orig, addr, ETH_ALEN);
+       ether_addr_copy(search_entry.orig, addr);
        search_entry.vid = vid;
 
        index = batadv_choose_backbone_gw(&search_entry, hash->size);
@@ -305,7 +305,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                /* normal claim frame
                 * set Ethernet SRC to the clients mac
                 */
-               memcpy(ethhdr->h_source, mac, ETH_ALEN);
+               ether_addr_copy(ethhdr->h_source, mac);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_send_claim(): CLAIM %pM on vid %d\n", mac,
                           BATADV_PRINT_VID(vid));
@@ -314,7 +314,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                /* unclaim frame
                 * set HW SRC to the clients mac
                 */
-               memcpy(hw_src, mac, ETH_ALEN);
+               ether_addr_copy(hw_src, mac);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac,
                           BATADV_PRINT_VID(vid));
@@ -323,7 +323,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                /* announcement frame
                 * set HW SRC to the special mac containg the crc
                 */
-               memcpy(hw_src, mac, ETH_ALEN);
+               ether_addr_copy(hw_src, mac);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
                           ethhdr->h_source, BATADV_PRINT_VID(vid));
@@ -333,8 +333,8 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                 * set HW SRC and header destination to the receiving backbone
                 * gws mac
                 */
-               memcpy(hw_src, mac, ETH_ALEN);
-               memcpy(ethhdr->h_dest, mac, ETH_ALEN);
+               ether_addr_copy(hw_src, mac);
+               ether_addr_copy(ethhdr->h_dest, mac);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_send_claim(): REQUEST of %pM to %pM on vid %d\n",
                           ethhdr->h_source, ethhdr->h_dest,
@@ -395,7 +395,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
        entry->bat_priv = bat_priv;
        atomic_set(&entry->request_sent, 0);
        atomic_set(&entry->wait_periods, 0);
-       memcpy(entry->orig, orig, ETH_ALEN);
+       ether_addr_copy(entry->orig, orig);
 
        /* one for the hash, one for returning */
        atomic_set(&entry->refcount, 2);
@@ -563,7 +563,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
        struct batadv_bla_claim search_claim;
        int hash_added;
 
-       memcpy(search_claim.addr, mac, ETH_ALEN);
+       ether_addr_copy(search_claim.addr, mac);
        search_claim.vid = vid;
        claim = batadv_claim_hash_find(bat_priv, &search_claim);
 
@@ -573,7 +573,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
                if (!claim)
                        return;
 
-               memcpy(claim->addr, mac, ETH_ALEN);
+               ether_addr_copy(claim->addr, mac);
                claim->vid = vid;
                claim->lasttime = jiffies;
                claim->backbone_gw = backbone_gw;
@@ -624,7 +624,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
 {
        struct batadv_bla_claim search_claim, *claim;
 
-       memcpy(search_claim.addr, mac, ETH_ALEN);
+       ether_addr_copy(search_claim.addr, mac);
        search_claim.vid = vid;
        claim = batadv_claim_hash_find(bat_priv, &search_claim);
        if (!claim)
@@ -800,11 +800,6 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv,
        bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
        bla_dst_own = &bat_priv->bla.claim_dest;
 
-       /* check if it is a claim packet in general */
-       if (memcmp(bla_dst->magic, bla_dst_own->magic,
-                  sizeof(bla_dst->magic)) != 0)
-               return 0;
-
        /* if announcement packet, use the source,
         * otherwise assume it is in the hw_src
         */
@@ -866,12 +861,13 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
                                    struct batadv_hard_iface *primary_if,
                                    struct sk_buff *skb)
 {
-       struct batadv_bla_claim_dst *bla_dst;
+       struct batadv_bla_claim_dst *bla_dst, *bla_dst_own;
        uint8_t *hw_src, *hw_dst;
-       struct vlan_ethhdr *vhdr;
+       struct vlan_hdr *vhdr, vhdr_buf;
        struct ethhdr *ethhdr;
        struct arphdr *arphdr;
        unsigned short vid;
+       int vlan_depth = 0;
        __be16 proto;
        int headlen;
        int ret;
@@ -882,9 +878,24 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
        proto = ethhdr->h_proto;
        headlen = ETH_HLEN;
        if (vid & BATADV_VLAN_HAS_TAG) {
-               vhdr = (struct vlan_ethhdr *)ethhdr;
-               proto = vhdr->h_vlan_encapsulated_proto;
-               headlen += VLAN_HLEN;
+               /* Traverse the VLAN/Ethertypes.
+                *
+                * At this point it is known that the first protocol is a VLAN
+                * header, so start checking at the encapsulated protocol.
+                *
+                * The depth of the VLAN headers is recorded to drop BLA claim
+                * frames encapsulated into multiple VLAN headers (QinQ).
+                */
+               do {
+                       vhdr = skb_header_pointer(skb, headlen, VLAN_HLEN,
+                                                 &vhdr_buf);
+                       if (!vhdr)
+                               return 0;
+
+                       proto = vhdr->h_vlan_encapsulated_proto;
+                       headlen += VLAN_HLEN;
+                       vlan_depth++;
+               } while (proto == htons(ETH_P_8021Q));
        }
 
        if (proto != htons(ETH_P_ARP))
@@ -914,6 +925,19 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
        hw_src = (uint8_t *)arphdr + sizeof(struct arphdr);
        hw_dst = hw_src + ETH_ALEN + 4;
        bla_dst = (struct batadv_bla_claim_dst *)hw_dst;
+       bla_dst_own = &bat_priv->bla.claim_dest;
+
+       /* check if it is a claim frame in general */
+       if (memcmp(bla_dst->magic, bla_dst_own->magic,
+                  sizeof(bla_dst->magic)) != 0)
+               return 0;
+
+       /* check if there is a claim frame encapsulated deeper in (QinQ) and
+        * drop that, as this is not supported by BLA but should also not be
+        * sent via the mesh.
+        */
+       if (vlan_depth > 1)
+               return 1;
 
        /* check if it is a claim frame. */
        ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
@@ -1103,8 +1127,8 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
                                                oldif->net_dev->dev_addr))
                                continue;
 
-                       memcpy(backbone_gw->orig,
-                              primary_if->net_dev->dev_addr, ETH_ALEN);
+                       ether_addr_copy(backbone_gw->orig,
+                                       primary_if->net_dev->dev_addr);
                        /* send an announce frame so others will ask for our
                         * claims and update their tables.
                         */
@@ -1310,7 +1334,7 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
        entry = &bat_priv->bla.bcast_duplist[curr];
        entry->crc = crc;
        entry->entrytime = jiffies;
-       memcpy(entry->orig, bcast_packet->orig, ETH_ALEN);
+       ether_addr_copy(entry->orig, bcast_packet->orig);
        bat_priv->bla.bcast_duplist_curr = curr;
 
 out:
@@ -1458,7 +1482,7 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
                if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
                        goto handled;
 
-       memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN);
+       ether_addr_copy(search_claim.addr, ethhdr->h_source);
        search_claim.vid = vid;
        claim = batadv_claim_hash_find(bat_priv, &search_claim);
 
@@ -1547,9 +1571,6 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
        if (!atomic_read(&bat_priv->bridge_loop_avoidance))
                goto allow;
 
-       /* in VLAN case, the mac header might not be set. */
-       skb_reset_mac_header(skb);
-
        if (batadv_bla_process_claim(bat_priv, primary_if, skb))
                goto handled;
 
@@ -1560,7 +1581,7 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
                if (is_multicast_ether_addr(ethhdr->h_dest))
                        goto handled;
 
-       memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN);
+       ether_addr_copy(search_claim.addr, ethhdr->h_source);
        search_claim.vid = vid;
 
        claim = batadv_claim_hash_find(bat_priv, &search_claim);
This page took 0.031089 seconds and 5 git commands to generate.