aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarek Lindner <mareklindner@neomailbox.ch>2018-05-11 12:23:07 -0400
committerSimon Wunderlich <sw@simonwunderlich.de>2018-05-12 12:53:08 -0400
commit16116dac23396e73c01eeee97b102e4833a4b205 (patch)
tree36b2d037ecd8946c346fc2944013a02fd0bc1b3f /net
parent7072337e52b3e9d5460500d8dc9cbc1ba2db084c (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/translation-table.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 23f9c212ab1e..3986551397ca 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -931,15 +931,20 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
931 struct batadv_tvlv_tt_vlan_data *tt_vlan; 931 struct batadv_tvlv_tt_vlan_data *tt_vlan;
932 struct batadv_softif_vlan *vlan; 932 struct batadv_softif_vlan *vlan;
933 u16 num_vlan = 0; 933 u16 num_vlan = 0;
934 u16 num_entries = 0; 934 u16 vlan_entries = 0;
935 u16 total_entries = 0;
935 u16 tvlv_len; 936 u16 tvlv_len;
936 u8 *tt_change_ptr; 937 u8 *tt_change_ptr;
937 int change_offset; 938 int change_offset;
938 939
939 spin_lock_bh(&bat_priv->softif_vlan_list_lock); 940 spin_lock_bh(&bat_priv->softif_vlan_list_lock);
940 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { 941 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
941 num_vlan++; 946 num_vlan++;
942 num_entries += atomic_read(&vlan->tt.num_entries); 947 total_entries += vlan_entries;
943 } 948 }
944 949
945 change_offset = sizeof(**tt_data); 950 change_offset = sizeof(**tt_data);
@@ -947,7 +952,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
947 952
948 /* if tt_len is negative, allocate the space needed by the full table */ 953 /* if tt_len is negative, allocate the space needed by the full table */
949 if (*tt_len < 0) 954 if (*tt_len < 0)
950 *tt_len = batadv_tt_len(num_entries); 955 *tt_len = batadv_tt_len(total_entries);
951 956
952 tvlv_len = *tt_len; 957 tvlv_len = *tt_len;
953 tvlv_len += change_offset; 958 tvlv_len += change_offset;
@@ -964,6 +969,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
964 969
965 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1); 970 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
966 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { 971 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
967 tt_vlan->vid = htons(vlan->vid); 976 tt_vlan->vid = htons(vlan->vid);
968 tt_vlan->crc = htonl(vlan->tt.crc); 977 tt_vlan->crc = htonl(vlan->tt.crc);
969 978