您的位置:首页 > 理论基础 > 计算机网络

在多个网卡的机器上利用socket进行网络测试的问题

2012-09-07 10:31 357 查看
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=program&Number=641137&fpart=all

用的是arm的嵌入式板子,内核用的是linux-2.6.19,有四块dm9000网卡。系统起来之后用ifconfig配置eth0-eth3不同的ip地址/mac地址,然后用socket监听四个不同的端口(5005-5007)。

一个板子的ip地址加一个不同的端口(5005-5007)形成一个socket接口,在pc上分别向这四个socket接口,发送数据。按理说数据会通过板子的每一个网卡传送到应用层。但是奇怪的是应用软件工作正常,但是底层的数据竟然只是通过其中的两个网卡,另外两个基本上空闲。

再做一个简单的例子,在pc上ping板子的四个ip。然后将板子上的其中一个ip地址ifconfig down掉,这个地址竟然也能ping通。也说明数据包是通过另外的网卡传递的。

这样的话,网卡的负载岂不是不均衡。这种现象所表现出的策略,内核是在哪一部分实现的呢?

你这4个网卡是分别通过各自的链路连接到外面吗?

在linux里面,ip地址是属于host的,不是属于网卡的,

因此可以ping通,只要这个ip地址是host的ip之一。

我想这可能是原因。

但如果你的数据是从不同的链路到达不同的网卡,

那应该是每个网卡各自处理自己的数据啊?

\

这四个网卡是通过hub接到一个局域网的,也就是同一个网段的地址

我也怀疑这是linux系统的特性,或者windows也是这样?

如果二个网卡都连到一个hub,但是分成两个子网段,那么会不会出现这种现象呢。ip地址既然属于host的,那不同子网段的ip地址,host也应该能认识阿。

问题是,你如果mac地址不同的话,什么情况也应该不会接收啊?

我猜可能和arp协议有关系。

由于几个网卡的ip地址属于同一个网段,解析ip->mac地址的包所有的网卡都能收到,

由于接收的时间可能有先后,同时由于在linux中,ip地址是属于host的,

因此某个网卡会代为回应arp,告知自己的mac,因此形成这样的局面。

Understanding Linux Network internals这本书应该讲了.

\

查了一下书,就是这个原因。

由于所有的网卡都收到所有的arp request(包括针对其他网卡的request),

并且都会回应,但回应的先后顺序不同,最后一个有效,

会导致其他网卡的ip地址绑定到本网卡的mac地址上。

从而造成这种结果。

可以设置

/proc/sys/net/ipv4/conf/all/arp_ignore = 1

/proc/sys/net/ipv4/conf/all/arp_filter = 1

>>问题是,你如果mac地址不同的话,什么情况也应该不会接收啊?

正怀疑这个问题

>>查了一下书,就是这个原因。

能告诉我出处吗,谢了

>>由于所有的网卡都收到所有的arp request(包括针对其他网卡的request),

并且都会回应,但回应的先后顺序不同,最后一个有效

你是说系统上的arp服务会把本机同一个网段所有的ip地址对应的mac地址都回复出去?

这样做有什么意义呢?而且还会出现网卡负载不均衡的情况。

我用sniffer抓抓看。

>>proc/sys/net/ipv4/conf/all/arp_ignore = 1

/proc/sys/net/ipv4/conf/all/arp_filter = 1

多谢!

出处是

Understanding Linux Network internals

讲ARP的那一章。

》你是说系统上的arp服务会把本机同一个网段所有的ip地址对应的mac地址都回复出去?

》这样做有什么意义呢?而且还会出现网卡负载不均衡的情况。

linux内核会把针对本host的所有ip地址的arp request都响应。

比如,本host有两个网卡netcard1和netcard2,ip地址分别是ip1和ip2。

如果在netcard2上接收到arp request,而这个arp request是要求解析ip1的,即netcard1的ip地址。

由于linux认为ip地址是属于host的,netcard2同样会回应这个请求,

但回复的mac地址是自己的mac地址,即netcard2的mac地址。

这样,ip1就和netcard2的mac地址绑定了,

以后,所有发给ip1的数据都会发给netcard2。

不管是不是同一个网段,情况都是一样的。

确实是这样,即使不是同一个网段

但是设置arp_filter好像根本就没有起作用。arp回复的mac地址还是另外一个网卡的

arp_ignore应该是禁止arp回复了。

看了一下代码,

/proc/sys/net/ipv4/conf/all/arp_ignore=1的确切含义是,

