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

Reply via email to