* [PATCH 0/7] mesh fixes and improvements
@ 2011-11-23 20:32 Thomas Pedersen
2011-11-23 20:32 ` [PATCH 1/7] {nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh Thomas Pedersen
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
This series contains several (relatively minor) fixes and improvements for the
mesh stack. Chun-Yeow has also submitted a patch which adds the capability of
specifying a legacy rate for multicast frames in mesh, similar to what is
currently possible in IBSS. A follow-up patch for iw will be submitted
separately.
A couple of these will fail checpatch due to overstepping the 80 column limit,
but this is fixed in the final patch.
Thanks,
Thomas
Chun-Yeow Yeoh (1):
{nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh
Thomas Pedersen (6):
mac80211: failed forwarded mesh frame addressing
mac80211: fix switched HWMP frame addresses
mac80211: fix forwarded mesh frame queue mapping
{nl,cfg,mac}80211: implement dot11MeshHWMPperrMinInterval
mac80211: don't initiate path discovery when forwarding frame with
unknown DA
mac80211: clean up rx_h_mesh_fwding
include/linux/nl80211.h | 5 ++
include/net/cfg80211.h | 3 +
net/mac80211/cfg.c | 9 +++
net/mac80211/debugfs_netdev.c | 3 +
net/mac80211/ieee80211_i.h | 4 +-
net/mac80211/iface.c | 15 +----
net/mac80211/mesh.c | 1 +
net/mac80211/mesh.h | 2 +
net/mac80211/mesh_hwmp.c | 146 ++++++++++++++++++++++++-----------------
net/mac80211/mesh_pathtbl.c | 29 +--------
net/mac80211/rx.c | 105 +++++++++++++-----------------
net/mac80211/tx.c | 3 +-
net/mac80211/wme.c | 23 +++++++
net/mac80211/wme.h | 3 +
net/wireless/mesh.c | 2 +
net/wireless/nl80211.c | 11 +++
16 files changed, 201 insertions(+), 163 deletions(-)
--
1.7.5.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/7] {nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
@ 2011-11-23 20:32 ` Thomas Pedersen
2011-11-24 15:15 ` Johannes Berg
2011-11-23 20:32 ` [PATCH 2/7] mac80211: failed forwarded mesh frame addressing Thomas Pedersen
` (5 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Chun-Yeow Yeoh, Thomas Pedersen, johannes, linville
From: Chun-Yeow Yeoh <yeohchunyeow@gmail.com>
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com>
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
include/net/cfg80211.h | 2 ++
net/mac80211/cfg.c | 6 ++++++
net/mac80211/tx.c | 1 +
net/wireless/nl80211.c | 5 +++++
4 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d5e1891..edf1a4b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -802,6 +802,7 @@ struct mesh_config {
* @ie_len: length of vendor information elements
* @is_authenticated: this mesh requires authentication
* @is_secure: this mesh uses security
+ * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]
*
* These parameters are fixed when the mesh is created.
*/
@@ -814,6 +815,7 @@ struct mesh_setup {
u8 ie_len;
bool is_authenticated;
bool is_secure;
+ int mcast_rate[IEEE80211_NUM_BANDS];
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2577c45..8fa85db 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1185,6 +1185,8 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
{
u8 *new_ie;
const u8 *old_ie;
+ struct ieee80211_sub_if_data *sdata = container_of(ifmsh,
+ struct ieee80211_sub_if_data, u.mesh);
/* allocate information elements */
new_ie = NULL;
@@ -1211,6 +1213,10 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
if (setup->is_secure)
ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
+ /* mcast rate setting in Mesh Node */
+ memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate,
+ sizeof(setup->mcast_rate));
+
return 0;
}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8d31933..6ec3194 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -636,6 +636,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
else
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
+ tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
/* set up RTS protection if desired */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a1cabde..9b8f9d9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5648,6 +5648,11 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
+ if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
+ !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
+ nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
+ return -EINVAL;
+
if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
/* parse additional setup parameters if given */
err = nl80211_parse_mesh_setup(info, &setup);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/7] mac80211: failed forwarded mesh frame addressing
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
2011-11-23 20:32 ` [PATCH 1/7] {nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh Thomas Pedersen
@ 2011-11-23 20:32 ` Thomas Pedersen
2011-11-23 20:32 ` [PATCH 3/7] mac80211: fix switched HWMP frame addresses Thomas Pedersen
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
Don't write the TA until next hop is actually known, since we might need
the original TA for sending a PERR. Previously we would send a PERR to
ourself if path resolution for a forwarded frame failed.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Javier Cardona <javier@cozybit.com>
---
net/mac80211/mesh_hwmp.c | 5 +++--
net/mac80211/mesh_pathtbl.c | 6 ++++--
net/mac80211/rx.c | 8 +-------
3 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index ce3db27..1b13135 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1029,9 +1029,10 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
PREQ_Q_F_START | PREQ_Q_F_REFRESH);
}
next_hop = rcu_dereference(mpath->next_hop);
- if (next_hop)
+ if (next_hop) {
memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
- else
+ memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
+ } else
err = -ENOENT;
} else {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 7bd2a76..4c50d8a 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -221,6 +221,7 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) {
hdr = (struct ieee80211_hdr *) skb->data;
memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
+ memcpy(hdr->addr2, mpath->sdata->vif.addr, ETH_ALEN);
__skb_queue_tail(&tmpq, skb);
}
@@ -264,6 +265,7 @@ static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
next_hop = rcu_dereference(gate_mpath->next_hop)->sta.addr;
memcpy(hdr->addr1, next_hop, ETH_ALEN);
rcu_read_unlock();
+ memcpy(hdr->addr2, gate_mpath->sdata->vif.addr, ETH_ALEN);
memcpy(hdr->addr3, dst_addr, ETH_ALEN);
}
@@ -990,7 +992,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
u8 *ra, *da;
da = hdr->addr3;
- ra = hdr->addr1;
+ ra = hdr->addr2;
rcu_read_lock();
mpath = mesh_path_lookup(da, sdata);
if (mpath) {
@@ -999,7 +1001,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
spin_unlock_bh(&mpath->state_lock);
}
rcu_read_unlock();
- mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data,
+ mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, da,
cpu_to_le32(sn), reason, ra, sdata);
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d1a8869..eef5302 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1977,7 +1977,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
goto out;
fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
- memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
info = IEEE80211_SKB_CB(fwd_skb);
memset(info, 0, sizeof(*info));
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
@@ -1986,14 +1985,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_mcast);
+ memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
} else {
int err;
- /*
- * Save TA to addr1 to send TA a path error if a
- * suitable next hop is not found
- */
- memcpy(fwd_hdr->addr1, fwd_hdr->addr2,
- ETH_ALEN);
err = mesh_nexthop_lookup(fwd_skb, sdata);
/* Failed to immediately resolve next hop:
* fwded frame was dropped or will be added
--
1.7.5.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/7] mac80211: fix switched HWMP frame addresses
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
2011-11-23 20:32 ` [PATCH 1/7] {nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh Thomas Pedersen
2011-11-23 20:32 ` [PATCH 2/7] mac80211: failed forwarded mesh frame addressing Thomas Pedersen
@ 2011-11-23 20:32 ` Thomas Pedersen
2011-11-23 20:32 ` [PATCH 4/7] mac80211: fix forwarded mesh frame queue mapping Thomas Pedersen
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
HWMP originator and target addresses were switched on the air but also
on reception, which is why path selection still worked.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
net/mac80211/mesh_hwmp.c | 30 +++++++++++-------------------
1 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 1b13135..208ba35 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -393,15 +393,13 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
orig_metric = PREQ_IE_METRIC(hwmp_ie);
break;
case MPATH_PREP:
- /* Originator here refers to the MP that was the destination in
- * the Path Request. The draft refers to that MP as the
- * destination address, even though usually it is the origin of
- * the PREP frame. We divert from the nomenclature in the draft
+ /* Originator here refers to the MP that was the target in the
+ * Path Request. We divert from the nomenclature in the draft
* so that we can easily use a single function to gather path
* information from both PREQ and PREP frames.
*/
- orig_addr = PREP_IE_ORIG_ADDR(hwmp_ie);
- orig_sn = PREP_IE_ORIG_SN(hwmp_ie);
+ orig_addr = PREP_IE_TARGET_ADDR(hwmp_ie);
+ orig_sn = PREP_IE_TARGET_SN(hwmp_ie);
orig_lifetime = PREP_IE_LIFETIME(hwmp_ie);
orig_metric = PREP_IE_METRIC(hwmp_ie);
break;
@@ -562,9 +560,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
ttl = ifmsh->mshcfg.element_ttl;
if (ttl != 0) {
mhwmp_dbg("replying to the PREQ");
- mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr,
- cpu_to_le32(target_sn), 0, orig_addr,
- cpu_to_le32(orig_sn), mgmt->sa, 0, ttl,
+ mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
+ cpu_to_le32(orig_sn), 0, target_addr,
+ cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
cpu_to_le32(lifetime), cpu_to_le32(metric),
0, sdata);
} else
@@ -618,14 +616,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem));
- /* Note that we divert from the draft nomenclature and denominate
- * destination to what the draft refers to as origininator. So in this
- * function destnation refers to the final destination of the PREP,
- * which corresponds with the originator of the PREQ which this PREP
- * replies
- */
- target_addr = PREP_IE_TARGET_ADDR(prep_elem);
- if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0)
+ orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
+ if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
/* destination, no forwarding required */
return;
@@ -636,7 +628,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
}
rcu_read_lock();
- mpath = mesh_path_lookup(target_addr, sdata);
+ mpath = mesh_path_lookup(orig_addr, sdata);
if (mpath)
spin_lock_bh(&mpath->state_lock);
else
@@ -651,7 +643,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
flags = PREP_IE_FLAGS(prep_elem);
lifetime = PREP_IE_LIFETIME(prep_elem);
hopcount = PREP_IE_HOPCOUNT(prep_elem) + 1;
- orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
+ target_addr = PREP_IE_TARGET_ADDR(prep_elem);
target_sn = PREP_IE_TARGET_SN(prep_elem);
orig_sn = PREP_IE_ORIG_SN(prep_elem);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/7] mac80211: fix forwarded mesh frame queue mapping
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
` (2 preceding siblings ...)
2011-11-23 20:32 ` [PATCH 3/7] mac80211: fix switched HWMP frame addresses Thomas Pedersen
@ 2011-11-23 20:32 ` Thomas Pedersen
2011-11-24 15:16 ` Johannes Berg
2011-11-23 20:32 ` [PATCH 5/7] {nl,cfg,mac}80211: implement dot11MeshHWMPperrMinInterval Thomas Pedersen
` (2 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
We can't rely on ieee80211_select_queue() to do its job at this point
since the skb->protocol is not yet known. Instead, factor out and reuse
the queue mapping logic for injected frames.
Also, to mitigate congestion, forwarded frames should be dropped if the
outgoing queue was stopped. This was not correctly implemented as we
were not checking the right queue. Furthermore, we were dropping frames
that had arrived to their destination if that queue was stopped.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Javier Cardona <javier@cozybit.com>
---
net/mac80211/iface.c | 15 +--------------
net/mac80211/rx.c | 15 ++++++++-------
net/mac80211/wme.c | 23 +++++++++++++++++++++++
net/mac80211/wme.h | 3 +++
4 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b34ca0c..3070918 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -672,7 +672,6 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
struct ieee80211_local *local = sdata->local;
struct ieee80211_hdr *hdr;
struct ieee80211_radiotap_header *rtap = (void *)skb->data;
- u8 *p;
if (local->hw.queues < 4)
return 0;
@@ -683,19 +682,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
- if (!ieee80211_is_data(hdr->frame_control)) {
- skb->priority = 7;
- return ieee802_1d_to_ac[skb->priority];
- }
- if (!ieee80211_is_data_qos(hdr->frame_control)) {
- skb->priority = 0;
- return ieee802_1d_to_ac[skb->priority];
- }
-
- p = ieee80211_get_qos_ctl(hdr);
- skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
-
- return ieee80211_downgrade_queue(local, skb);
+ return ieee80211_select_queue_cooked(local, skb, hdr);
}
static const struct net_device_ops ieee80211_monitorif_ops = {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index eef5302..9da4528 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1902,6 +1902,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ u16 q;
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1920,12 +1921,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
/* illegal frame */
return RX_DROP_MONITOR;
- if (ieee80211_queue_stopped(&local->hw, skb_get_queue_mapping(skb))) {
- IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
- dropped_frames_congestion);
- return RX_DROP_MONITOR;
- }
-
if (mesh_hdr->flags & MESH_FLAGS_AE) {
struct mesh_path *mppath;
char *proxied_addr;
@@ -1957,7 +1952,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0)
return RX_CONTINUE;
- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb));
+ q = ieee80211_select_queue_cooked(local, skb, hdr);
+ if (ieee80211_queue_stopped(&local->hw, q)) {
+ IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+ dropped_frames_congestion);
+ return RX_DROP_MONITOR;
+ }
+ skb_set_queue_mapping(skb, q);
mesh_hdr->ttl--;
if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 4332711..2b36754 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -52,6 +52,29 @@ static int wme_downgrade_ac(struct sk_buff *skb)
}
}
+/* Indicate which queue to use for this fully formed 802.11 frame */
+u16 ieee80211_select_queue_cooked(struct ieee80211_local *local,
+ struct sk_buff *skb,
+ struct ieee80211_hdr *hdr) {
+ u8 *p;
+
+ if (local->hw.queues < 4)
+ return 0;
+
+ if (!ieee80211_is_data(hdr->frame_control)) {
+ skb->priority = 7;
+ return ieee802_1d_to_ac[skb->priority];
+ }
+ if (!ieee80211_is_data_qos(hdr->frame_control)) {
+ skb->priority = 0;
+ return ieee802_1d_to_ac[skb->priority];
+ }
+
+ p = ieee80211_get_qos_ctl(hdr);
+ skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
+
+ return ieee80211_downgrade_queue(local, skb);
+}
/* Indicate which queue to use. */
u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index 34e166f..1c46917 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -15,6 +15,9 @@
extern const int ieee802_1d_to_ac[8];
+u16 ieee80211_select_queue_cooked(struct ieee80211_local *local,
+ struct sk_buff *skb,
+ struct ieee80211_hdr *hdr);
u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
--
1.7.5.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/7] {nl,cfg,mac}80211: implement dot11MeshHWMPperrMinInterval
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
` (3 preceding siblings ...)
2011-11-23 20:32 ` [PATCH 4/7] mac80211: fix forwarded mesh frame queue mapping Thomas Pedersen
@ 2011-11-23 20:32 ` Thomas Pedersen
2011-11-23 20:32 ` [PATCH 6/7] mac80211: don't initiate path discovery when forwarding frame with unknown DA Thomas Pedersen
2011-11-23 20:32 ` [PATCH 7/7] mac80211: clean up rx_h_mesh_fwding Thomas Pedersen
6 siblings, 0 replies; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
As per 802.11mb 13.9.11.3
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Javier Cardona <javier@cozybit.com>
---
include/linux/nl80211.h | 5 +++++
include/net/cfg80211.h | 1 +
net/mac80211/cfg.c | 3 +++
net/mac80211/debugfs_netdev.c | 3 +++
net/mac80211/ieee80211_i.h | 4 +++-
net/mac80211/mesh.c | 1 +
net/mac80211/mesh_hwmp.c | 6 ++++++
net/wireless/mesh.c | 2 ++
net/wireless/nl80211.c | 6 ++++++
9 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 97bfebf..efbdfaf 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2084,6 +2084,10 @@ enum nl80211_mntr_flags {
* access to a broader network beyond the MBSS. This is done via Root
* Announcement frames.
*
+ * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in
+ * TUs) during which a mesh STA can send only one Action frame containing a
+ * PERR element.
+ *
* @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
*
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -2107,6 +2111,7 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_ELEMENT_TTL,
NL80211_MESHCONF_HWMP_RANN_INTERVAL,
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
+ NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
/* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index edf1a4b..8fb7d12 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -782,6 +782,7 @@ struct mesh_config {
u16 min_discovery_timeout;
u32 dot11MeshHWMPactivePathTimeout;
u16 dot11MeshHWMPpreqMinInterval;
+ u16 dot11MeshHWMPperrMinInterval;
u16 dot11MeshHWMPnetDiameterTraversalTime;
u8 dot11MeshHWMPRootMode;
u16 dot11MeshHWMPRannInterval;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 8fa85db..0eba909 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1262,6 +1262,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
conf->dot11MeshHWMPpreqMinInterval =
nconf->dot11MeshHWMPpreqMinInterval;
+ if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, mask))
+ conf->dot11MeshHWMPperrMinInterval =
+ nconf->dot11MeshHWMPperrMinInterval;
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
mask))
conf->dot11MeshHWMPnetDiameterTraversalTime =
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 9352819..8df2891 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -405,6 +405,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
+ u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
@@ -534,6 +536,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
MESHPARAMS_ADD(dot11MeshMaxPeerLinks);
MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout);
MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval);
+ MESHPARAMS_ADD(dot11MeshHWMPperrMinInterval);
MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime);
MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries);
MESHPARAMS_ADD(path_refresh_time);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 762243e..0c872b8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -514,7 +514,9 @@ struct ieee80211_if_mesh {
atomic_t mpaths;
/* Timestamp of last SN update */
unsigned long last_sn_update;
- /* Timestamp of last SN sent */
+ /* Time when it's ok to send next PERR */
+ unsigned long next_perr;
+ /* Timestamp of last PREQ sent */
unsigned long last_preq;
struct mesh_rmc *rmc;
spinlock_t mesh_preq_queue_lock;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index ee82d2f..c707c8b 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -749,6 +749,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
atomic_set(&ifmsh->mpaths, 0);
mesh_rmc_init(sdata);
ifmsh->last_preq = jiffies;
+ ifmsh->next_perr = jiffies;
/* Allocate all mesh structures when creating the first mesh interface. */
if (!mesh_allocated)
ieee80211s_init();
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 208ba35..fe93386 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -241,11 +241,15 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
{
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_mgmt *mgmt;
u8 *pos, ie_len;
int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
sizeof(mgmt->u.action.u.mesh_action);
+ if (time_before(jiffies, ifmsh->next_perr))
+ return -EAGAIN;
+
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
hdr_len +
2 + 15 /* PERR IE */);
@@ -290,6 +294,8 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
/* see note in function header */
prepare_frame_for_deferred_tx(sdata, skb);
+ ifmsh->next_perr = TU_TO_EXP_TIME(
+ ifmsh->mshcfg.dot11MeshHWMPperrMinInterval);
ieee80211_add_pending_skb(local, skb);
return 0;
}
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index b7b7868..8c550df 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -20,6 +20,7 @@
* interface
*/
#define MESH_PREQ_MIN_INT 10
+#define MESH_PERR_MIN_INT 100
#define MESH_DIAM_TRAVERSAL_TIME 50
/*
@@ -47,6 +48,7 @@ const struct mesh_config default_mesh_config = {
.dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS,
.dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT,
.dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT,
+ .dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT,
.dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME,
.dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES,
.path_refresh_time = MESH_PATH_REFRESH_TIME,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9b8f9d9..52cc311 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3176,6 +3176,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
cur_params.dot11MeshHWMPactivePathTimeout);
NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
cur_params.dot11MeshHWMPpreqMinInterval);
+ NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+ cur_params.dot11MeshHWMPperrMinInterval);
NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
cur_params.dot11MeshHWMPnetDiameterTraversalTime);
NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
@@ -3210,6 +3212,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
[NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
+ [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
[NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
[NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
@@ -3284,6 +3287,9 @@ do {\
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
nla_get_u16);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
+ mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+ nla_get_u16);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
dot11MeshHWMPnetDiameterTraversalTime,
mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
--
1.7.5.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 6/7] mac80211: don't initiate path discovery when forwarding frame with unknown DA
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
` (4 preceding siblings ...)
2011-11-23 20:32 ` [PATCH 5/7] {nl,cfg,mac}80211: implement dot11MeshHWMPperrMinInterval Thomas Pedersen
@ 2011-11-23 20:32 ` Thomas Pedersen
2011-11-23 20:32 ` [PATCH 7/7] mac80211: clean up rx_h_mesh_fwding Thomas Pedersen
6 siblings, 0 replies; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
We used to initiate a path discovery when receiving a frame for which
there is no forwarding information. To cut down on PREQ spam, just send
a (gated) PERR in response.
Also separate path discovery logic from nexthop querying. This patch
means we no longer queue frames when forwarding, so kill the PERR TX
stuff in discard_frame().
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
net/mac80211/mesh.h | 2 +
net/mac80211/mesh_hwmp.c | 111 ++++++++++++++++++++++++++-----------------
net/mac80211/mesh_pathtbl.c | 27 ----------
net/mac80211/rx.c | 14 +++--
net/mac80211/tx.c | 2 +-
5 files changed, 79 insertions(+), 77 deletions(-)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 622cc96..bd14bd2 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -233,6 +233,8 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
/* Mesh paths */
int mesh_nexthop_lookup(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata);
+int mesh_nexthop_resolve(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata);
void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
struct mesh_path *mesh_path_lookup(u8 *dst,
struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index fe93386..73abb75 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -982,72 +982,97 @@ enddiscovery:
kfree(preq_node);
}
-/**
- * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame
+/* mesh_nexthop_resolve - lookup next hop for given skb and start path
+ * discovery if no forwarding information is found.
*
* @skb: 802.11 frame to be sent
* @sdata: network subif the frame will be sent through
*
- * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is
- * found, the function will start a path discovery and queue the frame so it is
- * sent when the path is resolved. This means the caller must not free the skb
- * in this case.
+ * Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
+ * skb is freeed here if no mpath could be allocated.
*/
-int mesh_nexthop_lookup(struct sk_buff *skb,
- struct ieee80211_sub_if_data *sdata)
+int mesh_nexthop_resolve(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
{
- struct sk_buff *skb_to_free = NULL;
- struct mesh_path *mpath;
- struct sta_info *next_hop;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct mesh_path *mpath;
+ struct sk_buff *skb_to_free = NULL;
u8 *target_addr = hdr->addr3;
int err = 0;
rcu_read_lock();
- mpath = mesh_path_lookup(target_addr, sdata);
+ err = mesh_nexthop_lookup(skb, sdata);
+ if (!err)
+ goto endlookup;
+ /* no nexthop found, start resolving */
+ mpath = mesh_path_lookup(target_addr, sdata);
if (!mpath) {
mesh_path_add(target_addr, sdata);
mpath = mesh_path_lookup(target_addr, sdata);
if (!mpath) {
- sdata->u.mesh.mshstats.dropped_frames_no_route++;
+ mesh_path_discard_frame(skb, sdata);
err = -ENOSPC;
goto endlookup;
}
}
- if (mpath->flags & MESH_PATH_ACTIVE) {
- if (time_after(jiffies,
- mpath->exp_time -
- msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
- !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) &&
- !(mpath->flags & MESH_PATH_RESOLVING) &&
- !(mpath->flags & MESH_PATH_FIXED)) {
- mesh_queue_preq(mpath,
- PREQ_Q_F_START | PREQ_Q_F_REFRESH);
- }
- next_hop = rcu_dereference(mpath->next_hop);
- if (next_hop) {
- memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
- memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
- } else
- err = -ENOENT;
- } else {
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- if (!(mpath->flags & MESH_PATH_RESOLVING)) {
- /* Start discovery only if it is not running yet */
- mesh_queue_preq(mpath, PREQ_Q_F_START);
- }
+ if (!(mpath->flags & MESH_PATH_RESOLVING))
+ mesh_queue_preq(mpath, PREQ_Q_F_START);
+
+ if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN)
+ skb_to_free = skb_dequeue(&mpath->frame_queue);
+
+ info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+ ieee80211_set_qos_hdr(sdata, skb);
+ skb_queue_tail(&mpath->frame_queue, skb);
+ err = -ENOENT;
+ if (skb_to_free)
+ mesh_path_discard_frame(skb_to_free, sdata);
+
+endlookup:
+ rcu_read_unlock();
+ return err;
+}
+/**
+ * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
+ * this function is considered "using" the associated mpath, so preempt a path
+ * refresh if this mpath expires soon.
+ *
+ * @skb: 802.11 frame to be sent
+ * @sdata: network subif the frame will be sent through
+ *
+ * Returns: 0 if the next hop was found. Nonzero otherwise.
+ */
+int mesh_nexthop_lookup(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct mesh_path *mpath;
+ struct sta_info *next_hop;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ u8 *target_addr = hdr->addr3;
+ int err = -ENOENT;
- if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN)
- skb_to_free = skb_dequeue(&mpath->frame_queue);
+ rcu_read_lock();
+ mpath = mesh_path_lookup(target_addr, sdata);
+
+ if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
+ goto endlookup;
+
+ if (time_after(jiffies,
+ mpath->exp_time -
+ msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
+ !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) &&
+ !(mpath->flags & MESH_PATH_RESOLVING) &&
+ !(mpath->flags & MESH_PATH_FIXED))
+ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
- info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
- ieee80211_set_qos_hdr(sdata, skb);
- skb_queue_tail(&mpath->frame_queue, skb);
- if (skb_to_free)
- mesh_path_discard_frame(skb_to_free, sdata);
- err = -ENOENT;
+ next_hop = rcu_dereference(mpath->next_hop);
+ if (next_hop) {
+ memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
+ memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
+ err = 0;
}
endlookup:
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 4c50d8a..edf167e 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -973,38 +973,11 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
* @skb: frame to discard
* @sdata: network subif the frame was to be sent through
*
- * If the frame was being forwarded from another MP, a PERR frame will be sent
- * to the precursor. The precursor's address (i.e. the previous hop) was saved
- * in addr1 of the frame-to-be-forwarded, and would only be overwritten once
- * the destination is successfully resolved.
- *
* 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)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct mesh_path *mpath;
- u32 sn = 0;
- __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
-
- if (memcmp(hdr->addr4, sdata->vif.addr, ETH_ALEN) != 0) {
- u8 *ra, *da;
-
- da = hdr->addr3;
- ra = hdr->addr2;
- rcu_read_lock();
- mpath = mesh_path_lookup(da, sdata);
- if (mpath) {
- spin_lock_bh(&mpath->state_lock);
- sn = ++mpath->sn;
- spin_unlock_bh(&mpath->state_lock);
- }
- rcu_read_unlock();
- mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, da,
- cpu_to_le32(sn), reason, ra, sdata);
- }
-
kfree_skb(skb);
sdata->u.mesh.mshstats.dropped_frames_no_route++;
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9da4528..ac09f55 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1902,6 +1902,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
u16 q;
hdr = (struct ieee80211_hdr *) skb->data;
@@ -1988,13 +1989,14 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
fwded_mcast);
memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
} else {
- int err;
- err = mesh_nexthop_lookup(fwd_skb, sdata);
- /* Failed to immediately resolve next hop:
- * fwded frame was dropped or will be added
- * later to the pending skb queue. */
- if (err)
+ if (mesh_nexthop_lookup(fwd_skb, sdata)) {
+ /* can't resolve next hop, send a PERR */
+ mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl,
+ fwd_hdr->addr3, 0, reason,
+ fwd_hdr->addr2, sdata);
+ sdata->u.mesh.mshstats.dropped_frames_no_route++;
return RX_DROP_MONITOR;
+ }
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_unicast);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 6ec3194..75eadce 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1459,7 +1459,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
if (ieee80211_vif_is_mesh(&sdata->vif) &&
ieee80211_is_data(hdr->frame_control) &&
!is_multicast_ether_addr(hdr->addr1))
- if (mesh_nexthop_lookup(skb, sdata)) {
+ if (mesh_nexthop_resolve(skb, sdata)) {
/* skb queued: don't free */
rcu_read_unlock();
return;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 7/7] mac80211: clean up rx_h_mesh_fwding
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
` (5 preceding siblings ...)
2011-11-23 20:32 ` [PATCH 6/7] mac80211: don't initiate path discovery when forwarding frame with unknown DA Thomas Pedersen
@ 2011-11-23 20:32 ` Thomas Pedersen
6 siblings, 0 replies; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-23 20:32 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
Lose about two levels of unnecessary indentation.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
net/mac80211/rx.c | 88 +++++++++++++++++++++++-----------------------------
1 files changed, 39 insertions(+), 49 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ac09f55..a166c3c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1895,15 +1895,16 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
static ieee80211_rx_result
ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
{
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr *fwd_hdr, *hdr;
+ struct ieee80211_tx_info *info;
struct ieee80211s_hdr *mesh_hdr;
- unsigned int hdrlen;
struct sk_buff *skb = rx->skb, *fwd_skb;
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
__le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
- u16 q;
+ u16 q, hdrlen;
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1919,7 +1920,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
return RX_CONTINUE;
if (!mesh_hdr->ttl)
- /* illegal frame */
return RX_DROP_MONITOR;
if (mesh_hdr->flags & MESH_FLAGS_AE) {
@@ -1955,58 +1955,48 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
q = ieee80211_select_queue_cooked(local, skb, hdr);
if (ieee80211_queue_stopped(&local->hw, q)) {
- IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
- dropped_frames_congestion);
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
return RX_DROP_MONITOR;
}
skb_set_queue_mapping(skb, q);
- mesh_hdr->ttl--;
- if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
- if (!mesh_hdr->ttl)
- IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh,
- dropped_frames_ttl);
- else {
- struct ieee80211_hdr *fwd_hdr;
- struct ieee80211_tx_info *info;
-
- fwd_skb = skb_copy(skb, GFP_ATOMIC);
-
- if (!fwd_skb && net_ratelimit())
- printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
- sdata->name);
- if (!fwd_skb)
- goto out;
-
- fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
- info = IEEE80211_SKB_CB(fwd_skb);
- memset(info, 0, sizeof(*info));
- info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
- info->control.vif = &rx->sdata->vif;
- info->control.jiffies = jiffies;
- if (is_multicast_ether_addr(fwd_hdr->addr1)) {
- IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
- fwded_mcast);
- memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
- } else {
- if (mesh_nexthop_lookup(fwd_skb, sdata)) {
- /* can't resolve next hop, send a PERR */
- mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl,
- fwd_hdr->addr3, 0, reason,
- fwd_hdr->addr2, sdata);
- sdata->u.mesh.mshstats.dropped_frames_no_route++;
- return RX_DROP_MONITOR;
- }
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
+ goto out;
- IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
- fwded_unicast);
- }
- IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
- fwded_frames);
- ieee80211_add_pending_skb(local, fwd_skb);
- }
+ if (!--mesh_hdr->ttl) {
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
+ return RX_DROP_MONITOR;
+ }
+
+ fwd_skb = skb_copy(skb, GFP_ATOMIC);
+ if (!fwd_skb) {
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
+ sdata->name);
+ goto out;
+ }
+
+ fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
+ info = IEEE80211_SKB_CB(fwd_skb);
+ memset(info, 0, sizeof(*info));
+ info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+ info->control.vif = &rx->sdata->vif;
+ info->control.jiffies = jiffies;
+ if (is_multicast_ether_addr(fwd_hdr->addr1)) {
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast);
+ memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
+ } else if (!mesh_nexthop_lookup(fwd_skb, sdata)) {
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast);
+ } else {
+ /* unable to resolve next hop */
+ mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3,
+ 0, reason, fwd_hdr->addr2, sdata);
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
+ return RX_DROP_MONITOR;
}
+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames);
+ ieee80211_add_pending_skb(local, fwd_skb);
out:
if (is_multicast_ether_addr(hdr->addr1) ||
sdata->dev->flags & IFF_PROMISC)
--
1.7.5.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/7] {nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh
2011-11-23 20:32 ` [PATCH 1/7] {nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh Thomas Pedersen
@ 2011-11-24 15:15 ` Johannes Berg
0 siblings, 0 replies; 11+ messages in thread
From: Johannes Berg @ 2011-11-24 15:15 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: linux-wireless, devel, Chun-Yeow Yeoh, linville
On Wed, 2011-11-23 at 12:32 -0800, Thomas Pedersen wrote:
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -5648,6 +5648,11 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
> setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
> setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
>
> + if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
> + !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
> + nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
> + return -EINVAL;
That could use some better indentation ...
johannes
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/7] mac80211: fix forwarded mesh frame queue mapping
2011-11-23 20:32 ` [PATCH 4/7] mac80211: fix forwarded mesh frame queue mapping Thomas Pedersen
@ 2011-11-24 15:16 ` Johannes Berg
2011-11-25 1:03 ` Thomas Pedersen
0 siblings, 1 reply; 11+ messages in thread
From: Johannes Berg @ 2011-11-24 15:16 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: linux-wireless, devel, linville
> +/* Indicate which queue to use for this fully formed 802.11 frame */
> +u16 ieee80211_select_queue_cooked(struct ieee80211_local *local,
> + struct sk_buff *skb,
> + struct ieee80211_hdr *hdr) {
Where's that opening brace? ;-)
Can't say I like the name -- maybe select_queue_80211 or so would be
better? The "cooked" term is really only relevant for the special case
of monitor interfaces for AP mode that I'm even trying to get rid of ...
johannes
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/7] mac80211: fix forwarded mesh frame queue mapping
2011-11-24 15:16 ` Johannes Berg
@ 2011-11-25 1:03 ` Thomas Pedersen
0 siblings, 0 replies; 11+ messages in thread
From: Thomas Pedersen @ 2011-11-25 1:03 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, devel, linville
On Thu, Nov 24, 2011 at 7:16 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
>
>> +/* Indicate which queue to use for this fully formed 802.11 frame */
>> +u16 ieee80211_select_queue_cooked(struct ieee80211_local *local,
>> + struct sk_buff *skb,
>> + struct ieee80211_hdr *hdr) {
>
> Where's that opening brace? ;-)
Good catch, looked fine to me :)
>
> Can't say I like the name -- maybe select_queue_80211 or so would be
> better? The "cooked" term is really only relevant for the special case
> of monitor interfaces for AP mode that I'm even trying to get rid of ...
>
OK, I understood "cooked" to be analogous to "802.11 frame", but
_80211 is probably clearer. v2 coming shortly.
Thanks!
Thomas
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-11-25 1:03 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-23 20:32 [PATCH 0/7] mesh fixes and improvements Thomas Pedersen
2011-11-23 20:32 ` [PATCH 1/7] {nl,cfg,mac}80211: Allow Setting Multicast Rate in Mesh Thomas Pedersen
2011-11-24 15:15 ` Johannes Berg
2011-11-23 20:32 ` [PATCH 2/7] mac80211: failed forwarded mesh frame addressing Thomas Pedersen
2011-11-23 20:32 ` [PATCH 3/7] mac80211: fix switched HWMP frame addresses Thomas Pedersen
2011-11-23 20:32 ` [PATCH 4/7] mac80211: fix forwarded mesh frame queue mapping Thomas Pedersen
2011-11-24 15:16 ` Johannes Berg
2011-11-25 1:03 ` Thomas Pedersen
2011-11-23 20:32 ` [PATCH 5/7] {nl,cfg,mac}80211: implement dot11MeshHWMPperrMinInterval Thomas Pedersen
2011-11-23 20:32 ` [PATCH 6/7] mac80211: don't initiate path discovery when forwarding frame with unknown DA Thomas Pedersen
2011-11-23 20:32 ` [PATCH 7/7] mac80211: clean up rx_h_mesh_fwding Thomas Pedersen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).