svn commit: r195406 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Mon Jul 6 12:20:00 UTC 2009
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 *,
More information about the svn-src-projects
mailing list