Commit 941a46a2 authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge

Included changes:
- fix a bug generated by the wrong interaction between the GW feature and the
  Bridge Loop Avoidance
parents 313b037c 2d3f6ccc
...@@ -1351,6 +1351,7 @@ void bla_free(struct bat_priv *bat_priv) ...@@ -1351,6 +1351,7 @@ void bla_free(struct bat_priv *bat_priv)
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: the frame to be checked * @skb: the frame to be checked
* @vid: the VLAN ID of the frame * @vid: the VLAN ID of the frame
* @is_bcast: the packet came in a broadcast packet type.
* *
* bla_rx avoidance checks if: * bla_rx avoidance checks if:
* * we have to race for a claim * * we have to race for a claim
...@@ -1361,7 +1362,8 @@ void bla_free(struct bat_priv *bat_priv) ...@@ -1361,7 +1362,8 @@ void bla_free(struct bat_priv *bat_priv)
* process the skb. * process the skb.
* *
*/ */
int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid,
bool is_bcast)
{ {
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
struct claim search_claim, *claim = NULL; struct claim search_claim, *claim = NULL;
...@@ -1380,7 +1382,7 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) ...@@ -1380,7 +1382,7 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid)
if (unlikely(atomic_read(&bat_priv->bla_num_requests))) if (unlikely(atomic_read(&bat_priv->bla_num_requests)))
/* don't allow broadcasts while requests are in flight */ /* don't allow broadcasts while requests are in flight */
if (is_multicast_ether_addr(ethhdr->h_dest)) if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
goto handled; goto handled;
memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN);
...@@ -1406,8 +1408,13 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) ...@@ -1406,8 +1408,13 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid)
} }
/* if it is a broadcast ... */ /* if it is a broadcast ... */
if (is_multicast_ether_addr(ethhdr->h_dest)) { if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
/* ... drop it. the responsible gateway is in charge. */ /* ... drop it. the responsible gateway is in charge.
*
* We need to check is_bcast because with the gateway
* feature, broadcasts (like DHCP requests) may be sent
* using a unicast packet type.
*/
goto handled; goto handled;
} else { } else {
/* seems the client considers us as its best gateway. /* seems the client considers us as its best gateway.
......
...@@ -23,7 +23,8 @@ ...@@ -23,7 +23,8 @@
#define _NET_BATMAN_ADV_BLA_H_ #define _NET_BATMAN_ADV_BLA_H_
#ifdef CONFIG_BATMAN_ADV_BLA #ifdef CONFIG_BATMAN_ADV_BLA
int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid,
bool is_bcast);
int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid);
int bla_is_backbone_gw(struct sk_buff *skb, int bla_is_backbone_gw(struct sk_buff *skb,
struct orig_node *orig_node, int hdr_size); struct orig_node *orig_node, int hdr_size);
...@@ -41,7 +42,7 @@ void bla_free(struct bat_priv *bat_priv); ...@@ -41,7 +42,7 @@ void bla_free(struct bat_priv *bat_priv);
#else /* ifdef CONFIG_BATMAN_ADV_BLA */ #else /* ifdef CONFIG_BATMAN_ADV_BLA */
static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb,
short vid) short vid, bool is_bcast)
{ {
return 0; return 0;
} }
......
...@@ -256,7 +256,11 @@ void interface_rx(struct net_device *soft_iface, ...@@ -256,7 +256,11 @@ void interface_rx(struct net_device *soft_iface,
struct bat_priv *bat_priv = netdev_priv(soft_iface); struct bat_priv *bat_priv = netdev_priv(soft_iface);
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
struct vlan_ethhdr *vhdr; struct vlan_ethhdr *vhdr;
struct batman_header *batadv_header = (struct batman_header *)skb->data;
short vid __maybe_unused = -1; short vid __maybe_unused = -1;
bool is_bcast;
is_bcast = (batadv_header->packet_type == BAT_BCAST);
/* check if enough space is available for pulling, and pull */ /* check if enough space is available for pulling, and pull */
if (!pskb_may_pull(skb, hdr_size)) if (!pskb_may_pull(skb, hdr_size))
...@@ -302,7 +306,7 @@ void interface_rx(struct net_device *soft_iface, ...@@ -302,7 +306,7 @@ void interface_rx(struct net_device *soft_iface,
/* Let the bridge loop avoidance check the packet. If will /* Let the bridge loop avoidance check the packet. If will
* not handle it, we can safely push it up. * not handle it, we can safely push it up.
*/ */
if (bla_rx(bat_priv, skb, vid)) if (bla_rx(bat_priv, skb, vid, is_bcast))
goto out; goto out;
netif_rx(skb); netif_rx(skb);
......
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