Rete bridge Linux influenzata dalla tabella di route


0

Stavo facendo un esperimento sul bridge linux e la mia topologia di rete è come:

inserisci qui la descrizione dell'immagine

Come puoi vedere, ci sono due host situati in una LAN, Host1 (10.74.68.58) e Host2 (10.74.68.47). Su Host1, ho creato un ponte br0 e assegnato un IP per esso (192.168.3.101). Quindi ho attaccato eth0 al bridge:

[root@10.74.68.58:~] # bridge link
2: eth0 state UP : <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 2

Ho impostato il percorso predefinito come br0 ed è ok per ping 10.74.68.47:

[root@10.74.68.58:~] # ip r
default dev br0  scope link
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.42.1
192.168.3.0/24 dev br0  proto kernel  scope link  src 192.168.3.101

Ma le cose sono diventate inspiegabili quando ho impostato il percorso predefinito su eth0 :

[root@10.74.68.58:~] # ip r
default dev eth0  scope link
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.42.1
192.168.3.0/24 dev br0  proto kernel  scope link  src 192.168.3.101

Quando eth0 è l'interfaccia di route predefinita, provo a eseguire il ping di host2 in due modi diversi:

1, ping 10.74.68.47

Impossibile. Dopo aver controllato il file tcpdump (acquisito sull'interfaccia br0), ho scoperto che br0 ha ricevuto solo una risposta ARP. Quindi non ci sono informazioni ARP sull'interfaccia eth0, quindi non può ottenere il mac di host2. Penso che questo sia il comportamento giusto, la mia comprensione è giusta?

2, poi ho provato ping -I br0 10.74.68.47

Volevo usare l'opzione -I per evitare la rotta predefinita, ma ho anche fallito. Dopo aver verificato il file tcpdump (acquisito sull'interfaccia br0), ho scoperto che esiste già una coppia di richieste di eco echo e pacchetti di risposte echo. Questo mi ha confuso molto. Ora che br0 ha ricevuto la risposta echo, perché non riesco a eseguire il ping su host2 correttamente?

[root@10.74.68.58:~] # ping -I br0 10.74.68.47
2 packets transmitted, 0 received, 100% packet loss, time 1006ms

inserisci qui la descrizione dell'immagine

Ragazzi, potete darmi dei consigli?

Risposte:


3

Il bridging non funziona come pensi che funzioni. :-)

Un bridge riguarda solo il livello OSI 2 (frame Ethernet). A questo livello, non esistono indirizzi IP ecc. Concettualmente, puoi pensare a un bridge come a una raccolta di interfacce Ethernet. Ogni interfaccia è chiamata porta e un pacchetto che va in una porta esce su tutte le altre porte. (In realtà, nell'implementazione di Linux, c'è un'ottimizzazione che mantiene una tabella di indirizzi MAC visti, ma concettualmente, non importa).

Quindi un bridge può collegare ("bridge") diversi segmenti Ethernet in un unico grande segmento.

Quindi cosa significa "assegnare a un bridge Linux un indirizzo IP"? Nell'implementazione di Linux, il bridge non è un dispositivo hardware separato (come in origine), ma è accessibile anche dall'host stesso. Ciò significa che si comporta come una sorta di "interfaccia super-ethernet" con molte porte, ma i pacchetti che vanno nel kernel o escono da questo kernel verso o da una di queste porte raggiungono il sistema operativo Linux con un singolo indirizzo IP.

Quindi non appena un'interfaccia Ethernet diventa uno slave (porta) di un bridge, cessa di avere il proprio indirizzo. L'unica cosa che conta è l'indirizzo IP del bridge.

In altre parole, creare un bridge con una sola porta non ha senso (avresti potuto usare l'interfaccia da sola). Cercare di instradare i pacchetti verso una porta di un bridge non ha senso (per quanto riguarda il kernel, il bridge è un singolo dispositivo).

Se vuoi giocare con un bridge, hai bisogno di una struttura come questa:

  10.0.2.1/23    10.0.2.2/23    10.0.3.254/23     10.0.3.1/23    10.0.3.2/23 

  ............   ............   ...............   ............   ............
  .  Host A  .   .  Host B  .   .  Host X     .   .  Host C  .   .  Host D  .
  .          .   .          .   . <-- br0 --> .   .          .   .          .
  .   eth0   .   .   eth0   .   . eth0   eth1 .   .   eth0   .   .   eth0   .
  .....|......   .....|......   ...|......|....   .....|......   .....|......
       |              |            |      |            |              |      
  -----+--------------+------------+      +------------+--------------+------

  <-------- left Segment  --------->      <------- right Segment ----------->

Qui il segmento sinistro con host A e B è collegato dall'host X al segmento destro con host C e D, e ogni host è accessibile da un singolo indirizzo IP (che è assegnato alle interfacce o al bridge nel suo insieme).


grazie mille per le tue istruzioni. Hai ragione, la mia topologia qui non è la pratica corretta per Linux Bridge. Ho impostato questa strana topologia per scoprire come scorre il pacchetto quando esiste un bridge. Ma dopo aver letto del materiale sul kernel Linux, ho scoperto che la mia domanda ha a che fare con l'opzione 'rp_filter'. E sebbene questa sia una topologia molto strana, può capitare di essere un ambiente di esperimento per testare la funzione 'rp_filter' :)
ruanhao,

AFAIK, rp_filterè il "filtro inverso" e funziona al livello 3 (pacchetti IP, routing), non al livello 2 (frame ethernet, bridge), quindi non credo che ci sia una connessione. Se si desidera testare il routing del kernel Linux, è necessario configurarlo come router, non come bridge.
Dirkt

1
Grazie! Questa è una risposta fantastica che ha chiarito alcune idee sbagliate che avevo sul bridge di rete.
gcarvelli,

-1

Quando trovi ping -I br0 10.74.68.47, Protocol stackl'ip (10.74.68.47) non è nella stessa LAN con br0, quindi invia ARP tramite eth0. Ma eth0 ha attaccato br0, non può connettere lo stack di protocollo, eth0 invierà la risposta ARP a br0, quindi br0 trova mac non corrispondente, quindi lo rilascia. quindi lo stack di protocollo non ottiene la risposta ARP.
È possibile modificare l'ip di br0 in 10.74.68.x / 24. sarà ok.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.