linux – 不同界面上的相同网络

前端之家收集整理的这篇文章主要介绍了linux – 不同界面上的相同网络前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们使用在USB网络连接上使用TFTP进行闪存(工厂)的设备.

服务器具有固定的192.168.2.100地址,设备具有固定的192.168.2.101地址.启动时,它会连接下载固件.

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

为了绕过路由问题,我制作了一个xinetd版本,将setsockopt设置为SO_BIND_DEVICE.

但我没有说的是,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,length 64

但另一方面它不会:

IP 192.168.2.100 > 192.168.2.101: ICMP echo request,id 31071,length 64
ARP,Request who-has 192.168.2.100 tell 192.168.2.101,seq 2,length 64
IP 192.168.2.100 > 192.168.2.101: ICMP echo request,id 31077,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,那么您应该尝试使用proxy arp.
echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp

选项1:一些connmark / policy route mangling

如果单独使用代理arp不起作用,我不能保证这会起作用,但我认为它值得一试.我要描述的是如何设置策略路由以使用conntrack基于输入接口绑定响应.我将描述如何为两个接口设置它,它应该很容易扩展到任何数字.另一方面,它可能只是变得非常困惑而不是工作(可能是因为内核arp表不知道它应该缓存每个设备的ip / mac对).如果发生这种情况,请尝试第二种更难看的方法.

首先,设置一些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

对于这些表中的每一个,添加以下内容(将< 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

现在测试两个设备.如果它工作,优秀,否则尝试下一个方法

选项2:每个usb网络设备的kvm容器

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

创建tap设备和桥接器,每个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.

创建一个kvm映像文件或启动CD,设计为只读并托管您的tftp服务器和映像…或省略只读,并为每个vm制作一个映像文件(使用快照更好,但更多的是范围比这个答案得到的).

使用tap界面和图像文件运行kvm并测试usb网络连接.

对照

如果connmark / policy route工作,则同步维护tftp存储库要容易得多.使用KVM,您可能需要为每个VM映像创建一个存储库(除非您将只读目录传递给每个VM,这是可行的). Connmark /策略路由有点挑剔,但它也只需要一个tftp服务器,但如果你的端口不够随机,conntrack可能会混淆并覆盖端口重叠(或者它可能没有).另一方面,桥接到kvms需要更多的内存;每个连接的USB设备都有一个完整的虚拟机,但每次都有可能工作,因为虚拟机有一个完整的隔离网络堆栈可以使用,而主机内核只需要通过网桥来回传递数据包,尤其是桥接过滤时已关闭.

希望这两个中的一个适合你.

猜你在找的Linux相关文章