Jak zmienić kolejność kart sieciowych (eth1 <-> eth0) w systemie Linux

20

Czy jest jakiś sposób na zamianę interfejsów sieciowych ( eth1 <-> eth0 ) po instalacji systemu?

Mój nowy Debian 6.0 instaluje domyślnie przypisaną kartę sieciową PCI jako „ eth0 ”, a zintegrowane urządzenie sieciowe płyty głównej jako „ eth1 ”. Problem polega na tym, że chcę używać zintegrowanego urządzenia jako domyślnego interfejsu sieciowego ( eth0 ).

Już edytowałem:

/etc/udev/rules.d/70-persistent-net.rules

do zamiany nazw i wszystko wydaje się być w porządku, a sieć działa, ale programy nadal próbują używać karty sieciowej PCI (która jest teraz „ eth1 ”) jako domyślnego interfejsu. Na przykład iftop próbuje teraz użyć „ eth1 ” jako domyślnego urządzenia, ponieważ używał „ eth0 ” przed zamianą.

Czy jest to czysto problem programowy, ponieważ aplikacje próbują użyć pierwszego znalezionego urządzenia jako urządzenia domyślnego pomimo nazw interfejsu lub czy jest jakiś sposób, aby to naprawić, konfigurując system operacyjny?


edycja: Napisałem małą aplikację do wydrukowania iflist, a urządzenie PCI ( eth1 ) pojawiło się przed „ eth0 ”. Wszelkie pomysły, jak zamienić kolejność urządzeń.


edytuj: Znalazłem wątek na ten sam problem i wypróbowałem wszystko, co sugerują, i żadne z rozwiązań nie działa, z wyjątkiem zamiany nazw „wirtualnie”.

Athabaska Dick
źródło
Uwaga: edytowanie /etc/udev/rules.d/70-persistent-net.rules i ponowne uruchomienie zrobiły dla mnie
robotę

Odpowiedzi:

18

Odpowiadam teraz na moje pytanie, ponieważ w końcu znalazłem obejście tego problemu.

Dowiedziałem się, że można zmienić kolejność urządzeń, rozładowując sterowniki, a następnie ładując je we właściwej kolejności.

Pierwsza metoda (bruteforce):

Tak więc pierwszą metodą, którą wymyśliłem, była prosta brutalizacja siły przeładowania sterownika za pomocą skryptu init.d.

Poniższy skrypt init jest dostosowany do Debiana 6.0, ale ta sama zasada powinna działać na prawie każdej dystrybucji przy użyciu odpowiednich skryptów init.d.

#!/bin/sh -e

### BEGIN INIT INFO
# Provides:          reorder-nics
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Reloads the nics in correct order
### END INIT INFO

#
# This script should reload the nic drivers in corrected order.
# Basically it just unloads and then loads the drivers in different order.
#

echo "Reloading NICs!"

# unload the drivers
modprobe -r driver_0        # eth0 nic interface
modprobe -r driver_1        # eth1 nic interface

# load the drivers in corrected order
modprobe driver_1
modprobe driver_0

#EOF

Następnie skrypt należy dodać do odpowiedniego katalogu poziomu uruchamiania. Można to łatwo zrobić w Debianie za pomocą polecenia „ update-rc.d ”. Na przykład:update-rc.d reorder-nics start S


Druga metoda (lepiej myślę):

Znalazłem też nieco bardziej elegancki sposób (przynajmniej dla systemów Debian i Ubuntu).

Najpierw upewnij się, że jądro nie ładuje automatycznie sterowników karty sieciowej. Można to zrobić, tworząc plik czarnej listy w /etc/modprobe.d/. Utworzyłem plik o nazwie „ disable-nics.conf”. Pamiętaj, że pliki w /etc/modprobe.d/muszą mieć .confsufiks. Nazywanie modułów również /etc/modprobe.d/blacklist.confnie wpływa na automatyczne ładowanie modułów przez jądro, więc musisz stworzyć własny plik.

