============= Ciclo de vida ============= Siguiendo el orden lógico de vida de un dispositivo de red, empezaremos analizando en detalle el primer bloque: ``hwnet_setup`` y ``hwnet_init_module``. 1. La función de inicialización del dispositivo (``hwnet_setup``) ================================================================= Esta función es un callback de configuración que utiliza la pila de red al invocar ``alloc_netdev`` (o internamente dentro de ``alloc_etherdev``). Su propósito es preparar el objeto ``struct net_device`` antes de ser registrado: * **Asignación de operaciones:** Asigna nuestra tabla de callbacks ``struct net_device_ops`` (que contiene las firmas de ``open``, ``close`` y ``xmit``) al campo ``dev->netdev_ops``. * **Valores Ethernet predeterminados:** Al ser un controlador virtual de capa 2, la función de soporte ``ether_setup(dev)`` (invocada automáticamente por ``alloc_etherdev``) rellena parámetros clave como: * Tipo de hardware (``ARPHRD_ETHER``). * Longitud de dirección MAC (``ETH_ALEN``, 6 bytes). * Tamaño de MTU (``ETH_DATA_LEN``, 1500 bytes). * Cabecera de red (``ETH_HLEN``, 14 bytes). * Flags por defecto (soporte para ``IFF_BROADCAST`` y ``IFF_MULTICAST``). * **Dirección MAC virtual:** En este punto es donde asignamos una MAC aleatoria o arbitraria a la interfaz (por ejemplo, mediante ``eth_hw_addr_random(dev)``), ya que no contamos con una tarjeta física con EEPROM. 2. La función de carga del módulo (``hwnet_init_module``) ========================================================= Es el punto de entrada cuando hacemos ``insmod`` o ``modprobe``. Su responsabilidad es: * **Asignación de memoria** (``alloc_etherdev``): Reserva la memoria para la estructura ``struct net_device`` más el tamaño de nuestra estructura privada ``struct hwnet_priv``. *Internamente llama al setup para dejar el dispositivo en un estado coherente.* * **Vinculación de datos privados:** Obtenemos el puntero a nuestra estructura privada mediante ``netdev_priv(dev)`` y guardamos la referencia al propio ``net_device`` dentro de ``priv->dev``. * **Registro en el Kernel** (``register_netdev``): Pasa el dispositivo al subsistema de red del kernel Linux. A partir de que esta llamada devuelve ``0`` (éxito), la interfaz pasa a existir visiblemente en el sistema (por ejemplo, en ``ip link`` o ``/proc/net/dev``). * **Gestión de fallos:** Si ``register_netdev`` falla, debemos liberar la memoria reservada previamente con ``free_netdev(dev)`` antes de salir con un código de error (como ``-ENOMEM``).