Data transfer on the link layer of the Linux protocol stack (new bridge (3))

  

New bridge: From the above analysis, you can know that ioctl (br_socket_fd, SIOCBRADDBR, brname) is called in user space. Go to br_ioctl_deviceless_stub , you can see its associated processing: int br_ioctl_deviceless_stub (unsigned int cmd, void __user * uarg) {switch (cmd) {case SIOCGIFBR: case SIOCSIFBR: return old_deviceless (uarg); //New bridge case SIOCBRADDBR: //delete Bridge case SIOCBRDELBR: {char buf[IFNAMSIZ]; if (!capable(CAP_NET_ADMIN))return -EPERM;//copy_from_user: copy user space data into kernel space if (copy_from_user(buf, uarg, IFNAMSIZ)) return - EFAULT;buf[IFNAMSIZ-1] = 0;if (cmd == SIOCBRADDBR)return br_add_bridge(buf);return br_del_bridge(buf);}}return -EOPNOTSUPP;} Here, we pass in cmd to SIOCBRADDBR. In br_add_bridge(buf): int br_add_bridge(const char *name){struct net_device *dev;int ret;//Create a net_device//for the virtual bridge in front of the management of the network device& quoquo; described this structure dev = New_br Idge_dev(name);if (!dev)

return -ENOMEM;rtnl_lock();//The interface name is determined by the kernel, such as eth0 eth1, etc. if (strchr(dev->name, '%') ) {ret = dev_alloc_name (dev, dev- & gt; name); if (ret & lt; 0) goto err1;} //Register this network device ret = register_netdevice (dev) to the kernel; if (ret) goto err2; dev_hold ( Dev);rtnl_unlock();//Create relevant information in sysfs ret = br_sysfs_addbr(dev); dev_put(dev);if (ret)

unregister_netdev(dev);out:return ret;err2:free_netdev (dev);err1:rtnl_unlock();goto out;}The registration of the bridge is the same as the registration of the physical network device we saw before. We are concerned that the bridge structure corresponding net_device what, continue to follow into new_bridge_dev: static struct net_device * new_bridge_dev (const char * name) {struct net_bridge * br; struct net_device * dev; //assign net_devicedev = alloc_netdev (sizeof (struct net_bridge), name, br_dev_setup); if (!dev)return NULL; the private structure of the bridge is net_bridgebr = netdev_priv(dev); //The dev field in the private area structure points to itself br->dev = Dev;br->lock = SPIN_LOCK_UNLOCKED; //queue initialization. The port list on the bridge is saved in the port_list. INIT_LIST_HEAD(&br->port_list);br->hash_lock = SPIN_LOCK_UNLOCKED;//The following part of the code is related to the stp protocol, we don't care about 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- & gt; bridge_id; br- & gt; root_path_cost = 0; br- & gt; root_port = 0; br- & gt; bridge_max_age = br- & gt; max_age = 20 * HZ; br- & gt; bridge_hello_time = br- & gt; hello_time = 2 * HZ; br- & gt; bridge_forward_delay = br- & gt; forward_delay = 15 * HZ; br- & gt; topology_change = 0; br- & gt; topology_change_detected = 0; br- & gt; ageing_time = 300 * HZ; INIT_LIST_HEAD (&br->age_list);br_stp_timer_init(br);return dev;} Also done in br_dev_setup in addition to function pointer initialization: void br_dev_setup(struct net_device *dev){//set the bridge's MAC address to zero memset (dev->dev_addr, 0, ETH_ALEN);//Ethernet structure initializes ether_setup(dev); //A series of function pointers initialize dev->do_ioctl = Br_dev_ioctl; dev- & gt; get_stats = br_dev_get_stats; dev- & gt; hard_start_xmit = br_dev_xmit; dev- & gt; open = br_dev_open; dev- & gt; set_multicast_list = br_dev_set_multicast_list; dev- & gt; change_mtu = br_change_mtu; dev- & gt; 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;} The private space of the bridge device is initialized. Here, it is necessary to give the private area structure of the bridge's net_device:

Copyright © Windows knowledge All Rights Reserved