batman-adv: fix packet loss for broadcasted DHCP packets to a server
DHCP connectivity issues can currently occur if the following conditions
are met:
1) A DHCP packet from a client to a server
2) This packet has a multicast destination
3) This destination has a matching entry in the translation table
(FF:FF:FF:FF:FF:FF for IPv4, 33:33:00:01:00:02/33:33:00:01:00:03
for IPv6)
4) The orig-node determined by TT for the multicast destination
does not match the orig-node determined by best-gateway-selection
In this case the DHCP packet will be dropped.
The "gateway-out-of-range" check is supposed to only be applied to
unicasted DHCP packets to a specific DHCP server.
In that case dropping the the unicasted frame forces the client to
retry via a broadcasted one, but now directed to the new best
gateway.
A DHCP packet with broadcast/multicast destination is already ensured to
always be delivered to the best gateway. Dropping a multicasted
DHCP packet here will only prevent completing DHCP as there is no
other fallback.
So far, it seems the unicast check was implicitly performed by
expecting the batadv_transtable_search() to return NULL for multicast
destinations. However, a multicast address could have always ended up in
the translation table and in fact is now common.
To fix this potential loss of a DHCP client-to-server packet to a
multicast address this patch adds an explicit multicast destination
check to reliably bail out of the gateway-out-of-range check for such
destinations.
The issue and fix were tested in the following three node setup:
- Line topology, A-B-C
- A: gateway client, DHCP client
- B: gateway server, hop-penalty increased: 30->60, DHCP server
- C: gateway server, code modifications to announce FF:FF:FF:FF:FF:FF
Without this patch, A would never transmit its DHCP Discover packet
due to an always "out-of-range" condition. With this patch,
a full DHCP handshake between A and B was possible again.
Fixes: be7af5cf9c
("batman-adv: refactoring gateway handling code")
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
This commit is contained in:
parent
f8fb3419ea
commit
a752c0a452
|
@ -746,7 +746,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
|
||||||
{
|
{
|
||||||
struct batadv_neigh_node *neigh_curr = NULL;
|
struct batadv_neigh_node *neigh_curr = NULL;
|
||||||
struct batadv_neigh_node *neigh_old = NULL;
|
struct batadv_neigh_node *neigh_old = NULL;
|
||||||
struct batadv_orig_node *orig_dst_node;
|
struct batadv_orig_node *orig_dst_node = NULL;
|
||||||
struct batadv_gw_node *gw_node = NULL;
|
struct batadv_gw_node *gw_node = NULL;
|
||||||
struct batadv_gw_node *curr_gw = NULL;
|
struct batadv_gw_node *curr_gw = NULL;
|
||||||
struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
|
struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
|
||||||
|
@ -757,6 +757,9 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
|
||||||
|
|
||||||
vid = batadv_get_vid(skb, 0);
|
vid = batadv_get_vid(skb, 0);
|
||||||
|
|
||||||
|
if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||||
|
goto out;
|
||||||
|
|
||||||
orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
|
orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
|
||||||
ethhdr->h_dest, vid);
|
ethhdr->h_dest, vid);
|
||||||
if (!orig_dst_node)
|
if (!orig_dst_node)
|
||||||
|
|
Loading…
Reference in New Issue