Author: monthadar
Date: Tue May  1 16:02:31 2012
New Revision: 234881
URL: http://svn.freebsd.org/changeset/base/234881

Log:
  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

Modified:
  head/sys/net80211/ieee80211_hwmp.c
  head/sys/net80211/ieee80211_mesh.c

Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c  Tue May  1 16:00:31 2012        
(r234880)
+++ head/sys/net80211/ieee80211_hwmp.c  Tue May  1 16:02:31 2012        
(r234881)
@@ -887,7 +887,8 @@ hwmp_recv_preq(struct ieee80211vap *vap,
                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,
         * 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,
                         * 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,
        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,
                        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,
        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,
                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,
                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,
                    "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

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c  Tue May  1 16:00:31 2012        
(r234880)
+++ head/sys/net80211/ieee80211_mesh.c  Tue May  1 16:02:31 2012        
(r234881)
@@ -239,6 +239,8 @@ ieee80211_mesh_rt_update(struct ieee8021
        int timesince, now;
        uint32_t lifetime = 0;
 
+       KASSERT(rt != NULL, ("route is NULL"));
+
        now = ticks;
        RT_ENTRY_LOCK(rt);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to