44
44
if (bat_priv->orig_hash)
47
spin_lock_bh(&bat_priv->orig_hash_lock);
48
47
bat_priv->orig_hash = hash_new(1024);
50
49
if (!bat_priv->orig_hash)
53
spin_unlock_bh(&bat_priv->orig_hash_lock);
54
52
start_purge_timer(bat_priv);
58
spin_unlock_bh(&bat_priv->orig_hash_lock);
63
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
64
uint8_t *neigh, struct batman_if *if_incoming)
59
static void neigh_node_free_rcu(struct rcu_head *rcu)
61
struct neigh_node *neigh_node;
63
neigh_node = container_of(rcu, struct neigh_node, rcu);
67
void neigh_node_free_ref(struct neigh_node *neigh_node)
69
if (atomic_dec_and_test(&neigh_node->refcount))
70
call_rcu(&neigh_node->rcu, neigh_node_free_rcu);
73
struct neigh_node *create_neighbor(struct orig_node *orig_node,
74
struct orig_node *orig_neigh_node,
76
struct hard_iface *if_incoming)
66
78
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
67
79
struct neigh_node *neigh_node;
76
INIT_LIST_HEAD(&neigh_node->list);
88
INIT_HLIST_NODE(&neigh_node->list);
89
INIT_LIST_HEAD(&neigh_node->bonding_list);
78
91
memcpy(neigh_node->addr, neigh, ETH_ALEN);
79
92
neigh_node->orig_node = orig_neigh_node;
80
93
neigh_node->if_incoming = if_incoming;
82
list_add_tail(&neigh_node->list, &orig_node->neigh_list);
95
/* extra reference for return */
96
atomic_set(&neigh_node->refcount, 2);
98
spin_lock_bh(&orig_node->neigh_list_lock);
99
hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
100
spin_unlock_bh(&orig_node->neigh_list_lock);
83
101
return neigh_node;
86
static void free_orig_node(void *data, void *arg)
104
static void orig_node_free_rcu(struct rcu_head *rcu)
88
struct list_head *list_pos, *list_pos_tmp;
89
struct neigh_node *neigh_node;
90
struct orig_node *orig_node = (struct orig_node *)data;
91
struct bat_priv *bat_priv = (struct bat_priv *)arg;
106
struct hlist_node *node, *node_tmp;
107
struct neigh_node *neigh_node, *tmp_neigh_node;
108
struct orig_node *orig_node;
110
orig_node = container_of(rcu, struct orig_node, rcu);
112
spin_lock_bh(&orig_node->neigh_list_lock);
114
/* for all bonding members ... */
115
list_for_each_entry_safe(neigh_node, tmp_neigh_node,
116
&orig_node->bond_list, bonding_list) {
117
list_del_rcu(&neigh_node->bonding_list);
118
neigh_node_free_ref(neigh_node);
93
121
/* for all neighbors towards this originator ... */
94
list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
95
neigh_node = list_entry(list_pos, struct neigh_node, list);
122
hlist_for_each_entry_safe(neigh_node, node, node_tmp,
123
&orig_node->neigh_list, list) {
124
hlist_del_rcu(&neigh_node->list);
125
neigh_node_free_ref(neigh_node);
128
spin_unlock_bh(&orig_node->neigh_list_lock);
101
130
frag_list_free(&orig_node->frag_list);
102
hna_global_del_orig(bat_priv, orig_node, "originator timed out");
131
hna_global_del_orig(orig_node->bat_priv, orig_node,
132
"originator timed out");
104
134
kfree(orig_node->bcast_own);
105
135
kfree(orig_node->bcast_own_sum);
106
136
kfree(orig_node);
139
void orig_node_free_ref(struct orig_node *orig_node)
141
if (atomic_dec_and_test(&orig_node->refcount))
142
call_rcu(&orig_node->rcu, orig_node_free_rcu);
109
145
void originator_free(struct bat_priv *bat_priv)
111
if (!bat_priv->orig_hash)
147
struct hashtable_t *hash = bat_priv->orig_hash;
148
struct hlist_node *node, *node_tmp;
149
struct hlist_head *head;
150
spinlock_t *list_lock; /* spinlock to protect write access */
151
struct orig_node *orig_node;
114
157
cancel_delayed_work_sync(&bat_priv->orig_work);
116
spin_lock_bh(&bat_priv->orig_hash_lock);
117
hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv);
118
159
bat_priv->orig_hash = NULL;
119
spin_unlock_bh(&bat_priv->orig_hash_lock);
161
for (i = 0; i < hash->size; i++) {
162
head = &hash->table[i];
163
list_lock = &hash->list_locks[i];
165
spin_lock_bh(list_lock);
166
hlist_for_each_entry_safe(orig_node, node, node_tmp,
170
orig_node_free_ref(orig_node);
172
spin_unlock_bh(list_lock);
122
178
/* this function finds or creates an originator entry for the given
144
INIT_LIST_HEAD(&orig_node->neigh_list);
197
INIT_HLIST_HEAD(&orig_node->neigh_list);
198
INIT_LIST_HEAD(&orig_node->bond_list);
199
spin_lock_init(&orig_node->ogm_cnt_lock);
200
spin_lock_init(&orig_node->bcast_seqno_lock);
201
spin_lock_init(&orig_node->neigh_list_lock);
203
/* extra reference for return */
204
atomic_set(&orig_node->refcount, 2);
206
orig_node->bat_priv = bat_priv;
146
207
memcpy(orig_node->orig, addr, ETH_ALEN);
147
208
orig_node->router = NULL;
148
209
orig_node->hna_buff = NULL;
185
248
struct orig_node *orig_node,
186
249
struct neigh_node **best_neigh_node)
188
struct list_head *list_pos, *list_pos_tmp;
251
struct hlist_node *node, *node_tmp;
189
252
struct neigh_node *neigh_node;
190
253
bool neigh_purged = false;
192
255
*best_neigh_node = NULL;
257
spin_lock_bh(&orig_node->neigh_list_lock);
194
259
/* for all neighbors towards this originator ... */
195
list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
196
neigh_node = list_entry(list_pos, struct neigh_node, list);
260
hlist_for_each_entry_safe(neigh_node, node, node_tmp,
261
&orig_node->neigh_list, list) {
198
263
if ((time_after(jiffies,
199
264
neigh_node->last_valid + PURGE_TIMEOUT * HZ)) ||
200
265
(neigh_node->if_incoming->if_status == IF_INACTIVE) ||
266
(neigh_node->if_incoming->if_status == IF_NOT_IN_USE) ||
201
267
(neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) {
203
if (neigh_node->if_incoming->if_status ==
269
if ((neigh_node->if_incoming->if_status ==
271
(neigh_node->if_incoming->if_status ==
273
(neigh_node->if_incoming->if_status ==
205
275
bat_dbg(DBG_BATMAN, bat_priv,
206
276
"neighbor purge: originator %pM, "
207
277
"neighbor: %pM, iface: %s\n",
257
328
static void _purge_orig(struct bat_priv *bat_priv)
259
330
struct hashtable_t *hash = bat_priv->orig_hash;
260
struct hlist_node *walk, *safe;
331
struct hlist_node *node, *node_tmp;
261
332
struct hlist_head *head;
262
struct element_t *bucket;
333
spinlock_t *list_lock; /* spinlock to protect write access */
263
334
struct orig_node *orig_node;
269
spin_lock_bh(&bat_priv->orig_hash_lock);
271
340
/* for all origins... */
272
341
for (i = 0; i < hash->size; i++) {
273
342
head = &hash->table[i];
275
hlist_for_each_entry_safe(bucket, walk, safe, head, hlist) {
276
orig_node = bucket->data;
343
list_lock = &hash->list_locks[i];
345
spin_lock_bh(list_lock);
346
hlist_for_each_entry_safe(orig_node, node, node_tmp,
278
348
if (purge_orig_node(bat_priv, orig_node)) {
279
349
if (orig_node->gw_flags)
280
350
gw_node_delete(bat_priv, orig_node);
283
free_orig_node(orig_node, bat_priv);
352
orig_node_free_ref(orig_node);
286
356
if (time_after(jiffies, orig_node->last_frag_packet +
287
357
msecs_to_jiffies(FRAG_TIMEOUT)))
288
358
frag_list_free(&orig_node->frag_list);
360
spin_unlock_bh(list_lock);
292
spin_unlock_bh(&bat_priv->orig_hash_lock);
294
363
gw_node_purge(bat_priv);
295
364
gw_election(bat_priv);
348
416
"Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
349
417
"outgoingIF", "Potential nexthops");
351
spin_lock_bh(&bat_priv->orig_hash_lock);
353
419
for (i = 0; i < hash->size; i++) {
354
420
head = &hash->table[i];
356
hlist_for_each_entry(bucket, walk, head, hlist) {
357
orig_node = bucket->data;
423
hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
359
424
if (!orig_node->router)
426
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
490
int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num)
428
struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
492
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
429
493
struct hashtable_t *hash = bat_priv->orig_hash;
430
struct hlist_node *walk;
494
struct hlist_node *node;
431
495
struct hlist_head *head;
432
struct element_t *bucket;
433
496
struct orig_node *orig_node;
436
499
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
438
spin_lock_bh(&bat_priv->orig_hash_lock);
440
501
for (i = 0; i < hash->size; i++) {
441
502
head = &hash->table[i];
443
hlist_for_each_entry(bucket, walk, head, hlist) {
444
orig_node = bucket->data;
505
hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
506
spin_lock_bh(&orig_node->ogm_cnt_lock);
507
ret = orig_node_add_if(orig_node, max_if_num);
508
spin_unlock_bh(&orig_node->ogm_cnt_lock);
446
if (orig_node_add_if(orig_node, max_if_num) == -1)
451
spin_unlock_bh(&bat_priv->orig_hash_lock);
455
spin_unlock_bh(&bat_priv->orig_hash_lock);
511
int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
575
int orig_hash_del_if(struct hard_iface *hard_iface, int max_if_num)
513
struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
577
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
514
578
struct hashtable_t *hash = bat_priv->orig_hash;
515
struct hlist_node *walk;
579
struct hlist_node *node;
516
580
struct hlist_head *head;
517
struct element_t *bucket;
518
struct batman_if *batman_if_tmp;
581
struct hard_iface *hard_iface_tmp;
519
582
struct orig_node *orig_node;
522
585
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
524
spin_lock_bh(&bat_priv->orig_hash_lock);
526
587
for (i = 0; i < hash->size; i++) {
527
588
head = &hash->table[i];
529
hlist_for_each_entry(bucket, walk, head, hlist) {
530
orig_node = bucket->data;
591
hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
592
spin_lock_bh(&orig_node->ogm_cnt_lock);
532
593
ret = orig_node_del_if(orig_node, max_if_num,
595
spin_unlock_bh(&orig_node->ogm_cnt_lock);
540
603
/* renumber remaining batman interfaces _inside_ of orig_hash_lock */
542
list_for_each_entry_rcu(batman_if_tmp, &if_list, list) {
543
if (batman_if_tmp->if_status == IF_NOT_IN_USE)
546
if (batman_if == batman_if_tmp)
549
if (batman_if->soft_iface != batman_if_tmp->soft_iface)
552
if (batman_if_tmp->if_num > batman_if->if_num)
553
batman_if_tmp->if_num--;
605
list_for_each_entry_rcu(hard_iface_tmp, &hardif_list, list) {
606
if (hard_iface_tmp->if_status == IF_NOT_IN_USE)
609
if (hard_iface == hard_iface_tmp)
612
if (hard_iface->soft_iface != hard_iface_tmp->soft_iface)
615
if (hard_iface_tmp->if_num > hard_iface->if_num)
616
hard_iface_tmp->if_num--;
555
618
rcu_read_unlock();
557
batman_if->if_num = -1;
558
spin_unlock_bh(&bat_priv->orig_hash_lock);
620
hard_iface->if_num = -1;
562
spin_unlock_bh(&bat_priv->orig_hash_lock);