svn commit: r195404 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Mon Jul 6 10:40:47 UTC 2009
Author: rpaulo
Date: Mon Jul 6 10:40:46 2009
New Revision: 195404
URL: http://svn.freebsd.org/changeset/base/195404
Log:
Overhaul the routing structures used and move them to common mesh code
so that they can be used by future routing protocols.
XXX not finished
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_mesh.c
projects/mesh11s/sys/net80211/ieee80211_mesh.h
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c Mon Jul 6 09:31:04 2009 (r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Mon Jul 6 10:40:46 2009 (r195404)
@@ -64,15 +64,6 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_hwmp.h>
#include <net80211/ieee80211_input.h>
-static struct ieee80211_hwmp_route *
- hwmp_rt_find(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
-static struct ieee80211_hwmp_route *
- hwmp_rt_add(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
-static void hwmp_rt_del(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN]);
-static void hwmp_rt_flush(struct ieee80211vap *);
static int ieee80211_hwmp_send_action(struct ieee80211_node *,
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN],
@@ -137,9 +128,6 @@ static const struct timeval ieee80211_hw
#define HWMP_ROOTMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hwmp_rootint))
#define HWMP_RANNMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hwmp_rannint))
-#define HWMP_LOCK(hs) mtx_lock(&(hs)->hs_lock)
-#define HWMP_UNLOCK(hs) mtx_unlock(&(hs)->hs_lock)
-
/* unalligned little endian access */
#define LE_WRITE_2(p, v) do { \
((uint8_t *)(p))[0] = (v) & 0xff; \
@@ -166,8 +154,6 @@ SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, tar
SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, replyforward, CTLTYPE_INT | CTLFLAG_RW,
&ieee80211_hwmp_replyforward, 0, "Set RF bit on generated PREQs");
-MALLOC_DEFINE(M_80211_HWMP, "80211hwmp", "802.11 HWMP routing table");
-
#define IEEE80211_HWMP_DEFAULT_MAXHOPS 31
#define IEEE80211_HWMP_DEFAULT_TTL 31
@@ -193,83 +179,6 @@ ieee80211_hwmp_init(void)
}
SYSINIT(wlan_hwmp, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_hwmp_init, NULL);
-/*
- * Helper functions to manipulate the HWMP routing table.
- */
-static struct ieee80211_hwmp_route *
-hwmp_rt_find(struct ieee80211vap *vap, const uint8_t dest[IEEE80211_ADDR_LEN])
-{
- struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt;
-
- HWMP_LOCK(hs);
- TAILQ_FOREACH(rt, &hs->hs_routes, rt_next) {
- if (IEEE80211_ADDR_EQ(dest, rt->rt_dest)) {
- HWMP_UNLOCK(hs);
- return rt;
- }
- }
- HWMP_UNLOCK(hs);
- return NULL;
-}
-
-static struct ieee80211_hwmp_route *
-hwmp_rt_add(struct ieee80211vap *vap, const uint8_t dest[IEEE80211_ADDR_LEN])
-{
- struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt;
-
- 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);
- IEEE80211_ADDR_COPY(rt->rt_dest, dest);
- HWMP_LOCK(hs);
- TAILQ_INSERT_TAIL(&hs->hs_routes, rt, rt_next);
- HWMP_UNLOCK(hs);
- return rt;
-}
-
-static void
-hwmp_rt_del(struct ieee80211vap *vap, const uint8_t dest[IEEE80211_ADDR_LEN])
-{
- struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt, *next;
-
- KASSERT(hs != NULL, ("no HWMP state"));
- HWMP_LOCK(hs);
- TAILQ_FOREACH_SAFE(rt, &hs->hs_routes, rt_next, next) {
- if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) {
- TAILQ_REMOVE(&hs->hs_routes, rt, rt_next);
- free(rt, M_80211_HWMP);
- HWMP_UNLOCK(hs);
- return;
- }
- }
- HWMP_UNLOCK(hs);
-}
-
-static void
-hwmp_rt_flush(struct ieee80211vap *vap)
-{
- struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt, *next;
-
- if (hs == NULL)
- return;
- HWMP_LOCK(hs);
- TAILQ_FOREACH_SAFE(rt, &hs->hs_routes, rt_next, next) {
- TAILQ_REMOVE(&hs->hs_routes, rt, rt_next);
- free(rt, M_80211_HWMP);
- }
- HWMP_UNLOCK(hs);
-}
-
void
ieee80211_hwmp_vattach(struct ieee80211vap *vap)
{
@@ -278,14 +187,12 @@ ieee80211_hwmp_vattach(struct ieee80211v
KASSERT(vap->iv_opmode == IEEE80211_M_MBSS,
("not a mesh vap, opmode %d", vap->iv_opmode));
- hs = malloc(sizeof(struct ieee80211_hwmp_state), M_80211_HWMP,
+ hs = malloc(sizeof(struct ieee80211_hwmp_state), M_80211_VAP,
M_NOWAIT | M_ZERO);
if (hs == NULL) {
printf("%s: couldn't alloc HWMP state\n", __func__);
return;
}
- TAILQ_INIT(&hs->hs_routes);
- 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);
@@ -297,11 +204,9 @@ ieee80211_hwmp_vdetach(struct ieee80211v
{
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- hwmp_rt_flush(vap);
if (callout_active(&hs->hs_roottimer))
callout_drain(&hs->hs_roottimer);
- mtx_destroy(&hs->hs_lock);
- free(vap->iv_hwmp, M_80211_HWMP);
+ free(vap->iv_hwmp, M_80211_VAP);
vap->iv_hwmp = NULL;
}
@@ -316,10 +221,8 @@ ieee80211_hwmp_newstate(struct ieee80211
ieee80211_state_name[nstate], arg);
/* Flush the table on !INIT -> INIT, e.g. interface down & up */
- if (nstate != IEEE80211_S_INIT && ostate == IEEE80211_S_INIT) {
- hwmp_rt_flush(vap);
+ if (nstate != IEEE80211_S_INIT && ostate == IEEE80211_S_INIT)
callout_drain(&hs->hs_roottimer);
- }
return 0;
}
@@ -724,8 +627,9 @@ hwmp_recv_preq(struct ieee80211vap *vap,
const struct ieee80211_frame *wh, const struct ieee80211_meshpreq_ie *preq)
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
+ struct ieee80211_mesh_route *rt = NULL;
+ struct ieee80211_hwmp_route *hr;
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt = NULL;
struct ieee80211_meshprep_ie prep;
if (ni == vap->iv_bss ||
@@ -774,7 +678,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
/*
* Build the reverse path, if we don't have it already.
*/
- rt = hwmp_rt_find(vap, preq->preq_origaddr);
+ rt = ieee80211_mesh_rt_find(vap, preq->preq_origaddr);
if (rt == NULL)
ieee80211_hwmp_discover(vap, preq->preq_origaddr, NULL);
else if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr))
@@ -795,9 +699,10 @@ hwmp_recv_preq(struct ieee80211vap *vap,
"root mesh station @ %s",
ether_sprintf(preq->preq_origaddr));
IEEE80211_ADDR_COPY(rootmac, preq->preq_origaddr);
- rt = hwmp_rt_find(vap, rootmac);
+ rt = ieee80211_mesh_rt_find(vap, rootmac);
if (rt == NULL)
- rt = hwmp_rt_add(vap, rootmac);
+ rt = ieee80211_mesh_rt_add(vap, rootmac,
+ sizeof(struct ieee80211_hwmp_route));
/*
* Reply with a PREP if we don't have a path to the root
* or if the root sent us a proactive PREQ.
@@ -822,7 +727,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
ieee80211_hwmp_discover(vap, rootmac, NULL);
return;
}
- rt = hwmp_rt_find(vap, PREQ_TADDR(0));
+ rt = ieee80211_mesh_rt_find(vap, PREQ_TADDR(0));
/* XXX missing. Check for AE bit and update proxy information */
@@ -838,10 +743,12 @@ hwmp_recv_preq(struct ieee80211vap *vap,
*/
if (rt != NULL &&
!IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr)) {
- rt->rt_preqid = preq->preq_id;
- rt->rt_seq = preq->preq_origseq;
- if (preq->preq_ttl > 1) {
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+ struct ieee80211_hwmp_route);
+ hr->hr_preqid = preq->preq_id;
+ hr->hr_seq = preq->preq_origseq;
+ if (preq->preq_ttl > 1) {
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"forwarding PREQ from %s",
ether_sprintf(preq->preq_origaddr));
@@ -877,7 +784,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
prep.prep_ttl = hs->hs_ttl;
IEEE80211_ADDR_COPY(&prep.prep_targetaddr,
preq->preq_origaddr);
- prep.prep_targetseq = rt->rt_seq;
+ prep.prep_targetseq = hr->hr_seq;
prep.prep_lifetime = preq->preq_lifetime;
prep.prep_metric = rt->rt_metric +
ieee80211_airtime_calc(ni);
@@ -893,11 +800,14 @@ hwmp_recv_preq(struct ieee80211vap *vap,
*/
} else if (preq->preq_ttl > 1) {
if (rt == NULL)
- rt = hwmp_rt_add(vap, PREQ_TADDR(0));
+ rt = ieee80211_mesh_rt_add(vap, PREQ_TADDR(0),
+ sizeof(struct ieee80211_hwmp_route));
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+ struct ieee80211_hwmp_route);
rt->rt_metric = preq->preq_metric;
rt->rt_lifetime = preq->preq_lifetime;
- rt->rt_seq = preq->preq_origseq;
- rt->rt_preqid = preq->preq_id;
+ hr->hr_seq = preq->preq_origseq;
+ hr->hr_preqid = preq->preq_id;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"forwarding PREQ from %s",
@@ -950,7 +860,8 @@ hwmp_recv_prep(struct ieee80211vap *vap,
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt = NULL;
+ struct ieee80211_mesh_route *rt = NULL;
+ struct ieee80211_hwmp_route *hr;
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp;
struct mbuf *m, *next;
@@ -989,14 +900,14 @@ hwmp_recv_prep(struct ieee80211vap *vap,
hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep);
}
- rt = hwmp_rt_find(vap, prep->prep_origaddr);
+ rt = ieee80211_mesh_rt_find(vap, prep->prep_origaddr);
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);
+ rt = ieee80211_mesh_rt_add(vap, prep->prep_origaddr,
+ sizeof(struct ieee80211_hwmp_route));
IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2);
rt->rt_nhops = prep->prep_hopcount;
rt->rt_lifetime = prep->prep_lifetime;
@@ -1005,7 +916,8 @@ hwmp_recv_prep(struct ieee80211vap *vap,
}
return;
}
- if (prep->prep_targetseq == rt->rt_seq) {
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+ if (prep->prep_targetseq == hr->hr_seq) {
int useprep = 0;
/*
* Check if we already have a path to this node.
@@ -1093,18 +1005,20 @@ ieee80211_hwmp_peerdown(struct ieee80211
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_meshperr_ie perr;
- struct ieee80211_hwmp_route *rt;
+ struct ieee80211_mesh_route *rt;
+ struct ieee80211_hwmp_route *hr;
- rt = hwmp_rt_find(vap, ni->ni_macaddr);
+ rt = ieee80211_mesh_rt_find(vap, ni->ni_macaddr);
if (rt == NULL)
return;
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"%s", "deleting route entry");
perr.perr_mode = 0;
perr.perr_ndests = 1;
IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest);
- PERR_DSEQ(0) = rt->rt_seq;
- hwmp_rt_del(vap, ni->ni_macaddr);
+ PERR_DSEQ(0) = hr->hr_seq;
+ ieee80211_mesh_rt_del(vap, ni->ni_macaddr);
hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
}
#undef PERR_DADDR
@@ -1118,7 +1032,8 @@ hwmp_recv_perr(struct ieee80211vap *vap,
const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr)
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
- struct ieee80211_hwmp_route *rt = NULL;
+ struct ieee80211_mesh_route *rt = NULL;
+ struct ieee80211_hwmp_route *hr;
struct ieee80211_meshperr_ie pperr;
int i, forward = 0;
@@ -1134,11 +1049,13 @@ hwmp_recv_perr(struct ieee80211vap *vap,
* Find all routing entries that match and delete them.
*/
for (i = 0; i < perr->perr_ndests; i++) {
- rt = hwmp_rt_find(vap, PERR_DADDR(i));
+ rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i));
if (rt == NULL)
continue;
- if (PERR_DSEQ(i) >= rt->rt_seq) {
- hwmp_rt_del(vap, rt->rt_dest);
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+ struct ieee80211_hwmp_route);
+ if (PERR_DSEQ(i) >= hr->hr_seq) {
+ ieee80211_mesh_rt_del(vap, rt->rt_dest);
rt = NULL;
forward = 1;
}
@@ -1191,21 +1108,25 @@ hwmp_recv_rann(struct ieee80211vap *vap,
const struct ieee80211_frame *wh, const struct ieee80211_meshrann_ie *rann)
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
- struct ieee80211_hwmp_route *rt = NULL;
+ struct ieee80211_mesh_route *rt = NULL;
+ struct ieee80211_hwmp_route *hr;
struct ieee80211_meshrann_ie prann;
if (ni == vap->iv_bss ||
ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
return;
- rt = hwmp_rt_find(vap, rann->rann_addr);
+ rt = ieee80211_mesh_rt_find(vap, rann->rann_addr);
/*
* Discover the path to the root mesh STA.
* If we already know it, propagate the RANN element.
*/
- if (rt == NULL)
+ if (rt == NULL) {
ieee80211_hwmp_discover(vap, rann->rann_addr, NULL);
- else if (rann->rann_seq > rt->rt_seq && rann->rann_ttl > 1 &&
+ return;
+ }
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+ if (rann->rann_seq > hr->hr_seq && rann->rann_ttl > 1 &&
(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) {
memcpy(&prann, rann, sizeof(prann));
prann.rann_hopcount += 1;
@@ -1244,10 +1165,11 @@ ieee80211_hwmp_discover(struct ieee80211
const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
{
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt = NULL;
+ struct ieee80211_mesh_route *rt = NULL;
+ struct ieee80211_hwmp_route *hr;
struct ieee80211_meshpreq_ie preq;
struct ieee80211_node *ni;
- int sendpreq = 0, unknowndst = 0;
+ int sendpreq = 0;
KASSERT(vap->iv_opmode == IEEE80211_M_MBSS,
("not a mesh vap, opmode %d", vap->iv_opmode));
@@ -1257,25 +1179,25 @@ ieee80211_hwmp_discover(struct ieee80211
ni = NULL;
if (!IEEE80211_IS_MULTICAST(dest)) {
- rt = hwmp_rt_find(vap, dest);
+ rt = ieee80211_mesh_rt_find(vap, dest);
if (rt == NULL) {
- rt = hwmp_rt_add(vap, dest);
+ rt = ieee80211_mesh_rt_add(vap, dest,
+ sizeof(struct ieee80211_hwmp_route));
if (rt == NULL) {
/* XXX stat+msg */
goto done;
}
}
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+ struct ieee80211_hwmp_route);
if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr)) {
- rt->rt_seq = ++hs->hs_seq;
- rt->rt_preqid = ++hs->hs_preqid;
+ hr->hr_seq = ++hs->hs_seq;
+ hr->hr_preqid = ++hs->hs_preqid;
rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
rt->rt_lifetime =
timeval2msecs(ieee80211_hwmp_pathtimeout);
/* XXX check preq retries */
sendpreq = 1;
- unknowndst = 1;
- }
- if (sendpreq) {
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, dest,
"%s", "initiating path discovery");
/*
@@ -1284,9 +1206,9 @@ ieee80211_hwmp_discover(struct ieee80211
preq.preq_flags = 0;
preq.preq_hopcount = 0;
preq.preq_ttl = hs->hs_ttl;
- preq.preq_id = rt->rt_preqid;
+ preq.preq_id = hr->hr_preqid;
IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr);
- preq.preq_origseq = rt->rt_seq;
+ preq.preq_origseq = hr->hr_seq;
preq.preq_lifetime = rt->rt_lifetime;
preq.preq_metric = rt->rt_metric;
preq.preq_tcount = 1;
@@ -1296,11 +1218,8 @@ ieee80211_hwmp_discover(struct ieee80211
PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_TO;
if (ieee80211_hwmp_replyforward)
PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_RF;
- if (unknowndst) {
- PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN;
- PREQ_TSEQ(0) = 0;
- } else
- PREQ_TSEQ(0) = rt->rt_seq;
+ PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN;
+ PREQ_TSEQ(0) = 0;
/* XXX check return value */
hwmp_send_preq(vap->iv_bss, vap->iv_myaddr,
broadcastaddr, &preq);
@@ -1336,55 +1255,22 @@ done:
#undef PREQ_TADDR
#undef PREQ_TSEQ
-/*
- * Iterate the forwarding information table and locate the
- * next hop.
- */
-struct ieee80211_node *
-ieee80211_hwmp_find_txnode(struct ieee80211vap *vap,
- const uint8_t dest[IEEE80211_ADDR_LEN])
-{
- struct ieee80211_hwmp_route *rt;
-
- rt = hwmp_rt_find(vap, dest);
- if (rt == NULL)
- return NULL;
- return ieee80211_find_txnode(vap, rt->rt_nexthop);
-}
-
-int
-ieee80211_hwmp_checkpseq(struct ieee80211vap *vap,
- const uint8_t source[IEEE80211_ADDR_LEN], uint32_t seq)
-{
- struct ieee80211_hwmp_route *rt;
-
- rt = hwmp_rt_find(vap, source);
- if (rt == NULL) {
- rt = hwmp_rt_add(vap, source);
- rt->rt_lastpseq = seq;
- return 0;
- }
- if (IEEE80211_MESH_SEQ_GEQ(rt->rt_lastpseq, seq)) {
- return 1;
- } else {
- rt->rt_lastpseq = seq;
- return 0;
- }
-}
-
static int
hwmp_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_route *rt;
+#if 0
+ struct ieee80211_mesh_route *rt;
size_t len, off;
uint8_t *p;
+#endif
int error;
if (vap->iv_opmode != IEEE80211_M_MBSS)
return ENOSYS;
error = 0;
switch (ireq->i_type) {
+#if 0
case IEEE80211_IOC_HWMP_CMD:
switch (ireq->i_val) {
case IEEE80211_HWMP_CMD_LIST:
@@ -1421,6 +1307,7 @@ hwmp_ioctl_get80211(struct ieee80211vap
return ENOSYS;
}
break;
+#endif
case IEEE80211_IOC_HWMP_ROOTMODE:
ireq->i_val = hs->hs_rootmode;
break;
@@ -1447,6 +1334,7 @@ hwmp_ioctl_set80211(struct ieee80211vap
return ENOSYS;
error = 0;
switch (ireq->i_type) {
+#if 0
case IEEE80211_IOC_HWMP_CMD:
switch (ireq->i_val) {
case IEEE80211_HWMP_CMD_LIST:
@@ -1464,6 +1352,7 @@ hwmp_ioctl_set80211(struct ieee80211vap
return ENOSYS;
}
break;
+#endif
case IEEE80211_IOC_HWMP_ROOTMODE:
if (ireq->i_val < 0 || ireq->i_val > 3)
return EINVAL;
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.h Mon Jul 6 09:31:04 2009 (r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.h Mon Jul 6 10:40:46 2009 (r195404)
@@ -31,38 +31,25 @@
#ifndef _NET80211_IEEE80211_HWMP_H_
#define _NET80211_IEEE80211_HWMP_H_
+#ifdef _KERNEL
/* HWMP sequence numbers are 32 bit, so we can't use ieee80211_seq */
typedef uint32_t ieee80211_hwmp_seq;
-
+#define IEEE80211_HWMP_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0)
+#define IEEE80211_HWMP_SEQ_GEQ(a, b) ((int32_t)((a)-(b)) >= 0)
/*
- * HWMP Forwarding Information table, part of each VAP.
+ * Private extension of ieee80211_mesh_route.
*/
struct ieee80211_hwmp_route {
- TAILQ_ENTRY(ieee80211_hwmp_route) rt_next;
- uint8_t rt_dest[IEEE80211_ADDR_LEN];
- ieee80211_hwmp_seq rt_seq; /* HWMP sequence number */
- ieee80211_hwmp_seq rt_preqid; /* Last PREQ ID seen */
- uint8_t rt_nexthop[IEEE80211_ADDR_LEN];
- uint32_t rt_metric; /* Path Metric */
- uint32_t rt_nhops; /* Number of Hops */
- uint32_t rt_lifetime;
- int rt_preqretries;
- uint32_t rt_lastpseq; /* last mesh seq number
- from this node */
+ ieee80211_hwmp_seq hr_seq; /* HWMP sequence number */
+ ieee80211_hwmp_seq hr_preqid; /* Last PREQ ID seen */
+ int hr_preqretries;
};
-
-#ifdef _KERNEL
-
-MALLOC_DECLARE(M_80211_HWMP);
-
struct ieee80211_hwmp_state {
- TAILQ_HEAD(, ieee80211_hwmp_route) hs_routes;
ieee80211_hwmp_seq hs_seq; /* next seq to be used */
ieee80211_hwmp_seq hs_preqid; /* next PREQ ID to be used */
struct timeval hs_lastpreq; /* last time we sent a PREQ */
struct timeval hs_lastprep; /* last time we sent a PREP */
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 */
@@ -78,11 +65,6 @@ void ieee80211_hwmp_recv_action(struct
struct ieee80211_node *
ieee80211_hwmp_discover(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN], struct mbuf *);
-struct ieee80211_node *
- ieee80211_hwmp_find_txnode(struct ieee80211vap *vap,
- const uint8_t dest[IEEE80211_ADDR_LEN]);
-int ieee80211_hwmp_checkpseq(struct ieee80211vap *,
- const uint8_t [IEEE80211_ADDR_LEN], uint32_t);
void ieee80211_hwmp_peerdown(struct ieee80211_node *);
#endif /* _KERNEL */
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Jul 6 09:31:04 2009 (r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Jul 6 10:40:46 2009 (r195404)
@@ -64,11 +64,19 @@ __FBSDID("$FreeBSD$");
static void mesh_vattach(struct ieee80211vap *);
static int mesh_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static inline void mesh_linkchange(struct ieee80211_node *,
- enum ieee80211_mesh_mlstate);
+ enum ieee80211_mesh_mlstate);
+static void mesh_checkid(void *, struct ieee80211_node *);
static uint32_t mesh_generateid(struct ieee80211vap *);
+static int mesh_checkpseq(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN], uint32_t);
+static struct ieee80211_node *
+ mesh_find_txnode(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN]);
+static void mesh_forward(struct ieee80211vap *, struct mbuf *,
+ const struct ieee80211_meshcntl *);
static int mesh_input(struct ieee80211_node *, struct mbuf *, int, int);
static void mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
- int, int);
+ int, int);
static inline void mesh_peer_timeout_setup(struct ieee80211_node *);
static void mesh_peer_timeout_backoff(struct ieee80211_node *);
static void mesh_peer_timeout_cb(void *);
@@ -86,9 +94,6 @@ static const int ieee80211_mesh_confirmt
#define CONFIRM_TIMEOUT msecs_to_ticks(ieee80211_mesh_confirmtimeout)
static const int ieee80211_mesh_maxretries = 2;
-SYSCTL_NODE(_net_wlan, OID_AUTO, mesh, CTLFLAG_RD, 0,
- "IEEE 802.11s parameters");
-
#define IEEE80211_MESH_DEFAULT_TTL 31
static ieee80211_recv_action_func mesh_recv_action_meshpeering_open;
@@ -103,6 +108,97 @@ static ieee80211_send_action_func mesh_s
static ieee80211_send_action_func mesh_send_action_meshlink_request;
static ieee80211_send_action_func mesh_send_action_meshlink_reply;
+#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock)
+#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock)
+
+MALLOC_DEFINE(M_80211_MESH_RT, "80211mesh", "802.11s routing table");
+
+/*
+ * Helper functions to manipulate the Mesh routing table.
+ */
+struct ieee80211_mesh_route *
+ieee80211_mesh_rt_find(struct ieee80211vap *vap,
+ const uint8_t dest[IEEE80211_ADDR_LEN])
+{
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
+ struct ieee80211_mesh_route *rt;
+
+ MESH_RT_LOCK(ms);
+ TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
+ if (IEEE80211_ADDR_EQ(dest, rt->rt_dest)) {
+ MESH_RT_UNLOCK(ms);
+ return rt;
+ }
+ }
+ MESH_RT_UNLOCK(ms);
+ return NULL;
+}
+
+struct ieee80211_mesh_route *
+ieee80211_mesh_rt_add(struct ieee80211vap *vap,
+ const uint8_t dest[IEEE80211_ADDR_LEN], size_t privlen)
+{
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
+ struct ieee80211_mesh_route *rt;
+ static const uint8_t broadcastaddr[IEEE80211_ADDR_LEN] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ KASSERT(ieee80211_mesh_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_mesh_route), M_80211_MESH_RT,
+ M_NOWAIT | M_ZERO);
+ IEEE80211_ADDR_COPY(rt->rt_dest, dest);
+ rt->rt_priv = malloc(privlen, M_80211_MESH_RT, M_NOWAIT | M_ZERO);
+ MESH_RT_LOCK(ms);
+ TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next);
+ MESH_RT_UNLOCK(ms);
+ return rt;
+}
+
+void
+ieee80211_mesh_rt_del(struct ieee80211vap *vap,
+ const uint8_t dest[IEEE80211_ADDR_LEN])
+{
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
+ struct ieee80211_mesh_route *rt, *next;
+
+ KASSERT(ms != NULL, ("no HWMP state"));
+ MESH_RT_LOCK(ms);
+ TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
+ if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) {
+ TAILQ_REMOVE(&ms->ms_routes, rt, rt_next);
+ free(rt->rt_priv, M_80211_MESH_RT);
+ free(rt, M_80211_MESH_RT);
+ MESH_RT_UNLOCK(ms);
+ return;
+ }
+ }
+ MESH_RT_UNLOCK(ms);
+}
+
+void
+ieee80211_mesh_rt_flush(struct ieee80211vap *vap)
+{
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
+ struct ieee80211_mesh_route *rt, *next;
+
+ if (ms == NULL)
+ return;
+ MESH_RT_LOCK(ms);
+ TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
+ TAILQ_REMOVE(&ms->ms_routes, rt, rt_next);
+ free(rt->rt_priv, M_80211_MESH_RT);
+ free(rt, M_80211_MESH_RT);
+ }
+ MESH_RT_UNLOCK(ms);
+}
+
+
static void
ieee80211_mesh_init(void)
{
@@ -173,8 +269,12 @@ mesh_vdetach_peers(void *arg, struct iee
static void
mesh_vdetach(struct ieee80211vap *vap)
{
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
+
ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_vdetach_peers,
NULL);
+ ieee80211_mesh_rt_flush(vap);
+ mtx_destroy(&ms->ms_rt_lock);
ieee80211_hwmp_vdetach(vap);
free(vap->iv_mesh, M_80211_VAP);
vap->iv_mesh = NULL;
@@ -199,6 +299,8 @@ mesh_vattach(struct ieee80211vap *vap)
ms->ms_seq = 0;
ms->ms_flags = (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_FWD);
ms->ms_ttl = IEEE80211_MESH_DEFAULT_TTL;
+ TAILQ_INIT(&ms->ms_routes);
+ mtx_init(&ms->ms_rt_lock, "MBSS", "802.11s routing table", MTX_DEF);
ieee80211_hwmp_vattach(vap);
}
@@ -223,6 +325,9 @@ mesh_newstate(struct ieee80211vap *vap,
if (ostate != IEEE80211_S_SCAN)
ieee80211_cancel_scan(vap); /* background scan */
ni = vap->iv_bss; /* NB: no reference held */
+ /* Flush the routing table */
+ if (nstate != INIT && ostate == INIT)
+ ieee80211_mesh_rt_flush(vap);
switch (nstate) {
case IEEE80211_S_INIT:
switch (ostate) {
@@ -426,6 +531,45 @@ mesh_generateid(struct ieee80211vap *vap
}
/*
+ * Verifies if we already received this packet by checking its
+ * sequence number.
+ */
+static int
+mesh_checkpseq(struct ieee80211vap *vap,
+ const uint8_t source[IEEE80211_ADDR_LEN], uint32_t seq)
+{
+ struct ieee80211_mesh_route *rt;
+
+ rt = ieee80211_mesh_rt_find(vap, source);
+ if (rt == NULL) {
+ rt = ieee80211_mesh_rt_add(vap, source, 12);
+ rt->rt_lastmseq = seq;
+ return 0;
+ }
+ if (IEEE80211_MESH_SEQ_GEQ(rt->rt_lastmseq, seq)) {
+ return 1;
+ } else {
+ rt->rt_lastmseq = seq;
+ return 0;
+ }
+}
+
+/*
+ * Iterate the routing table and locate the next hop.
+ */
+static struct ieee80211_node *
+mesh_find_txnode(struct ieee80211vap *vap,
+ const uint8_t dest[IEEE80211_ADDR_LEN])
+{
+ struct ieee80211_mesh_route *rt;
+
+ rt = ieee80211_mesh_rt_find(vap, dest);
+ if (rt == NULL)
+ return NULL;
+ return ieee80211_find_txnode(vap, rt->rt_nexthop);
+}
+
+/*
* Forward the specified frame.
* Decrement the TTL and set TA to our MAC address.
*/
@@ -491,7 +635,7 @@ mesh_forward(struct ieee80211vap *vap, s
params.ibp_try0 = 1;
mcopy->m_flags |= M_MCAST;
} else {
- ni = ieee80211_hwmp_find_txnode(vap, whcopy->i_addr3);
+ ni = mesh_find_txnode(vap, whcopy->i_addr3);
if (ni == NULL) {
IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
"%s", "frame not fwd'd, no path");
@@ -679,7 +823,7 @@ mesh_input(struct ieee80211_node *ni, st
vap->iv_stats.is_rx_wrongbss++; /* XXX kinda */
goto out;
}
- if (ieee80211_hwmp_checkpseq(vap, addr, seq) != 0) {
+ if (mesh_checkpseq(vap, addr, seq) != 0) {
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
addr, "data", "duplicate mesh seqno %u ttl %u",
seq, mc->mc_ttl);
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.h Mon Jul 6 09:31:04 2009 (r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.h Mon Jul 6 10:40:46 2009 (r195404)
@@ -371,7 +371,24 @@ struct ieee80211_meshcntl_ae11 {
uint8_t mc_addr6[IEEE80211_ADDR_LEN];
} __packed;
+struct ieee80211req_mesh_routes {
+/* XXX TBD */
+};
+
#ifdef _KERNEL
+MALLOC_DECLARE(M_80211_MESH_RT);
+struct ieee80211_mesh_route {
+ TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
+ uint8_t rt_dest[IEEE80211_ADDR_LEN];
+ uint8_t rt_nexthop[IEEE80211_ADDR_LEN];
+ uint32_t rt_metric; /* path metric */
+ uint16_t rt_nhops; /* number of hops */
+ uint32_t rt_lifetime;
+ uint32_t rt_lastmseq;/* last seq# seen from this dest */
+ void *rt_priv; /* pointer to private data */
+};
+#define IEEE80211_MESH_ROUTE_PRIV(rt, cast) (cast *)rt->rt_priv
+
struct ieee80211_mesh_proto {
/* Action frame categories to intercept */
uint8_t mpr_actpath;
@@ -405,11 +422,23 @@ struct ieee80211_mesh_state {
#define IEEE80211_MESHFLAGS_PORTAL 0x02 /* mesh portal role */
#define IEEE80211_MESHFLAGS_FWD 0x04 /* forward packets */
uint8_t ms_flags;
+ struct mtx ms_rt_lock;
+ TAILQ_HEAD(, ieee80211_mesh_route) ms_routes;
struct ieee80211_mesh_proto *ms_proto;
};
void ieee80211_mesh_attach(struct ieee80211com *);
void ieee80211_mesh_detach(struct ieee80211com *);
+struct ieee80211_mesh_route *
+ ieee80211_mesh_rt_find(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN]);
+struct ieee80211_mesh_route *
+ ieee80211_mesh_rt_add(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN], size_t);
+void ieee80211_mesh_rt_del(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN]);
+void ieee80211_mesh_rt_flush(struct ieee80211vap *);
+
uint8_t * ieee80211_add_meshpeerver(uint8_t *, struct ieee80211vap *);
uint8_t * ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
uint8_t * ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
More information about the svn-src-projects
mailing list