aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2013-07-30 16:16:25 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-19 17:25:12 -0400
commit7ea7b4a142758deaf46c1af0ca9ceca6dd55138b (patch)
tree02803d96cc171936e7c973f389ec19f7e0295a97
parenta70a9aa990bdf24039cb4167993bcc5a0f9cbb18 (diff)
batman-adv: make the TT CRC logic VLAN specific
This change allows nodes to handle the TT table on a per-VLAN basis. This is needed because nodes may have to store only some of the global entries advertised by another node. In this scenario such nodes would re-create only a partial global table and would not be able to compute a correct CRC anymore. This patch splits the logic and introduces one CRC per VLAN. In this way a node fetching only some entries belonging to some VLANs is still able to compute the needed CRCs and still check the table correctness. With this patch the shape of the TVLV-TT is changed too because now a node needs to advertise all the CRCs of all the VLANs that it is wired to. The debug output of the local Translation Table now shows the CRC along with each entry since there is not a common value for the entire table anymore. Signed-off-by: Antonio Quartulli <antonio@open-mesh.com> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
-rw-r--r--net/batman-adv/originator.c101
-rw-r--r--net/batman-adv/originator.h7
-rw-r--r--net/batman-adv/packet.h18
-rw-r--r--net/batman-adv/translation-table.c720
-rw-r--r--net/batman-adv/types.h41
5 files changed, 730 insertions, 157 deletions
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 867778e8184d..7a499dad53d3 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -44,6 +44,88 @@ static int batadv_compare_orig(const struct hlist_node *node, const void *data2)
44 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); 44 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
45} 45}
46 46
47/**
48 * batadv_orig_node_vlan_get - get an orig_node_vlan object
49 * @orig_node: the originator serving the VLAN
50 * @vid: the VLAN identifier
51 *
52 * Returns the vlan object identified by vid and belonging to orig_node or NULL
53 * if it does not exist.
54 */
55struct batadv_orig_node_vlan *
56batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
57 unsigned short vid)
58{
59 struct batadv_orig_node_vlan *vlan = NULL, *tmp;
60
61 rcu_read_lock();
62 list_for_each_entry_rcu(tmp, &orig_node->vlan_list, list) {
63 if (tmp->vid != vid)
64 continue;
65
66 if (!atomic_inc_not_zero(&tmp->refcount))
67 continue;
68
69 vlan = tmp;
70
71 break;
72 }
73 rcu_read_unlock();
74
75 return vlan;
76}
77
78/**
79 * batadv_orig_node_vlan_new - search and possibly create an orig_node_vlan
80 * object
81 * @orig_node: the originator serving the VLAN
82 * @vid: the VLAN identifier
83 *
84 * Returns NULL in case of failure or the vlan object identified by vid and
85 * belonging to orig_node otherwise. The object is created and added to the list
86 * if it does not exist.
87 *
88 * The object is returned with refcounter increased by 1.
89 */
90struct batadv_orig_node_vlan *
91batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
92 unsigned short vid)
93{
94 struct batadv_orig_node_vlan *vlan;
95
96 spin_lock_bh(&orig_node->vlan_list_lock);
97
98 /* first look if an object for this vid already exists */
99 vlan = batadv_orig_node_vlan_get(orig_node, vid);
100 if (vlan)
101 goto out;
102
103 vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
104 if (!vlan)
105 goto out;
106
107 atomic_set(&vlan->refcount, 2);
108 vlan->vid = vid;
109
110 list_add_rcu(&vlan->list, &orig_node->vlan_list);
111
112out:
113 spin_unlock_bh(&orig_node->vlan_list_lock);
114
115 return vlan;
116}
117
118/**
119 * batadv_orig_node_vlan_free_ref - decrement the refcounter and possibly free
120 * the originator-vlan object
121 * @orig_vlan: the originator-vlan object to release
122 */
123void batadv_orig_node_vlan_free_ref(struct batadv_orig_node_vlan *orig_vlan)
124{
125 if (atomic_dec_and_test(&orig_vlan->refcount))
126 kfree_rcu(orig_vlan, rcu);
127}
128
47int batadv_originator_init(struct batadv_priv *bat_priv) 129int batadv_originator_init(struct batadv_priv *bat_priv)
48{ 130{
49 if (bat_priv->orig_hash) 131 if (bat_priv->orig_hash)
@@ -218,6 +300,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
218 const uint8_t *addr) 300 const uint8_t *addr)
219{ 301{
220 struct batadv_orig_node *orig_node; 302 struct batadv_orig_node *orig_node;
303 struct batadv_orig_node_vlan *vlan;
221 int size, i; 304 int size, i;
222 int hash_added; 305 int hash_added;
223 unsigned long reset_time; 306 unsigned long reset_time;
@@ -235,11 +318,13 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
235 318
236 INIT_HLIST_HEAD(&orig_node->neigh_list); 319 INIT_HLIST_HEAD(&orig_node->neigh_list);
237 INIT_LIST_HEAD(&orig_node->bond_list); 320 INIT_LIST_HEAD(&orig_node->bond_list);
321 INIT_LIST_HEAD(&orig_node->vlan_list);
238 spin_lock_init(&orig_node->ogm_cnt_lock); 322 spin_lock_init(&orig_node->ogm_cnt_lock);
239 spin_lock_init(&orig_node->bcast_seqno_lock); 323 spin_lock_init(&orig_node->bcast_seqno_lock);
240 spin_lock_init(&orig_node->neigh_list_lock); 324 spin_lock_init(&orig_node->neigh_list_lock);
241 spin_lock_init(&orig_node->tt_buff_lock); 325 spin_lock_init(&orig_node->tt_buff_lock);
242 spin_lock_init(&orig_node->tt_lock); 326 spin_lock_init(&orig_node->tt_lock);
327 spin_lock_init(&orig_node->vlan_list_lock);
243 328
244 batadv_nc_init_orig(orig_node); 329 batadv_nc_init_orig(orig_node);
245 330
@@ -251,22 +336,30 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
251 memcpy(orig_node->orig, addr, ETH_ALEN); 336 memcpy(orig_node->orig, addr, ETH_ALEN);
252 batadv_dat_init_orig_node_addr(orig_node); 337 batadv_dat_init_orig_node_addr(orig_node);
253 orig_node->router = NULL; 338 orig_node->router = NULL;
254 orig_node->tt_crc = 0;
255 atomic_set(&orig_node->last_ttvn, 0); 339 atomic_set(&orig_node->last_ttvn, 0);
256 orig_node->tt_buff = NULL; 340 orig_node->tt_buff = NULL;
257 orig_node->tt_buff_len = 0; 341 orig_node->tt_buff_len = 0;
258 atomic_set(&orig_node->tt_size, 0);
259 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); 342 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
260 orig_node->bcast_seqno_reset = reset_time; 343 orig_node->bcast_seqno_reset = reset_time;
261 orig_node->batman_seqno_reset = reset_time; 344 orig_node->batman_seqno_reset = reset_time;
262 345
263 atomic_set(&orig_node->bond_candidates, 0); 346 atomic_set(&orig_node->bond_candidates, 0);
264 347
348 /* create a vlan object for the "untagged" LAN */
349 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
350 if (!vlan)
351 goto free_orig_node;
352 /* batadv_orig_node_vlan_new() increases the refcounter.
353 * Immediately release vlan since it is not needed anymore in this
354 * context
355 */
356 batadv_orig_node_vlan_free_ref(vlan);
357
265 size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS; 358 size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS;
266 359
267 orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); 360 orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
268 if (!orig_node->bcast_own) 361 if (!orig_node->bcast_own)
269 goto free_orig_node; 362 goto free_vlan;
270 363
271 size = bat_priv->num_ifaces * sizeof(uint8_t); 364 size = bat_priv->num_ifaces * sizeof(uint8_t);
272 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); 365 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
@@ -291,6 +384,8 @@ free_bcast_own_sum:
291 kfree(orig_node->bcast_own_sum); 384 kfree(orig_node->bcast_own_sum);
292free_bcast_own: 385free_bcast_own:
293 kfree(orig_node->bcast_own); 386 kfree(orig_node->bcast_own);
387free_vlan:
388 batadv_orig_node_vlan_free_ref(vlan);
294free_orig_node: 389free_orig_node:
295 kfree(orig_node); 390 kfree(orig_node);
296 return NULL; 391 return NULL;
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 7887b84a9af4..cc6d686cfe6d 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -40,6 +40,13 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
40 int max_if_num); 40 int max_if_num);
41int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, 41int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
42 int max_if_num); 42 int max_if_num);
43struct batadv_orig_node_vlan *