La transmisión de datos en la capa de enlace de la Linux pila de protocolos (New Bridge (iii))

  

New Puente: puede ser conocido a partir del análisis anterior, llamada ioctl (br_socket_fd, SIOCBRADDBR, brname) en el espacio de usuario en br_ioctl_deviceless_stub , se puede ver su procesamiento asociado: int br_ioctl_deviceless_stub (unsigned int cmd, nula __user * uarg) {switch (cmd) {case SIOCGIFBR: caso SIOCSIFBR: volver old_deviceless (uarg); //Nueva SIOCBRADDBR caso puente: //eliminar;: caso SIOCBRDELBR puente {char buf [IFNAMSIZ] si el retorno -EPERM; //copy_from_user (capaz (CAP_NET_ADMIN)!): si los datos en un espacio del núcleo al espacio de usuario (copy_from_user (buf, uarg, IFNAMSIZ)) return - EFAULT; buf [IFNAMSIZ-1] = 0; si (cmd == SIOCBRADDBR) br_add_bridge retorno (buf); br_del_bridge retorno (buf);}} regreso -EOPNOTSUPP;} aquí nos cmd es pasado a SIOCBRADDBR. br_add_bridge (BUF) se lleva a cabo: int br_add_bridge (const char * nombre) {struct net_device * dev; int ret; //puente virtual un nuevo net_device //delante y " &" dispositivos de red gestión; después de esta estructura dev = new_b ridge_dev (nombre); (! dev) si

Vuelta -ENOMEM; rtnl_lock (); //el nombre de la interfaz se determina por el núcleo, por ejemplo eth0 eth1 como si (strchr (dev- > nombre, '%') ) {ret = dev_alloc_name (dev, dev- > nombre), y si (r < 0) Goto ERR1;} //Registrar este dispositivo de red ret = register_netdevice (dev) al núcleo; si (RET) Goto Err2; dev_hold ( dev); rtnl_unlock (); //crear información ret = br_sysfs_addbr (dev) en sysfs; dev_put (dev), si (r)

unregister_netdev (dev); salida: ret retorno; Err2: free_netdev (dev); err1: rtnl_unlock (); valla a cabo;} puente que hemos visto antes de registrarse en el registro del dispositivo de red física es la misma. Nos preocupa que la estructura del puente net_device qué, continúe siguiendo en new_bridge_dev correspondiente: net_device estructura estática * new_bridge_dev (const char * nombre) {struct net_bridge * sa; struct net_device * dev; //asigna net_devicedev = alloc_netdev (sizeof (net_bridge struct), nombre, br_dev_setup), si (dev) de retorno NULL;! zona privada de la estructura del puente net_bridgebr = netdev_priv (dev); //puntos de campo estructura dev área privada para sí BR > dev = dev; BR > de bloqueo = SPIN_LOCK_UNLOCKED; //inicializar cola. Port_list guardado en la lista de puertos en el INIT_LIST_HEAD puente (&BR > Port_list); BR > hash_lock = SPIN_LOCK_UNLOCKED; //código STP asociado con el acuerdo bajo esta parte, no se preocupan por BR > bridge_id.prio [0] = 0x80; BR > bridge_id.prio [1] = 0x00; memset (BR > bridge_id.addr, 0, ETH_ALEN); BR > stp_enabled = 0; BR > designated_root = BR > bridge_id; BR > root_path_cost = 0; BR > root_port = 0; BR > bridge_max_age = BR > max_age = 20 * HZ; BR > bridge_hello_time = BR > hello_time = 2 * HZ; BR > bridge_forward_delay = BR > forward_delay = 15 * HZ; BR > topology_change = 0; BR > topology_change_detected = 0; BR > ageing_time = 300 * HZ; INIT_LIST_HEAD (&BR > age_list); br_stp_timer_init (ancho); dev retorno;} br_dev_setup también hecho en alguna otra inicialización puntero de función: br_dev_setup vacío (struct net_device * dev) {//la dirección MAC del puente a cero memset (dev- > dev_addr, 0, ETH_ALEN); //inicializar ether_setup configuración Ethernet (dev); //inicializar serie puntero de función dev- > do_ioctl = Br_dev_ioctl; dev- > get_stats = br_dev_get_stats; dev- > hard_start_xmit = br_dev_xmit; dev- > abierto = br_dev_open; dev- > set_multicast_list = br_dev_set_multicast_list; dev- > change_mtu = br_change_mtu; dev- > destructor = free_netdev; SET_MODULE_OWNER (dev); dev- > stop = br_dev_stop; dev- > accept_fastpath = br_dev_accept_fastpath; dev- > tx_queue_len = 0; dev- > set_mac_address = NULL; dev- > priv_flags = IFF_EBRIDGE;} esta parte copias del dispositivo de puente área de espacio privado se inicializa. En este caso, es necesario tender un puente net_device estructura de dominio privada correspondiente:

Copyright © Conocimiento de Windows All Rights Reserved