Commit d46b6bfa authored by Simon Wunderlich's avatar Simon Wunderlich Committed by Antonio Quartulli

batman-adv: drop QinQ claim frames in bridge loop avoidance

Since bridge loop avoidance only supports untagged or simple 802.1q
tagged VLAN claim frames, claim frames with stacked VLAN headers (QinQ)
should be detected and dropped. Transporting the over the mesh may cause
problems on the receivers, or create bogus entries in the local tt
tables.
Reported-by: default avatarAntonio Quartulli <antonio@open-mesh.com>
Signed-off-by: default avatarSimon Wunderlich <simon@open-mesh.com>
Signed-off-by: default avatarMarek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: default avatarAntonio Quartulli <antonio@meshcoding.com>
parent 640d7efe
...@@ -800,11 +800,6 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, ...@@ -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 = (struct batadv_bla_claim_dst *)hw_dst;
bla_dst_own = &bat_priv->bla.claim_dest; 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, /* if announcement packet, use the source,
* otherwise assume it is in the hw_src * otherwise assume it is in the hw_src
*/ */
...@@ -866,12 +861,13 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, ...@@ -866,12 +861,13 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
struct batadv_hard_iface *primary_if, struct batadv_hard_iface *primary_if,
struct sk_buff *skb) 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; uint8_t *hw_src, *hw_dst;
struct vlan_ethhdr *vhdr; struct vlan_hdr *vhdr, vhdr_buf;
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
struct arphdr *arphdr; struct arphdr *arphdr;
unsigned short vid; unsigned short vid;
int vlan_depth = 0;
__be16 proto; __be16 proto;
int headlen; int headlen;
int ret; int ret;
...@@ -882,9 +878,24 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, ...@@ -882,9 +878,24 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
proto = ethhdr->h_proto; proto = ethhdr->h_proto;
headlen = ETH_HLEN; headlen = ETH_HLEN;
if (vid & BATADV_VLAN_HAS_TAG) { if (vid & BATADV_VLAN_HAS_TAG) {
vhdr = vlan_eth_hdr(skb); /* Traverse the VLAN/Ethertypes.
proto = vhdr->h_vlan_encapsulated_proto; *
headlen += VLAN_HLEN; * 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)) if (proto != htons(ETH_P_ARP))
...@@ -914,6 +925,19 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, ...@@ -914,6 +925,19 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
hw_src = (uint8_t *)arphdr + sizeof(struct arphdr); hw_src = (uint8_t *)arphdr + sizeof(struct arphdr);
hw_dst = hw_src + ETH_ALEN + 4; hw_dst = hw_src + ETH_ALEN + 4;
bla_dst = (struct batadv_bla_claim_dst *)hw_dst; 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. */ /* check if it is a claim frame. */
ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst, ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment