Hi Bishal, I'm not sure I fully understand your patch, but let me make a few of general suggestions:
1. Why not make mesh_iface_fwding a runtime configurable variable, not a compile time option? It doesn't look like you are adding that much code. 2. Can extract a function from the big hunk @@ -581,17 +587,53 @@ ? That function is getting huge. 3. Have you considered testing this with hwsim? That's the ideal kitchen sink for that feature. Cheers, Javier On Sat, Jan 14, 2012 at 1:23 PM, Bishal Thapa <[email protected]> wrote: > 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 -- Javier Cardona cozybit Inc. http://www.cozybit.com _______________________________________________ Devel mailing list [email protected] http://open80211s.com/mailman/listinfo/devel
