Date: Tue, 1 May 2012 16:13:22 +0000 (UTC) From: Monthadar Al Jaberi <monthadar@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r234891 - head/sys/net80211 Message-ID: <201205011613.q41GDMtT034114@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: monthadar Date: Tue May 1 16:13:22 2012 New Revision: 234891 URL: http://svn.freebsd.org/changeset/base/234891 Log: RANN update * Introduced a new HWMP sysctl, Root Confirmation Interval; * Added hr_lastrootconf to hwmp_route, is for ratecheck for a specific ROOT; * We missed reading RANN.interval subfield from a RANN frame before; * Updated hwmp_recv_rann according to amendment, see comments; Approved by: adrian Modified: head/sys/net80211/ieee80211_hwmp.c head/sys/net80211/ieee80211_mesh.h Modified: head/sys/net80211/ieee80211_hwmp.c ============================================================================== --- head/sys/net80211/ieee80211_hwmp.c Tue May 1 16:12:39 2012 (r234890) +++ head/sys/net80211/ieee80211_hwmp.c Tue May 1 16:13:22 2012 (r234891) @@ -157,6 +157,7 @@ struct ieee80211_hwmp_route { ieee80211_hwmp_seq hr_preqid; /* last PREQ ID seen from dst */ ieee80211_hwmp_seq hr_origseq; /* seq. no. on our latest PREQ*/ struct timeval hr_lastpreq; /* last time we sent a PREQ */ + struct timeval hr_lastrootconf; /* last sent PREQ root conf */ int hr_preqretries; /* number of discoveries */ int hr_lastdiscovery; /* last discovery in ticks */ }; @@ -199,6 +200,11 @@ static int ieee80211_hwmp_rannint = -1; SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, rannint, CTLTYPE_INT | CTLFLAG_RW, &ieee80211_hwmp_rannint, 0, ieee80211_sysctl_msecs_ticks, "I", "root announcement interval (ms)"); +static struct timeval ieee80211_hwmp_rootconfint = { 0, 0 }; +static int ieee80211_hwmp_rootconfint_internal = -1; +SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, rootconfint, CTLTYPE_INT | CTLFLAG_RD, + &ieee80211_hwmp_rootconfint_internal, 0, ieee80211_sysctl_msecs_ticks, "I", + "root confirmation interval (ms) (read-only)"); #define IEEE80211_HWMP_DEFAULT_MAXHOPS 31 @@ -228,6 +234,7 @@ ieee80211_hwmp_init(void) ieee80211_hwmp_roottimeout = msecs_to_ticks(5*1000); ieee80211_hwmp_rootint = msecs_to_ticks(2*1000); ieee80211_hwmp_rannint = msecs_to_ticks(1*1000); + ieee80211_hwmp_rootconfint_internal = msecs_to_ticks(2*1000); ieee80211_hwmp_maxpreq_retries = 3; /* * (TU): A measurement of time equal to 1024 μs, @@ -236,6 +243,13 @@ ieee80211_hwmp_init(void) ieee80211_hwmp_net_diameter_traversaltime = msecs_to_ticks(512); /* + * NB: I dont know how to make SYSCTL_PROC that calls ms to ticks + * and return a struct timeval... + */ + ieee80211_hwmp_rootconfint.tv_usec = + ieee80211_hwmp_rootconfint_internal * 1000; + + /* * Register action frame handler. */ ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESH, @@ -555,6 +569,7 @@ hwmp_recv_action_meshpath(struct ieee802 } memcpy(&rann, mrann, sizeof(rann)); rann.rann_seq = LE_READ_4(&mrann->rann_seq); + rann.rann_interval = LE_READ_4(&mrann->rann_interval); rann.rann_metric = LE_READ_4(&mrann->rann_metric); hwmp_recv_rann(vap, ni, wh, &rann); found++; @@ -873,6 +888,7 @@ hwmp_rootmode_rann_cb(void *arg) rann.rann_ttl = ms->ms_ttl; IEEE80211_ADDR_COPY(rann.rann_addr, vap->iv_myaddr); rann.rann_seq = ++hs->hs_seq; + rann.rann_interval = ieee80211_hwmp_rannint; rann.rann_metric = IEEE80211_MESHLMETRIC_INITIALVAL; vap->iv_stats.is_hwmp_rootrann++; @@ -1684,7 +1700,9 @@ hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_hwmp_state *hs = vap->iv_hwmp; struct ieee80211_mesh_route *rt = NULL; struct ieee80211_hwmp_route *hr; + struct ieee80211_meshpreq_ie preq; struct ieee80211_meshrann_ie prann; + uint32_t metric = 0; if (ni == vap->iv_bss || ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED || @@ -1692,27 +1710,74 @@ hwmp_recv_rann(struct ieee80211vap *vap, return; 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 && rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) { + hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); + + /* Acceptance criteria: if RANN.seq < stored seq, discard RANN */ + if (HWMP_SEQ_LT(rann->rann_seq, hr->hr_seq)) { + IEEE80211_DISCARD(vap, IEEE80211_MSG_HWMP, wh, NULL, + "RANN seq %u < %u", rann->rann_seq, hr->hr_seq); + return; + } + + /* Acceptance criteria: if RANN.seq == stored seq AND + * RANN.metric > stored metric, discard RANN */ + if (HWMP_SEQ_EQ(rann->rann_seq, hr->hr_seq) && + rann->rann_metric > rt->rt_metric) { + IEEE80211_DISCARD(vap, IEEE80211_MSG_HWMP, wh, NULL, + "RANN metric %u > %u", rann->rann_metric, rt->rt_metric); + return; + } + } + + /* RANN ACCEPTED */ + + ieee80211_hwmp_rannint = rann->rann_interval; /* XXX: mtx lock? */ + metric = rann->rann_metric + ms->ms_pmetric->mpm_metric(ni); + if (rt == NULL) { - hwmp_discover(vap, rann->rann_addr, NULL); - return; + rt = ieee80211_mesh_rt_add(vap, rann->rann_addr); + if (rt == NULL) { + IEEE80211_DISCARD(vap, IEEE80211_MSG_HWMP, wh, NULL, + "unable to add mac for RANN root %6D", + rann->rann_addr, ":"); + vap->iv_stats.is_mesh_rtaddfailed++; + return; + } } hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (HWMP_SEQ_GT(rann->rann_seq, hr->hr_seq)) { + /* discovery timeout */ + ieee80211_mesh_rt_update(rt, + ticks_to_msecs(ieee80211_hwmp_roottimeout)); + + preq.preq_flags = IEEE80211_MESHPREQ_FLAGS_AM; + preq.preq_hopcount = 0; + preq.preq_ttl = ms->ms_ttl; + preq.preq_id = 0; /* reserved */ + IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); + preq.preq_origseq = ++hs->hs_seq; + preq.preq_lifetime = ieee80211_hwmp_roottimeout; + preq.preq_metric = IEEE80211_MESHLMETRIC_INITIALVAL; + preq.preq_tcount = 1; + preq.preq_targets[0].target_flags = IEEE80211_MESHPREQ_TFLAGS_TO; + /* NB: IEEE80211_MESHPREQ_TFLAGS_USN = 0 implicitly implied */ + IEEE80211_ADDR_COPY(preq.preq_targets[0].target_addr, rann->rann_addr); + preq.preq_targets[0].target_seq = rann->rann_seq; + /* XXX: if rootconfint have not passed, we built this preq in vain */ + hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, wh->i_addr2, &preq, + &hr->hr_lastrootconf, &ieee80211_hwmp_rootconfint); + + /* propagate a RANN */ + if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID && + rann->rann_ttl > 1 && + ms->ms_flags & IEEE80211_MESHFLAGS_FWD) { hr->hr_seq = rann->rann_seq; - if (rann->rann_ttl > 1 && - rann->rann_hopcount < hs->hs_maxhops && - (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { - memcpy(&prann, rann, sizeof(prann)); - prann.rann_hopcount += 1; - prann.rann_ttl -= 1; - prann.rann_metric += ms->ms_pmetric->mpm_metric(ni); - hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, - broadcastaddr, &prann); - } + memcpy(&prann, rann, sizeof(prann)); + prann.rann_hopcount += 1; + prann.rann_ttl -= 1; + prann.rann_metric += ms->ms_pmetric->mpm_metric(ni); + hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, + broadcastaddr, &prann); } } Modified: head/sys/net80211/ieee80211_mesh.h ============================================================================== --- head/sys/net80211/ieee80211_mesh.h Tue May 1 16:12:39 2012 (r234890) +++ head/sys/net80211/ieee80211_mesh.h Tue May 1 16:13:22 2012 (r234891) @@ -426,7 +426,7 @@ struct ieee80211_mesh_route { uint32_t rt_metric; /* path metric */ uint16_t rt_nhops; /* number of hops */ uint16_t rt_flags; -#define IEEE80211_MESHRT_FLAGS_VALID 0x01 /* patch discovery complete */ +#define IEEE80211_MESHRT_FLAGS_VALID 0x01 /* path discovery complete */ #define IEEE80211_MESHRT_FLAGS_PROXY 0x02 /* proxy entry */ uint32_t rt_lifetime; /* route timeout */ uint32_t rt_lastmseq; /* last seq# seen dest */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205011613.q41GDMtT034114>