mesh_pathtbl.c (404c3bc30cb1361e1b3533643326ab472d24a618) mesh_pathtbl.c (2c53040f018b6c36a46eec75b9b937aaa5f78e6d)
1/*
2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * 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 */

--- 4 unchanged lines hidden (view full) ---

13#include <linux/slab.h>
14#include <linux/spinlock.h>
15#include <linux/string.h>
16#include <net/mac80211.h>
17#include "wme.h"
18#include "ieee80211_i.h"
19#include "mesh.h"
20
1/*
2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * 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 */

--- 4 unchanged lines hidden (view full) ---

13#include <linux/slab.h>
14#include <linux/spinlock.h>
15#include <linux/string.h>
16#include <net/mac80211.h>
17#include "wme.h"
18#include "ieee80211_i.h"
19#include "mesh.h"
20
21#ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG
22#define mpath_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args)
23#else
24#define mpath_dbg(fmt, args...) do { (void)(0); } while (0)
25#endif
26
27/* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */
28#define INIT_PATHS_SIZE_ORDER 2
29
30/* Keep the mean chain length below this constant */
31#define MEAN_CHAIN_LEN 2
32
33#define MPATH_EXPIRED(mpath) ((mpath->flags & MESH_PATH_ACTIVE) && \
34 time_after(jiffies, mpath->exp_time) && \

--- 282 unchanged lines hidden (view full) ---

317 }
318
319 prepare_for_gate(skb, gate_mpath->dst, gate_mpath);
320 __skb_queue_tail(&gateq, skb);
321 }
322
323 spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags);
324 skb_queue_splice(&gateq, &gate_mpath->frame_queue);
21/* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */
22#define INIT_PATHS_SIZE_ORDER 2
23
24/* Keep the mean chain length below this constant */
25#define MEAN_CHAIN_LEN 2
26
27#define MPATH_EXPIRED(mpath) ((mpath->flags & MESH_PATH_ACTIVE) && \
28 time_after(jiffies, mpath->exp_time) && \

--- 282 unchanged lines hidden (view full) ---

311 }
312
313 prepare_for_gate(skb, gate_mpath->dst, gate_mpath);
314 __skb_queue_tail(&gateq, skb);
315 }
316
317 spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags);
318 skb_queue_splice(&gateq, &gate_mpath->frame_queue);
325 mpath_dbg("Mpath queue for gate %pM has %d frames\n",
326 gate_mpath->dst,
327 skb_queue_len(&gate_mpath->frame_queue));
319 mpath_dbg(gate_mpath->sdata, "Mpath queue for gate %pM has %d frames\n",
320 gate_mpath->dst, skb_queue_len(&gate_mpath->frame_queue));
328 spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags);
329
330 if (!copy)
331 return;
332
333 spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
334 skb_queue_splice(&failq, &from_mpath->frame_queue);
335 spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);

--- 105 unchanged lines hidden (view full) ---

441
442 mpath->is_gate = true;
443 mpath->sdata->u.mesh.num_gates++;
444 new_gate->mpath = mpath;
445 spin_lock_bh(&tbl->gates_lock);
446 hlist_add_head_rcu(&new_gate->list, tbl->known_gates);
447 spin_unlock_bh(&tbl->gates_lock);
448 rcu_read_unlock();
321 spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags);
322
323 if (!copy)
324 return;
325
326 spin_lock_irqsave(&from_mpath->frame_queue.lock, flags);
327 skb_queue_splice(&failq, &from_mpath->frame_queue);
328 spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags);

--- 105 unchanged lines hidden (view full) ---

434
435 mpath->is_gate = true;
436 mpath->sdata->u.mesh.num_gates++;
437 new_gate->mpath = mpath;
438 spin_lock_bh(&tbl->gates_lock);
439 hlist_add_head_rcu(&new_gate->list, tbl->known_gates);
440 spin_unlock_bh(&tbl->gates_lock);
441 rcu_read_unlock();
449 mpath_dbg("Mesh path (%s): Recorded new gate: %pM. %d known gates\n",
450 mpath->sdata->name, mpath->dst,
451 mpath->sdata->u.mesh.num_gates);
442 mpath_dbg(mpath->sdata,
443 "Mesh path: Recorded new gate: %pM. %d known gates\n",
444 mpath->dst, mpath->sdata->u.mesh.num_gates);
452 return 0;
453err_rcu:
454 rcu_read_unlock();
455 return err;
456}
457
458/**
459 * mesh_gate_del - remove a mesh gate from the list of known gates

--- 12 unchanged lines hidden (view full) ---

472 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list)
473 if (gate->mpath == mpath) {
474 spin_lock_bh(&tbl->gates_lock);
475 hlist_del_rcu(&gate->list);
476 kfree_rcu(gate, rcu);
477 spin_unlock_bh(&tbl->gates_lock);
478 mpath->sdata->u.mesh.num_gates--;
479 mpath->is_gate = false;
445 return 0;
446err_rcu:
447 rcu_read_unlock();
448 return err;
449}
450
451/**
452 * mesh_gate_del - remove a mesh gate from the list of known gates

--- 12 unchanged lines hidden (view full) ---

465 hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list)
466 if (gate->mpath == mpath) {
467 spin_lock_bh(&tbl->gates_lock);
468 hlist_del_rcu(&gate->list);
469 kfree_rcu(gate, rcu);
470 spin_unlock_bh(&tbl->gates_lock);
471 mpath->sdata->u.mesh.num_gates--;
472 mpath->is_gate = false;
480 mpath_dbg("Mesh path (%s): Deleted gate: %pM. "
481 "%d known gates\n", mpath->sdata->name,
473 mpath_dbg(mpath->sdata,
474 "Mesh path: Deleted gate: %pM. %d known gates\n",
482 mpath->dst, mpath->sdata->u.mesh.num_gates);
483 break;
484 }
485
486 return 0;
487}
488
489/**

--- 290 unchanged lines hidden (view full) ---

780 call_rcu(&node->rcu, mesh_path_node_reclaim);
781 spin_unlock(&mpath->state_lock);
782 atomic_dec(&tbl->entries);
783}
784
785/**
786 * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches
787 *
475 mpath->dst, mpath->sdata->u.mesh.num_gates);
476 break;
477 }
478
479 return 0;
480}
481
482/**

--- 290 unchanged lines hidden (view full) ---

773 call_rcu(&node->rcu, mesh_path_node_reclaim);
774 spin_unlock(&mpath->state_lock);
775 atomic_dec(&tbl->entries);
776}
777
778/**
779 * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches
780 *
788 * @sta - mesh peer to match
781 * @sta: mesh peer to match
789 *
790 * RCU notes: this function is called when a mesh plink transitions from
791 * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that
792 * allows path creation. This will happen before the sta can be freed (because
793 * sta_info_destroy() calls this) so any reader in a rcu read block will be
794 * protected against the plink disappearing.
795 */
796void mesh_path_flush_by_nexthop(struct sta_info *sta)

