From owner-svn-src-projects@FreeBSD.ORG Mon Jun 29 15:53:53 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 0446A106566C; Mon, 29 Jun 2009 15:53:53 +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 E58078FC08; Mon, 29 Jun 2009 15:53:52 +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 n5TFrqtB048539; Mon, 29 Jun 2009 15:53:52 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5TFrqG7048533; Mon, 29 Jun 2009 15:53:52 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <200906291553.n5TFrqG7048533@svn.freebsd.org> From: Rui Paulo Date: Mon, 29 Jun 2009 15:53:52 +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: r195158 - in projects/mesh11s: sbin/ifconfig 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: Mon, 29 Jun 2009 15:53:53 -0000 Author: rpaulo Date: Mon Jun 29 15:53:52 2009 New Revision: 195158 URL: http://svn.freebsd.org/changeset/base/195158 Log: * introduce the HWMP TTL and stop using the mesh TTL in HWMP * misc HWMP fixups, now we display the correct hop count and metric * disable age while the panic isn't fixed * handle PERR by removing the entry from the HWMP table and propating the PERR * add a new callback function to be called whenever a peer link goes down * add ifconfig wlan0 hwmpttl setting Sponsored by: The FreeBSD Foundation Modified: projects/mesh11s/sbin/ifconfig/ifieee80211.c projects/mesh11s/sys/net80211/ieee80211_hwmp.c projects/mesh11s/sys/net80211/ieee80211_hwmp.h projects/mesh11s/sys/net80211/ieee80211_ioctl.h projects/mesh11s/sys/net80211/ieee80211_mesh.c Modified: projects/mesh11s/sbin/ifconfig/ifieee80211.c ============================================================================== --- projects/mesh11s/sbin/ifconfig/ifieee80211.c Mon Jun 29 15:23:50 2009 (r195157) +++ projects/mesh11s/sbin/ifconfig/ifieee80211.c Mon Jun 29 15:53:52 2009 (r195158) @@ -1329,6 +1329,12 @@ DECL_CMD_FUNC(set80211hwmpmaxhops, val, set80211(s, IEEE80211_IOC_HWMP_MAXHOPS, atoi(val), 0, NULL); } +static +DECL_CMD_FUNC(set80211hwmpttl, val, d) +{ + set80211(s, IEEE80211_IOC_HWMP_TTL, atoi(val), 0, NULL); +} + static void set80211pureg(const char *val, int d, int s, const struct afswtch *rafp) { @@ -4823,6 +4829,9 @@ end: if (get80211val(s, IEEE80211_IOC_HWMP_MAXHOPS, &val) != -1) { LINE_CHECK("hwmpmaxhops %u", val); } + if (get80211val(s, IEEE80211_IOC_HWMP_TTL, &val) != -1) { + LINE_CHECK("hwmpttl %u", val); + } } LINE_BREAK(); @@ -5136,9 +5145,6 @@ static struct cmd ieee80211_cmds[] = { DEF_CMD_ARG("mac:add", set80211addmac), DEF_CMD_ARG("mac:del", set80211delmac), DEF_CMD_ARG("mac:kick", set80211kickmac), - DEF_CMD("hwmp:flush", IEEE80211_HWMP_CMD_FLUSH, set80211hwmpcmd), - DEF_CMD_ARG("hwmp:add", set80211addhwmp), - DEF_CMD_ARG("hwmp:del", set80211delhwmp), DEF_CMD("pureg", 1, set80211pureg), DEF_CMD("-pureg", 0, set80211pureg), DEF_CMD("ff", 1, set80211fastframes), @@ -5229,8 +5235,12 @@ static struct cmd ieee80211_cmds[] = { DEF_CMD("-meshforward", 0, set80211meshforward), DEF_CMD("meshpeering", 1, set80211meshpeering), DEF_CMD("-meshpeering", 0, set80211meshpeering), + DEF_CMD("hwmp:flush", IEEE80211_HWMP_CMD_FLUSH, set80211hwmpcmd), + DEF_CMD_ARG("hwmp:add", set80211addhwmp), + DEF_CMD_ARG("hwmp:del", set80211delhwmp), DEF_CMD_ARG("hwmprootmode", set80211hwmprootmode), DEF_CMD_ARG("hwmpmaxhops", set80211hwmpmaxhops), + DEF_CMD_ARG("hwmptll", set80211hwmpttl), /* vap cloning support */ DEF_CLONE_CMD_ARG("wlanaddr", set80211clone_wlanaddr), Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_hwmp.c Mon Jun 29 15:23:50 2009 (r195157) +++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Mon Jun 29 15:53:52 2009 (r195158) @@ -140,6 +140,7 @@ SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, rep MALLOC_DEFINE(M_80211_HWMP, "80211hwmp", "802.11 HWMP routing table"); #define IEEE80211_HWMP_DEFAULT_MAXHOPS 31 +#define IEEE80211_HWMP_DEFAULT_TTL 31 /* * Helper functions to manipulate the HWMP routing table. @@ -232,6 +233,7 @@ ieee80211_hwmp_vattach(struct ieee80211v TAILQ_INIT(&hs->hs_head); 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; vap->iv_hwmp = hs; } @@ -583,9 +585,6 @@ hwmp_recv_preq(struct ieee80211vap *vap, preq->preq_origaddr, NULL, "%s", "not accepting PREQ"); return; } - fi = hwmp_rt_find(vap, PREQ_TADDR(0)); - if (fi) - fi->fi_preqid = preq->preq_id; /* * Check if the PREQ is addressed to us. * XXX: check if this is part of a proxy address. @@ -600,7 +599,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, */ prep.prep_flags = 0; prep.prep_hopcount = 0; - prep.prep_ttl = ms->ms_ttl; + prep.prep_ttl = hs->hs_ttl; IEEE80211_ADDR_COPY(prep.prep_targetaddr, preq->preq_origaddr); prep.prep_targetseq = preq->preq_origseq; prep.prep_lifetime = preq->preq_lifetime; @@ -608,24 +607,28 @@ hwmp_recv_preq(struct ieee80211vap *vap, IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr); prep.prep_origseq = hs->hs_seq++; hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep); +#if 0 /* * Build the reverse path, if we don't have it already. */ fi = hwmp_rt_find(vap, preq->preq_origaddr); if (fi == NULL) { - fi = hwmp_rt_add(vap, preq->preq_origaddr); - ieee80211_hwmp_discover(vap, fi->fi_dest, NULL); + uint8_t *dest = (uint8_t *)preq->preq_origaddr; + + ieee80211_hwmp_discover(vap, dest, NULL); } else if (IEEE80211_ADDR_EQ(fi->fi_nexthop, invalidaddr)) ieee80211_hwmp_discover(vap, fi->fi_dest, NULL); +#endif return; } + fi = hwmp_rt_find(vap, PREQ_TADDR(0)); /* XXX missing. Check for AE bit and update proxy information */ /* - * Intermediate reply for PREQs with 1 target. + * Forwarding and Intermediate reply for PREQs with 1 target. */ - if (preq->preq_ttl > 1 && preq->preq_tcount == 1) { + if (preq->preq_tcount == 1) { struct ieee80211_meshpreq_ie ppreq; /* propagated PREQ */ memcpy(&ppreq, preq, sizeof(ppreq)); @@ -634,27 +637,33 @@ hwmp_recv_preq(struct ieee80211vap *vap, */ if (fi != NULL && !IEEE80211_ADDR_EQ(fi->fi_nexthop, invalidaddr)) { - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "forwarding PREQ from %s", - ether_sprintf(preq->preq_origaddr)); - /* - * Propagate the original PREQ. - */ - ppreq.preq_hopcount += 1; - ppreq.preq_ttl -= 1; - ppreq.preq_metric += ieee80211_airtime_calc(ni); - /* - * Set TO and unset RF bits because we are going - * to send a PREP next. - */ - ppreq.preq_targets[0].target_flags |= - IEEE80211_MESHPREQ_TFLAGS_TO; - ppreq.preq_targets[0].target_flags &= - ~IEEE80211_MESHPREQ_TFLAGS_RF; - hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr, - &ppreq); + fi->fi_preqid = preq->preq_id; + fi->fi_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)); + /* + * Propagate the original PREQ. + */ + ppreq.preq_hopcount += 1; + ppreq.preq_ttl -= 1; + ppreq.preq_metric += ieee80211_airtime_calc(ni); + /* + * Set TO and unset RF bits because we are going + * to send a PREP next. + */ + ppreq.preq_targets[0].target_flags |= + IEEE80211_MESHPREQ_TFLAGS_TO; + ppreq.preq_targets[0].target_flags &= + ~IEEE80211_MESHPREQ_TFLAGS_RF; + hwmp_send_preq(ni, vap->iv_myaddr, + broadcastaddr, &ppreq); + } /* - * Check if we can send an intermediate Path Reply. + * Check if we can send an intermediate Path Reply, + * i.e., Target Only bit is not set. */ if (!(PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO)) { struct ieee80211_meshprep_ie prep; @@ -663,33 +672,36 @@ hwmp_recv_preq(struct ieee80211vap *vap, "intermediate reply for PREQ from %s", ether_sprintf(preq->preq_origaddr)); prep.prep_flags = 0; - prep.prep_hopcount = 0; - prep.prep_ttl = ms->ms_ttl; + prep.prep_hopcount = fi->fi_nhops + 1; + prep.prep_ttl = hs->hs_ttl; IEEE80211_ADDR_COPY(&prep.prep_targetaddr, preq->preq_origaddr); prep.prep_targetseq = fi->fi_seq; prep.prep_lifetime = preq->preq_lifetime; - prep.prep_metric = fi->fi_metric; + prep.prep_metric = fi->fi_metric + + ieee80211_airtime_calc(ni); IEEE80211_ADDR_COPY(&prep.prep_origaddr, PREQ_TADDR(0)); prep.prep_origseq = hs->hs_seq++; hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &prep); } - } else { - fi = hwmp_rt_add(vap, PREQ_TADDR(0)); + /* + * We have no information about this path, + * propagate the PREQ based on TTL. + */ + } else if (preq->preq_ttl > 1) { + if (fi == NULL) { + fi = hwmp_rt_add(vap, PREQ_TADDR(0)); + fi->fi_metric = preq->preq_metric; + fi->fi_lifetime = preq->preq_lifetime; + } fi->fi_seq = preq->preq_origseq; - fi->fi_metric = preq->preq_metric; - fi->fi_lifetime = preq->preq_lifetime; fi->fi_preqid = preq->preq_id; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "forwarding PREQ from %s", ether_sprintf(preq->preq_origaddr)); - /* - * We have no information about this path, - * propagate the PREQ. - */ ppreq.preq_hopcount += 1; ppreq.preq_ttl -= 1; ppreq.preq_metric += ieee80211_airtime_calc(ni); @@ -701,7 +713,6 @@ hwmp_recv_preq(struct ieee80211vap *vap, */ return; } - /* * XXX: Proactive PREQ: reply with a proactive PREP to the @@ -770,7 +781,6 @@ hwmp_recv_prep(struct ieee80211vap *vap, IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "received PREP from %s", ether_sprintf(prep->prep_origaddr)); - fi = hwmp_rt_find(vap, prep->prep_origaddr); /* * If it's NOT for us, propagate the PREP if TTL is * greater than 1. @@ -795,6 +805,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, return; } + fi = hwmp_rt_find(vap, prep->prep_origaddr); if (fi != NULL) { /* * Build the rest of the entry. @@ -815,7 +826,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, * XXX: If it's NOT for us and the AE bit is set, * update the proxy information table. */ - +#if 0 if (fi != NULL) { struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = vap->iv_ifp; @@ -836,6 +847,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, ifp->if_transmit(ifp, m); } } +#endif } static inline int @@ -867,6 +879,31 @@ hwmp_send_prep(struct ieee80211_node *ni sizeof(struct ieee80211_meshprep_ie)); } +#define PERR_DADDR(n) perr.perr_dests[n].dest_addr +#define PERR_DSEQ(n) perr.perr_dests[n].dest_seq +void +ieee80211_hwmp_peerdown(struct ieee80211_node *ni) +{ + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211_meshperr_ie perr; + struct ieee80211_hwmp_fi *fi; + + fi = hwmp_rt_find(vap, ni->ni_macaddr); + if (fi == NULL) + return; + 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), fi->fi_dest); + PERR_DSEQ(0) = fi->fi_seq; + hwmp_rt_del(vap, ni->ni_macaddr); + hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr); +} +#undef PERR_DADDR +#undef PERR_DSEQ + + #define PERR_DADDR(n) perr->perr_dests[n].dest_addr #define PERR_DSEQ(n) perr->perr_dests[n].dest_seq static void @@ -876,7 +913,7 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_mesh_state *ms = vap->iv_mesh; struct ieee80211_hwmp_fi *fi = NULL; struct ieee80211_meshperr_ie pperr; - int i; + int i, forward = 0; /* * Acceptance criteria: check if we received a PERR from a @@ -886,24 +923,29 @@ hwmp_recv_perr(struct ieee80211vap *vap, ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED || !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) return; - + /* + * Find all routing entries that match and delete them. + */ for (i = 0; i < perr->perr_ndests; i++) { fi = hwmp_rt_find(vap, PERR_DADDR(i)); if (fi == NULL) - break; - if (PERR_DSEQ(i) > fi->fi_seq) { + continue; + if (PERR_DSEQ(i) >= fi->fi_seq) { hwmp_rt_del(vap, fi->fi_dest); fi = NULL; + forward = 1; } } /* - * Propagate the PERR. + * Propagate the PERR if we previously found it on our routing table. * XXX handle ndest > 1 */ - IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "propagating PERR from %s", ether_sprintf(wh->i_addr2)); - memcpy(&pperr, perr, sizeof(*perr)); - hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &pperr); + if (forward) { + IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, + "propagating PERR from %s", ether_sprintf(wh->i_addr2)); + memcpy(&pperr, perr, sizeof(*perr)); + hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &pperr); + } } #undef PEER_DADDR #undef PERR_DSEQ @@ -932,6 +974,7 @@ hwmp_send_perr(struct ieee80211_node *ni * [1] category * [tlv] mesh path error */ + perr->perr_ie = IEEE80211_ELEMID_MESHPERR; return ieee80211_hwmp_send_action(ni, sa, da, (uint8_t *)perr, sizeof(struct ieee80211_meshperr_ie)); } @@ -960,7 +1003,7 @@ hwmp_recv_rann(struct ieee80211vap *vap, */ preq.preq_flags = 0; preq.preq_hopcount = 0; - preq.preq_ttl = ms->ms_ttl; + preq.preq_ttl = hs->hs_ttl; IEEE80211_ADDR_COPY(&preq.preq_origaddr, vap->iv_myaddr); preq.preq_origseq = hs->hs_seq++; @@ -1014,7 +1057,6 @@ struct ieee80211_node * ieee80211_hwmp_discover(struct ieee80211vap *vap, uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m) { - struct ieee80211_mesh_state *ms = vap->iv_mesh; struct ieee80211_hwmp_state *hs = vap->iv_hwmp; struct ieee80211_hwmp_fi *fi = NULL; struct ieee80211_meshpreq_ie preq; @@ -1056,7 +1098,7 @@ ieee80211_hwmp_discover(struct ieee80211 */ preq.preq_flags = 0; preq.preq_hopcount = 0; - preq.preq_ttl = ms->ms_ttl; + preq.preq_ttl = hs->hs_ttl; preq.preq_id = fi->fi_preqid; IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); preq.preq_origseq = fi->fi_seq; @@ -1088,6 +1130,7 @@ done: if (ni == NULL && m != NULL) { IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_HWMP, dest, NULL, "%s", "no valid path to this node"); +#if 0 if (sendpreq) { struct ieee80211com *ic = vap->iv_ic; /* @@ -1101,6 +1144,7 @@ done: ieee80211_ageq_append(&ic->ic_stageq, m, IEEE80211_INACT_WAIT); } else +#endif m_freem(m); } return ni; @@ -1180,6 +1224,9 @@ hwmp_ioctl_get80211(struct ieee80211vap case IEEE80211_IOC_HWMP_MAXHOPS: ireq->i_val = hs->hs_maxhops; break; + case IEEE80211_IOC_HWMP_TTL: + ireq->i_val = hs->hs_ttl; + break; default: return ENOSYS; } @@ -1224,6 +1271,11 @@ hwmp_ioctl_set80211(struct ieee80211vap return EINVAL; hs->hs_maxhops = ireq->i_val; break; + case IEEE80211_IOC_HWMP_TTL: + if (ireq->i_val <= 0 || ireq->i_val > 255) + return EINVAL; + hs->hs_ttl = ireq->i_val; + break; default: return ENOSYS; } Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_hwmp.h Mon Jun 29 15:23:50 2009 (r195157) +++ projects/mesh11s/sys/net80211/ieee80211_hwmp.h Mon Jun 29 15:53:52 2009 (r195158) @@ -64,6 +64,7 @@ struct ieee80211_hwmp_state { struct mtx hs_lock; /* lock for the fi table */ int hs_rootmode; /* proactive HWMP */ uint8_t hs_maxhops; /* max hop count */ + uint8_t hs_ttl; /* HWMP ttl */ }; void ieee80211_hwmp_vattach(struct ieee80211vap *); @@ -77,6 +78,7 @@ struct ieee80211_node *ieee80211_hwmp_di struct ieee80211_node * ieee80211_hwmp_find_txnode(struct ieee80211vap *vap, uint8_t dest[IEEE80211_ADDR_LEN]); +void ieee80211_hwmp_peerdown(struct ieee80211_node *); #endif /* _KERNEL */ #endif /* _NET80211_IEEE80211_HWMP_H_ */ Modified: projects/mesh11s/sys/net80211/ieee80211_ioctl.h ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_ioctl.h Mon Jun 29 15:23:50 2009 (r195157) +++ projects/mesh11s/sys/net80211/ieee80211_ioctl.h Mon Jun 29 15:53:52 2009 (r195158) @@ -669,6 +669,7 @@ struct ieee80211req { #define IEEE80211_IOC_HWMP_CMD 195 /* HWMP table commands */ #define IEEE80211_IOC_HWMP_ROOTMODE 196 /* HWMP root mode */ #define IEEE80211_IOC_HWMP_MAXHOPS 197 /* number of hops before drop */ +#define IEEE80211_IOC_HWMP_TTL 198 /* HWMP TTL */ #define IEEE80211_IOC_TDMA_SLOT 201 /* TDMA: assigned slot */ #define IEEE80211_IOC_TDMA_SLOTCNT 202 /* TDMA: slots in bss */ Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c ============================================================================== --- projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Jun 29 15:23:50 2009 (r195157) +++ projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Jun 29 15:53:52 2009 (r195158) @@ -285,7 +285,8 @@ mesh_linkchange(struct ieee80211_node *n IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, ni, "peer link: switching to state %s", meshlinkstates[ni->ni_mlstate]); - + if (state == IEEE80211_NODE_MESH_HOLDING) + ieee80211_hwmp_peerdown(ni); } /*