.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2008, 2009 open80211s Ltd. |
---|
3 | 4 | * Author: Luis Carlos Cobo <luisca@cozybit.com> |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License version 2 as |
---|
7 | | - * published by the Free Software Foundation. |
---|
8 | 5 | */ |
---|
9 | 6 | |
---|
10 | 7 | #include <linux/etherdevice.h> |
---|
.. | .. |
---|
50 | 47 | mesh_path_free_rcu(tbl, mpath); |
---|
51 | 48 | } |
---|
52 | 49 | |
---|
53 | | -static struct mesh_table *mesh_table_alloc(void) |
---|
| 50 | +static void mesh_table_init(struct mesh_table *tbl) |
---|
54 | 51 | { |
---|
55 | | - struct mesh_table *newtbl; |
---|
| 52 | + INIT_HLIST_HEAD(&tbl->known_gates); |
---|
| 53 | + INIT_HLIST_HEAD(&tbl->walk_head); |
---|
| 54 | + atomic_set(&tbl->entries, 0); |
---|
| 55 | + spin_lock_init(&tbl->gates_lock); |
---|
| 56 | + spin_lock_init(&tbl->walk_lock); |
---|
56 | 57 | |
---|
57 | | - newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC); |
---|
58 | | - if (!newtbl) |
---|
59 | | - return NULL; |
---|
60 | | - |
---|
61 | | - INIT_HLIST_HEAD(&newtbl->known_gates); |
---|
62 | | - INIT_HLIST_HEAD(&newtbl->walk_head); |
---|
63 | | - atomic_set(&newtbl->entries, 0); |
---|
64 | | - spin_lock_init(&newtbl->gates_lock); |
---|
65 | | - spin_lock_init(&newtbl->walk_lock); |
---|
66 | | - if (rhashtable_init(&newtbl->rhead, &mesh_rht_params)) { |
---|
67 | | - kfree(newtbl); |
---|
68 | | - return NULL; |
---|
69 | | - } |
---|
70 | | - |
---|
71 | | - return newtbl; |
---|
| 58 | + /* rhashtable_init() may fail only in case of wrong |
---|
| 59 | + * mesh_rht_params |
---|
| 60 | + */ |
---|
| 61 | + WARN_ON(rhashtable_init(&tbl->rhead, &mesh_rht_params)); |
---|
72 | 62 | } |
---|
73 | 63 | |
---|
74 | 64 | static void mesh_table_free(struct mesh_table *tbl) |
---|
75 | 65 | { |
---|
76 | 66 | rhashtable_free_and_destroy(&tbl->rhead, |
---|
77 | 67 | mesh_path_rht_free, tbl); |
---|
78 | | - kfree(tbl); |
---|
79 | 68 | } |
---|
80 | 69 | |
---|
81 | 70 | /** |
---|
82 | | - * |
---|
83 | 71 | * mesh_path_assign_nexthop - update mesh path next hop |
---|
84 | 72 | * |
---|
85 | 73 | * @mpath: mesh path to update |
---|
.. | .. |
---|
147 | 135 | } |
---|
148 | 136 | |
---|
149 | 137 | /** |
---|
150 | | - * |
---|
151 | 138 | * mesh_path_move_to_queue - Move or copy frames from one mpath queue to another |
---|
152 | 139 | * |
---|
153 | 140 | * This function is used to transfer or copy frames from an unresolved mpath to |
---|
.. | .. |
---|
159 | 146 | * |
---|
160 | 147 | * The gate mpath must be an active mpath with a valid mpath->next_hop. |
---|
161 | 148 | * |
---|
162 | | - * @mpath: An active mpath the frames will be sent to (i.e. the gate) |
---|
| 149 | + * @gate_mpath: An active mpath the frames will be sent to (i.e. the gate) |
---|
163 | 150 | * @from_mpath: The failed mpath |
---|
164 | 151 | * @copy: When true, copy all the frames to the new mpath queue. When false, |
---|
165 | 152 | * move them. |
---|
.. | .. |
---|
221 | 208 | { |
---|
222 | 209 | struct mesh_path *mpath; |
---|
223 | 210 | |
---|
224 | | - mpath = rhashtable_lookup_fast(&tbl->rhead, dst, mesh_rht_params); |
---|
| 211 | + mpath = rhashtable_lookup(&tbl->rhead, dst, mesh_rht_params); |
---|
225 | 212 | |
---|
226 | 213 | if (mpath && mpath_expired(mpath)) { |
---|
227 | 214 | spin_lock_bh(&mpath->state_lock); |
---|
.. | .. |
---|
243 | 230 | struct mesh_path * |
---|
244 | 231 | mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) |
---|
245 | 232 | { |
---|
246 | | - return mpath_lookup(sdata->u.mesh.mesh_paths, dst, sdata); |
---|
| 233 | + return mpath_lookup(&sdata->u.mesh.mesh_paths, dst, sdata); |
---|
247 | 234 | } |
---|
248 | 235 | |
---|
249 | 236 | struct mesh_path * |
---|
250 | 237 | mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst) |
---|
251 | 238 | { |
---|
252 | | - return mpath_lookup(sdata->u.mesh.mpp_paths, dst, sdata); |
---|
| 239 | + return mpath_lookup(&sdata->u.mesh.mpp_paths, dst, sdata); |
---|
253 | 240 | } |
---|
254 | 241 | |
---|
255 | 242 | static struct mesh_path * |
---|
.. | .. |
---|
286 | 273 | struct mesh_path * |
---|
287 | 274 | mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) |
---|
288 | 275 | { |
---|
289 | | - return __mesh_path_lookup_by_idx(sdata->u.mesh.mesh_paths, idx); |
---|
| 276 | + return __mesh_path_lookup_by_idx(&sdata->u.mesh.mesh_paths, idx); |
---|
290 | 277 | } |
---|
291 | 278 | |
---|
292 | 279 | /** |
---|
.. | .. |
---|
301 | 288 | struct mesh_path * |
---|
302 | 289 | mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) |
---|
303 | 290 | { |
---|
304 | | - return __mesh_path_lookup_by_idx(sdata->u.mesh.mpp_paths, idx); |
---|
| 291 | + return __mesh_path_lookup_by_idx(&sdata->u.mesh.mpp_paths, idx); |
---|
305 | 292 | } |
---|
306 | 293 | |
---|
307 | 294 | /** |
---|
.. | .. |
---|
314 | 301 | int err; |
---|
315 | 302 | |
---|
316 | 303 | rcu_read_lock(); |
---|
317 | | - tbl = mpath->sdata->u.mesh.mesh_paths; |
---|
| 304 | + tbl = &mpath->sdata->u.mesh.mesh_paths; |
---|
318 | 305 | |
---|
319 | 306 | spin_lock_bh(&mpath->state_lock); |
---|
320 | 307 | if (mpath->is_gate) { |
---|
.. | .. |
---|
408 | 395 | { |
---|
409 | 396 | struct mesh_table *tbl; |
---|
410 | 397 | struct mesh_path *mpath, *new_mpath; |
---|
411 | | - int ret; |
---|
412 | 398 | |
---|
413 | 399 | if (ether_addr_equal(dst, sdata->vif.addr)) |
---|
414 | 400 | /* never add ourselves as neighbours */ |
---|
.. | .. |
---|
424 | 410 | if (!new_mpath) |
---|
425 | 411 | return ERR_PTR(-ENOMEM); |
---|
426 | 412 | |
---|
427 | | - tbl = sdata->u.mesh.mesh_paths; |
---|
| 413 | + tbl = &sdata->u.mesh.mesh_paths; |
---|
428 | 414 | spin_lock_bh(&tbl->walk_lock); |
---|
429 | | - do { |
---|
430 | | - ret = rhashtable_lookup_insert_fast(&tbl->rhead, |
---|
431 | | - &new_mpath->rhash, |
---|
432 | | - mesh_rht_params); |
---|
433 | | - |
---|
434 | | - if (ret == -EEXIST) |
---|
435 | | - mpath = rhashtable_lookup_fast(&tbl->rhead, |
---|
436 | | - dst, |
---|
437 | | - mesh_rht_params); |
---|
438 | | - else if (!ret) |
---|
439 | | - hlist_add_head(&new_mpath->walk_list, &tbl->walk_head); |
---|
440 | | - } while (unlikely(ret == -EEXIST && !mpath)); |
---|
| 415 | + mpath = rhashtable_lookup_get_insert_fast(&tbl->rhead, |
---|
| 416 | + &new_mpath->rhash, |
---|
| 417 | + mesh_rht_params); |
---|
| 418 | + if (!mpath) |
---|
| 419 | + hlist_add_head(&new_mpath->walk_list, &tbl->walk_head); |
---|
441 | 420 | spin_unlock_bh(&tbl->walk_lock); |
---|
442 | 421 | |
---|
443 | | - if (ret) { |
---|
| 422 | + if (mpath) { |
---|
444 | 423 | kfree(new_mpath); |
---|
445 | 424 | |
---|
446 | | - if (ret != -EEXIST) |
---|
447 | | - return ERR_PTR(ret); |
---|
| 425 | + if (IS_ERR(mpath)) |
---|
| 426 | + return mpath; |
---|
448 | 427 | |
---|
449 | 428 | new_mpath = mpath; |
---|
450 | 429 | } |
---|
.. | .. |
---|
473 | 452 | return -ENOMEM; |
---|
474 | 453 | |
---|
475 | 454 | memcpy(new_mpath->mpp, mpp, ETH_ALEN); |
---|
476 | | - tbl = sdata->u.mesh.mpp_paths; |
---|
| 455 | + tbl = &sdata->u.mesh.mpp_paths; |
---|
477 | 456 | |
---|
478 | 457 | spin_lock_bh(&tbl->walk_lock); |
---|
479 | 458 | ret = rhashtable_lookup_insert_fast(&tbl->rhead, |
---|
.. | .. |
---|
502 | 481 | void mesh_plink_broken(struct sta_info *sta) |
---|
503 | 482 | { |
---|
504 | 483 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
---|
505 | | - struct mesh_table *tbl = sdata->u.mesh.mesh_paths; |
---|
| 484 | + struct mesh_table *tbl = &sdata->u.mesh.mesh_paths; |
---|
506 | 485 | static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
---|
507 | 486 | struct mesh_path *mpath; |
---|
508 | 487 | |
---|
.. | .. |
---|
561 | 540 | void mesh_path_flush_by_nexthop(struct sta_info *sta) |
---|
562 | 541 | { |
---|
563 | 542 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
---|
564 | | - struct mesh_table *tbl = sdata->u.mesh.mesh_paths; |
---|
| 543 | + struct mesh_table *tbl = &sdata->u.mesh.mesh_paths; |
---|
565 | 544 | struct mesh_path *mpath; |
---|
566 | 545 | struct hlist_node *n; |
---|
567 | 546 | |
---|
.. | .. |
---|
576 | 555 | static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata, |
---|
577 | 556 | const u8 *proxy) |
---|
578 | 557 | { |
---|
579 | | - struct mesh_table *tbl = sdata->u.mesh.mpp_paths; |
---|
| 558 | + struct mesh_table *tbl = &sdata->u.mesh.mpp_paths; |
---|
580 | 559 | struct mesh_path *mpath; |
---|
581 | 560 | struct hlist_node *n; |
---|
582 | 561 | |
---|
.. | .. |
---|
610 | 589 | */ |
---|
611 | 590 | void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) |
---|
612 | 591 | { |
---|
613 | | - table_flush_by_iface(sdata->u.mesh.mesh_paths); |
---|
614 | | - table_flush_by_iface(sdata->u.mesh.mpp_paths); |
---|
| 592 | + table_flush_by_iface(&sdata->u.mesh.mesh_paths); |
---|
| 593 | + table_flush_by_iface(&sdata->u.mesh.mpp_paths); |
---|
615 | 594 | } |
---|
616 | 595 | |
---|
617 | 596 | /** |
---|
.. | .. |
---|
657 | 636 | /* flush relevant mpp entries first */ |
---|
658 | 637 | mpp_flush_by_proxy(sdata, addr); |
---|
659 | 638 | |
---|
660 | | - err = table_path_del(sdata->u.mesh.mesh_paths, sdata, addr); |
---|
| 639 | + err = table_path_del(&sdata->u.mesh.mesh_paths, sdata, addr); |
---|
661 | 640 | sdata->u.mesh.mesh_paths_generation++; |
---|
662 | 641 | return err; |
---|
663 | 642 | } |
---|
.. | .. |
---|
695 | 674 | struct mesh_path *gate; |
---|
696 | 675 | bool copy = false; |
---|
697 | 676 | |
---|
698 | | - tbl = sdata->u.mesh.mesh_paths; |
---|
| 677 | + tbl = &sdata->u.mesh.mesh_paths; |
---|
699 | 678 | |
---|
700 | 679 | rcu_read_lock(); |
---|
701 | 680 | hlist_for_each_entry_rcu(gate, &tbl->known_gates, gate_list) { |
---|
.. | .. |
---|
731 | 710 | void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, |
---|
732 | 711 | struct sk_buff *skb) |
---|
733 | 712 | { |
---|
734 | | - kfree_skb(skb); |
---|
| 713 | + ieee80211_free_txskb(&sdata->local->hw, skb); |
---|
735 | 714 | sdata->u.mesh.mshstats.dropped_frames_no_route++; |
---|
736 | 715 | } |
---|
737 | 716 | |
---|
.. | .. |
---|
775 | 754 | mesh_path_tx_pending(mpath); |
---|
776 | 755 | } |
---|
777 | 756 | |
---|
778 | | -int mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) |
---|
| 757 | +void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata) |
---|
779 | 758 | { |
---|
780 | | - struct mesh_table *tbl_path, *tbl_mpp; |
---|
781 | | - int ret; |
---|
782 | | - |
---|
783 | | - tbl_path = mesh_table_alloc(); |
---|
784 | | - if (!tbl_path) |
---|
785 | | - return -ENOMEM; |
---|
786 | | - |
---|
787 | | - tbl_mpp = mesh_table_alloc(); |
---|
788 | | - if (!tbl_mpp) { |
---|
789 | | - ret = -ENOMEM; |
---|
790 | | - goto free_path; |
---|
791 | | - } |
---|
792 | | - |
---|
793 | | - sdata->u.mesh.mesh_paths = tbl_path; |
---|
794 | | - sdata->u.mesh.mpp_paths = tbl_mpp; |
---|
795 | | - |
---|
796 | | - return 0; |
---|
797 | | - |
---|
798 | | -free_path: |
---|
799 | | - mesh_table_free(tbl_path); |
---|
800 | | - return ret; |
---|
| 759 | + mesh_table_init(&sdata->u.mesh.mesh_paths); |
---|
| 760 | + mesh_table_init(&sdata->u.mesh.mpp_paths); |
---|
801 | 761 | } |
---|
802 | 762 | |
---|
803 | 763 | static |
---|
.. | .. |
---|
819 | 779 | |
---|
820 | 780 | void mesh_path_expire(struct ieee80211_sub_if_data *sdata) |
---|
821 | 781 | { |
---|
822 | | - mesh_path_tbl_expire(sdata, sdata->u.mesh.mesh_paths); |
---|
823 | | - mesh_path_tbl_expire(sdata, sdata->u.mesh.mpp_paths); |
---|
| 782 | + mesh_path_tbl_expire(sdata, &sdata->u.mesh.mesh_paths); |
---|
| 783 | + mesh_path_tbl_expire(sdata, &sdata->u.mesh.mpp_paths); |
---|
824 | 784 | } |
---|
825 | 785 | |
---|
826 | 786 | void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) |
---|
827 | 787 | { |
---|
828 | | - mesh_table_free(sdata->u.mesh.mesh_paths); |
---|
829 | | - mesh_table_free(sdata->u.mesh.mpp_paths); |
---|
| 788 | + mesh_table_free(&sdata->u.mesh.mesh_paths); |
---|
| 789 | + mesh_table_free(&sdata->u.mesh.mpp_paths); |
---|
830 | 790 | } |
---|