//分配以太网设备描述符 1.1 struct net_device *alloc_etherdev(int sizeof_priv) { //设备名默认为eth%d,其中%d随系统中以太网络设备数递增 return alloc_netdev(sizeof_priv, "eth%d", ether_setup); } //网络设备描述符标准分配函数 // alloc_etherdev->alloc_netdev 1.2 struct net_device *alloc_netdev(int sizeof_priv, const char *name, void (*setup)(struct net_device *)) { void *p; struct net_device *dev; int alloc_size; //对齐到32bit alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; //kmalloc物理内存上连续 p = kmalloc(alloc_size, GFP_KERNEL); if (!p) { printk(KERN_ERR "alloc_dev: Unable to allocate device.\n"); return NULL; } memset(p, 0, alloc_size); dev = (struct net_device *) (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); //在padded中保存为对齐dev到32bit浪费的字节数 //dev-padded即可找到kmalloc分配的内存起始地址 dev->padded = (char *)dev - (char *)p; if (sizeof_priv) dev->priv = netdev_priv(dev); //初始化设备的函数指针 setup(dev); strcpy(dev->name, name); return dev; } //以太网设备通用的初始化函数 // 调用路径:alloc_netdev->ether_setup 1.3 void ether_setup(struct net_device *dev) { dev->change_mtu = eth_change_mtu;//保证ethdev的mtu > 68 && mtu < 1500 dev->hard_header = eth_header;//向skb填以太网报头 dev->rebuild_header = eth_rebuild_header;//完成arp解析以后,重建以太网报头 dev->set_mac_address = eth_mac_addr;//设置设备的mac地址 dev->hard_header_cache = eth_header_cache;//根据arp查询的结果,构造hh_cache,供邻居子系统使用 dev->header_cache_update= eth_header_cache_update;//更新hh_cache中的以太网头 dev->hard_header_parse = eth_header_parse;//从skb中取出以太网头,填充到一个unsigned char*指针中 dev->type = ARPHRD_ETHER;//以太网类型 dev->hard_header_len = ETH_HLEN;//以太网报头长度 14字节 dev->mtu = 1500; //最大支持的mtu dev->addr_len = ETH_ALEN;//地址长度 6字节 dev->tx_queue_len = 1000; //每个设备的传输队列长度 dev->flags = IFF_BROADCAST|IFF_MULTICAST;//设备默认支持广播和多播 memset(dev->broadcast,0xFF, ETH_ALEN);//以太网广播地址FF:FF:FF:FF:FF:FF }