Date: Thu, 7 Feb 2013 21:25:33 +0000 (UTC) From: Monthadar Al Jaberi <monthadar@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r246510 - head/sys/net80211 Message-ID: <201302072125.r17LPXku011546@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302072125.r17LPXku011546>