svn commit: r195158 - in projects/mesh11s: sbin/ifconfig
sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Mon Jun 29 15:53:53 UTC 2009
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);
}
/*
More information about the svn-src-projects
mailing list