Skip to content

Commit 4d2bbb0

Browse files
committed
Merge tag 'batadv-net-for-davem-20170802' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says: ==================== Here is a batman-adv bugfix: - fix TT sync flag inconsistency problems, which can lead to excess packets, by Linus Luessing ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents ed25497 + 54e22f2 commit 4d2bbb0

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

net/batman-adv/translation-table.c

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,9 +1549,41 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
15491549
return found;
15501550
}
15511551

1552+
/**
1553+
* batadv_tt_global_sync_flags - update TT sync flags
1554+
* @tt_global: the TT global entry to update sync flags in
1555+
*
1556+
* Updates the sync flag bits in the tt_global flag attribute with a logical
1557+
* OR of all sync flags from any of its TT orig entries.
1558+
*/
1559+
static void
1560+
batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global)
1561+
{
1562+
struct batadv_tt_orig_list_entry *orig_entry;
1563+
const struct hlist_head *head;
1564+
u16 flags = BATADV_NO_FLAGS;
1565+
1566+
rcu_read_lock();
1567+
head = &tt_global->orig_list;
1568+
hlist_for_each_entry_rcu(orig_entry, head, list)
1569+
flags |= orig_entry->flags;
1570+
rcu_read_unlock();
1571+
1572+
flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK);
1573+
tt_global->common.flags = flags;
1574+
}
1575+
1576+
/**
1577+
* batadv_tt_global_orig_entry_add - add or update a TT orig entry
1578+
* @tt_global: the TT global entry to add an orig entry in
1579+
* @orig_node: the originator to add an orig entry for
1580+
* @ttvn: translation table version number of this changeset
1581+
* @flags: TT sync flags
1582+
*/
15521583
static void
15531584
batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
1554-
struct batadv_orig_node *orig_node, int ttvn)
1585+
struct batadv_orig_node *orig_node, int ttvn,
1586+
u8 flags)
15551587
{
15561588
struct batadv_tt_orig_list_entry *orig_entry;
15571589

@@ -1561,7 +1593,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
15611593
* was added during a "temporary client detection"
15621594
*/
15631595
orig_entry->ttvn = ttvn;
1564-
goto out;
1596+
orig_entry->flags = flags;
1597+
goto sync_flags;
15651598
}
15661599

15671600
orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC);
@@ -1573,6 +1606,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
15731606
batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
15741607
orig_entry->orig_node = orig_node;
15751608
orig_entry->ttvn = ttvn;
1609+
orig_entry->flags = flags;
15761610
kref_init(&orig_entry->refcount);
15771611

15781612
spin_lock_bh(&tt_global->list_lock);
@@ -1582,6 +1616,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
15821616
spin_unlock_bh(&tt_global->list_lock);
15831617
atomic_inc(&tt_global->orig_list_count);
15841618

1619+
sync_flags:
1620+
batadv_tt_global_sync_flags(tt_global);
15851621
out:
15861622
if (orig_entry)
15871623
batadv_tt_orig_list_entry_put(orig_entry);
@@ -1703,10 +1739,10 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
17031739
}
17041740

17051741
/* the change can carry possible "attribute" flags like the
1706-
* TT_CLIENT_WIFI, therefore they have to be copied in the
1742+
* TT_CLIENT_TEMP, therefore they have to be copied in the
17071743
* client entry
17081744
*/
1709-
common->flags |= flags;
1745+
common->flags |= flags & (~BATADV_TT_SYNC_MASK);
17101746

17111747
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
17121748
* one originator left in the list and we previously received a
@@ -1723,7 +1759,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
17231759
}
17241760
add_orig_entry:
17251761
/* add the new orig_entry (if needed) or update it */
1726-
batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
1762+
batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn,
1763+
flags & BATADV_TT_SYNC_MASK);
17271764

17281765
batadv_dbg(BATADV_DBG_TT, bat_priv,
17291766
"Creating new global tt entry: %pM (vid: %d, via %pM)\n",
@@ -1946,6 +1983,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
19461983
struct batadv_tt_orig_list_entry *orig,
19471984
bool best)
19481985
{
1986+
u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags;
19491987
void *hdr;
19501988
struct batadv_orig_node_vlan *vlan;
19511989
u8 last_ttvn;
@@ -1975,7 +2013,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
19752013
nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) ||
19762014
nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
19772015
nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) ||
1978-
nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags))
2016+
nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags))
19792017
goto nla_put_failure;
19802018

19812019
if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
@@ -2589,6 +2627,7 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
25892627
unsigned short vid)
25902628
{
25912629
struct batadv_hashtable *hash = bat_priv->tt.global_hash;
2630+
struct batadv_tt_orig_list_entry *tt_orig;
25922631
struct batadv_tt_common_entry *tt_common;
25932632
struct batadv_tt_global_entry *tt_global;
25942633
struct hlist_head *head;
@@ -2627,8 +2666,9 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
26272666
/* find out if this global entry is announced by this
26282667
* originator
26292668
*/
2630-
if (!batadv_tt_global_entry_has_orig(tt_global,
2631-
orig_node))
2669+
tt_orig = batadv_tt_global_orig_entry_find(tt_global,
2670+
orig_node);
2671+
if (!tt_orig)
26322672
continue;
26332673

26342674
/* use network order to read the VID: this ensures that
@@ -2640,10 +2680,12 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
26402680
/* compute the CRC on flags that have to be kept in sync
26412681
* among nodes
26422682
*/
2643-
flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2683+
flags = tt_orig->flags;
26442684
crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
26452685

26462686
crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
2687+
2688+
batadv_tt_orig_list_entry_put(tt_orig);
26472689
}
26482690
rcu_read_unlock();
26492691
}

net/batman-adv/types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,13 +1260,15 @@ struct batadv_tt_global_entry {
12601260
* struct batadv_tt_orig_list_entry - orig node announcing a non-mesh client
12611261
* @orig_node: pointer to orig node announcing this non-mesh client
12621262
* @ttvn: translation table version number which added the non-mesh client
1263+
* @flags: per orig entry TT sync flags
12631264
* @list: list node for batadv_tt_global_entry::orig_list
12641265
* @refcount: number of contexts the object is used
12651266
* @rcu: struct used for freeing in an RCU-safe manner
12661267
*/
12671268
struct batadv_tt_orig_list_entry {
12681269
struct batadv_orig_node *orig_node;
12691270
u8 ttvn;
1271+
u8 flags;
12701272
struct hlist_node list;
12711273
struct kref refcount;
12721274
struct rcu_head rcu;

0 commit comments

Comments
 (0)