Mi programa necesita conectarse a dos interfaces TAP que viven en su propio espacio de nombres de red. Debido a que setns() funciona en el nivel de pthread, planeo tener un pthread dedicado para cada interfaz. (Mi programa en sí se ejecuta en el espacio de nombres "raíz").
Sin embargo, la función setns() requiere que pase un descriptor de archivo al espacio de nombres de la red que quiero ingresar. Obtener este descriptor requiere el pid de un proceso que ya existe en ese espacio de nombres. Una vez que tenga ese PID, puedo hacer una llamada a open() para obtener el descriptor del archivo en el espacio de nombres de la red:
int fd = open("/proc/<pid>/ns/net");Pero, ¿cómo obtengo ese PID?
Una forma sería crear un proceso "ficticio" en el espacio de nombres deseado:
ip netns exec tap101-ns sleep 100 & [1] 30645 Y luego use ese PID en mi programa: int fd = open("/proc/30645/ns/net")
Sin embargo, esta forma de trabajar parece un poco tonta...
¿Existe una forma más limpia de ingresar un espacio de nombres de red cuando todo lo que tengo es el nombre del espacio de nombres que quiero ingresar?
Me topé con una solución poco después de publicar mi pregunta.
La ruta /var/run/netns/ también se puede usar para obtener un descriptor de archivo. Según la documentación de ip-netns :
El descriptor de archivo resultante de abrir /var/run/netns/NAME hace referencia al espacio de nombres de red especificado. Mantener ese descriptor de archivo abierto mantiene vivo el espacio de nombres de la red. El descriptor de archivo se puede usar con la llamada al sistema setns(2) para cambiar el espacio de nombres de red asociado con una tarea.
Entonces puedo usar este código para cambiar a un espacio de nombres dentro de mi pthread:
int namespace_fd = open("/var/run/netns/tap101-ns"); setns(namespace_fd, CLONE_NEWNET);