1 From: Linus Lüssing <linus.luessing@c0d3.blue>
2 Date: Thu, 22 Mar 2018 00:21:32 +0100
3 Subject: [PATCH] batman-adv: fix packet loss for broadcasted DHCP packets to a server
5 DHCP connectivity issues can currently occur if the following conditions
8 1) A DHCP packet from a client to a server
9 2) This packet has a multicast destination
10 3) This destination has a matching entry in the translation table
11 (FF:FF:FF:FF:FF:FF for IPv4, 33:33:00:01:00:02/33:33:00:01:00:03
13 4) The orig-node determined by TT for the multicast destination
14 does not match the orig-node determined by best-gateway-selection
16 In this case the DHCP packet will be dropped.
18 The "gateway-out-of-range" check is supposed to only be applied to
19 unicasted DHCP packets to a specific DHCP server.
21 In that case dropping the the unicasted frame forces the client to
22 retry via a broadcasted one, but now directed to the new best
25 A DHCP packet with broadcast/multicast destination is already ensured to
26 always be delivered to the best gateway. Dropping a multicasted
27 DHCP packet here will only prevent completing DHCP as there is no
30 So far, it seems the unicast check was implicitly performed by
31 expecting the batadv_transtable_search() to return NULL for multicast
32 destinations. However, a multicast address could have always ended up in
33 the translation table and in fact is now common.
35 To fix this potential loss of a DHCP client-to-server packet to a
36 multicast address this patch adds an explicit multicast destination
37 check to reliably bail out of the gateway-out-of-range check for such
40 The issue and fix were tested in the following three node setup:
42 - Line topology, A-B-C
43 - A: gateway client, DHCP client
44 - B: gateway server, hop-penalty increased: 30->60, DHCP server
45 - C: gateway server, code modifications to announce FF:FF:FF:FF:FF:FF
47 Without this patch, A would never transmit its DHCP Discover packet
48 due to an always "out-of-range" condition. With this patch,
49 a full DHCP handshake between A and B was possible again.
51 Fixes: afae4e42aae6 ("batman-adv: refactoring gateway handling code")
52 Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
53 Signed-off-by: Sven Eckelmann <sven@narfation.org>
55 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/49b2132f0fe2753a3b46103db9719898c5cd44aa
57 net/batman-adv/gateway_client.c | 5 ++++-
58 1 file changed, 4 insertions(+), 1 deletion(-)
60 diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
61 index 52b8bd6ec43183519a63483950c2e886e47a6f9e..f1fdf4e7f5c3ce7f20339dcee3b6e43290ea3b4e 100644
62 --- a/net/batman-adv/gateway_client.c
63 +++ b/net/batman-adv/gateway_client.c
64 @@ -705,7 +705,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
66 struct batadv_neigh_node *neigh_curr = NULL;
67 struct batadv_neigh_node *neigh_old = NULL;
68 - struct batadv_orig_node *orig_dst_node;
69 + struct batadv_orig_node *orig_dst_node = NULL;
70 struct batadv_gw_node *gw_node = NULL;
71 struct batadv_gw_node *curr_gw = NULL;
72 struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
73 @@ -716,6 +716,9 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
75 vid = batadv_get_vid(skb, 0);
77 + if (is_multicast_ether_addr(ethhdr->h_dest))
80 orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,