diff options
author | monthadar <monthadar@FreeBSD.org> | 2012-05-01 16:02:31 +0000 |
---|---|---|
committer | monthadar <monthadar@FreeBSD.org> | 2012-05-01 16:02:31 +0000 |
commit | 3e48b3819f05a81690c262194c3084ce774f1509 (patch) | |
tree | 204e670c850312fd0be7df906db9b168806f33d1 /sys/net80211/ieee80211_hwmp.c | |
parent | 01443cbc253e17eeadf6a1f879f0ad02ae79203f (diff) | |
download | FreeBSD-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.c | 125 |
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 |