Mesma rede em interface diferente

4

Trabalhamos com dispositivos que são transmitidos (de fábrica) usando o TFTP em uma conexão de rede USB.

O servidor tem um endereço fixo 192.168.2.100 e o dispositivo um endereço fixo 192.168.2.101. Quando ele inicia, ele se conecta para fazer o download do firmware.

Na configuração atual, apenas um dispositivo pode funcionar ao mesmo tempo. Mas eu gostaria de tornar possível o flash de tantos dispositivos que podemos conectar (porque podemos ter alguns requisitos de flashing massivos).

Para contornar o problema de roteamento, fiz uma versão do xinetd que define um setsockopt para SO_BIND_DEVICE.

Mas o que eu não fiz foi que o Linux não é capaz de lidar com as solicitações ARP em ambas as interfaces ao mesmo tempo.

se eu fizer um "ping 192.168.2.101 -I usb0" e "ping 192.168.2.101 -I usb1" ao mesmo tempo, ele funcionará em uma interface:

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

Mas, por outro lado, não vai:

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

O servidor não parece responder à solicitação ARP.

É assim que a conexão do dispositivo é tratada no servidor com um script /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 

Aqui está a versão modificada do xinetd: link

    
por Florent 07.09.2013 / 02:30

1 resposta

2

Primeiro, se você não tentou o proxy arp sozinho, você deve tentar o proxy arp.

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

Opção 1: alguma configuração de rota connmark / política

Se o proxy arp sozinho não funcionasse, não posso garantir que isso funcionará, mas vale a pena um tiro, eu acho. O que estou prestes a descrever é como configurar o roteamento de políticas para vincular respostas com base na interface de entrada usando o conntrack. Descreverei como configurá-lo para duas interfaces e será fácil expandir para qualquer número. Por outro lado, em vez de funcionar, ele pode ficar muito confuso e não fazer nada (provavelmente porque a tabela de arp do kernel não sabe se deve armazenar em cache pares ip / mac por dispositivo). Se isso acontecer, tente o segundo método mais feio.

Primeiro, configure algumas regras de mangle do connmark:

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

Em / etc / iproute2 / rt_tables adicionar duas tabelas, 100 e 101, rotulá-las usb0 e usb1

100    usb0
101    usb1

Para cada uma dessas tabelas, adicione o seguinte (substitua < N > pelo número apropriado):

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>

Não tenho certeza, mas você pode precisar configurar uma interface fictícia para que seu daemon tftp escute:

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

Agora teste com dois dispositivos. Se funcionar, excelente, caso contrário, tente o próximo método:

Opção 2: contêiner kvm por dispositivo de rede usb

A opção 2 é mais feia, envolvendo alguma ponte e qemu / kvm. virt-manager é provavelmente a maneira mais fácil de criar essas coisas.

Crie dispositivos de toque e pontes, um por interface 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.

Crie um arquivo de imagem kvm ou um CD de inicialização projetado para ser somente de leitura e hospede seu servidor tftp e imagem ... ou omita somente leitura e crie um arquivo de imagem por vm (usar instantâneos para isso seria melhor, mas isso está mais fora do escopo do que esta resposta está ficando).

Execute um kvm usando a interface de toque e seu arquivo de imagem e teste a conectividade de rede usb.

Comparação

Se a rota connmark / policy funcionar, é muito mais fácil manter o repositório tftp em sincronia. Com o KVM, talvez seja necessário ter um repositório por imagem de VM (a menos que você passe um diretório somente leitura para cada VM, o que é factível). O Connmark / policy route é um pouco mais meticuloso, mas também requer apenas um servidor tftp, embora se suas portas não forem aleatórias o suficiente, o conntrack pode ficar confuso e sobrescrever se houver uma sobreposição de porta (ou talvez não). Por outro lado, colmatar a kvms requer muito mais memória; uma VM inteira por dispositivo USB conectado, mas é muito mais provável que funcione sempre porque a VM tem uma pilha de rede isolada inteira para trabalhar enquanto o kernel do host precisa passar pacotes de uma ponte para outra, especialmente se a filtragem de ponte está desligado.

Espero que um desses dois funcione para você.

    
por 08.09.2013 / 08:38

Tags