Date: Mon, 6 Jul 2009 10:40:46 +0000 (UTC) From: Rui Paulo <rpaulo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r195404 - projects/mesh11s/sys/net80211 Message-ID: <200907061040.n66AekpV079729@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907061040.n66AekpV079729>