svn commit: r234877 - head/sys/net80211
Monthadar Al Jaberi
monthadar at FreeBSD.org
Tue May 1 15:47:31 UTC 2012
Author: monthadar
Date: Tue May 1 15:47:30 2012
New Revision: 234877
URL: http://svn.freebsd.org/changeset/base/234877
Log:
Implemented so that Mesh forwarding information lifetime is dynamic.
* Introduced ieee80211_mesh_rt_update that updates a route with the
maximum(lifetime left, new lifetime);
* Modified ieee80211_mesh_route struct by adding a lock that will be used
by both ieee80211_mesh_rt_update and precursor code (added in future commit);
* Modified in ieee80211_hwmp.c HWMP code to use new ieee80211_mesh_rt_update;
* Modified mesh_rt_flush_invalid to use new ieee80211_mesh_rt_update;
* mesh_rt_flush also checks that lifetime == 0, this gives route discovery
a change to complete;
* Modified mesh_recv_mgmt case IEEE80211_FC0_SUBTYPE_BEACON:
when ever we received a beacon from a neighbor we update route lifetime;
Approved by: adrian
Modified:
head/sys/net80211/ieee80211_ddb.c
head/sys/net80211/ieee80211_hwmp.c
head/sys/net80211/ieee80211_mesh.c
head/sys/net80211/ieee80211_mesh.h
Modified: head/sys/net80211/ieee80211_ddb.c
==============================================================================
--- head/sys/net80211/ieee80211_ddb.c Tue May 1 15:42:41 2012 (r234876)
+++ head/sys/net80211/ieee80211_ddb.c Tue May 1 15:47:30 2012 (r234877)
@@ -870,8 +870,10 @@ _db_show_mesh(const struct ieee80211_mes
TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
db_printf("entry %d:\tdest: %6D nexthop: %6D metric: %u", i,
rt->rt_dest, ":", rt->rt_nexthop, ":", rt->rt_metric);
+
db_printf("\tlifetime: %u lastseq: %u priv: %p\n",
- rt->rt_lifetime, rt->rt_lastmseq, rt->rt_priv);
+ ieee80211_mesh_rt_update(rt, 0),
+ rt->rt_lastmseq, rt->rt_priv);
i++;
}
}
Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c Tue May 1 15:42:41 2012 (r234876)
+++ head/sys/net80211/ieee80211_hwmp.c Tue May 1 15:47:30 2012 (r234877)
@@ -143,9 +143,6 @@ typedef uint32_t ieee80211_hwmp_seq;
#define HWMP_SEQ_GT(a, b) ((int32_t)((a)-(b)) > 0)
#define HWMP_SEQ_GEQ(a, b) ((int32_t)((a)-(b)) >= 0)
-/* The longer one of the lifetime should be stored as new lifetime */
-#define MESH_ROUTE_LIFETIME_MAX(a, b) (a > b ? a : b)
-
/*
* Private extension of ieee80211_mesh_route.
*/
@@ -938,7 +935,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
/* Data creation and update of forwarding information
* according to Table 11C-8 for originator mesh STA.
*/
- if(HWMP_SEQ_GT(preq->preq_origseq, hrorig->hr_seq) ||
+ if (HWMP_SEQ_GT(preq->preq_origseq, hrorig->hr_seq) ||
(HWMP_SEQ_EQ(preq->preq_origseq, hrorig->hr_seq) &&
preq->preq_metric < rtorig->rt_metric)) {
hrorig->hr_seq = preq->preq_origseq;
@@ -946,8 +943,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
rtorig->rt_metric = preq->preq_metric +
ms->ms_pmetric->mpm_metric(ni);
rtorig->rt_nhops = preq->preq_hopcount + 1;
- rtorig->rt_lifetime = MESH_ROUTE_LIFETIME_MAX(
- preq->preq_lifetime, rtorig->rt_lifetime);
+ ieee80211_mesh_rt_update(rtorig, preq->preq_lifetime);
/* path to orig is valid now */
rtorig->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID;
}else if(hrtarg != NULL &&
@@ -1124,7 +1120,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
}
}
rt->rt_metric = preq->preq_metric;
- rt->rt_lifetime = preq->preq_lifetime;
+ ieee80211_mesh_rt_update(rt, preq->preq_lifetime);
hrorig = IEEE80211_MESH_ROUTE_PRIV(rt,
struct ieee80211_hwmp_route);
hrorig->hr_seq = preq->preq_origseq;
@@ -1221,7 +1217,7 @@ hwmp_recv_prep(struct ieee80211vap *vap,
}
IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2);
rt->rt_nhops = prep->prep_hopcount;
- rt->rt_lifetime = prep->prep_lifetime;
+ ieee80211_mesh_rt_update(rt, prep->prep_lifetime);
rt->rt_metric = prep->prep_metric;
rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
@@ -1300,7 +1296,7 @@ hwmp_recv_prep(struct ieee80211vap *vap,
rt->rt_metric, prep->prep_metric);
IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2);
rt->rt_nhops = prep->prep_hopcount + 1;
- rt->rt_lifetime = prep->prep_lifetime;
+ ieee80211_mesh_rt_update(rt, prep->prep_lifetime);
rt->rt_metric = metric;
rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID;
} else {
@@ -1594,8 +1590,9 @@ hwmp_discover(struct ieee80211vap *vap,
if (hr->hr_origseq == 0)
hr->hr_origseq = ++hs->hs_seq;
rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
- rt->rt_lifetime =
- ticks_to_msecs(ieee80211_hwmp_pathtimeout);
+ /* XXX: special discovery timeout, larger lifetime? */
+ ieee80211_mesh_rt_update(rt,
+ ticks_to_msecs(ieee80211_hwmp_pathtimeout));
/* XXX check preq retries */
sendpreq = 1;
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, dest,
@@ -1613,7 +1610,8 @@ hwmp_discover(struct ieee80211vap *vap,
preq.preq_id = ++hs->hs_preqid;
IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr);
preq.preq_origseq = hr->hr_origseq;
- preq.preq_lifetime = rt->rt_lifetime;
+ preq.preq_lifetime =
+ ticks_to_msecs(ieee80211_hwmp_pathtimeout);
preq.preq_metric = rt->rt_metric;
preq.preq_tcount = 1;
IEEE80211_ADDR_COPY(PREQ_TADDR(0), dest);
Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c Tue May 1 15:42:41 2012 (r234876)
+++ head/sys/net80211/ieee80211_mesh.c Tue May 1 15:47:30 2012 (r234877)
@@ -138,6 +138,10 @@ static const struct ieee80211_mesh_proto
static struct ieee80211_mesh_proto_path mesh_proto_paths[4];
static struct ieee80211_mesh_proto_metric mesh_proto_metrics[4];
+#define RT_ENTRY_LOCK(rt) mtx_lock(&(rt)->rt_lock)
+#define RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
+#define RT_ENTRY_UNLOCK(rt) mtx_unlock(&(rt)->rt_lock)
+
#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock)
#define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock)
@@ -146,6 +150,9 @@ MALLOC_DEFINE(M_80211_MESH_PREQ, "80211p
MALLOC_DEFINE(M_80211_MESH_PREP, "80211prep", "802.11 MESH Path Reply frame");
MALLOC_DEFINE(M_80211_MESH_PERR, "80211perr", "802.11 MESH Path Error frame");
+/* The longer one of the lifetime should be stored as new lifetime */
+#define MESH_ROUTE_LIFETIME_MAX(a, b) (a > b ? a : b)
+
MALLOC_DEFINE(M_80211_MESH_RT, "80211mesh", "802.11s routing table");
/*
@@ -183,7 +190,8 @@ mesh_rt_add_locked(struct ieee80211_mesh
if (rt != NULL) {
IEEE80211_ADDR_COPY(rt->rt_dest, dest);
rt->rt_priv = (void *)ALIGN(&rt[1]);
- rt->rt_crtime = ticks;
+ mtx_init(&rt->rt_lock, "MBSS_RT", "802.11s route entry", MTX_DEF);
+ rt->rt_updtime = ticks; /* create time */
TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next);
}
return rt;
@@ -221,6 +229,41 @@ ieee80211_mesh_rt_add(struct ieee80211va
}
/*
+ * Update the route lifetime and returns the updated lifetime.
+ * If new_lifetime is zero and route is timedout it will be invalidated.
+ * new_lifetime is in msec
+ */
+int
+ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int new_lifetime)
+{
+ int timesince, now;
+ uint32_t lifetime = 0;
+
+ now = ticks;
+ RT_ENTRY_LOCK(rt);
+ timesince = ticks_to_msecs(now - rt->rt_updtime);
+ rt->rt_updtime = now;
+ if (timesince >= rt->rt_lifetime) {
+ if (new_lifetime != 0) {
+ rt->rt_lifetime = new_lifetime;
+ }
+ else {
+ rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID;
+ rt->rt_lifetime = 0;
+ }
+ } else {
+ /* update what is left of lifetime */
+ rt->rt_lifetime = rt->rt_lifetime - timesince;
+ rt->rt_lifetime = MESH_ROUTE_LIFETIME_MAX(
+ new_lifetime, rt->rt_lifetime);
+ }
+ lifetime = rt->rt_lifetime;
+ RT_ENTRY_UNLOCK(rt);
+
+ return lifetime;
+}
+
+/*
* Add a proxy route (as needed) for the specified destination.
*/
void
@@ -271,6 +314,12 @@ static __inline void
mesh_rt_del(struct ieee80211_mesh_state *ms, struct ieee80211_mesh_route *rt)
{
TAILQ_REMOVE(&ms->ms_routes, rt, rt_next);
+ /*
+ * Grab the lock before destroying it, to be sure no one else
+ * is holding the route.
+ */
+ RT_ENTRY_LOCK(rt);
+ mtx_destroy(&rt->rt_lock);
free(rt, M_80211_MESH_RT);
}
@@ -335,8 +384,13 @@ mesh_rt_flush_invalid(struct ieee80211va
return;
MESH_RT_LOCK(ms);
TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
+ ieee80211_mesh_rt_update(rt, 0);
+ /*
+ * NB: we check for lifetime == 0 so that we give a chance
+ * for route discovery to complete.
+ */
if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0 &&
- ticks - rt->rt_crtime >= ms->ms_ppath->mpp_inact)
+ rt->rt_lifetime == 0)
mesh_rt_del(ms, rt);
}
MESH_RT_UNLOCK(ms);
@@ -1338,6 +1392,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211_frame *wh;
+ struct ieee80211_mesh_route *rt;
uint8_t *frm, *efrm;
wh = mtod(m0, struct ieee80211_frame *);
@@ -1430,20 +1485,40 @@ mesh_recv_mgmt(struct ieee80211_node *ni
* XXX backoff on repeated failure
*/
if (ni != vap->iv_bss &&
- (ms->ms_flags & IEEE80211_MESHFLAGS_AP) &&
- ni->ni_mlstate == IEEE80211_NODE_MESH_IDLE) {
- uint16_t args[1];
-
- ni->ni_mlpid = mesh_generateid(vap);
- if (ni->ni_mlpid == 0)
- return;
- mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENSNT);
- args[0] = ni->ni_mlpid;
- ieee80211_send_action(ni,
- IEEE80211_ACTION_CAT_SELF_PROT,
- IEEE80211_ACTION_MESHPEERING_OPEN, args);
- ni->ni_mlrcnt = 0;
- mesh_peer_timeout_setup(ni);
+ (ms->ms_flags & IEEE80211_MESHFLAGS_AP)) {
+ switch (ni->ni_mlstate) {
+ case IEEE80211_NODE_MESH_IDLE:
+ {
+ uint16_t args[1];
+
+ ni->ni_mlpid = mesh_generateid(vap);
+ if (ni->ni_mlpid == 0)
+ return;
+ mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENSNT);
+ args[0] = ni->ni_mlpid;
+ ieee80211_send_action(ni,
+ IEEE80211_ACTION_CAT_SELF_PROT,
+ IEEE80211_ACTION_MESHPEERING_OPEN, args);
+ ni->ni_mlrcnt = 0;
+ mesh_peer_timeout_setup(ni);
+ break;
+ }
+ case IEEE80211_NODE_MESH_ESTABLISHED:
+ {
+ /*
+ * Valid beacon from a peer mesh STA
+ * bump TA lifetime
+ */
+ rt = ieee80211_mesh_rt_find(vap, wh->i_addr2);
+ if(rt != NULL) {
+ ieee80211_mesh_rt_update(rt,
+ ms->ms_ppath->mpp_inact);
+ }
+ break;
+ }
+ default:
+ break; /* ignore */
+ }
}
break;
}
@@ -2701,15 +2776,16 @@ mesh_ioctl_get80211(struct ieee80211vap
break;
imr = (struct ieee80211req_mesh_route *)
(p + off);
- imr->imr_flags = rt->rt_flags;
IEEE80211_ADDR_COPY(imr->imr_dest,
rt->rt_dest);
IEEE80211_ADDR_COPY(imr->imr_nexthop,
rt->rt_nexthop);
imr->imr_metric = rt->rt_metric;
imr->imr_nhops = rt->rt_nhops;
- imr->imr_lifetime = rt->rt_lifetime;
+ imr->imr_lifetime =
+ ieee80211_mesh_rt_update(rt, 0);
imr->imr_lastmseq = rt->rt_lastmseq;
+ imr->imr_flags = rt->rt_flags; /* last */
off += sizeof(*imr);
}
MESH_RT_UNLOCK(ms);
Modified: head/sys/net80211/ieee80211_mesh.h
==============================================================================
--- head/sys/net80211/ieee80211_mesh.h Tue May 1 15:42:41 2012 (r234876)
+++ head/sys/net80211/ieee80211_mesh.h Tue May 1 15:47:30 2012 (r234877)
@@ -409,9 +409,19 @@ MALLOC_DECLARE(M_80211_MESH_PREP);
MALLOC_DECLARE(M_80211_MESH_PERR);
MALLOC_DECLARE(M_80211_MESH_RT);
+/*
+ * Basic forwarding information:
+ * o Destination MAC
+ * o Next-hop MAC
+ * o Precursor list (not implemented yet)
+ * o Path timeout
+ * The rest is part of the active Mesh path selection protocol.
+ * XXX: to be moved out later.
+ */
struct ieee80211_mesh_route {
TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
- int rt_crtime; /* creation time */
+ struct mtx rt_lock; /* fine grained route lock */
+ int rt_updtime; /* last update time */
uint8_t rt_dest[IEEE80211_ADDR_LEN];
uint8_t rt_nexthop[IEEE80211_ADDR_LEN];
uint32_t rt_metric; /* path metric */
@@ -419,7 +429,7 @@ struct ieee80211_mesh_route {
uint16_t rt_flags;
#define IEEE80211_MESHRT_FLAGS_VALID 0x01 /* patch discovery complete */
#define IEEE80211_MESHRT_FLAGS_PROXY 0x02 /* proxy entry */
- uint32_t rt_lifetime;
+ uint32_t rt_lifetime; /* route timeout */
uint32_t rt_lastmseq; /* last seq# seen dest */
void *rt_priv; /* private data */
};
@@ -508,6 +518,7 @@ void ieee80211_mesh_rt_del(struct ieee8
void ieee80211_mesh_rt_flush(struct ieee80211vap *);
void ieee80211_mesh_rt_flush_peer(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
+int ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int);
void ieee80211_mesh_proxy_check(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
More information about the svn-src-all
mailing list