Observe la estructura de la dirección IP de la tarjeta de red Linux a partir de la diferencia entre ip addr add e ifconfig
La dirección IP representada por cada nodo identifica un segmento de red. La IP de este nodo es la dirección principal de este segmento de red y la IP debajo de él es la dirección secundaria de este segmento de red. En otras palabras, una tarjeta de red puede tener la suma de las longitudes de las listas enlazadas de cada nodo, y estas IP no son lineales, sino la estructura de catenaria mencionada anteriormente. Veamos cuáles son los beneficios de esto. Los amigos que han jugado con enrutadores Cisco probablemente sepan que existe un concepto de IP secundaria, que puede crear subredes lógicas, lo que significa conectar dos subredes en un puerto de red físico. Esto puede parecer increíble, pero en realidad es muy sencillo. Por ejemplo, si este puerto de red está conectado a un conmutador, si este puerto de red no está configurado con una IP secundaria, este conmutador solo puede conectarse a hosts en un segmento de red. Por ejemplo, 192.168.1.1/24. Pero si se configura una IP secundaria, puede conectar hosts en dos segmentos de red, como 192.168.1/24. Tenga en cuenta que la IP secundaria en el ejemplo anterior no es la dirección secundaria de Linux mencionada aquí. Por el contrario, en Linux, siempre que la IP configurada en la tarjeta de red no sea un segmento de red, es una IP de primer nivel, es decir, la IP en la cadena principal sobre la estructura de la cadena colgante. La dirección en Linux es el punto de subenlace del punto de enlace principal. Hay que tener cuidado de no confundir conceptos. Lo que mencioné anteriormente es solo el papel de la cadena principal en la cadena de elevación, pero ¿qué pasa con la subcadena? De hecho, es muy sencillo de imaginar. En relación con la máquina que ejecuta el servidor proxy o el servicio de equilibrio de carga, el servidor proxy o el servicio de equilibrio de carga y el servidor principal deben escuchar el mismo puerto, entonces la dirección secundaria se puede usar para resolver el problema, siempre que sea una La aplicación que necesita escuchar el mismo puerto en el mismo segmento de red son todas razones para la existencia de subcadenas en la cadena colgante. Por lo tanto, se puede decir que la cadena principal virtualiza múltiples tarjetas de red en la capa de enlace externa o inferior, y la subcadena virtualiza múltiples máquinas en la capa superior. Si un host Linux con estructura de catenaria tiene solo una tarjeta de red, el exterior pensará que tiene varias tarjetas de red y, internamente, la capa de aplicación pensará que están en diferentes hosts. ?
Además de la introducción general anterior, hay muchos detalles. No hay primario ni secundario en la cadena principal. Todos los nodos de la subcadena, excepto el primer nodo, son paralelos, pero el primer nodo de la subcadena siempre está vinculado en la cadena principal. Las direcciones que llevan son las direcciones principales. Ellos La dirección que lleva la subcadena a continuación es la dirección secundaria de esta dirección principal. De esta manera, una vez que se elimina un nodo de la cadena principal, esta estrategia no siempre es tan buena, porque cuando el padre comete un error, el hijo sufrirá. Esto ya ha sucedido de vez en cuando en la sociedad moderna. es necesario cambiar el mecanismo. Entonces, hay una opción en Linux, es decir, cuando se elimina una dirección primaria, si tiene una dirección secundaria, entonces su primera dirección secundaria (el hijo mayor) hereda la ubicación de la dirección primaria eliminada y se convierte en la dirección primaria. es muy razonable. De lo contrario, si un programa utiliza una dirección secundaria al eliminar la dirección principal, la eliminación se retrasará o el programa fallará y no habrá ningún problema con la estrategia de promoción automática. ?
En cuanto a los alias de IP, existían en versiones anteriores. Este es un problema de implementación. El problema resuelto es el mismo que el del mecanismo de IP secundario actual. Principalmente agrega un sufijo al nombre de la tarjeta de red física para convertirse en una interfaz de red virtual, que es esencialmente el mismo que el mecanismo de IP secundario.
La diferencia es que los alias de IP no son tan intuitivos. Sin embargo, las IP secundarias realmente permiten que las aplicaciones vean múltiples direcciones para una sola tarjeta de red. Por ejemplo, cuando uso alias de IP, a veces siempre pregunto qué es eth0:0. Una vez intenté encontrar el código de registro para el dispositivo de red eth0:0 en el kernel, pero me volví loco y no pude encontrarlo. En realidad no soy estúpido, sólo hice estupideces por ese maldito nombre. ?
Echemos un vistazo al código de implementación del kernel de Linux. Primero comprenda algunas estructuras de datos, la más importante es net_device, seguida de in_device y luego in_ifaddr. Una vez que comprendas estas tres estructuras de datos, todo tendrá sentido, es cierto. ?
estructura? dispositivo_net?
{?
...?
¿nulo*ip_ptr? //Apunta a una estructura in_device. Este campo está separado de net_device. ¿Significa que una tarjeta de red puede admitir múltiples protocolos de capa de red?
...?
}?
estructura? ¿en_dispositivo?
{?
estructura? dispositivo_net? *¿desarrollador? //Apunta al net_device al que pertenece, ¿cuál es la tarjeta de red?
atomic_trefcnt? // ¿Conteo de referencias?
int? muerto;?
estructura? in _ ifaddr * ifa _ list // ¿Todas las listas vinculadas de direcciones IP?
...?
};?
estructura? in_ifaddr? // ¿Representa la dirección IP?
{?
estructura? en_ifaddr*ifa_siguiente? // ¿El campo ifa_list en in_device arriba está vinculado a este campo?
estructura? in _ dispositivo * ifa _ dev//¿volver a la estructura in_device?
estructura? rcu_head? rcu_head?
u32? ifa_local? //dirección ip?
u32? dirección_ifa?
u32? ifa_mascarilla//¿Máscara?
u32? ifa_broadcast;? // ¿Dirección de transmisión?
u32? ifa_anycast?
¿No está firmado? ¿Ciel? ifa_scope
¿Sin firmar? ¿Ciel? banderas_ifa? // ¿Solo la bandera IFA_F_SECONDARY, porque además de esa es la dirección principal?
¿No está firmado? ¿Ciel? ifa_prefixlen?
chari fa_label[IFNAMSIZ];? //Nombre, en ip? En la era de los alias, ¿tal vez de la forma ethx:y, en el segundo nivel? En la era de la propiedad intelectual, ¿su unificación es ética?
};Nota: La estructura anterior no significa que la estructura de dirección IP de la tarjeta de red Linux sea una estructura de cadena colgante. La llamada estructura de cadena colgante sólo tiene lógica. En términos de estructura de datos, todas las direcciones IP de una tarjeta de red están vinculadas en una lista lineal vinculada en ifa_list. Si es la dirección principal o la dirección secundaria depende del campo ifa_flags de in_ifaddr. Siempre se llama a Inet_insert_ifa al configurar una nueva dirección. ¿Por qué Linux no usa código para representar direcciones IP como estructuras catenarias? No tengo ni idea. Personalmente, creo que sería mejor si un net_device tuviera una lista vinculada de IP de primer nivel y luego cada nodo de IP de primer nivel tuviera una lista vinculada de IP de segundo nivel. Siento que la implementación de inet_insert_ifa es deficiente. Dos programas de espacio de usuario pueden agregar direcciones, uno es ifconfig y el otro es ip addr add. ifconfig agrega una dirección basada en ioctl, mientras que el programa ip agrega una dirección basada en netlink. De cualquier manera cumplirá el propósito.
Ahora podemos ver otra pregunta: por qué la dirección IP agregada con ip addr add no se puede ver en ifconfig, pero se puede ver el IP addr show establecido por ifconfig. Este problema se puede entender tan pronto como se mira el código. Cuando ifconfig obtiene la dirección IP, el código:?
¿Para qué? (ifap?=?&in_dev->ifa_list?(ifa?=?*ifap)?!=?NULL?ifap?=?&IFA->ifa_next)?
{?
¿Y si? (!strcmp(ifr.ifr_name,IFA->ifa_label)?& amp& amp?sin_orig.sin_addr.s_addr?==?IFA->ifa_address)?
{?
Romper;?
}?
} es la dirección IP del ifa encontrado. Sabemos que todos los IFA están vinculados en una lista enlazada lineal. Si encontramos el primero, no iremos. atrás, por lo que solo podemos obtener un resultado que está al principio de la lista vinculada, pero ip add show es diferente. Se implementa en la función inet_dump_ifaddr, que atraviesa todos los IFA y los pasa al búfer de espacio del usuario. Puede hacer un experimento aquí: primero use ip addr add para agregar varias direcciones IP principales que no están en el mismo segmento de red y luego configure una IP que no esté en el mismo segmento de red que la IP anterior. Luego puede usar ifconfig. para verificar y descubrir que no es la que acaba de usar. La IP configurada por ifconfig se agrega con ip addr add. Esto significa que ifconfig es siempre el primero en la lista ifa. Otra cosa a tener en cuenta es que si usa ip addr add para agregar muchas direcciones IP secundarias, entonces la dirección IP que configuró con ifconfig está en el mismo segmento de red que esas IP secundarias, entonces todas las IP secundarias se eliminarán. Esto está determinado por la especificación de la IP secundaria y también se refleja en el código. Otra cosa a tener en cuenta es que las entradas en la tabla de enrutamiento se basan en la IP principal, porque todas las operaciones se basan en la IP principal, como cuando se agrega una ruta:
¿Anulado? fib_add_ifaddr(struct?in_ifaddr?*ifa)?
{?
estructura? ¿en_dispositivo? *en_dev? =?IFA->ifa_dev?
estructura? dispositivo_net? *¿desarrollador? =?in_dev->dev?
estructura? in_ifaddr? *¿Remilgado? =?ifá?
...?
¿Y si? (IFA->ifa_flags&IFA-Secondary)? {?// Si ifa es una dirección de segundo nivel, entonces busque la dirección de primer nivel a la que pertenece y configúrela de acuerdo con esta dirección de primer nivel.
Prim. =?inet_ifa_byprefix(in_dev, prefijo,?máscara);?
¿Y si? (¿Prim?==?NULL)? {?
printk(KERN_DEBUG?"fib_add_ifaddr:?bug:?prim.==?NULL/n");?
Volver;?
}?
}?
fib_magic(RTM_NEWROUTE,?RTN_LOCAL,?addr?32,?prim); //¿Agregar a la tabla de enrutamiento?
...?
Hemos aprendido mucho hasta ahora. Lo más importante es la estructura de cadena colgante de la dirección IP de la tarjeta de red en Linux y los beneficios de este diseño. Además, existen métodos ioctl y netlink para configurar la dirección IP. De hecho, las tarjetas de red multi-IP no causarán ningún conflicto. Básicamente, la IP no tiene nada que ver con la tarjeta de red. Sus únicas relaciones están vinculadas por el modelo de jerarquía de red y los detalles están vinculados por rutas.
Por ejemplo, cuando agrego una ruta, especifico la dirección de destino, la dirección IP del siguiente salto y la salida de la tarjeta de red. Luego, el kernel insertará la ruta en la ubicación combinada según la dirección de destino proporcionada. Luego configure el dispositivo de red nh en la salida de la tarjeta de red que proporcionó. Cuando se transmitan los datos, encontrará la ruta a la salida. Es así de simple. Las rutas configuradas manualmente se pueden configurar como desee, e incluso si son completamente incorrectas, el kernel las agregará a la tabla de enrutamiento. La otra ruta la genera automáticamente el kernel. Cuando la tarjeta de red se instala por primera vez, encontrará su in_device a través del net_device de la tarjeta de red y luego encontrará su dirección IP. Este tipo de enrutamiento se llama enrutamiento de enlace. ?
A través del mecanismo de IP secundaria, se puede considerar que su máquina tiene muchas tarjetas de red. Para las aplicaciones, las aplicaciones que escuchan en el mismo puerto pensarán que están en diferentes máquinas de la LAN. Puede utilizar estas direcciones IP como desee sin confusión. Por supuesto, el enrutamiento y el arp subyacente se encargan de todo esto si lo configuras correctamente. ?
Adjunto: El espacio de usuario tiene demonios ifup/ifdown, /sbin/ip, ifconfig y netplugd. ¿Algo de esto tiene algo que ver con eso? El programa de IP intermedio es el más básico y no tiene estrategia. La estrategia es especificar parámetros, o otros programas lo llaman, y netplugd es un demonio de monitoreo que monitorea el estado de la tarjeta de red a través de netlink y luego llama al script /etc/netplug.d/netplug según diferentes resultados de monitoreo, y entonces puede llamar al script ifup/ifdown, es decir, el script. Si se llamará al pie de página up-eth, y después de ordenar finalmente los parámetros, se llamará al programa ip (generalmente: ip link set eth0 up/down). Por supuesto, el programa ip también se puede llamar por sí mismo, como ip addr add, ip route add, etc. Aunque ifconfig no es tan complicado, se configura a través de ioctl y se puede observar a través de strace. El misterio radica en la separación de estrategia y mecanismo, lo que también muestra que muchas funciones en Linux están compuestas por programas muy pequeños.
La estructura de cadena colgante de la dirección IP de Linux y las características de direccionamiento de la dirección IP (consulte "Acerca del acceso mutuo entre segmentos de red IP: el enrutamiento es fundamental" para obtener más detalles) ilustran completamente lo perfecta que es la pila de protocolos de Linux. está completamente en línea con el modelo de encapsulación jerárquico. La lógica de la capa inferior está completamente desacoplada de la lógica de la capa superior, lo que significa que la capa IP es completamente independiente del diseño físico de la capa de enlace y la capa física. Finalmente, recuerde que las cosas de la capa IP, como el enrutamiento de direcciones, solo las implementa la capa IP. Todas las rutas descubiertas por la capa de enlace son puramente por conveniencia.