Date: Mon, 6 Jul 2009 12:20:00 +0000 (UTC) From: Rui Paulo <rpaulo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r195406 - projects/mesh11s/sys/net80211 Message-ID: <200907061220.n66CK0aJ081806@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rpaulo Date: Mon Jul 6 12:19:59 2009 New Revision: 195406 URL: http://svn.freebsd.org/changeset/base/195406 Log: Modularize path metric code. Sponsored by: The FreeBSD Foundation Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c 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 11:46:18 2009 (r195405) +++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Mon Jul 6 12:19:59 2009 (r195406) @@ -757,7 +757,8 @@ hwmp_recv_preq(struct ieee80211vap *vap, */ ppreq.preq_hopcount += 1; ppreq.preq_ttl -= 1; - ppreq.preq_metric += ieee80211_airtime_calc(ni); + ppreq.preq_metric += + ms->ms_pmetric->mpm_metric(ni); /* * Set TO and unset RF bits because we are going * to send a PREP next. @@ -787,7 +788,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, prep.prep_targetseq = hr->hr_seq; prep.prep_lifetime = preq->preq_lifetime; prep.prep_metric = rt->rt_metric + - ieee80211_airtime_calc(ni); + ms->ms_pmetric->mpm_metric(ni); IEEE80211_ADDR_COPY(&prep.prep_origaddr, PREQ_TADDR(0)); prep.prep_origseq = hs->hs_seq++; @@ -814,7 +815,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, ether_sprintf(preq->preq_origaddr)); ppreq.preq_hopcount += 1; ppreq.preq_ttl -= 1; - ppreq.preq_metric += ieee80211_airtime_calc(ni); + ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni); hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr, &ppreq); } @@ -895,7 +896,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, memcpy(&pprep, prep, sizeof(pprep)); pprep.prep_hopcount += 1; pprep.prep_ttl -= 1; - pprep.prep_metric += ieee80211_airtime_calc(ni); + pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni); IEEE80211_ADDR_COPY(pprep.prep_origaddr, vap->iv_myaddr); hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep); } @@ -1131,7 +1132,7 @@ hwmp_recv_rann(struct ieee80211vap *vap, memcpy(&prann, rann, sizeof(prann)); prann.rann_hopcount += 1; prann.rann_ttl -= 1; - prann.rann_metric += ieee80211_airtime_calc(ni); + prann.rann_metric += ms->ms_pmetric->mpm_metric(ni); hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &prann); } Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Jul 6 11:46:18 2009 (r195405) +++ projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Jul 6 12:19:59 2009 (r195406) @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <net80211/ieee80211_input.h> #include <net80211/ieee80211_mesh.h> +static int mesh_select_proto_metric(struct ieee80211vap *, const char *); static void mesh_vattach(struct ieee80211vap *); static int mesh_newstate(struct ieee80211vap *, enum ieee80211_state, int); static inline void mesh_linkchange(struct ieee80211_node *, @@ -84,6 +85,7 @@ static inline void mesh_peer_timeout_sto static int mesh_verify_meshpeerver(struct ieee80211vap *, const uint8_t *); static int mesh_verify_meshid(struct ieee80211vap *, const uint8_t *); static int mesh_verify_meshconf(struct ieee80211vap *, const uint8_t *); +uint32_t mesh_airtime_calc(struct ieee80211_node *); /* timeout values in miliseconds */ static const int ieee80211_mesh_retrytimeout = 40; @@ -108,6 +110,15 @@ 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; +static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = { + .mpm_descr = "AIRTIME", + .mpm_ie = IEEE80211_MESHCONF_AIRTIME, + .mpm_metric = mesh_airtime_calc, +}; + +static struct ieee80211_mesh_proto_path mesh_proto_paths[4]; +static struct ieee80211_mesh_proto_metric mesh_proto_metrics[4]; + #define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock) #define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock) @@ -198,10 +209,71 @@ ieee80211_mesh_rt_flush(struct ieee80211 MESH_RT_UNLOCK(ms); } +#define N(a) (sizeof(a) / sizeof(a[0])) +int +ieee80211_mesh_register_proto_path(const struct ieee80211_mesh_proto_path *mpp) +{ + int i, firstempty = -1; + static const uint8_t emptyie[4] = { 0, 0, 0, 0 }; + + for (i = 0; i < N(mesh_proto_paths); i++) { + if (memcmp(mpp->mpp_ie, mesh_proto_paths[i].mpp_ie, 4) == 0) + return EEXIST; + if (memcmp(mesh_proto_paths[i].mpp_ie, emptyie, 4) == 0 && + firstempty == -1) + firstempty = i; + } + if (firstempty < 0) + return ENOSPC; + memcpy(&mesh_proto_paths[firstempty], mpp, sizeof(*mpp)); + return 0; +} + +int +ieee80211_mesh_register_proto_metric(const struct + ieee80211_mesh_proto_metric *mpm) +{ + int i, firstempty = -1; + static const uint8_t emptyie[4] = { 0, 0, 0, 0 }; + + for (i = 0; i < N(mesh_proto_metrics); i++) { + if (memcmp(mpm->mpm_ie, mesh_proto_metrics[i].mpm_ie, 4) == 0) + return EEXIST; + if (memcmp(mesh_proto_metrics[i].mpm_ie, emptyie, 4) == 0 && + firstempty == -1) + firstempty = i; + } + if (firstempty < 0) + return ENOSPC; + memcpy(&mesh_proto_metrics[firstempty], mpm, sizeof(*mpm)); + return 0; +} + +static int +mesh_select_proto_metric(struct ieee80211vap *vap, const char *name) +{ + struct ieee80211_mesh_state *ms = vap->iv_mesh; + int i; + + for (i = 0; i < N(mesh_proto_metrics); i++) { + if (strcmp(mesh_proto_metrics[i].mpm_descr, name) == 0) { + ms->ms_pmetric = &mesh_proto_metrics[i]; + if (vap->iv_state == IEEE80211_S_RUN) + vap->iv_newstate(vap, IEEE80211_S_INIT, 0); + return 0; + } + } + return ENOENT; +} + +#undef N static void ieee80211_mesh_init(void) { + memset(mesh_proto_paths, 0, sizeof(mesh_proto_paths)); + memset(mesh_proto_metrics, 0, sizeof(mesh_proto_metrics)); + /* * Register action frame handlers. */ @@ -234,6 +306,12 @@ ieee80211_mesh_init(void) ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC, IEEE80211_ACTION_MESHLMETRIC_REP, mesh_send_action_meshlink_reply); + + /* + * Register Airtime Link Metric. + */ + ieee80211_mesh_register_proto_metric(&mesh_metric_airtime); + } SYSINIT(wlan_mesh, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_mesh_init, NULL); @@ -284,7 +362,6 @@ static void mesh_vattach(struct ieee80211vap *vap) { struct ieee80211_mesh_state *ms; - vap->iv_newstate = mesh_newstate; vap->iv_input = mesh_input; vap->iv_opdetach = mesh_vdetach; @@ -301,6 +378,7 @@ mesh_vattach(struct ieee80211vap *vap) 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); + mesh_select_proto_metric(vap, "AIRTIME"); ieee80211_hwmp_vattach(vap); } @@ -326,7 +404,7 @@ mesh_newstate(struct ieee80211vap *vap, ieee80211_cancel_scan(vap); /* background scan */ ni = vap->iv_bss; /* NB: no reference held */ /* Flush the routing table */ - if (nstate != INIT && ostate == INIT) + if (nstate != IEEE80211_S_INIT && ostate == IEEE80211_S_INIT) ieee80211_mesh_rt_flush(vap); switch (nstate) { case IEEE80211_S_INIT: @@ -1541,8 +1619,7 @@ mesh_recv_action_meshlmetric_req(struct { uint32_t metric; - /* XXX: check if we are using airtime or aother algorithm */ - metric = ieee80211_airtime_calc(ni); + metric = mesh_airtime_calc(ni); ieee80211_send_action(ni, IEEE80211_ACTION_CAT_MESHLMETRIC, IEEE80211_ACTION_MESHLMETRIC_REP, @@ -2188,7 +2265,7 @@ ieee80211_add_meshpeer(uint8_t *frm, uin + IEEE80211_WEP_MICLEN \ + IEEE80211_CRC_LEN) uint32_t -ieee80211_airtime_calc(struct ieee80211_node *ni) +mesh_airtime_calc(struct ieee80211_node *ni) { #define M_BITS 8 #define S_FACTOR (2 * M_BITS) Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_mesh.h Mon Jul 6 11:46:18 2009 (r195405) +++ projects/mesh11s/sys/net80211/ieee80211_mesh.h Mon Jul 6 12:19:59 2009 (r195406) @@ -389,25 +389,42 @@ struct ieee80211_mesh_route { }; #define IEEE80211_MESH_ROUTE_PRIV(rt, cast) (cast *)rt->rt_priv -struct ieee80211_mesh_proto { - /* Action frame categories to intercept */ - uint8_t mpr_actpath; - uint8_t mpr_actlinkmetric; - /* Values to be sent in the Mesh Configuration IE */ - uint8_t mpr_pathid[4]; - uint8_t mpr_metricid[4]; - uint8_t mpr_congid[4]; - uint8_t mpr_syncid[4]; - uint8_t mpr_authid[4]; - void (*mpr_recv_action)(struct ieee80211vap *, - struct ieee80211_node *, struct mbuf *); - struct ieee80211_node * (*mpr_discover)(struct ieee80211vap *, - uint8_t [IEEE80211_ADDR_LEN], struct mbuf *); - struct ieee80211_node * (*mpr_find_txnode)(struct ieee80211vap *vap, - uint8_t dest[IEEE80211_ADDR_LEN]); - uint32_t (*mpr_linkmetric)(struct ieee80211_node *); - /* XXX needs more methods */ +/* + * Mesh Path Selection Protocol. + */ +struct ieee80211_mesh_proto_path { + char mpp_descr[12]; + uint8_t mpp_ie[4]; + struct ieee80211_node * + (*mpr_discover)(struct ieee80211vap *, + uint8_t [IEEE80211_ADDR_LEN], + struct mbuf *); + size_t mpp_privlen; /* size required in the routing table + for private data */ }; +/* + * Mesh Link Metric Report Protocol. + */ +struct ieee80211_mesh_proto_metric { + char mpm_descr[12]; + uint8_t mpm_ie[4]; + uint32_t (*mpm_metric)(struct ieee80211_node *); +}; + +#ifdef notyet +/* + * Mesh Authentication Protocol. + */ +struct ieee80211_mesh_proto_auth { + uint8_t mpa_ie[4]; +}; + +struct ieee80211_mesh_proto_congestion { +}; + +struct ieee80211_mesh_proto_sync { +}; +#endif typedef uint32_t ieee80211_mesh_seq; #define IEEE80211_MESH_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0) @@ -423,8 +440,10 @@ struct ieee80211_mesh_state { #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; + TAILQ_HEAD(, ieee80211_mesh_route) + ms_routes; + struct ieee80211_mesh_proto_metric + *ms_pmetric; }; void ieee80211_mesh_attach(struct ieee80211com *); void ieee80211_mesh_detach(struct ieee80211com *); @@ -439,12 +458,16 @@ void ieee80211_mesh_rt_del(struct ieee8 const uint8_t [IEEE80211_ADDR_LEN]); void ieee80211_mesh_rt_flush(struct ieee80211vap *); +int ieee80211_mesh_register_proto_path(const + struct ieee80211_mesh_proto_path *); +int ieee80211_mesh_register_proto_metric(const + struct ieee80211_mesh_proto_metric *); + 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 *); uint8_t * ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t, uint16_t); -uint32_t ieee80211_airtime_calc(struct ieee80211_node *); uint8_t * ieee80211_add_meshlmetric(uint8_t *, uint32_t); void ieee80211_mesh_node_init(struct ieee80211vap *,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907061220.n66CK0aJ081806>