# Disable automatic loading of kernel driver modules
# Disable NIC drivers

blacklist driver_0     # eth0 by default
blacklist driver_1     # eth1 by default

Następnie uruchom „ depmod -ae ” jako root

Odtwórz initrd za pomocą ' update-initramfs -u '

I wreszcie dodaj nazwy sterowników w poprawionej kolejności do pliku / etc / modules .

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.

# drivers in wanted order
driver_1    # this one should be loaded as eth0
driver_0    # this one should be loaded as eth1

Zmiany powinny wejść w życie po następnym uruchomieniu.

Ponowne uruchomienie nie jest jednak konieczne; łatwo jest przełączać urządzenia za pomocą następującego polecenia (oczywiście jako root):

modprobe -r driver_0; modprobe -r driver_1; modprobe driver_1; modprobe driver_0

Kilka przydatnych linków, które znalazłem podczas wyszukiwania rozwiązania:

Athabaska Dick
źródło
2
+1 Zdecydowanie zasługujesz na więcej niż tylko jeden głos za to.
bahamat
Mam podobny problem: mam zintegrowaną kartę sieciową, a następnie czasami uruchamiam program VPN, który tworzy inny interfejs. Interfejs VPN zawsze wydaje się mieć pierwszeństwo, ale nie wiem dlaczego. Chcę, aby był używany tylko w bardzo rzadkich okolicznościach (chcę, aby aplikacja, która go używa, musiała określać interfejs VPN). Jakieś pomysły? ^ _ ^ Prawdopodobnie i tak wkrótce opublikuję nowe pytanie.
Ograniczone Zadośćuczynienie
2

Możesz użyć netdev=parametru wiersza poleceń jądra (musisz przekazać go do jądra w Grub), aby poinstruować jądro, aby połączyć dane IRQ z danym interfejsem, np .:netdev=irq=2,name=eth0

Frederik Deweerdt
źródło
1
Uruchomiłem swoje urządzenie z modyfikacjami konfiguracji gruba i wciąż otrzymuję eth1 jako domyślne urządzenie w wielu aplikacjach. Sprawdziłem dmesg dla sieci i informacji, a ona mówi, że zintegrowana karta sieciowa ma nadal „ eth1 ” jako ifname: forcedeth 0000:00:04.0: ifname eth1, PHY OUI 0x57d @ 1, addr 40:40:00:40:40:40. To nie jest zbyt poważny problem, ale naprawdę szlifuje mój sprzęt, ponieważ zintegrowana karta ma 1 GB i powinna być domyślnym urządzeniem.
Athabaska Dick
1
Próbowałem teraz użyć nameif do zmiany nazw interfejsów sieciowych, ale wygląda na to, że robi to samo co udev. Brak zmian w „prawdziwej” kolejności kart sieciowych. Próbowałem także zmienić fizyczną lokalizację PCI NIC, ale to też nie pomogło. Zintegrowana karta sieciowa ma IRQ 22, a karta PCI ma IRQ 17, więc wygląda na to, że jądro zamawia je przez IRQ i użytkownik nie może w żaden sposób zmienić tego faktu. Jakieś świeże pomysły?
Athabaska Dick
1

Prawdopodobnie będziesz musiał przejść do plików konfiguracyjnych programów, których dotyczy problem, i zmienić „eth1” na „eth0”. Domyślne ustawienia takich programów są konfigurowane podczas instalacji lub pierwszego uruchomienia z aktualnie wykrytymi kartami sieciowymi.

Używam Linuksa jako routera i miałem ten problem podczas używania skryptów. Mam teraz piękny fragment skryptu o nazwie netconfże źródło w jakiegokolwiek innego skryptu, gdy trzeba użyć nazwy NIC, plik ten daje mi centralnej lokalizacji, aby je określić (tj LAN_IFACE=eth0, WAN_IFACE=eth1itp)

