From b7d7f8ea5d144e4a6e8150c43dad9805d79448d9 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Wed, 8 Aug 2012 20:40:16 +0000 Subject: [PATCH] batman-adv: bla2 & gateway mode interaction fix Signed-off-by: Marek Lindner git-svn-id: svn://svn.openwrt.org/openwrt/packages/net/batman-adv@33064 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- Makefile | 2 +- ...v-check-incoming-packet-type-for-bla.patch | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 patches/0005-batman-adv-check-incoming-packet-type-for-bla.patch diff --git a/Makefile b/Makefile index e0ba232..40e8a51 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ PKG_NAME:=batman-adv PKG_VERSION:=2012.2.0 BATCTL_VERSION:=2012.2.0 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_MD5SUM:=68967ed1df709de18ab795722dde9341 BATCTL_MD5SUM:=7abd284098c514d3f2858e8a956c495e diff --git a/patches/0005-batman-adv-check-incoming-packet-type-for-bla.patch b/patches/0005-batman-adv-check-incoming-packet-type-for-bla.patch new file mode 100644 index 0000000..bc42dd1 --- /dev/null +++ b/patches/0005-batman-adv-check-incoming-packet-type-for-bla.patch @@ -0,0 +1,121 @@ +From e32470167379db2ca7713108f1e917c531426eee Mon Sep 17 00:00:00 2001 +From: Simon Wunderlich +Date: Wed, 4 Jul 2012 20:38:19 +0200 +Subject: [PATCH] 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 +Signed-off-by: Simon Wunderlich +--- + bridge_loop_avoidance.c | 15 +++++++++++---- + bridge_loop_avoidance.h | 5 +++-- + soft-interface.c | 6 +++++- + 3 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c +index 8bf9751..c5863f4 100644 +--- a/bridge_loop_avoidance.c ++++ b/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. +diff --git a/bridge_loop_avoidance.h b/bridge_loop_avoidance.h +index e39f93a..dc5227b 100644 +--- a/bridge_loop_avoidance.h ++++ b/bridge_loop_avoidance.h +@@ -23,7 +23,8 @@ + #define _NET_BATMAN_ADV_BLA_H_ + + #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_is_backbone_gw(struct sk_buff *skb, + struct orig_node *orig_node, int hdr_size); +@@ -41,7 +42,7 @@ void bla_free(struct bat_priv *bat_priv); + #else /* ifdef CONFIG_BATMAN_ADV_BLA */ + + static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, +- short vid) ++ short vid, bool is_bcast) + { + return 0; + } +diff --git a/soft-interface.c b/soft-interface.c +index 6e2530b..a0ec0e4 100644 +--- a/soft-interface.c ++++ b/soft-interface.c +@@ -256,7 +256,11 @@ void interface_rx(struct net_device *soft_iface, + struct bat_priv *bat_priv = netdev_priv(soft_iface); + struct ethhdr *ethhdr; + struct vlan_ethhdr *vhdr; ++ struct batman_header *batadv_header = (struct batman_header *)skb->data; + 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 */ + if (!pskb_may_pull(skb, hdr_size)) +@@ -302,7 +306,7 @@ void interface_rx(struct net_device *soft_iface, + /* Let the bridge loop avoidance check the packet. If will + * 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; + + netif_rx(skb); +-- +1.7.9.1 + -- 2.30.2