Author: monthadar
Date: Thu Feb  7 21:25:32 2013
New Revision: 246510
URL: http://svnweb.freebsd.org/changeset/base/246510

Log:
  Send frames to mesh gate if 11s discovery fails.
  
  * Send frames that have no path to a known valid Mesh Gate;
  * Added the function ieee80211_mesh_forward_to_gates that sends the frame
    to the first found Mesh Gate in the forwarding information;
  * If we try to discover again while we are discovering queue frame,
    the discovery callout will send the frames either to mesh gates
    or discards them silently;
  * Queue frame also if we try to discover to frequently;
  
  Approved by:  adrian (mentor)

Modified:
  head/sys/net80211/ieee80211_hwmp.c
  head/sys/net80211/ieee80211_mesh.c
  head/sys/net80211/ieee80211_mesh.h

Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c  Thu Feb  7 21:24:52 2013        
(r246509)
+++ head/sys/net80211/ieee80211_hwmp.c  Thu Feb  7 21:25:32 2013        
(r246510)
@@ -1839,12 +1839,11 @@ hwmp_rediscover_cb(void *arg)
        hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
        if (hr->hr_preqretries >=
                ieee80211_hwmp_maxpreq_retries) {
-               IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
-                       rt->rt_dest, NULL, "%s",
-                       "no valid path , max number of discovery, send GATE");
-               /* TODO: send to known gates */
+               IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY,
+                       rt->rt_dest, "%s",
+                       "max number of discovery, send queued frames to GATE");
+               ieee80211_mesh_forward_to_gates(vap, rt);
                vap->iv_stats.is_mesh_fwd_nopath++;
-               rt->rt_flags = 0; /* Mark invalid */
                return ; /* XXX: flush queue? */
        }
 
@@ -1914,6 +1913,12 @@ hwmp_discover(struct ieee80211vap *vap,
                }
                hr = IEEE80211_MESH_ROUTE_PRIV(rt,
                    struct ieee80211_hwmp_route);
+               if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_DISCOVER) {
+                       IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, dest,
+                           "%s", "already discovering queue frame until path 
found");
+                       sendpreq = 1;
+                       goto done;
+               }
                if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) {
                        if (hr->hr_lastdiscovery != 0 &&
                            (ticks - hr->hr_lastdiscovery <
@@ -1921,7 +1926,7 @@ hwmp_discover(struct ieee80211vap *vap,
                                IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
                                    dest, NULL, "%s",
                                    "too frequent discovery requeust");
-                               /* XXX: stats? */
+                               sendpreq = 1;
                                goto done;
                        }
                        hr->hr_lastdiscovery = ticks;

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c  Thu Feb  7 21:24:52 2013        
(r246509)
+++ head/sys/net80211/ieee80211_mesh.c  Thu Feb  7 21:25:32 2013        
(r246510)
@@ -1022,6 +1022,71 @@ mesh_find_txnode(struct ieee80211vap *va
 }
 
 /*
+ * Forward the queued frames to known valid mesh gates.
+ * Assume destination to be outside the MBSS (i.e. proxy entry),
+ * If no valid mesh gates are known silently discard queued frames.
+ * If there is no 802.2 path route will be timedout.
+ */
+void
+ieee80211_mesh_forward_to_gates(struct ieee80211vap *vap,
+    struct ieee80211_mesh_route *rt_dest)
+{
+       struct ieee80211com *ic = vap->iv_ic;
+       struct ieee80211_mesh_state *ms = vap->iv_mesh;
+       struct ifnet *ifp = vap->iv_ifp;
+       struct ieee80211_mesh_route *rt_gate;
+       struct ieee80211_mesh_gate_route *gr = NULL, *gr_next;
+       struct mbuf *m, *next;
+       int gates_found = 0;
+
+       KASSERT( rt_dest->rt_flags == IEEE80211_MESHRT_FLAGS_DISCOVER,
+           ("Route is not marked with IEEE80211_MESHRT_FLAGS_DISCOVER"));
+
+       /* XXX: send to more than one valid mash gate */
+       MESH_RT_LOCK(ms);
+       TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, gr_next) {
+               rt_gate = gr->gr_route;
+               if (rt_gate == NULL) {
+                       IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP,
+                               rt_dest->rt_dest,
+                               "mesh gate with no path %6D",
+                               gr->gr_addr, ":");
+                       continue;
+               }
+               gates_found = 1;
+               /* convert route to a proxy route */
+               rt_dest->rt_flags = IEEE80211_MESHRT_FLAGS_PROXY |
+                       IEEE80211_MESHRT_FLAGS_VALID;
+               rt_dest->rt_ext_seq = 1; /* random value */
+               IEEE80211_ADDR_COPY(rt_dest->rt_mesh_gate, rt_gate->rt_dest);
+               IEEE80211_ADDR_COPY(rt_dest->rt_nexthop, rt_gate->rt_nexthop);
+               rt_dest->rt_metric = rt_gate->rt_metric;
+               rt_dest->rt_nhops = rt_gate->rt_nhops;
+               ieee80211_mesh_rt_update(rt_dest, ms->ms_ppath->mpp_inact);
+               MESH_RT_UNLOCK(ms);
+               m = ieee80211_ageq_remove(&ic->ic_stageq,
+               (struct ieee80211_node *)(uintptr_t)
+               ieee80211_mac_hash(ic, rt_dest->rt_dest));
+               for (; m != NULL; m = next) {
+                       next = m->m_nextpkt;
+                       m->m_nextpkt = NULL;
+                       IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, 
rt_dest->rt_dest,
+                       "flush queued frame %p len %d", m, m->m_pkthdr.len);
+                       ifp->if_transmit(ifp, m);
+               }
+               MESH_RT_LOCK(ms);
+       }
+
+       if (gates_found == 0) {
+               rt_dest->rt_flags = 0; /* Mark invalid */
+               IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, rt_dest->rt_dest,
+                   "%s", "no mesh gate found, or no path setup for mesh gate 
yet");
+       }
+       MESH_RT_UNLOCK(ms);
+
+}
+
+/*
  * Forward the specified frame.
  * Decrement the TTL and set TA to our MAC address.
  */

Modified: head/sys/net80211/ieee80211_mesh.h
==============================================================================
--- head/sys/net80211/ieee80211_mesh.h  Thu Feb  7 21:24:52 2013        
(r246509)
+++ head/sys/net80211/ieee80211_mesh.h  Thu Feb  7 21:25:32 2013        
(r246510)
@@ -569,6 +569,8 @@ void                ieee80211_mesh_update_beacon(struc
 struct ieee80211_mesh_gate_route *
                ieee80211_mesh_mark_gate(struct ieee80211vap *,
                    const uint8_t *, struct ieee80211_mesh_route *);
+void           ieee80211_mesh_forward_to_gates(struct ieee80211vap *,
+                   struct ieee80211_mesh_route *);
 
 /*
  * Return non-zero if proxy operation is enabled.
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to