svn commit: r195284 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Thu Jul 2 12:41:22 UTC 2009
Author: rpaulo
Date: Thu Jul 2 12:41:21 2009
New Revision: 195284
URL: http://svn.freebsd.org/changeset/base/195284
Log:
Finish proactive root mode implementation.
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_hwmp.c
projects/mesh11s/sys/net80211/ieee80211_hwmp.h
projects/mesh11s/sys/net80211/ieee80211_ioctl.h
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c Thu Jul 2 10:02:10 2009 (r195283)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Thu Jul 2 12:41:21 2009 (r195284)
@@ -83,6 +83,8 @@ static uint8_t *hwmp_add_meshperr(uint8_
const struct ieee80211_meshperr_ie *);
static uint8_t *hwmp_add_meshrann(uint8_t *,
const struct ieee80211_meshrann_ie *);
+static void hwmp_rootmode_setup(struct ieee80211vap *);
+static void hwmp_rootmode_cb(void *);
static void hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *,
const struct ieee80211_frame *, const struct ieee80211_meshpreq_ie *);
static int hwmp_send_preq(struct ieee80211_node *,
@@ -121,6 +123,9 @@ static const struct timeval ieee80211_hw
#define timeval2msecs(tv) (tv.tv_sec * 1000 + tv.tv_usec / 1000)
+#define HWMP_ROOTMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hmwp_rootint))
+#define HWMP_RANNMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hmwp_rannint))
+
#define HWMP_LOCK(hs) mtx_lock(&(hs)->hs_lock)
#define HWMP_UNLOCK(hs) mtx_unlock(&(hs)->hs_lock)
@@ -170,6 +175,10 @@ hwmp_rt_add(struct ieee80211vap *vap, co
KASSERT(hwmp_rt_find(vap, dest) == NULL,
("%s: duplicate entry in the routing table", __func__));
+ KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest),
+ ("%s: adding self to the routing table", __func__));
+ KASSERT(!IEEE80211_ADDR_EQ(broadcastaddr, dest),
+ ("%s: adding broadcast to the routing table", __func__));
rt = malloc(sizeof(struct ieee80211_hwmp_route), M_80211_HWMP,
M_NOWAIT | M_ZERO);
@@ -233,6 +242,7 @@ ieee80211_hwmp_vattach(struct ieee80211v
mtx_init(&hs->hs_lock, "HWMP", "802.11s HWMP", MTX_DEF);
hs->hs_maxhops = IEEE80211_HWMP_DEFAULT_MAXHOPS;
hs->hs_ttl = IEEE80211_HWMP_DEFAULT_TTL;
+ callout_init(&hs->hs_roottimer, CALLOUT_MPSAFE);
vap->iv_hwmp = hs;
}
@@ -242,6 +252,8 @@ ieee80211_hwmp_vdetach(struct ieee80211v
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
hwmp_rt_flush(vap);
+ if (callout_pending(&hs->hs_roottimer))
+ callout_stop(&hs->hs_roottimer);
mtx_destroy(&hs->hs_lock);
free(vap->iv_hwmp, M_80211_HWMP);
}
@@ -250,10 +262,14 @@ int
ieee80211_hwmp_newstate(struct ieee80211vap *vap, enum ieee80211_state ostate, int arg)
{
enum ieee80211_state nstate = vap->iv_state;
+ struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
/* Flush the table on INIT -> SCAN, e.g. interface down & up */
- if (nstate == IEEE80211_S_SCAN && ostate == IEEE80211_S_INIT)
+ if (nstate == IEEE80211_S_SCAN && ostate == IEEE80211_S_INIT) {
hwmp_rt_flush(vap);
+ if (callout_pending(&hs->hs_roottimer))
+ callout_stop(&hs->hs_roottimer);
+ }
return 0;
}
@@ -553,7 +569,18 @@ hwmp_add_meshrann(uint8_t *frm, const st
return frm;
}
-#ifdef notyet
+static void
+hwmp_rootmode_setup(struct ieee80211vap *vap)
+{
+ struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
+
+ if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED)
+ callout_reset(&hs->hs_roottimer, HWMP_ROOTMODEINT,
+ hwmp_rootmode_cb, vap);
+ else
+ callout_stop(&hs->hs_roottimer);
+}
+
/*
* Send a broadcast Path Request to find all nodes on the mesh. We are
* called when the vap is configured as a HWMP root node.
@@ -562,14 +589,17 @@ hwmp_add_meshrann(uint8_t *frm, const st
#define PREQ_TADDR(n) preq.preq_targets[n].target_addr
#define PREQ_TSEQ(n) preq.preq_targets[n].target_seq
static void
-hwmp_rootmode_cb(struct ieee80211vap *vap)
+hwmp_rootmode_cb(void *arg)
{
+ struct ieee80211vap *vap = (struct ieee80211vap *)arg;
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
struct ieee80211_meshpreq_ie preq;
+ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss,
+ "%s", "sending broadcast PREQ");
+
/* XXX check portal role */
- preq.preq_flags = 0;
- preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_AM;
+ preq.preq_flags = IEEE80211_MESHPREQ_FLAGS_AM;
if (hs->hs_rootmode == IEEE80211_HWMP_ROOTMODE_PROACTIVE)
preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PP;
preq.preq_hopcount = 0;
@@ -584,12 +614,13 @@ hwmp_rootmode_cb(struct ieee80211vap *va
PREQ_TFLAGS(0) = IEEE80211_MESHPREQ_TFLAGS_TO |
IEEE80211_MESHPREQ_TFLAGS_RF;
PREQ_TSEQ(0) = 0;
+ vap->iv_stats.is_hwmp_rootreqs++;
hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq);
+ hwmp_rootmode_setup(vap);
}
#undef PREQ_TFLAGS
#undef PREQ_TADDR
#undef PREQ_TSEQ
-#endif
#define PREQ_TFLAGS(n) preq->preq_targets[n].target_flags
#define PREQ_TADDR(n) preq->preq_targets[n].target_addr
@@ -657,6 +688,47 @@ hwmp_recv_preq(struct ieee80211vap *vap,
ieee80211_hwmp_discover(vap, rt->rt_dest, NULL);
return;
}
+ /*
+ * Proactive PREQ: reply with a proactive PREP to the
+ * root STA if requested.
+ */
+ if (IEEE80211_ADDR_EQ(PREQ_TADDR(0), broadcastaddr) &&
+ (PREQ_TFLAGS(0) &
+ ((IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF) ==
+ (IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF)))) {
+ uint8_t rootmac[IEEE80211_ADDR_LEN];
+
+ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+ "root mesh station @ %s",
+ ether_sprintf(preq->preq_origaddr));
+ IEEE80211_ADDR_COPY(rootmac, preq->preq_origaddr);
+ rt = hwmp_rt_find(vap, rootmac);
+ if (rt == NULL)
+ rt = hwmp_rt_add(vap, rootmac);
+ /*
+ * Reply with a PREP if we don't have a path to the root
+ * or if the root sent us a proactive PREQ.
+ */
+ if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr) ||
+ (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_PP)) {
+ prep.prep_flags = 0;
+ prep.prep_hopcount = 0;
+ prep.prep_ttl = hs->hs_ttl;
+ IEEE80211_ADDR_COPY(prep.prep_origaddr,
+ vap->iv_myaddr);
+ prep.prep_origseq = preq->preq_origseq;
+ prep.prep_targetseq = ++hs->hs_seq;
+ prep.prep_lifetime = preq->preq_lifetime;
+ prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
+ IEEE80211_ADDR_COPY(prep.prep_targetaddr,
+ rootmac);
+ prep.prep_targetseq = PREQ_TSEQ(0);
+ hwmp_send_prep(vap->iv_bss, vap->iv_myaddr,
+ broadcastaddr, &prep);
+ }
+ ieee80211_hwmp_discover(vap, rootmac, NULL);
+ return;
+ }
rt = hwmp_rt_find(vap, PREQ_TADDR(0));
/* XXX missing. Check for AE bit and update proxy information */
@@ -745,38 +817,6 @@ hwmp_recv_preq(struct ieee80211vap *vap,
}
}
- /*
- * Proactive PREQ: reply with a proactive PREP to the
- * root STA if requested.
- */
- if (IEEE80211_ADDR_EQ(PREQ_TADDR(0), broadcastaddr) &&
- (PREQ_TFLAGS(0) &
- ((IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF) ==
- (IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF)))) {
- rt = hwmp_rt_find(vap, preq->preq_origaddr);
- if (rt == NULL)
- rt = hwmp_rt_add(vap, preq->preq_origaddr);
- /*
- * Reply with a PREP if we don't have a path to the root
- * or if the root sent us a proactive PREQ.
- */
- if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr) ||
- (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_PP)) {
- prep.prep_flags = 0;
- prep.prep_hopcount = 0;
- prep.prep_ttl = hs->hs_ttl;
- IEEE80211_ADDR_COPY(prep.prep_targetaddr,
- vap->iv_myaddr);
- prep.prep_targetseq = ++hs->hs_seq;
- prep.prep_lifetime = preq->preq_lifetime;
- prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
- IEEE80211_ADDR_COPY(prep.prep_origaddr,
- preq->preq_origaddr);
- prep.prep_origseq = preq->preq_origseq;
- hwmp_send_prep(vap->iv_bss, vap->iv_myaddr,
- broadcastaddr, &prep);
- }
- }
}
#undef PREQ_TFLAGS
#undef PREQ_TADDR
@@ -816,14 +856,15 @@ hwmp_recv_prep(struct ieee80211vap *vap,
const struct ieee80211_frame *wh, const struct ieee80211_meshprep_ie *prep)
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
+ struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
struct ieee80211_hwmp_route *rt = NULL;
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp;
struct mbuf *m, *next;
/*
- * Acceptance criteria: if the PREP was not generated by us and
- * forwarding is disabled, discard this PREP.
+ * Acceptance criteria: if the corresponding PREQ was not generated
+ * by us and forwarding is disabled, discard this PREP.
*/
if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) &&
!(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
@@ -853,8 +894,21 @@ hwmp_recv_prep(struct ieee80211vap *vap,
}
rt = hwmp_rt_find(vap, prep->prep_origaddr);
- if (rt == NULL)
+ if (rt == NULL) {
+ /*
+ * If we have no entry this could be a reply to a root PREQ.
+ */
+ if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) {
+ printf("1\n");
+ rt = hwmp_rt_add(vap, prep->prep_origaddr);
+ IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2);
+ rt->rt_nhops = prep->prep_hopcount;
+ rt->rt_lifetime = prep->prep_lifetime;
+ rt->rt_metric = prep->prep_metric;
+ return;
+ }
return;
+ }
if (prep->prep_targetseq == rt->rt_seq) {
int useprep = 0;
/*
@@ -1124,7 +1178,7 @@ ieee80211_hwmp_discover(struct ieee80211
("not a mesh vap, opmode %d", vap->iv_opmode));
KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest),
- ("discovering self!"));
+ ("%s: discovering self!", __func__));
ni = NULL;
if (!IEEE80211_IS_MULTICAST(dest)) {
@@ -1339,6 +1393,7 @@ hwmp_ioctl_set80211(struct ieee80211vap
if (ireq->i_val < 0 || ireq->i_val > 3)
return EINVAL;
hs->hs_rootmode = ireq->i_val;
+ hwmp_rootmode_setup(vap);
break;
case IEEE80211_IOC_HWMP_MAXHOPS:
if (ireq->i_val <= 0 || ireq->i_val > 255)
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.h Thu Jul 2 10:02:10 2009 (r195283)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.h Thu Jul 2 12:41:21 2009 (r195284)
@@ -64,6 +64,7 @@ struct ieee80211_hwmp_state {
struct timeval hs_lastperr; /* last time we sent a PERR */
struct mtx hs_lock; /* lock for the fi table */
int hs_rootmode; /* proactive HWMP */
+ struct callout hs_roottimer;
uint8_t hs_maxhops; /* max hop count */
uint8_t hs_ttl; /* HWMP ttl */
};
Modified: projects/mesh11s/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ioctl.h Thu Jul 2 10:02:10 2009 (r195283)
+++ projects/mesh11s/sys/net80211/ieee80211_ioctl.h Thu Jul 2 12:41:21 2009 (r195284)
@@ -233,6 +233,7 @@ struct ieee80211_stats {
uint32_t is_mesh_fwd_nopath; /* mesh not fwd'd 'cuz path unknown */
uint32_t is_hwmp_wrongseq; /* wrong hwmp seq no. */
+ uint32_t is_hwmp_rootreqs; /* root PREQs sent */
uint32_t is_spare[8];
};
More information about the svn-src-projects
mailing list