From owner-svn-src-projects@FreeBSD.ORG Thu Jul 2 12:41:21 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B820E1065675; Thu, 2 Jul 2009 12:41:21 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A0E898FC0A; Thu, 2 Jul 2009 12:41:21 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n62CfLQX044669; Thu, 2 Jul 2009 12:41:21 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n62CfLkU044665; Thu, 2 Jul 2009 12:41:21 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <200907021241.n62CfLkU044665@svn.freebsd.org> From: Rui Paulo Date: Thu, 2 Jul 2009 12:41:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195284 - projects/mesh11s/sys/net80211 X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Jul 2009 12:41:22 -0000 Author: rpaulo Date: Thu Jul 2 12:41:21 2009 New Revision: 195284 URL: http://svn.freebsd.org/changeset/base/195284 Log: Finish proactive root mode implementation. 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_ioctl.h Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_hwmp.c Thu Jul 2 10:02:10 2009 (r195283) +++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Thu Jul 2 12:41:21 2009 (r195284) @@ -83,6 +83,8 @@ static uint8_t *hwmp_add_meshperr(uint8_ const struct ieee80211_meshperr_ie *); static uint8_t *hwmp_add_meshrann(uint8_t *, const struct ieee80211_meshrann_ie *); +static void hwmp_rootmode_setup(struct ieee80211vap *); +static void hwmp_rootmode_cb(void *); static void hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *, const struct ieee80211_frame *, const struct ieee80211_meshpreq_ie *); static int hwmp_send_preq(struct ieee80211_node *, @@ -121,6 +123,9 @@ static const struct timeval ieee80211_hw #define timeval2msecs(tv) (tv.tv_sec * 1000 + tv.tv_usec / 1000) +#define HWMP_ROOTMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hmwp_rootint)) +#define HWMP_RANNMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hmwp_rannint)) + #define HWMP_LOCK(hs) mtx_lock(&(hs)->hs_lock) #define HWMP_UNLOCK(hs) mtx_unlock(&(hs)->hs_lock) @@ -170,6 +175,10 @@ hwmp_rt_add(struct ieee80211vap *vap, co 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); @@ -233,6 +242,7 @@ ieee80211_hwmp_vattach(struct ieee80211v 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); vap->iv_hwmp = hs; } @@ -242,6 +252,8 @@ ieee80211_hwmp_vdetach(struct ieee80211v struct ieee80211_hwmp_state *hs = vap->iv_hwmp; hwmp_rt_flush(vap); + if (callout_pending(&hs->hs_roottimer)) + callout_stop(&hs->hs_roottimer); mtx_destroy(&hs->hs_lock); free(vap->iv_hwmp, M_80211_HWMP); } @@ -250,10 +262,14 @@ int ieee80211_hwmp_newstate(struct ieee80211vap *vap, enum ieee80211_state ostate, int arg) { enum ieee80211_state nstate = vap->iv_state; + struct ieee80211_hwmp_state *hs = vap->iv_hwmp; /* Flush the table on INIT -> SCAN, e.g. interface down & up */ - if (nstate == IEEE80211_S_SCAN && ostate == IEEE80211_S_INIT) + if (nstate == IEEE80211_S_SCAN && ostate == IEEE80211_S_INIT) { hwmp_rt_flush(vap); + if (callout_pending(&hs->hs_roottimer)) + callout_stop(&hs->hs_roottimer); + } return 0; } @@ -553,7 +569,18 @@ hwmp_add_meshrann(uint8_t *frm, const st return frm; } -#ifdef notyet +static void +hwmp_rootmode_setup(struct ieee80211vap *vap) +{ + struct ieee80211_hwmp_state *hs = vap->iv_hwmp; + + if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) + callout_reset(&hs->hs_roottimer, HWMP_ROOTMODEINT, + hwmp_rootmode_cb, vap); + else + callout_stop(&hs->hs_roottimer); +} + /* * Send a broadcast Path Request to find all nodes on the mesh. We are * called when the vap is configured as a HWMP root node. @@ -562,14 +589,17 @@ hwmp_add_meshrann(uint8_t *frm, const st #define PREQ_TADDR(n) preq.preq_targets[n].target_addr #define PREQ_TSEQ(n) preq.preq_targets[n].target_seq static void -hwmp_rootmode_cb(struct ieee80211vap *vap) +hwmp_rootmode_cb(void *arg) { + struct ieee80211vap *vap = (struct ieee80211vap *)arg; struct ieee80211_hwmp_state *hs = vap->iv_hwmp; struct ieee80211_meshpreq_ie preq; + IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, + "%s", "sending broadcast PREQ"); + /* XXX check portal role */ - preq.preq_flags = 0; - preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_AM; + preq.preq_flags = IEEE80211_MESHPREQ_FLAGS_AM; if (hs->hs_rootmode == IEEE80211_HWMP_ROOTMODE_PROACTIVE) preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PP; preq.preq_hopcount = 0; @@ -584,12 +614,13 @@ hwmp_rootmode_cb(struct ieee80211vap *va PREQ_TFLAGS(0) = IEEE80211_MESHPREQ_TFLAGS_TO | IEEE80211_MESHPREQ_TFLAGS_RF; PREQ_TSEQ(0) = 0; + vap->iv_stats.is_hwmp_rootreqs++; hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq); + hwmp_rootmode_setup(vap); } #undef PREQ_TFLAGS #undef PREQ_TADDR #undef PREQ_TSEQ -#endif #define PREQ_TFLAGS(n) preq->preq_targets[n].target_flags #define PREQ_TADDR(n) preq->preq_targets[n].target_addr @@ -657,6 +688,47 @@ hwmp_recv_preq(struct ieee80211vap *vap, ieee80211_hwmp_discover(vap, rt->rt_dest, NULL); return; } + /* + * Proactive PREQ: reply with a proactive PREP to the + * root STA if requested. + */ + if (IEEE80211_ADDR_EQ(PREQ_TADDR(0), broadcastaddr) && + (PREQ_TFLAGS(0) & + ((IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF) == + (IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF)))) { + uint8_t rootmac[IEEE80211_ADDR_LEN]; + + IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, + "root mesh station @ %s", + ether_sprintf(preq->preq_origaddr)); + IEEE80211_ADDR_COPY(rootmac, preq->preq_origaddr); + rt = hwmp_rt_find(vap, rootmac); + if (rt == NULL) + rt = hwmp_rt_add(vap, rootmac); + /* + * Reply with a PREP if we don't have a path to the root + * or if the root sent us a proactive PREQ. + */ + if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr) || + (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_PP)) { + prep.prep_flags = 0; + prep.prep_hopcount = 0; + prep.prep_ttl = hs->hs_ttl; + IEEE80211_ADDR_COPY(prep.prep_origaddr, + vap->iv_myaddr); + prep.prep_origseq = preq->preq_origseq; + prep.prep_targetseq = ++hs->hs_seq; + prep.prep_lifetime = preq->preq_lifetime; + prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; + IEEE80211_ADDR_COPY(prep.prep_targetaddr, + rootmac); + prep.prep_targetseq = PREQ_TSEQ(0); + hwmp_send_prep(vap->iv_bss, vap->iv_myaddr, + broadcastaddr, &prep); + } + ieee80211_hwmp_discover(vap, rootmac, NULL); + return; + } rt = hwmp_rt_find(vap, PREQ_TADDR(0)); /* XXX missing. Check for AE bit and update proxy information */ @@ -745,38 +817,6 @@ hwmp_recv_preq(struct ieee80211vap *vap, } } - /* - * Proactive PREQ: reply with a proactive PREP to the - * root STA if requested. - */ - if (IEEE80211_ADDR_EQ(PREQ_TADDR(0), broadcastaddr) && - (PREQ_TFLAGS(0) & - ((IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF) == - (IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF)))) { - rt = hwmp_rt_find(vap, preq->preq_origaddr); - if (rt == NULL) - rt = hwmp_rt_add(vap, preq->preq_origaddr); - /* - * Reply with a PREP if we don't have a path to the root - * or if the root sent us a proactive PREQ. - */ - if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr) || - (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_PP)) { - prep.prep_flags = 0; - prep.prep_hopcount = 0; - prep.prep_ttl = hs->hs_ttl; - IEEE80211_ADDR_COPY(prep.prep_targetaddr, - vap->iv_myaddr); - prep.prep_targetseq = ++hs->hs_seq; - prep.prep_lifetime = preq->preq_lifetime; - prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - IEEE80211_ADDR_COPY(prep.prep_origaddr, - preq->preq_origaddr); - prep.prep_origseq = preq->preq_origseq; - hwmp_send_prep(vap->iv_bss, vap->iv_myaddr, - broadcastaddr, &prep); - } - } } #undef PREQ_TFLAGS #undef PREQ_TADDR @@ -816,14 +856,15 @@ hwmp_recv_prep(struct ieee80211vap *vap, const struct ieee80211_frame *wh, const struct ieee80211_meshprep_ie *prep) { struct ieee80211_mesh_state *ms = vap->iv_mesh; + struct ieee80211_hwmp_state *hs = vap->iv_hwmp; struct ieee80211_hwmp_route *rt = NULL; struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = vap->iv_ifp; struct mbuf *m, *next; /* - * Acceptance criteria: if the PREP was not generated by us and - * forwarding is disabled, discard this PREP. + * Acceptance criteria: if the corresponding PREQ was not generated + * by us and forwarding is disabled, discard this PREP. */ if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) && !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) @@ -853,8 +894,21 @@ hwmp_recv_prep(struct ieee80211vap *vap, } rt = hwmp_rt_find(vap, prep->prep_origaddr); - if (rt == NULL) + 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); + IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2); + rt->rt_nhops = prep->prep_hopcount; + rt->rt_lifetime = prep->prep_lifetime; + rt->rt_metric = prep->prep_metric; + return; + } return; + } if (prep->prep_targetseq == rt->rt_seq) { int useprep = 0; /* @@ -1124,7 +1178,7 @@ ieee80211_hwmp_discover(struct ieee80211 ("not a mesh vap, opmode %d", vap->iv_opmode)); KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest), - ("discovering self!")); + ("%s: discovering self!", __func__)); ni = NULL; if (!IEEE80211_IS_MULTICAST(dest)) { @@ -1339,6 +1393,7 @@ hwmp_ioctl_set80211(struct ieee80211vap if (ireq->i_val < 0 || ireq->i_val > 3) return EINVAL; hs->hs_rootmode = ireq->i_val; + hwmp_rootmode_setup(vap); break; case IEEE80211_IOC_HWMP_MAXHOPS: if (ireq->i_val <= 0 || ireq->i_val > 255) Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_hwmp.h Thu Jul 2 10:02:10 2009 (r195283) +++ projects/mesh11s/sys/net80211/ieee80211_hwmp.h Thu Jul 2 12:41:21 2009 (r195284) @@ -64,6 +64,7 @@ struct ieee80211_hwmp_state { 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 */ uint8_t hs_ttl; /* HWMP ttl */ }; Modified: projects/mesh11s/sys/net80211/ieee80211_ioctl.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_ioctl.h Thu Jul 2 10:02:10 2009 (r195283) +++ projects/mesh11s/sys/net80211/ieee80211_ioctl.h Thu Jul 2 12:41:21 2009 (r195284) @@ -233,6 +233,7 @@ struct ieee80211_stats { uint32_t is_mesh_fwd_nopath; /* mesh not fwd'd 'cuz path unknown */ uint32_t is_hwmp_wrongseq; /* wrong hwmp seq no. */ + uint32_t is_hwmp_rootreqs; /* root PREQs sent */ uint32_t is_spare[8]; };