Mudar para um namespace de rede não muda / sys / class / net?

2

A página man do Linux para namespaces de rede (7) diz:

Network namespaces provide isolation of the system resources associated with networking: [...], the /sys/class/net directory, [...].

No entanto, simplesmente mudar para um namespace de rede diferente não parece alterar o conteúdo de /sys/class/net (veja abaixo como se reproduzir). Estou apenas enganado aqui ao pensar que o namespace setns() no network já é suficiente? É sempre necessário remontar /sys para obter o /sys/class/net correto correspondente ao namespace de rede atualmente unido? Ou estou faltando alguma outra coisa aqui?

Exemplo para reproduzir

Pegue um sistema * ubuntu, encontre o PID do daemon rtkit, digite o namespace de rede do daemon, mostre suas interfaces de rede e, em seguida, verifique /sys/class/net :

$ PID='sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2'
$ sudo nsenter -t $PID -n
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ls /sys/class/net
docker0  enp3s0  lo  lxcbr0  ...

Observe que, enquanto ip link show mostra corretamente lo , /sys/class/net mostra todas interfaces de rede visíveis no namespace de rede "raiz" (e namespace de montagem "root").

No caso de rtkit-daemon , também inserir o namespace de montagem não faz diferença: sudo nsenter -t $PID -n -m e, em seguida, ls /sys/class/net ainda mostram interfaces de rede não presentes no namespace da rede.

"Corrigir"

Muitos elogios para @Danila Kiver para explicar o que realmente está acontecendo por trás das cenas do kernel do Linux. Remontando sysfs enquanto o namespace de rede correto é unido, mostrará as entradas corretas em /sys/class/net :

$ PID='sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2'
$ sudo nsenter -t $PID -n
# MNT='mktemp -d'
# mount -t sysfs none $MNT
# ls $MNT/class/net/
lo
# umount $MNT
# rmdir $MNT
# exit

Portanto, isso agora gera os resultados corretos em /sys/class/net .

    
por TheDiveO 18.07.2018 / 16:59

1 resposta

2

Vamos analisar man 5 sysfs :

/sys/class/net
    Each  of the entries in this directory is a symbolic link representing
    one of the real or virtual networking devices that are visible in 
    the network namespace of the process that is accessing the directory.

Portanto, de acordo com essa manpage, a saída de ls /sys/class/net deve depender do namespace de rede do processo ls . Mas ... O comportamento real não parece ser o descrito nesta manpage. Existe uma boa documentação do kernel sobre como ele funciona .

Cada sysfs mount tem uma tag de namespace associado a isso. Esta tag é definida quando o sysfs é montado e depende do namespace de rede do processo de chamada . Cada entrada do sysfs (por exemplo, uma entrada em /sys/class/net ) também pode ter uma tag de namespace associado a ele.

Quando você faz iteração sobre o diretório sysfs, o kernel obtém a tag de namespace o sysfs mount e, em seguida, itera as entradas, filtrando aqueles que têm uma tag de namespace diferente .

Assim, os resultados de iteração sobre o /sys/class/net dependem do namespace de rede do processo que iniciou /sys mount em vez do namespace de rede do processo atual, portanto, você deve sempre montar /sys no namespace de rede atual (de qualquer processo pertencente a este namespace) para ver os resultados corretos.

    
por 20.07.2018 / 10:46