同一networking在不同的界面上

我们使用在USBnetworking连接上使用TFTP闪存(工厂)的设备。

服务器有一个固定的192.168.2.100地址和一个固定的192.168.2.101地址的设备。 当它启动时,它连接到下载固件。

在当前的设置中,只有一个设备可以同时工作。 但是我希望能够尽可能多的刷新设备(因为我们可以有一些大规模的刷新要求)。

为了绕过路由问题,我做了一个将setsockopt设置为SO_BIND_DEVICE的xinetd版本。

但是除了Linux无法同时处理两个接口上的ARP请求外,

如果我同时做一个“ping 192.168.2.101 -I usb0”和“ping 192.168.2.101 -I usb1”,它将在一个接口上工作:

ARP, Request who-has sk tell 192.168.2.100, length 28 ARP, Reply 192.168.2.101 is-at 7a:0f:66:7c:fc:2c (oui Unknown), length 28 IP 192.168.2.100 > 192.168.2.101: ICMP echo request, id 21807, seq 1, length 64 IP 192.168.2.101 > 192.168.2.100: ICMP echo reply, id 21807, seq 1, length 64 

但另一方面则不会:

 IP 192.168.2.100 > 192.168.2.101: ICMP echo request, id 31071, seq 1, length 64 ARP, Request who-has 192.168.2.100 tell 192.168.2.101, length 28 ARP, Request who-has 192.168.2.100 tell 192.168.2.101, length 28 IP 192.168.2.100 > 192.168.2.101: ICMP echo request, id 31071, seq 2, length 64 IP 192.168.2.100 > 192.168.2.101: ICMP echo request, id 31077, seq 1, length 64 ARP, Request who-has 192.168.2.100 tell 192.168.2.101, length 28 

服务器似乎没有回答ARP请求。

这是如何使用/etc/network/if-up.d/000-first脚本在服务器上处理来自设备的连接:

 ifconfig $IFACE up ifconfig $IFACE 192.168.2.100 PID=/var/run/xinetd-$IFACE.pid # this is the modified xinetd version to bind on one address kill -9 `cat $PID` xinetd -pidfile $PID -interface $IFACE # I tried this to force the handling of ARP table per interface, but it doesn't change anything: # /usr/sbin/arpd -b /tmp/$IFACE.db -a 3 -k $IFACE 

这是修改后的xinetd版本: https : //github.com/fclairamb/xinetd/commit/1f5c1e8f9944e372b137e6aa46247f8de807bece#L8R253

首先,如果你还没有尝试过自己的代理ARP,你应该尝试代理ARP。

 echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp 

选项1:一些connmark /政策路线mangling

如果代理arp单独不起作用,我不能保证这将工作,但我认为这是值得一试。 我将要描述的是如何设置策略路由来使用conntrack根据input接口绑定响应。 我将介绍如何设置两个接口,并且应该很容易扩展到任意数量。 另一方面,不是工作,它可能只是非常困惑,而不是做一个该死的事情(可能是因为内核ARP表不知道它应该caching每个设备的IP / MAC对)。 如果发生这种情况,尝试第二种更丑陋的方法。

首先,build立一些connmark mangle规则:

 iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT 

在/ etc / iproute2 / rt_tables中添加两个表100和101,将它们标记为usb0和usb1

 100 usb0 101 usb1 

对于每个表格,添加以下内容(用适当的数字replace<N>):

 ip route add 192.168.2.0/24 dev usb<N> table usb<N> ip rule add fw <N> table usb<N> iptables -t mangle -A PREROUTING -i usb<N> -j MARK --set-mark <N> 

我不确定,但是您可能需要为您的tftp守护进程设置一个虚拟接口来监听:

 modprobe dummy ifconfig dummy0 192.168.2.100/32 up echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp sysctl net.ipv4.ip_forward=1 iptables -I FORWARD -s 192.168.2.100 -j ACCEPT iptables -I FORWARD -d 192.168.2.100 -j ACCEPT 

现在用两个设备进行testing。 如果它工作,优秀,否则尝试下一个方法:

选项2:每个USB设备的kvm容器

选项2是丑陋的,涉及一些桥接和qemu / kvm。 virt-manager可能是创build这些东西的最简单的方法。

创build点击设备和网桥,每个USB接口一个。

 tunctl -t tap<N> brctl addbr usb<N>br brctl addif usb<N>br tap<N> brctl addif usb<N>br usb<N> # this may need to be done each time the usb device is connected/disconnected. 

创build一个kvm映像文件或引导CD,它被devise为只读,并托pipe您的tftp服务器和映像…或者省略只读,并且每个虚拟映像文件创build一个映像文件(使用快照会更好,但更多范围比这个答案越来越)。

使用tap界面和图像文件运行kvm并testingusbnetworking连接。

对照

如果connmark / policy路由起作用,那么同步维护tftp库就容易了。 使用KVM,您可能需要为每个虚拟机镜像创build一个存储库(除非您将只读目录传递给每个虚拟机,这是可行的)。 Connmark /策略路由是一个更挑剔的,但它也只需要一个tftp服务器,但如果你的端口不够随机,conntrack可能会混淆和覆盖,如果有一个端口重叠(或不可能)。 另一方面,桥接kvms需要更多的内存; 每个连接的USB设备都有一个整个虚拟机,但是每次都有可能工作,因为虚拟机有一个完整的独立networking堆栈可以使用,而主机内核只需要通过网桥来回传递数据包,尤其是在网桥过滤已closures。

希望这两个之一为你工作。