LawrenceC
źródło
2
Wygląda na to, że wiele programów polega na funkcji if_nameindex () z nagłówka <net / if.h> . Używają tylko pierwszego znalezionego urządzenia i całkowicie ignorują nazwy interfejsów. Rozumiem, dlaczego tak się dzieje, znacznie łatwiej jest użyć pierwszego znalezionego urządzenia niż posortować nazwy.
Athabaska Dick
1

Nie można zmienić interfejsu używanego domyślnie w aplikacjach takich jak iftop. Wywołują funkcję biblioteki C if_nameindexi domyślnie używają pierwszego elementu w zwróconej tablicy. GNU libc's if_nameindexw Linuksie jest cienkim opakowaniem wokół SIOCGIFCONFioctl . Zwraca interfejsy w ustalonej kolejności, w oparciu o kolejność, w jakiej sterowniki sieciowe zostały zainicjowane i kolejność, w której każdy sterownik wykrywa każde urządzenie.

Jeśli naprawdę nie chcesz przechodzić -ido iftoppodobnych programów, możesz utworzyć małe opakowanie, if_nameindexktóre zmieni kolejność elementów na liście zwracanej za pomocą LD_PRELOAD. Nazwałbym to znacznie większym kłopotem niż jest tego warte.

Gilles „SO- przestań być zły”
źródło
Udało mi się także wskazać „problem” na if_nameindexfunkcjonowanie. Być może po prostu zostawię to na razie. Na szczęście niektóre aplikacje naprawdę sprawdzają nazwę interfejsu. Z drugiej strony niektóre aplikacje nawet nie mają domyślnych opcji konfiguracji, więc po prostu muszę użyć opcji -i. Zastanawiałem się, dlaczego opcja ładowania jądra netdev=irq=22,name=eth0nie działa? Pomyślałem, że powinna być możliwa zmiana kolejności kart sieciowych podczas uruchamiania jądra.
Athabaska Dick
Po krótkim spojrzeniu na źródło jądra ( for_each_netdevmakro) interfejsy są wyliczane w kolejności, w jakiej sterowniki są ładowane (z grubsza). Twoje interfejsy prawdopodobnie używają różnych sterowników, więc musisz ustawić ładowanie sterowników w żądanej kolejności. Spodziewałbym się, że będzie to trudne, szczególnie jeśli chcesz, aby twoje ulepszenie działało w ramach aktualizacji jądra.
Gilles „SO- przestań być zły”
1

Jeśli mają różne sterowniki, przynajmniej w dniu, w którym można umieścić jeden z plików konfiguracyjnych modułu:

alias eth0 driver1
alias eth1 driver2

To trochę stara wiedza, ale może pomóc.

Aaron D. Marasco
źródło
-1

Spójrz na pakiet „ifrename”. Umożliwia to zmianę nazw nazw interfejsów na podstawie różnych informacji, takich jak adres MAC interfejsu, sterownik, przerwanie ..., skonfigurowane w pliku / etc / iftab.

Kilka przykładów ze strony man:

   # This is a comment
   eth2      mac 08:00:09:DE:82:0E
   eth3      driver wavelan interrupt 15 baseaddress 0x390
   eth4      driver pcnet32 businfo 0000:02:05.0
   air*      mac 00:07:0E:* arp 1
   myvpn     SYSFS{address} 00:10:83:* SYSFS{type} 1
   bcm*      SYSFS{device} 0000:03:00.0 SYSFS{device/driver} bcm43xx
   bcm*      SYSFS{..} 0000:03:00.0 SYSFS{../driver} bcm43xx
Ben White
źródło
Witamy w U&L. Czy możesz udzielić nam pełnej odpowiedzi, a nie tylko podpowiedzi? Nie powinieneś publikować czegoś w rodzaju „istnieje strona podręcznika…”.
Archemar