#define PERR_IE_TARGET_RCODE(x)        u16_field_get(x, 13, 0)
 
 #define MSEC_TO_TU(x) (x*1000/1024)
-#define SN_GT(x, y) ((long) (y) - (long) (x) < 0)
-#define SN_LT(x, y) ((long) (x) - (long) (y) < 0)
+#define SN_GT(x, y) ((s32)(y - x) < 0)
+#define SN_LT(x, y) ((s32)(x - y) < 0)
 
 #define net_traversal_jiffies(s) \
        msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
                                struct ieee80211_rann_ie *rann)
 {
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+       struct ieee80211_local *local = sdata->local;
+       struct sta_info *sta;
        struct mesh_path *mpath;
        u8 ttl, flags, hopcount;
        u8 *orig_addr;
-       u32 orig_sn, metric;
-       u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
+       u32 orig_sn, metric, metric_txsta, interval;
        bool root_is_gate;
 
        ttl = rann->rann_ttl;
        root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
        orig_addr = rann->rann_addr;
        orig_sn = le32_to_cpu(rann->rann_seq);
+       interval = le32_to_cpu(rann->rann_interval);
        hopcount = rann->rann_hopcount;
        hopcount++;
        metric = le32_to_cpu(rann->rann_metric);
                        orig_addr, mgmt->sa, root_is_gate);
 
        rcu_read_lock();
+       sta = sta_info_get(sdata, mgmt->sa);
+       if (!sta) {
+               rcu_read_unlock();
+               return;
+       }
+
+       metric_txsta = airtime_link_metric_get(local, sta);
+
        mpath = mesh_path_lookup(orig_addr, sdata);
        if (!mpath) {
                mesh_path_add(orig_addr, sdata);
                mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
        }
 
-       if (mpath->sn < orig_sn && ifmsh->mshcfg.dot11MeshForwarding) {
+       if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn &&
+          metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) {
                mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
                                       cpu_to_le32(orig_sn),
                                       0, NULL, 0, broadcast_addr,
                                       hopcount, ttl, cpu_to_le32(interval),
-                                      cpu_to_le32(metric + mpath->metric),
+                                      cpu_to_le32(metric + metric_txsta),
                                       0, sdata);
                mpath->sn = orig_sn;
+               mpath->rann_metric = metric + metric_txsta;
        }
 
        /* Using individually addressed PREQ for root node */