Skip to content

Commit 16116da

Browse files
Marek Lindnersimonwunderlich
authored andcommitted
batman-adv: prevent TT request storms by not sending inconsistent TT TLVLs
A translation table TVLV changset sent with an OGM consists of a number of headers (one per VLAN) plus the changeset itself (addition and/or deletion of entries). The per-VLAN headers are used by OGM recipients for consistency checks. Said consistency check might determine that a full translation table request is needed to restore consistency. If the TT sender adds per-VLAN headers of empty VLANs into the OGM, recipients are led to believe to have reached an inconsistent state and thus request a full table update. The full table does not contain empty VLANs (due to missing entries) the cycle restarts when the next OGM is issued. Consequently, when the translation table TVLV headers are composed, empty VLANs are to be excluded. Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific") Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch> Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
1 parent 7072337 commit 16116da

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

net/batman-adv/translation-table.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -931,23 +931,28 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
931931
struct batadv_tvlv_tt_vlan_data *tt_vlan;
932932
struct batadv_softif_vlan *vlan;
933933
u16 num_vlan = 0;
934-
u16 num_entries = 0;
934+
u16 vlan_entries = 0;
935+
u16 total_entries = 0;
935936
u16 tvlv_len;
936937
u8 *tt_change_ptr;
937938
int change_offset;
938939

939940
spin_lock_bh(&bat_priv->softif_vlan_list_lock);
940941
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
942+
vlan_entries = atomic_read(&vlan->tt.num_entries);
943+
if (vlan_entries < 1)
944+
continue;
945+
941946
num_vlan++;
942-
num_entries += atomic_read(&vlan->tt.num_entries);
947+
total_entries += vlan_entries;
943948
}
944949

945950
change_offset = sizeof(**tt_data);
946951
change_offset += num_vlan * sizeof(*tt_vlan);
947952

948953
/* if tt_len is negative, allocate the space needed by the full table */
949954
if (*tt_len < 0)
950-
*tt_len = batadv_tt_len(num_entries);
955+
*tt_len = batadv_tt_len(total_entries);
951956

952957
tvlv_len = *tt_len;
953958
tvlv_len += change_offset;
@@ -964,6 +969,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
964969

965970
tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
966971
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
972+
vlan_entries = atomic_read(&vlan->tt.num_entries);
973+
if (vlan_entries < 1)
974+
continue;
975+
967976
tt_vlan->vid = htons(vlan->vid);
968977
tt_vlan->crc = htonl(vlan->tt.crc);
969978

0 commit comments

Comments
 (0)