模拟NUD_FAILED

原由

在WIFI测试中,经常会遇到Nud fail的场景,有时候是flow的问题,拿到patch也需要验证有效性。所以就需要尝试修改driver 模拟一个ARP no response的场景。

原理

手机连线10s后,通过下iwpriv的cmd带入对应的参数,来在driver中drop arp req,造成收不到arp response的场景

patch

Subject: [PATCH] Debug Nud fail
---

diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
old mode 100644
new mode 100755
index 08a9255..d0d733b
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1374,6 +1374,7 @@
    uint8_t active_ac;
    uint32_t pkt_type_bitmap;
    uint32_t track_arp_ip;
+    uint32_t drop_arp_req;
    uint8_t dns_payload[256];
    uint32_t track_dns_domain_len;
    uint32_t track_src_port;
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
old mode 100644
new mode 100755
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
old mode 100644
new mode 100755
index e9e360d..45364e2
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -949,7 +949,18 @@
            QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
                  QDF_TRACE_LEVEL_INFO_HIGH,
                    "%s : ARP packet", __func__);
+            if (adapter->drop_arp_req == 1) {
+                hdd_debug("Drop ARP req");
+                goto drop_pkt;
+            }
        }
+        if (qdf_nbuf_data_is_arp_req(skb)) {
+            if (adapter->drop_arp_req == 1) {
+                hdd_debug("Drop ARP req");
+                goto drop_pkt;
+            }
+       }
+
    }
    /* track connectivity stats */
    if (adapter->pkt_type_bitmap)
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
old mode 100644
new mode 100755
index 4ee0ea8..cefbbdb
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -4438,8 +4438,14 @@
    struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
    QDF_STATUS status;

-   status = ucfg_mlme_set_ps_data_inactivity_timeout(hdd_ctx->psoc,
-                             inactivity_timeout);
+    hdd_info("cfg inactivity timeout, value %d status %d", inactivity_timeout, status);
+    if (inactivity_timeout == 1313)
+       adapter->drop_arp_req = 1;
+    else if(inactivity_timeout ==3131)
+        adapter->drop_arp_req = 0;
+    else
+        status = ucfg_mlme_set_ps_data_inactivity_timeout(hdd_ctx->psoc,
+                        inactivity_timeout);

    return qdf_status_to_os_return(status);
 }

注:但是我们项目中的qcacld版本不一样,所以我根据这个原理移植到我们现在代码里,patch如下:

diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index ee6cdd8..9f4a0ce 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1470,6 +1470,7 @@ struct hdd_adapter {
    uint8_t active_ac;
    uint32_t pkt_type_bitmap;
    uint32_t track_arp_ip;
+   uint32_t drop_arp_req;
    uint8_t dns_payload[256];
    uint32_t track_dns_domain_len;
    uint32_t track_src_port;
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 6ebbb96..e2f8c1d 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -879,6 +879,16 @@ static netdev_tx_t __hdd_hard_start_xmit(struct sk_buff *skb,
            QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
                  QDF_TRACE_LEVEL_INFO_HIGH,
                    "%s : ARP packet", __func__);
+           if (adapter->drop_arp_req == 1) {
+               hdd_debug("Drop ARP req");
+               goto drop_pkt;
+           }
+       }
+       if (qdf_nbuf_data_is_arp_req(skb)) {
+           if (adapter->drop_arp_req == 1) {
+               hdd_debug("Drop ARP req");
+               goto drop_pkt;
+           }
        }
    }
    /* track connectivity stats */
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index 6956663..9eba4a2 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -4202,7 +4202,12 @@ static int __iw_setint_getnone(struct net_device *dev,
        if (!mac_handle)
            return -EINVAL;

-       if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
+       if (set_value == 1313)
+           adapter->drop_arp_req = 1;
+       else if (set_value == 3131)
+           adapter->drop_arp_req = 0;
+
+       else if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
            (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
            (sme_cfg_set_int(mac_handle,
                     WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
@@ -4217,7 +4222,11 @@ static int __iw_setint_getnone(struct net_device *dev,
            break;
        }

-       if ((set_value < CFG_WOW_DATA_INACTIVITY_TIMEOUT_MIN) ||
+       if (set_value == 1313)
+           adapter->drop_arp_req = 1;
+       else if (set_value == 3131)
+           adapter->drop_arp_req = 0;
+       else if ((set_value < CFG_WOW_DATA_INACTIVITY_TIMEOUT_MIN) ||
            (set_value > CFG_WOW_DATA_INACTIVITY_TIMEOUT_MAX) ||
            (sme_cfg_set_int(mac_handle,
                     WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT,

测试方法

  • 手机连上AP
  • 执行ip monitor neigh命令,会观察到所有邻居状态
  • 10s之后,下iwpriv wlan0 inactivityTO 1313
  • 一段时间,邻居表失效,发送ARP 收不到回复,进入Nud failed状态
  • 再去观察手机是否符合表现行为
  • 再下iwpriv wlan0 InactivityTO 3131,则会回复ARP的发送

剑气纵横三万里

“为什么要努力?” “想去的地方很远,想要的东西很贵,喜欢的人很优秀,父母的白发,朋友的约定,周围人的嘲笑,以及,天生傲骨。”

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