Commit 0c9cd7c4 authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge

Antonio Quartulli says:

====================
Included changes:
- prevent compatibility issue between DAT and speedy join from creating
  inconsistencies in the global translation table
- make sure temporary TT entries are purged out if not claimed
- fix comparison function used for TT hash table
- fix invalid stack access in batadv_dat_select_candidates()
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fe82b330 b7fe3d4f
...@@ -566,6 +566,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) ...@@ -566,6 +566,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
int select; int select;
batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key; batadv_dat_addr_t last_max = BATADV_DAT_ADDR_MAX, ip_key;
struct batadv_dat_candidate *res; struct batadv_dat_candidate *res;
struct batadv_dat_entry dat;
if (!bat_priv->orig_hash) if (!bat_priv->orig_hash)
return NULL; return NULL;
...@@ -575,7 +576,9 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst) ...@@ -575,7 +576,9 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
if (!res) if (!res)
return NULL; return NULL;
ip_key = (batadv_dat_addr_t)batadv_hash_dat(&ip_dst, dat.ip = ip_dst;
dat.vid = 0;
ip_key = (batadv_dat_addr_t)batadv_hash_dat(&dat,
BATADV_DAT_ADDR_MAX); BATADV_DAT_ADDR_MAX);
batadv_dbg(BATADV_DBG_DAT, bat_priv, batadv_dbg(BATADV_DBG_DAT, bat_priv,
......
...@@ -836,6 +836,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, ...@@ -836,6 +836,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
u8 *orig_addr; u8 *orig_addr;
struct batadv_orig_node *orig_node = NULL; struct batadv_orig_node *orig_node = NULL;
int check, hdr_size = sizeof(*unicast_packet); int check, hdr_size = sizeof(*unicast_packet);
enum batadv_subtype subtype;
bool is4addr; bool is4addr;
unicast_packet = (struct batadv_unicast_packet *)skb->data; unicast_packet = (struct batadv_unicast_packet *)skb->data;
...@@ -863,10 +864,20 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, ...@@ -863,10 +864,20 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
/* packet for me */ /* packet for me */
if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
if (is4addr) { if (is4addr) {
batadv_dat_inc_counter(bat_priv, subtype = unicast_4addr_packet->subtype;
unicast_4addr_packet->subtype); batadv_dat_inc_counter(bat_priv, subtype);
/* Only payload data should be considered for speedy
* join. For example, DAT also uses unicast 4addr
* types, but those packets should not be considered
* for speedy join, since the clients do not actually
* reside at the sending originator.
*/
if (subtype == BATADV_P_DATA) {
orig_addr = unicast_4addr_packet->src; orig_addr = unicast_4addr_packet->src;
orig_node = batadv_orig_hash_find(bat_priv, orig_addr); orig_node = batadv_orig_hash_find(bat_priv,
orig_addr);
}
} }
if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb,
......
...@@ -68,13 +68,15 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv, ...@@ -68,13 +68,15 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
unsigned short vid, const char *message, unsigned short vid, const char *message,
bool roaming); bool roaming);
/* returns 1 if they are the same mac addr */ /* returns 1 if they are the same mac addr and vid */
static int batadv_compare_tt(const struct hlist_node *node, const void *data2) static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
{ {
const void *data1 = container_of(node, struct batadv_tt_common_entry, const void *data1 = container_of(node, struct batadv_tt_common_entry,
hash_entry); hash_entry);
const struct batadv_tt_common_entry *tt1 = data1;
const struct batadv_tt_common_entry *tt2 = data2;
return batadv_compare_eth(data1, data2); return (tt1->vid == tt2->vid) && batadv_compare_eth(data1, data2);
} }
/** /**
...@@ -1427,9 +1429,15 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, ...@@ -1427,9 +1429,15 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
} }
/* if the client was temporary added before receiving the first /* if the client was temporary added before receiving the first
* OGM announcing it, we have to clear the TEMP flag * OGM announcing it, we have to clear the TEMP flag. Also,
* remove the previous temporary orig node and re-add it
* if required. If the orig entry changed, the new one which
* is a non-temporary entry is preferred.
*/ */
if (common->flags & BATADV_TT_CLIENT_TEMP) {
batadv_tt_global_del_orig_list(tt_global_entry);
common->flags &= ~BATADV_TT_CLIENT_TEMP; common->flags &= ~BATADV_TT_CLIENT_TEMP;
}
/* the change can carry possible "attribute" flags like the /* the change can carry possible "attribute" flags like the
* TT_CLIENT_WIFI, therefore they have to be copied in the * TT_CLIENT_WIFI, therefore they have to be copied in the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment