Sorry if this gets posted twice in the list. My previous attempt didn't
work. Trying to post to the list with my new email address :).
Thanks,
Bishal.
Hello list and Yeoh,
First of all, Happy New Year. Made some progress regarding the
implementation of "joining meshes".
I tested it with changes to compat-wireless-2011-11-22 using a basic setup:
A<-->B1 ---(mesh_iface_forwarding)---B2<---> C. Something works (code
is ugly), somethings do
not work YET clearly, and thus have some more questions..please
help/suggest. The status first:
1. Sending PREQ on all interfaces:
==> Prerequisite:
a. Added a net_device struct member to mpath_table in
/include/net/cfg80211.h
b. Fix /net/mac80211/cfg.c to populate the net_device struct member
(after a)
Then, all changes to mesh_hwmp.c (Patch 1 of 3)
II. Change the mesh_path table to show just one mpath per destination
regardless of whatever interfaces we use to dump or look at the mpath
within a node:
--> This requires changing nl802.11.c in /net/wireless (for correct
mpath dump output)
(Patch 2 of 3)
III. Using the correct interface pointed by the mpath to send the
message on (correct sdata):
(Patch 3 of 3)
Things that do not work yet:
1. If the originator (Source) wants to send PREQ, it should send on all
interfaces. Right now, it only FORWARDS PREQ on all interfaces.
2. If the destination is one of the interfaces and the PREQ arrives on a
different interface than the target address, then it *should* (may be
not) know they
all exist on the same node. For this, I could think of two possibilities:
a. Loop through all interfaces just like for PREQ forwarding
b. "Internal forward" to the target interface knowing that it needs to
be done "internally".
diff -uNr compat-wireless-2011-11-22/include/net/cfg80211.h
compat-wireless-recent/include/net/cfg80211.h
--- compat-wireless-2011-11-22/include/net/cfg80211.h 2011-11-23
11:36:22.134347429 -0500
+++ compat-wireless-recent/include/net/cfg80211.h 2012-01-12
17:47:29.733769005 -0500
@@ -20,6 +20,7 @@
#include<linux/ieee80211.h>
#include<net/regulatory.h>
+#define MESH_IFACE_FORWARDING
/**
* DOC: Introduction
*
@@ -729,6 +730,10 @@
u8 flags;
int generation;
+#ifdef MESH_IFACE_FORWARDING
+ /*Adding additional member net_device for mesh_iface_forwarding*/
+ struct net_device *dev;
+#endif
};
/**
diff -uNr compat-wireless-2011-11-22/net/mac80211/cfg.c
compat-wireless-recent/net/mac80211/cfg.c
--- compat-wireless-2011-11-22/net/mac80211/cfg.c 2011-11-23
11:36:24.610347548 -0500
+++ compat-wireless-recent/net/mac80211/cfg.c 2012-01-12
17:51:56.653781924 -0500
@@ -20,6 +20,7 @@
#include "rate.h"
#include "mesh.h"
+#define MESH_IFACE_FORWARDING
static struct net_device *ieee80211_add_iface(struct wiphy *wiphy,
char *name,
enum nl80211_iftype type,
u32 *flags,
@@ -1120,6 +1121,9 @@
pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
pinfo->flags = mpath->flags;
+#ifdef MESH_IFACE_FORWARDING
+ pinfo->dev = mpath->sdata->dev;
+#endif
}
static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
diff -uNr compat-wireless-2011-11-22/net/mac80211/mesh_hwmp.c
compat-wireless-recent/net/mac80211/mesh_hwmp.c
--- compat-wireless-2011-11-22/net/mac80211/mesh_hwmp.c 2011-11-23
11:36:26.726347650 -0500
+++ compat-wireless-recent/net/mac80211/mesh_hwmp.c 2012-01-12
18:06:17.257823574 -0500
@@ -10,6 +10,7 @@
#include<linux/slab.h>
#include "wme.h"
#include "mesh.h"
+#include<linux/netdevice.h>
#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG
#define mhwmp_dbg(fmt, args...) \
@@ -35,6 +36,8 @@
/* Reason code Present */
#define MP_F_RCODE 0x02
+#define MESH_IFACE_FORWARDING
+
static void mesh_queue_preq(struct mesh_path *, u8);
static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
@@ -137,16 +140,16 @@
mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
mgmt->u.action.u.mesh_action.action_code =
WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
-
+
switch (action) {
case MPATH_PREQ:
- mhwmp_dbg("sending PREQ to %pM", target);
+ mhwmp_dbg("sending PREQ to %pM from [%s]\n", target, sdata->name);
ie_len = 37;
pos = skb_put(skb, 2 + ie_len);
*pos++ = WLAN_EID_PREQ;
break;
case MPATH_PREP:
- mhwmp_dbg("sending PREP to %pM", target);
+ mhwmp_dbg("sending PREP to %pM from [%s]\n", target, sdata->name);
ie_len = 31;
pos = skb_put(skb, 2 + ie_len);
*pos++ = WLAN_EID_PREP;
@@ -548,6 +551,9 @@
reply = true;
metric = mpath->metric;
target_sn = mpath->sn;
+#ifdef MESH_IFACE_FORWARDING
+ sdata=mpath->sdata;
+#endif
if (target_flags& MP_F_RF)
target_flags |= MP_F_DO;
else
@@ -581,17 +587,53 @@
ifmsh->mshstats.dropped_frames_ttl++;
return;
}
- mhwmp_dbg("forwarding the PREQ from %pM", orig_addr);
+ mhwmp_dbg("multi-interface forwarding of the PREQ from %pM",
orig_addr);
--ttl;
flags = PREQ_IE_FLAGS(preq_elem);
preq_id = PREQ_IE_PREQ_ID(preq_elem);
hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
+
+#ifndef MESH_IFACE_FORWARDING
mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
cpu_to_le32(orig_sn), target_flags, target_addr,
cpu_to_le32(target_sn), broadcast_addr,
hopcount, ttl, cpu_to_le32(lifetime),
cpu_to_le32(metric), cpu_to_le32(preq_id),
sdata);
+#else
+ { /*Code to retransmit PREQs on all interfaces regardless of
what interface PREQ arrived on*/
+ struct ieee80211_sub_if_data *nsdata;
+ struct net_device *ndev;
+ int i = 1;
+ rcu_read_lock();
+ ndev = first_net_device(&init_net);
+
+ mhwmp_dbg("PREQ arrived on interface %pM -> [%s]",
sdata->vif.addr, sdata->name);
+ while (ndev) {
+ nsdata = IEEE80211_DEV_TO_SUB_IF(ndev);
+ if(nsdata->vif.type == NL80211_IFTYPE_MESH_POINT&&
+ ieee80211_sdata_running(nsdata)){
+ struct ieee80211_if_mesh *sifmsh =&nsdata->u.mesh;
+ mhwmp_dbg("(%d). Looping through the interface %pM
-> [%s]", i, nsdata->vif.addr, nsdata->name);
+ if (ifmsh->mesh_id_len == sifmsh->mesh_id_len&&
+ memcmp(ifmsh->mesh_id,
sifmsh->mesh_id, ifmsh->mesh_id_len) == 0&&
+ (ifmsh->mesh_pp_id ==
sifmsh->mesh_pp_id)&&
+ (ifmsh->mesh_pm_id ==
sifmsh->mesh_pm_id)&&
+ (ifmsh->mesh_cc_id ==
sifmsh->mesh_cc_id)&&
+ (ifmsh->mesh_sp_id ==
sifmsh->mesh_sp_id)&&
+ (ifmsh->mesh_auth_id ==
sifmsh->mesh_auth_id))
+ mesh_path_sel_frame_tx(MPATH_PREQ,
flags, orig_addr,
+ cpu_to_le32(orig_sn),
target_flags, target_addr,
+ cpu_to_le32(target_sn),
broadcast_addr,
+ hopcount, ttl,
cpu_to_le32(lifetime),
+ cpu_to_le32(metric),
cpu_to_le32(preq_id), nsdata);
+ }
+ i++;
+ ndev = next_net_device(ndev);
+ }
+ rcu_read_unlock();
+ }
+#endif
ifmsh->mshstats.fwded_mcast++;
ifmsh->mshstats.fwded_frames++;
}
@@ -654,7 +696,9 @@
orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
target_sn = PREP_IE_TARGET_SN(prep_elem);
orig_sn = PREP_IE_ORIG_SN(prep_elem);
-
+#ifdef MESH_IFACE_FORWARDING
+ sdata = mpath->sdata;
+#endif
mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
cpu_to_le32(orig_sn), 0, target_addr,
cpu_to_le32(target_sn), next_hop, hopcount,
diff -uNr compat-wireless-2011-11-22/net/mac80211/mesh_pathtbl.c
compat-wireless-recent/net/mac80211/mesh_pathtbl.c
--- compat-wireless-2011-11-22/net/mac80211/mesh_pathtbl.c 2011-11-23
11:36:24.838347560 -0500
+++ compat-wireless-recent/net/mac80211/mesh_pathtbl.c 2012-01-12
18:00:03.829805507 -0500
@@ -18,6 +18,8 @@
#include "ieee80211_i.h"
#include "mesh.h"
+#define MESH_IFACE_FORWARDING
+
#ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG
#define mpath_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args)
#else
@@ -192,9 +194,15 @@
static u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
struct mesh_table *tbl)
{
+#ifndef MESH_IFACE_FORWARDING
/* 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;
+#else
+ /* Use last four bytes of hw addr hash index and eliminate the use
of incoming packet interface to index hash for mesh_iface_forwarding*/
+ return jhash_1word(*(u32 *)(addr+2), tbl->hash_rnd)
+& tbl->hash_mask;
+#endif
}
@@ -347,7 +355,12 @@
bucket =&tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)];
hlist_for_each_entry_rcu(node, n, bucket, list) {
mpath = node->mpath;
+#ifndef MESH_IFACE_FORWARDING
if (mpath->sdata == sdata&&
+#else
+ /*Do not check if the sdata to forward is the same one as the
one it arrived on because we want mesh_iface_forwarding to be
indifferent to it*/
+ if (
+#endif
memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
if (MPATH_EXPIRED(mpath)) {
spin_lock_bh(&mpath->state_lock);
@@ -398,14 +411,19 @@
int j = 0;
for_each_mesh_entry(tbl, p, node, i) {
+#ifndef MESH_IFACE_FORWARDING
if (sdata&& node->mpath->sdata != sdata)
continue;
+#endif
+ /*Again do not check if the sdata the packet arrived in is the same
one that we might forward the packet on*/
if (j++ == idx) {
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);
}
+ mpath_dbg("lookup_by_idx: idx=%d name=%s dst: %pM.\n",
+ idx, node->mpath->sdata->name, node->mpath->dst);
return node->mpath;
}
}
diff -uNr compat-wireless-2011-11-22/net/mac80211/rx.c
compat-wireless-recent/net/mac80211/rx.c
--- compat-wireless-2011-11-22/net/mac80211/rx.c 2011-11-23
11:36:22.834347463 -0500
+++ compat-wireless-recent/net/mac80211/rx.c 2012-01-12
17:55:29.657792234 -0500
@@ -29,6 +29,8 @@
#include "tkip.h"
#include "wme.h"
+#define MESH_IFACE_FORWARDING
+
/*
* monitor mode reception
*
@@ -1902,6 +1904,13 @@
struct ieee80211_local *local = rx->local;
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+#ifdef MESH_IFACE_FORWARDING
+ /*Code to send mesh data on the right interface (Part 1 of 2)*/
+ u8 *da = 0;
+ struct mesh_path *found_mesh_path = 0;
+ struct ieee80211_sub_if_data *found_sdata = 0;
+ struct ieee80211_local *found_local = 0;
+#endif
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -1920,6 +1929,24 @@
/* illegal frame */
return RX_DROP_MONITOR;
+#ifdef MESH_IFACE_FORWARDING
+ /*Code to send mesh data on the right interface (Part 2 of 2)*/
+ da = hdr->addr3;
+ rcu_read_lock();
+ /* Here we lookup path to destination BUT it no longer uses sdata */
+ found_mesh_path = mesh_path_lookup(da,sdata);
+ rcu_read_unlock();
+ if(found_mesh_path){ /* If a path is found, save sdata and nh */
+ found_sdata = found_mesh_path->sdata;
+ if(found_sdata){
+ found_local = found_sdata->local;
+ }
+ }
+ /* Update sdata and/or local if new ones found */
+ if(found_sdata) sdata = found_sdata;
+ if(found_local) local = found_local;
+#endif
+
if (ieee80211_queue_stopped(&local->hw, skb_get_queue_mapping(skb))) {
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
dropped_frames_congestion);
@@ -1981,7 +2008,12 @@
info = IEEE80211_SKB_CB(fwd_skb);
memset(info, 0, sizeof(*info));
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+#ifndef MESH_IFACE_FORWARDING
info->control.vif =&rx->sdata->vif;
+#else
+ /*Set the correct address for mesh_iface_forwarding*/
+ info->control.vif =&sdata->vif;
+#endif
info->control.jiffies = jiffies;
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
@@ -2006,6 +2038,10 @@
}
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_frames);
+#ifdef MESH_IFACE_FORWARDING
+ /*Set the correct net_dev for mesh_iface_forwarding*/
+ fwd_skb->dev = sdata->dev;
+#endif
ieee80211_add_pending_skb(local, fwd_skb);
}
}
diff -uNr compat-wireless-2011-11-22/net/wireless/nl80211.c
compat-wireless-recent/net/wireless/nl80211.c
--- compat-wireless-2011-11-22/net/wireless/nl80211.c 2011-11-23
11:36:28.270347726 -0500
+++ compat-wireless-recent/net/wireless/nl80211.c 2012-01-12
17:49:38.165775222 -0500
@@ -23,6 +23,8 @@
#include "nl80211.h"
#include "reg.h"
+#define MESH_IFACE_FORWARDING
+
static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type);
static int nl80211_crypto_settings(struct cfg80211_registered_device
*rdev,
struct genl_info *info,
@@ -2842,12 +2844,20 @@
break;
if (err)
goto out_err;
+#ifdef MESH_IFACE_FORWARDING
+ if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ pinfo.dev, dst, next_hop,
+&pinfo)< 0)
+ goto out;
+#else
if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
netdev, dst, next_hop,
&pinfo)< 0)
goto out;
+#endif
path_idx++;
}
_______________________________________________
Devel mailing list
[email protected]
http://open80211s.com/mailman/listinfo/devel