--- 38 unchanged lines hidden (view full) ---

835 }
836}
837
838/**
839 * mesh_path_flush_by_iface - Deletes all mesh paths associated with a given iface
840 *
841 * This function deletes both mesh paths as well as mesh portal paths.
842 *
782 *
783 * RCU notes: this function is called when a mesh plink transitions from
784 * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that
785 * allows path creation. This will happen before the sta can be freed (because
786 * sta_info_destroy() calls this) so any reader in a rcu read block will be
787 * protected against the plink disappearing.
788 */
789void mesh_path_flush_by_nexthop(struct sta_info *sta)

--- 38 unchanged lines hidden (view full) ---

828 }
829}
830
831/**
832 * mesh_path_flush_by_iface - Deletes all mesh paths associated with a given iface
833 *
834 * This function deletes both mesh paths as well as mesh portal paths.
835 *
843 * @sdata - interface data to match
836 * @sdata: interface data to match
844 *
845 */
846void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
847{
848 struct mesh_table *tbl;
849
850 rcu_read_lock();
851 read_lock_bh(&pathtbl_resize_lock);

--- 89 unchanged lines hidden (view full) ---

941 if (!known_gates)
942 return -EHOSTUNREACH;
943
944 hlist_for_each_entry_rcu(gate, n, known_gates, list) {
945 if (gate->mpath->sdata != sdata)
946 continue;
947
948 if (gate->mpath->flags & MESH_PATH_ACTIVE) {
837 *
838 */
839void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
840{
841 struct mesh_table *tbl;
842
843 rcu_read_lock();
844 read_lock_bh(&pathtbl_resize_lock);

--- 89 unchanged lines hidden (view full) ---

934 if (!known_gates)
935 return -EHOSTUNREACH;
936
937 hlist_for_each_entry_rcu(gate, n, known_gates, list) {
938 if (gate->mpath->sdata != sdata)
939 continue;
940
941 if (gate->mpath->flags & MESH_PATH_ACTIVE) {
949 mpath_dbg("Forwarding to %pM\n", gate->mpath->dst);
942 mpath_dbg(sdata, "Forwarding to %pM\n", gate->mpath->dst);
950 mesh_path_move_to_queue(gate->mpath, from_mpath, copy);
951 from_mpath = gate->mpath;
952 copy = true;
953 } else {
943 mesh_path_move_to_queue(gate->mpath, from_mpath, copy);
944 from_mpath = gate->mpath;
945 copy = true;
946 } else {
954 mpath_dbg("Not forwarding %p\n", gate->mpath);
955 mpath_dbg("flags %x\n", gate->mpath->flags);
947 mpath_dbg(sdata,
948 "Not forwarding %p (flags %#x)\n",
949 gate->mpath, gate->mpath->flags);
956 }
957 }
958
959 hlist_for_each_entry_rcu(gate, n, known_gates, list)
960 if (gate->mpath->sdata == sdata) {
950 }
951 }
952
953 hlist_for_each_entry_rcu(gate, n, known_gates, list)
954 if (gate->mpath->sdata == sdata) {
961 mpath_dbg("Sending to %pM\n", gate->mpath->dst);
955 mpath_dbg(sdata, "Sending to %pM\n", gate->mpath->dst);
962 mesh_path_tx_pending(gate->mpath);
963 }
964
965 return (from_mpath == mpath) ? -EHOSTUNREACH : 0;
966}
967
968/**
969 * mesh_path_discard_frame - discard a frame whose path could not be resolved

--- 157 unchanged lines hidden ---
956 mesh_path_tx_pending(gate->mpath);
957 }
958
959 return (from_mpath == mpath) ? -EHOSTUNREACH : 0;
960}
961
962/**
963 * mesh_path_discard_frame - discard a frame whose path could not be resolved

--- 157 unchanged lines hidden ---