summaryrefslogtreecommitdiff
path: root/net/mac80211/mesh_pathtbl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-20 18:58:50 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-20 18:58:50 -0800
commita0b1c42951dd06ec83cc1bc2c9788131d9fefcd8 (patch)
treea572f1523cf904c93020c9cdb32f3bc84ec3ac16 /net/mac80211/mesh_pathtbl.c
parent8ec4942212a6d337982967778a3dc3b60aea782e (diff)
parentecd9883724b78cc72ed92c98bcb1a46c764fff21 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking update from David Miller: 1) Checkpoint/restarted TCP sockets now can properly propagate the TCP timestamp offset. From Andrey Vagin. 2) VMWARE VM VSOCK layer, from Andy King. 3) Much improved support for virtual functions and SR-IOV in bnx2x, from Ariel ELior. 4) All protocols on ipv4 and ipv6 are now network namespace aware, and all the compatability checks for initial-namespace-only protocols is removed. Thanks to Tom Parkin for helping deal with the last major holdout, L2TP. 5) IPV6 support in netpoll and network namespace support in pktgen, from Cong Wang. 6) Multiple Registration Protocol (MRP) and Multiple VLAN Registration Protocol (MVRP) support, from David Ward. 7) Compute packet lengths more accurately in the packet scheduler, from Eric Dumazet. 8) Use per-task page fragment allocator in skb_append_datato_frags(), also from Eric Dumazet. 9) Add support for connection tracking labels in netfilter, from Florian Westphal. 10) Fix default multicast group joining on ipv6, and add anti-spoofing checks to 6to4 and 6rd. From Hannes Frederic Sowa. 11) Make ipv4/ipv6 fragmentation memory limits more reasonable in modern times, rearrange inet frag datastructures for better cacheline locality, and move more operations outside of locking. From Jesper Dangaard Brouer. 12) Instead of strict master <--> slave relationships, allow arbitrary scenerios with "upper device lists". From Jiri Pirko. 13) Improve rate limiting accuracy in TBF and act_police, also from Jiri Pirko. 14) Add a BPF filter netfilter match target, from Willem de Bruijn. 15) Orphan and delete a bunch of pre-historic networking drivers from Paul Gortmaker. 16) Add TSO support for GRE tunnels, from Pravin B SHelar. Although this still needs some minor bug fixing before it's %100 correct in all cases. 17) Handle unresolved IPSEC states like ARP, with a resolution packet queue. From Steffen Klassert. 18) Remove TCP Appropriate Byte Count support (ABC), from Stephen Hemminger. This was long overdue. 19) Support SO_REUSEPORT, from Tom Herbert. 20) Allow locking a socket BPF filter, so that it cannot change after a process drops capabilities. 21) Add VLAN filtering to bridge, from Vlad Yasevich. 22) Bring ipv6 on-par with ipv4 and do not cache neighbour entries in the ipv6 routes, from YOSHIFUJI Hideaki. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1538 commits) ipv6: fix race condition regarding dst->expires and dst->from. net: fix a wrong assignment in skb_split() ip_gre: remove an extra dst_release() ppp: set qdisc_tx_busylock to avoid LOCKDEP splat atl1c: restore buffer state net: fix a build failure when !CONFIG_PROC_FS net: ipv4: fix waring -Wunused-variable net: proc: fix build failed when procfs is not configured Revert "xen: netback: remove redundant xenvif_put" net: move procfs code to net/core/net-procfs.c qmi_wwan, cdc-ether: add ADU960S bonding: set sysfs device_type to 'bond' bonding: fix bond_release_all inconsistencies b44: use netdev_alloc_skb_ip_align() xen: netback: remove redundant xenvif_put net: fec: Do a sanity check on the gpio number ip_gre: propogate target device GSO capability to the tunnel device ip_gre: allow CSUM capable devices to handle packets bonding: Fix initialize after use for 3ad machine state spinlock bonding: Fix race condition between bond_enslave() and bond_3ad_update_lacp_rate() ...
Diffstat (limited to 'net/mac80211/mesh_pathtbl.c')
-rw-r--r--net/mac80211/mesh_pathtbl.c95
1 files changed, 50 insertions, 45 deletions
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index aa749818860e..6b3c4e119c63 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -24,9 +24,12 @@
/* Keep the mean chain length below this constant */
#define MEAN_CHAIN_LEN 2
-#define MPATH_EXPIRED(mpath) ((mpath->flags & MESH_PATH_ACTIVE) && \
- time_after(jiffies, mpath->exp_time) && \
- !(mpath->flags & MESH_PATH_FIXED))
+static inline bool mpath_expired(struct mesh_path *mpath)
+{
+ return (mpath->flags & MESH_PATH_ACTIVE) &&
+ time_after(jiffies, mpath->exp_time) &&
+ !(mpath->flags & MESH_PATH_FIXED);
+}
struct mpath_node {
struct hlist_node list;
@@ -181,12 +184,12 @@ errcopy:
return -ENOMEM;
}
-static u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
+static u32 mesh_table_hash(const u8 *addr, struct ieee80211_sub_if_data *sdata,
struct mesh_table *tbl)
{
/* Use last four bytes of hw addr and interface index as hash index */
- return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
- & tbl->hash_mask;
+ return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex,
+ tbl->hash_rnd) & tbl->hash_mask;
}
@@ -212,6 +215,7 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
hdr = (struct ieee80211_hdr *) skb->data;
memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
memcpy(hdr->addr2, mpath->sdata->vif.addr, ETH_ALEN);
+ ieee80211_mps_set_frame_flags(sta->sdata, sta, hdr);
}
spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
@@ -325,8 +329,8 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
}
-static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst,
- struct ieee80211_sub_if_data *sdata)
+static struct mesh_path *mpath_lookup(struct mesh_table *tbl, const u8 *dst,
+ struct ieee80211_sub_if_data *sdata)
{
struct mesh_path *mpath;
struct hlist_node *n;
@@ -338,7 +342,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst,
mpath = node->mpath;
if (mpath->sdata == sdata &&
ether_addr_equal(dst, mpath->dst)) {
- if (MPATH_EXPIRED(mpath)) {
+ if (mpath_expired(mpath)) {
spin_lock_bh(&mpath->state_lock);
mpath->flags &= ~MESH_PATH_ACTIVE;
spin_unlock_bh(&mpath->state_lock);
@@ -351,19 +355,21 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst,
/**
* mesh_path_lookup - look up a path in the mesh path table
- * @dst: hardware address (ETH_ALEN length) of destination
* @sdata: local subif
+ * @dst: hardware address (ETH_ALEN length) of destination
*
* Returns: pointer to the mesh path structure, or NULL if not found
*
* Locking: must be called within a read rcu section.
*/
-struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
+struct mesh_path *
+mesh_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
{
return mpath_lookup(rcu_dereference(mesh_paths), dst, sdata);
}
-struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
+struct mesh_path *
+mpp_path_lookup(struct ieee80211_sub_if_data *sdata, const u8 *dst)
{
return mpath_lookup(rcu_dereference(mpp_paths), dst, sdata);
}
@@ -378,7 +384,8 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
*
* Locking: must be called within a read rcu section.
*/
-struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata)
+struct mesh_path *
+mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx)
{
struct mesh_table *tbl = rcu_dereference(mesh_paths);
struct mpath_node *node;
@@ -390,7 +397,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
if (sdata && node->mpath->sdata != sdata)
continue;
if (j++ == idx) {
- if (MPATH_EXPIRED(node->mpath)) {
+ if (mpath_expired(node->mpath)) {
spin_lock_bh(&node->mpath->state_lock);
node->mpath->flags &= ~MESH_PATH_ACTIVE;
spin_unlock_bh(&node->mpath->state_lock);
@@ -434,11 +441,10 @@ int mesh_path_add_gate(struct mesh_path *mpath)
spin_lock_bh(&tbl->gates_lock);
hlist_add_head_rcu(&new_gate->list, tbl->known_gates);
spin_unlock_bh(&tbl->gates_lock);
- rcu_read_unlock();
mpath_dbg(mpath->sdata,
"Mesh path: Recorded new gate: %pM. %d known gates\n",
mpath->dst, mpath->sdata->u.mesh.num_gates);
- return 0;
+ err = 0;
err_rcu:
rcu_read_unlock();
return err;
@@ -449,30 +455,27 @@ err_rcu:
* @tbl: table which holds our list of known gates
* @mpath: gate mpath
*
- * Returns: 0 on success
- *
* Locking: must be called inside rcu_read_lock() section
*/
-static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
+static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
{
struct mpath_node *gate;
struct hlist_node *p, *q;
- hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list)
- if (gate->mpath == mpath) {
- spin_lock_bh(&tbl->gates_lock);
- hlist_del_rcu(&gate->list);
- kfree_rcu(gate, rcu);
- spin_unlock_bh(&tbl->gates_lock);
- mpath->sdata->u.mesh.num_gates--;
- mpath->is_gate = false;
- mpath_dbg(mpath->sdata,
- "Mesh path: Deleted gate: %pM. %d known gates\n",
- mpath->dst, mpath->sdata->u.mesh.num_gates);
- break;
- }
-
- return 0;
+ hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) {
+ if (gate->mpath != mpath)
+ continue;
+ spin_lock_bh(&tbl->gates_lock);
+ hlist_del_rcu(&gate->list);
+ kfree_rcu(gate, rcu);
+ spin_unlock_bh(&tbl->gates_lock);
+ mpath->sdata->u.mesh.num_gates--;
+ mpath->is_gate = false;
+ mpath_dbg(mpath->sdata,
+ "Mesh path: Deleted gate: %pM. %d known gates\n",
+ mpath->dst, mpath->sdata->u.mesh.num_gates);
+ break;
+ }
}
/**
@@ -486,14 +489,14 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata)
/**
* mesh_path_add - allocate and add a new path to the mesh path table
- * @addr: destination address of the path (ETH_ALEN length)
+ * @dst: destination address of the path (ETH_ALEN length)
* @sdata: local subif
*
* Returns: 0 on success
*
* State: the initial state of the new path is set to 0
*/
-int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
+int mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
@@ -628,7 +631,8 @@ void mesh_mpp_table_grow(void)
write_unlock_bh(&pathtbl_resize_lock);
}
-int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
+int mpp_path_add(struct ieee80211_sub_if_data *sdata,
+ const u8 *dst, const u8 *mpp)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
@@ -737,9 +741,10 @@ void mesh_plink_broken(struct sta_info *sta)
mpath->flags &= ~MESH_PATH_ACTIVE;
++mpath->sn;
spin_unlock_bh(&mpath->state_lock);
- mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl,
- mpath->dst, cpu_to_le32(mpath->sn),
- reason, bcast, sdata);
+ mesh_path_error_tx(sdata,
+ sdata->u.mesh.mshcfg.element_ttl,
+ mpath->dst, cpu_to_le32(mpath->sn),
+ reason, bcast);
}
}
rcu_read_unlock();
@@ -854,7 +859,7 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
*
* Returns: 0 if successful
*/
-int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
+int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
{
struct mesh_table *tbl;
struct mesh_path *mpath;
@@ -963,8 +968,8 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
*
* Locking: the function must me called within a rcu_read_lock region
*/
-void mesh_path_discard_frame(struct sk_buff *skb,
- struct ieee80211_sub_if_data *sdata)
+void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb)
{
kfree_skb(skb);
sdata->u.mesh.mshstats.dropped_frames_no_route++;
@@ -982,7 +987,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath)
struct sk_buff *skb;
while ((skb = skb_dequeue(&mpath->frame_queue)) != NULL)
- mesh_path_discard_frame(skb, mpath->sdata);
+ mesh_path_discard_frame(mpath->sdata, skb);
}
/**
@@ -1103,7 +1108,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
if ((!(mpath->flags & MESH_PATH_RESOLVING)) &&
(!(mpath->flags & MESH_PATH_FIXED)) &&
time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE))
- mesh_path_del(mpath->dst, mpath->sdata);
+ mesh_path_del(mpath->sdata, mpath->dst);
}
rcu_read_unlock();
}