summaryrefslogtreecommitdiffstats
path: root/net/batman-adv/bridge_loop_avoidance.c
diff options
context:
space:
mode:
authorSimon Wunderlich2012-07-04 20:38:19 +0200
committerAntonio Quartulli2012-07-06 00:08:46 +0200
commit2d3f6ccc4ea5c74d4b4af1b47c56b4cff4bbfcb7 (patch)
tree266d06843fa025def68bc00f56ab5912247f15cc /net/batman-adv/bridge_loop_avoidance.c
parentMerge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mturquette/linux (diff)
downloadkernel-qcow2-linux-2d3f6ccc4ea5c74d4b4af1b47c56b4cff4bbfcb7.tar.gz
kernel-qcow2-linux-2d3f6ccc4ea5c74d4b4af1b47c56b4cff4bbfcb7.tar.xz
kernel-qcow2-linux-2d3f6ccc4ea5c74d4b4af1b47c56b4cff4bbfcb7.zip
batman-adv: check incoming packet type for bla
If the gateway functionality is used, some broadcast packets (DHCP requests) may be transmitted as unicast packets. As the bridge loop avoidance code now only considers the payload Ethernet destination, it may drop the DHCP request for clients which are claimed by other backbone gateways, because it falsely infers from the broadcast address that the right backbone gateway should havehandled the broadcast. Fix this by checking and delegating the batman-adv packet type used for transmission. Reported-by: Guido Iribarren <guidoiribarren@buenosaireslibre.org> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Diffstat (limited to 'net/batman-adv/bridge_loop_avoidance.c')
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 8bf97515a77d..c5863f499133 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1351,6 +1351,7 @@ void bla_free(struct bat_priv *bat_priv)
* @bat_priv: the bat priv with all the soft interface information
* @skb: the frame to be checked
* @vid: the VLAN ID of the frame
+ * @is_bcast: the packet came in a broadcast packet type.
*
* bla_rx avoidance checks if:
* * we have to race for a claim
@@ -1361,7 +1362,8 @@ void bla_free(struct bat_priv *bat_priv)
* 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 claim search_claim, *claim = NULL;
@@ -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)))
/* 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;
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)
}
/* if it is a broadcast ... */
- if (is_multicast_ether_addr(ethhdr->h_dest)) {
- /* ... drop it. the responsible gateway is in charge. */
+ if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
+ /* ... 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;
} else {
/* seems the client considers us as its best gateway.