OSDN Git Service

mac80211: fix the update of path metric for RANN frame
authorChun-Yeow Yeoh <yeohchunyeow@gmail.com>
Tue, 14 Nov 2017 15:20:05 +0000 (23:20 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 Feb 2018 16:05:37 +0000 (17:05 +0100)
[ Upstream commit fbbdad5edf0bb59786a51b94a9d006bc8c2da9a2 ]

The previous path metric update from RANN frame has not considered
the own link metric toward the transmitting mesh STA. Fix this.

Reported-by: Michael65535
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/mac80211/mesh_hwmp.c

index b747c96..fed598a 100644 (file)
@@ -788,7 +788,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        struct mesh_path *mpath;
        u8 ttl, flags, hopcount;
        const u8 *orig_addr;
-       u32 orig_sn, metric, metric_txsta, interval;
+       u32 orig_sn, new_metric, orig_metric, last_hop_metric, interval;
        bool root_is_gate;
 
        ttl = rann->rann_ttl;
@@ -799,7 +799,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        interval = le32_to_cpu(rann->rann_interval);
        hopcount = rann->rann_hopcount;
        hopcount++;
-       metric = le32_to_cpu(rann->rann_metric);
+       orig_metric = le32_to_cpu(rann->rann_metric);
 
        /*  Ignore our own RANNs */
        if (ether_addr_equal(orig_addr, sdata->vif.addr))
@@ -816,7 +816,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
                return;
        }
 
-       metric_txsta = airtime_link_metric_get(local, sta);
+       last_hop_metric = airtime_link_metric_get(local, sta);
+       new_metric = orig_metric + last_hop_metric;
+       if (new_metric < orig_metric)
+               new_metric = MAX_METRIC;
 
        mpath = mesh_path_lookup(sdata, orig_addr);
        if (!mpath) {
@@ -829,7 +832,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        }
 
        if (!(SN_LT(mpath->sn, orig_sn)) &&
-           !(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
+           !(mpath->sn == orig_sn && new_metric < mpath->rann_metric)) {
                rcu_read_unlock();
                return;
        }
@@ -847,7 +850,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        }
 
        mpath->sn = orig_sn;
-       mpath->rann_metric = metric + metric_txsta;
+       mpath->rann_metric = new_metric;
        mpath->is_root = true;
        /* Recording RANNs sender address to send individually
         * addressed PREQs destined for root mesh STA */
@@ -867,7 +870,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
                mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
                                       orig_sn, 0, NULL, 0, broadcast_addr,
                                       hopcount, ttl, interval,
-                                      metric + metric_txsta, 0, sdata);
+                                      new_metric, 0, sdata);
        }
 
        rcu_read_unlock();