From patchwork Wed Jul 4 18:40:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Wunderlich X-Patchwork-Id: 2151 Return-Path: Received: from nick.hrz.tu-chemnitz.de (nick.hrz.tu-chemnitz.de [134.109.228.11]) by open-mesh.org (Postfix) with ESMTPS id 0B346600937 for ; Wed, 4 Jul 2012 20:40:18 +0200 (CEST) Authentication-Results: open-mesh.org; dkim=pass (1024-bit key; insecure key) header.i=@tu-chemnitz.de; dkim-adsp=none (insecure policy) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tu-chemnitz.de; s=dkim2010; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=cuzQtUEsO54DAUKgCXdVxlVYB643Dg7b7zo5fyVWBVk=; b=SFI7WSdn8yvuiLhZ82ixFhA8RsWiafO0ai008uyoCFNnvLrQMw2tr7ce3wIbngU6RXi0x8c9EYUs7KLErpC50w7UITdWoCTCVkPu+NAtd7n2OfwuW/T4hwkSydq54gi71LeFHNU1Xaa8qiQMa+iGG88x5IOQ5mR2iSXFRFp/te8=; Received: from p57aa19e2.dip0.t-ipconnect.de ([87.170.25.226] helo=pandem0nium) by nick.hrz.tu-chemnitz.de with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.76) (envelope-from ) id 1SmUUr-0005tO-7j; Wed, 04 Jul 2012 20:40:17 +0200 Received: from dotslash by pandem0nium with local (Exim 4.72) (envelope-from ) id 1SmUV7-0003FF-I3; Wed, 04 Jul 2012 20:40:33 +0200 From: Simon Wunderlich To: b.a.t.m.a.n@lists.open-mesh.org Date: Wed, 4 Jul 2012 20:40:32 +0200 Message-Id: <1341427232-12446-1-git-send-email-siwu@hrz.tu-chemnitz.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1341410374-11389-1-git-send-email-siwu@hrz.tu-chemnitz.de> References: <1341410374-11389-1-git-send-email-siwu@hrz.tu-chemnitz.de> X-Scan-AV: nick.hrz.tu-chemnitz.de; 2012-07-04 20:40:17; bd744129c698134b102bd0274c55d68d X-Scan-SA: nick.hrz.tu-chemnitz.de; 2012-07-04 20:40:17; 1eb0637d09f2ebd3fb92fe04849bb43c X-Spam-Score: -1.0 (-) X-Spam-Report: --- Textanalyse SpamAssassin 3.3.1 (-1.0 Punkte) Fragen an/questions to: Postmaster TU Chemnitz * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP --- Ende Textanalyse Cc: Simon Wunderlich Subject: [B.A.T.M.A.N.] [PATCH-v2] batman-adv: check incoming packet type for bla X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.13 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Jul 2012 18:40:18 -0000 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 --- PATCHv2 adds a comment why we are doing this, and adds the is_bcast check to the other is_multicast_ether_addr() check in this function, and remove obsolete !!. --- 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 6452e2f..1af7af5 100644 --- a/bridge_loop_avoidance.c +++ b/bridge_loop_avoidance.c @@ -1368,6 +1368,7 @@ void batadv_bla_free(struct batadv_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 @@ -1377,7 +1378,8 @@ void batadv_bla_free(struct batadv_priv *bat_priv) * returns 1, otherwise it returns 0 and the caller shall further * process the skb. */ -int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid) +int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid, + bool is_bcast) { struct ethhdr *ethhdr; struct batadv_claim search_claim, *claim = NULL; @@ -1396,7 +1398,7 @@ int batadv_bla_rx(struct batadv_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); @@ -1422,8 +1424,13 @@ int batadv_bla_rx(struct batadv_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 35d39e3..789cb73 100644 --- a/bridge_loop_avoidance.h +++ b/bridge_loop_avoidance.h @@ -21,7 +21,8 @@ #define _NET_BATMAN_ADV_BLA_H_ #ifdef CONFIG_BATMAN_ADV_BLA -int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid); +int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid, + bool is_bcast); int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid); int batadv_bla_is_backbone_gw(struct sk_buff *skb, struct batadv_orig_node *orig_node, int hdr_size); @@ -42,7 +43,7 @@ void batadv_bla_free(struct batadv_priv *bat_priv); #else /* ifdef CONFIG_BATMAN_ADV_BLA */ static inline int batadv_bla_rx(struct batadv_priv *bat_priv, - struct sk_buff *skb, short vid) + struct sk_buff *skb, short vid, bool is_bcast) { return 0; } diff --git a/soft-interface.c b/soft-interface.c index 96736ea..ae7d23e 100644 --- a/soft-interface.c +++ b/soft-interface.c @@ -274,9 +274,13 @@ void batadv_interface_rx(struct net_device *soft_iface, struct batadv_priv *bat_priv = netdev_priv(soft_iface); struct ethhdr *ethhdr; struct vlan_ethhdr *vhdr; + struct batadv_header *batadv_header = (struct batadv_header *)skb->data; short vid __maybe_unused = -1; + bool is_bcast; __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); + is_bcast = (batadv_header->packet_type == BATADV_BCAST); + /* check if enough space is available for pulling, and pull */ if (!pskb_may_pull(skb, hdr_size)) goto dropped; @@ -323,7 +327,7 @@ void batadv_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 (batadv_bla_rx(bat_priv, skb, vid)) + if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) goto out; netif_rx(skb);