如果arp请求的ip地址是本接收网卡的ip地址,才回应。

这就保证了只有自己才会回应自己ip地址的arp请求。

/proc/sys/net/ipv4/conf/all/arp_filter = 1 的确切含义是,

对arp请求的ip地址,内核会进行一次路由查找,

只有查找结果的输出网卡=接收时的网卡,才回应。

这样,问题应该是,

在你的机器上,由于设置了缺省路由,因此每次路由查找都会找到同一个网卡,

因此,对于另外3个网卡,会出现arp_filter条件不满足的情况。

所以会不回应arp。

你提到的那个链接的帖子,可以成功,是因为它分别设置了路由,

因此arp_filter会满足条件,所以会回应。

我想,下面的设置应该可以(应该不需要象那篇帖子那样设置路由):

/proc/sys/net/ipv4/conf/all/arp_ignore=1

/proc/sys/net/ipv4/conf/all/arp_filter = 0

另外,注意各个网卡自身的arp_ignore和arp_filter设置,不要冲突。

(缺省配置应该都是0,应该就可以)

/proc/sys/net/ipv4/conf/ethX/arp_ignore

/proc/sys/net/ipv4/conf/ethX/arp_filter

想到另外一点,为每个网卡分别设置policy routing rule路由还是有好处的(像你提到的那个帖子)。

(以下内容有错误,仅供参考)

因为如果只有一个缺省路由,会出现:

1)如果remote不是在同一个物理网段,会使得绑定在不同网卡的应用程序发出的所有数据,都从同一个网卡发出。

2)如果remote是在同一个物理网段,则会使得绑定在不同网卡的应用程序发出的所有数据,从不同的网卡发出,从而达到分散负载的目的。

这是因为,每配置一个ip地址时,内核只配置一个onlink的路由。如那个帖子中的

> # ip route

> 192.168.5.0/24 dev eth0 proto kernel scope link src 192.168.5.220

> 192.168.5.0/24 dev eth1 proto kernel scope link src 192.168.5.221

> 192.168.5.0/24 dev eth2 proto kernel scope link src 192.168.5.222

当remote是同一个物理网段的机器,即onlink,则数据的发送时,路由查找会找到相应的网卡。

当remote不是同一个物理网段的机器,则数据的发送时,路由查找会找到缺省路由,

这样,所有的数据将从同一个网卡发出,即那个缺省路由的网卡。

\

错了错了,更正一下。

如果不为每个网卡设置policy routing rule(如那个帖子中所示),

不管remote是不是在同一个物理网段,应用程序发出的数据都将只会从一个网卡发出。

虽然接收的数据会从各自的网卡接收。

这是因为,发送时查找路由时,如果有多条路由到达remote,内核只会选择第一条,

因此只依赖于哪条路由排在前面。

设定policy routing rule(如那个帖子中所示)后,路由查找加入了源地址的因素,

因此才可以找到合适的网卡。

chengzhu,能不能验证一下,是不是这样?

Oh,sh-i-t,又错了。

remote是否在一个子网,还是有区别的。

如果是在一个子网,路由查找将从几个onlink的路由中找到第一个。

如果不是一个子网,路由查找将始终找到缺省的路由。

测试结果:

(1)在不设置路由的情况下:

/proc/sys/net/ipv4/conf/all/arp_ignore=1

/proc/sys/net/ipv4/conf/all/arp_filter = 0

在PC上ping多网卡机器的两个ip地址,返回的mac地址和ip地址是一一对应的,但是因为多网卡机器获得的路由并不一定是请求arp的ip地址对应的网卡,所以多网卡系统的数据发送还是从一个网卡出去,后续的数据接收是根据ip地址对应。

/proc/sys/net/ipv4/conf/all/arp_ignore=1

/proc/sys/net/ipv4/conf/all/arp_filter = 1

正如你所说,因为路由满足不了arp_filter的要求,所以其中的一个网卡不会回复arp请求。

/proc/sys/net/ipv4/conf/all/arp_ignore=0

/proc/sys/net/ipv4/conf/all/arp_filter = 0

在PC上ping多网卡机器的两个ip地址,返回的mac基本上都是一样,所以多网卡系统的数据发送和接收基本上都是走那个mac地址所对应的网卡

(2)设置路由的情况下:

只要设置arp_ignore,数据基本上是根据ip从不同的网卡发送/接收

不同网段的ip地址表现基本上一样。

--------------------

Sinkin
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: