我有一个 STB 设备(参考板),它装有 Android-M 和 Linux 内核 3.14.28-1.9pre。
在此板上,我有 2 个网络接口:
- gphy:有线接口(10.131.24.211)
- wlan0:无线接口(192.168.1.3)
使用无线接口,我将其关联到信道 6 上的 AP。然后,我尝试 ping 到 AP (192.168.1.1)。但 ping 失败。
root@bcm_platform:/system/bin/amar/43242a1 # ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
^C
--- 192.168.1.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
在另一个终端上,有线接口的 tcpdump 显示有线接口发送了针对地址 10.131.24.1 的 arp 请求,并且有线接口也收到了 ARP 答复。但是当我尝试在无线接口上使用 tcpdump 时,没有看到任何 arp 请求/响应。
130|root@bcm_platform:/system/bin/amar/43242a1 # tcpdump -nni gphy arp
[ 2938.268561] device gphy entered promiscuous mode
[ 2938.273205] device eth0 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on gphy, link-type EN10MB (Ethernet), capture size 65535 bytes
13:51:20.047056 ARP, Request who-has 10.131.24.1 tell 10.131.24.211, length 28
13:51:20.048108 ARP, Reply 10.131.24.1 is-at 00:00:0c:07:ac:18, length 46
13:50:50.047057 ARP, Request who-has 10.131.24.1 tell 10.131.24.211, length 28
13:50:50.048132 ARP, Reply 10.131.24.1 is-at 00:00:0c:07:ac:18, length 46
检查 arp 条目时,只有 2 个条目与有线接口相关。第一个有线条目用于有线接口,第二个条目用于通过有线接口从主机 (10.131.24.203) 进行 adb 连接。没有为无线接口添加任何条目。
root@bcm_platform:/system/bin/amar/43242a1 # /system/xbin/busybox arp
? (10.131.24.1) at 00:00:0c:07:ac:18 [ether] on gphy
? (10.131.24.203) at d4:be:d9:6a:f8:77 [ether] on gphy
然后我尝试通过指定无线接口名称来 ping 操作,效果很好。
root@bcm_platform:/system/bin/amar/43242a1 # ping -I wlan0 192.168.1.1
64 bytes from 192.168.1.3 wlan0: 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=72.2 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=8.25 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=9.12 ms
在另一个终端上,无线接口上的 tcpdump 用于 arp 数据包,清楚地显示了对 192.168.1.1 的 arp 请求和 arp 回复。
130|root@bcm_platform:/system/bin/amar/43242a1 # tcpdump -nni wlan0 arp
[ 3191.490560] device wlan0 entered promiscuous mode
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
13:54:58.395951 ARP, Request who-has 192.168.1.3 tell 192.168.1.1, length 28
13:54:58.396032 ARP, Reply 192.168.1.3 is-at 00:90:4c:a5:12:38, length 28
现在我再次检查 arp 条目,发现添加了无线接口(wlan0)的条目。
130|root@bcm_platform:/system/bin/amar/43242a1 # /system/xbin/busybox arp
? (192.168.1.1) at 00:90:4c:0f:f1:47 [ether] on wlan0
? (10.131.24.203) at d4:be:d9:6a:f8:77 [ether] on gphy
? (10.131.24.1) at 00:00:0c:07:ac:18 [ether] on gphy
从该分析中可以看出,尽管在无线接口上为无线接口请求 arp,但 arp 请求仍在有线接口上和有线 ip 地址上发送。
如果我禁用有线接口,一切就正常工作。
1|root@bcm_platform:/system/bin/amar/43242a1 # ifconfig gphy down
1|root@bcm_platform:/system/bin/amar/43242a1 # ping 192.168.1.1
64 bytes from 192.168.1.3 wlan0: 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=72.2 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=8.25 ms
arp 表显示 192.168.1.1 的条目
有人能为这个问题提供解决方案吗?
问候,阿马尔
答案1
尝试这个:
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
从https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
arp_announce - INTEGER 定义在接口上发送的 ARP 请求中的 IP 数据包中宣布本地源 IP 地址的不同限制级别:
0 - (默认)使用在任何接口上配置的任何本地地址
1 - 尽量避免此接口的目标子网中没有的本地地址。当通过此接口可访问的目标主机需要 ARP 请求中的源 IP 地址是接收接口上配置的逻辑网络的一部分时,此模式非常有用。当我们生成请求时,我们将检查包含目标 IP 的所有子网,如果源地址来自此类子网,我们将保留源地址。如果没有这样的子网,我们将根据级别 2 的规则选择源地址。
2 - 始终为该目标使用最佳本地地址。在此模式下,我们忽略 IP 数据包中的源地址,并尝试选择我们喜欢的本地地址与目标主机进行通信。通过在包含目标 IP 地址的传出接口上查找我们所有子网上的主 IP 地址来选择此类本地地址。如果没有找到合适的本地地址,我们会选择传出接口或所有其他接口上的第一个本地地址,希望我们能收到对我们请求的回复,有时甚至不管我们宣布的源 IP 地址是什么。
使用 conf/{all,interface}/arp_announce 中的最大值。
增加限制级别会增加从已解析目标接收答复的机会,而降低限制级别则会公布更有效的发送者信息。