summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_hwmp.c
diff options
context:
space:
mode:
authormonthadar <monthadar@FreeBSD.org>2012-05-01 16:02:31 +0000
committermonthadar <monthadar@FreeBSD.org>2012-05-01 16:02:31 +0000
commit3e48b3819f05a81690c262194c3084ce774f1509 (patch)
tree204e670c850312fd0be7df906db9b168806f33d1 /sys/net80211/ieee80211_hwmp.c
parent01443cbc253e17eeadf6a1f879f0ad02ae79203f (diff)
downloadFreeBSD-src-3e48b3819f05a81690c262194c3084ce774f1509.zip
FreeBSD-src-3e48b3819f05a81690c262194c3084ce774f1509.tar.gz
PREP update
* Added assertion in mesh_rt_update; * Fixed some prep propagation that where multicast, ALL PREPS ARE UNICAST; * Fixed PREP acceptance criteria; * Fixed some PREP debug messages; * HWMP intermediate reply (PREP) should only be sent if we have newer forwarding infomration (FI) about target; * Fixed PREP propagation condition and PREP w/ AE handling; * Ignore PREPs that have unknown originator. * Removed old code inside PREP that was for proactive path building to root mesh; Other errors include: * use seq number of target and not orig mesh STA; * Metric is what we have stored in our FI; * Error in amendment, Hop count is not 0 but equals FI hopcount for target; Approved by: adrian
Diffstat (limited to 'sys/net80211/ieee80211_hwmp.c')
-rw-r--r--sys/net80211/ieee80211_hwmp.c125
1 files changed, 60 insertions, 65 deletions
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 334399e..4ea61b1 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -887,7 +887,8 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
return;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
- "received PREQ, source %6D", preq->preq_origaddr, ":");
+ "received PREQ, orig %6D, targ(0) %6D", preq->preq_origaddr, ":",
+ PREQ_TADDR(0), ":");
/*
* Acceptance criteria: if the PREQ is not for us or not broadcast
@@ -1010,9 +1011,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
* 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)))) {
+ (PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO)) {
uint8_t rootmac[IEEE80211_ADDR_LEN];
IEEE80211_ADDR_COPY(rootmac, preq->preq_origaddr);
@@ -1096,26 +1095,26 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
* 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)) {
+ if (!(PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO) &&
+ HWMP_SEQ_GEQ(hrtarg->hr_seq, PREQ_TSEQ(0))) {
struct ieee80211_meshprep_ie prep;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"intermediate reply for PREQ from %6D",
preq->preq_origaddr, ":");
prep.prep_flags = 0;
- prep.prep_hopcount = rt->rt_nhops + 1;
+ prep.prep_hopcount = rttarg->rt_nhops;
prep.prep_ttl = ms->ms_ttl;
IEEE80211_ADDR_COPY(&prep.prep_targetaddr,
PREQ_TADDR(0));
- prep.prep_targetseq = hrorig->hr_seq;
+ prep.prep_targetseq = hrtarg->hr_seq;
prep.prep_lifetime = preq->preq_lifetime;
- prep.prep_metric = rt->rt_metric +
- ms->ms_pmetric->mpm_metric(ni);
+ prep.prep_metric =rttarg->rt_metric;
IEEE80211_ADDR_COPY(&prep.prep_origaddr,
preq->preq_origaddr);
prep.prep_origseq = hrorig->hr_seq;
hwmp_send_prep(ni, vap->iv_myaddr,
- broadcastaddr, &prep);
+ rtorig->rt_nexthop, &prep);
}
/*
* We have no information about this path,
@@ -1191,6 +1190,9 @@ static void
hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
const struct ieee80211_frame *wh, const struct ieee80211_meshprep_ie *prep)
{
+#define IS_PROXY(rt) (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)
+#define PROXIED_BY_US(rt) \
+ (IEEE80211_ADDR_EQ(vap->iv_myaddr, rt->rt_mesh_gate))
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
struct ieee80211_mesh_route *rt = NULL;
@@ -1203,63 +1205,31 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
uint32_t metric = 0;
const uint8_t *addr;
- /*
- * Acceptance criteria: If the corresponding PREP was not generated
- * by us or generated by an external mac that is proxied by us
- * and forwarding is disabled, discard this PREP.
- */
if (ni == vap->iv_bss ||
ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
return;
- if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) &&
- !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
- return;
+
+ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+ "received PREP, orig %6D, targ %6D", prep->prep_origaddr, ":",
+ prep->prep_targetaddr, ":");
+
+ /*
+ * Acceptance criteria: (If the corresponding PREP was not generated
+ * by us OR not generated by an external mac that is not proxied by us)
+ * AND forwarding is disabled, discard this PREP.
+ */
rtorig = ieee80211_mesh_rt_find(vap, prep->prep_origaddr);
- if (rtorig != NULL &&
- !(rtorig->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)) {
+ if ((!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) ||
+ (rtorig != NULL && IS_PROXY(rtorig) && !PROXIED_BY_US(rtorig))) &&
+ !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)){
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
- "received PREP(%u) for an orig(%6D) not proxied by us",
- prep->prep_origseq, prep->prep_origaddr, ":");
+ "discard PREP, orig(%6D) not proxied or generated by us",
+ prep->prep_origaddr, ":");
return;
}
/* PREP ACCEPTED */
- IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
- "received PREP from %6D", prep->prep_targetaddr, ":");
-
-#if 0
- rt = ieee80211_mesh_rt_find(vap, prep->prep_targetaddr);
- if (rt == NULL) {
- /*
- * If we have no entry this could be a reply to a root PREQ.
- * XXX: not true anymore cause we dont create entry for target
- * when propagating PREQs like the old code did.
- */
- if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) {
- rt = ieee80211_mesh_rt_add(vap, prep->prep_targetaddr);
- if (rt == NULL) {
- IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP,
- ni, "unable to add PREP path to %6D",
- prep->prep_targetaddr, ":");
- vap->iv_stats.is_mesh_rtaddfailed++;
- return;
- }
- IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2);
- rt->rt_nhops = prep->prep_hopcount;
- ieee80211_mesh_rt_update(rt, prep->prep_lifetime);
- rt->rt_metric = prep->prep_metric;
- rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID;
- IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
- "add root path to %6D nhops %d metric %lu (PREP)",
- prep->prep_targetaddr, ":",
- rt->rt_nhops, rt->rt_metric);
- return;
- }
- return;
- }
-#endif
-
/*
* If accepted shall create or update the active forwarding information
* it maintains for the target mesh STA of the PREP (according to the
@@ -1278,6 +1248,8 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
vap->iv_stats.is_mesh_rtaddfailed++;
return;
}
+ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+ "adding target %6D", prep->prep_targetaddr, ":");
}
hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
/* update path metric */
@@ -1315,11 +1287,25 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; /* mark valid */
/*
- * If it's NOT for us, propagate the PREP.
+ * If it's NOT for us, propagate the PREP
*/
if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) &&
- prep->prep_ttl > 1 && prep->prep_hopcount < hs->hs_maxhops) {
+ prep->prep_ttl > 1 &&
+ prep->prep_hopcount < hs->hs_maxhops) {
struct ieee80211_meshprep_ie pprep; /* propagated PREP */
+ /*
+ * NB: We should already have setup the path to orig
+ * mesh STA when we propagated PREQ to target mesh STA,
+ * no PREP is generated without a corresponding PREQ.
+ * XXX: for now just ignore.
+ */
+ if (rtorig == NULL) {
+ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+ "received PREP for an unknown orig(%6D)",
+ prep->prep_origaddr, ":");
+ return;
+ }
+
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"propagate PREP from %6D",
prep->prep_targetaddr, ":");
@@ -1328,13 +1314,17 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
pprep.prep_hopcount += 1;
pprep.prep_ttl -= 1;
pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni);
- hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep);
+ hwmp_send_prep(ni, vap->iv_myaddr, rtorig->rt_nexthop, &pprep);
- /* may store target external address if recevied PREP w/ AE */
/* precursor list for the Target Mesh STA Address is updated */
}
- /* check if we received a PREP for a proxy address */
- else if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) {
+
+ /*
+ * Check if we received a PREP w/ AE and store target external address.
+ * We may store target external address if recevied PREP w/ AE
+ * and we are not final destination
+ */
+ if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) {
rtext = ieee80211_mesh_rt_find(vap,
prep->prep_target_ext_addr);
if (rtext == NULL) {
@@ -1366,8 +1356,11 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
rtext->rt_metric = metric;
rtext->rt_lifetime = prep->prep_lifetime;
rtext->rt_nhops = prep->prep_hopcount + 1;
- rtext->rt_ext_seq = prep->prep_origseq; /* proxy seq */
- /* proxy entries have no HWMP priv data, nullify them to be sure? */
+ rtext->rt_ext_seq = prep->prep_origseq; /* new proxy seq */
+ /*
+ * XXX: proxy entries have no HWMP priv data,
+ * nullify them to be sure?
+ */
}
/*
* Check for frames queued awaiting path discovery.
@@ -1388,6 +1381,8 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
"flush queued frame %p len %d", m, m->m_pkthdr.len);
ifp->if_transmit(ifp, m);
}
+#undef IS_PROXY
+#undef PROXIED_BY_US
}
static int
OpenPOWER on IntegriCloud