return -EOPNOTSUPP;}
这里,们传入cmdSIOCBRADDBR.转入br_add_bridge(buf)进行:int br_add_bridge(const char *name) {
struct net_device *dev; int ret;
//虚拟桥新建个net_device //面“网络设备管理”经讲述此结构 dev = new_bridge_dev(name); if (!dev)
return -ENOMEM; //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;}
网桥注册跟们以看物理网络设备注册样。们关心网桥应net_device结构什么样,继续跟踪进new_bridge_dev:static struct net_device *new_bridge_dev(const char *name) {
struct net_bridge *br; struct net_device *dev; //分配net_device
dev = alloc_netdev(sizeof(struct net_bridge), name,
br_dev_setup); if (!dev)
return NULL; 网桥私区结构net_bridge br = netdev_priv(dev); //私区结构dev字段指向本身 br->dev = dev;
br->lock = SPIN_LOCK_UNLOCKED; //队列始化。port_list保存这个桥端口列表 INIT_LIST_HEAD(&br->port_list); br->hash_lock = SPIN_LOCK_UNLOCKED; //面这部份代码跟stp协议相关,们暂不关心
br->bridge_id.prio[0] = 0x80; br->bridge_id.prio[1] = 0x00;
memset(br->bridge_id.addr, 0, ETH_ALEN); dev->open = 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; }这部份,桥设备私区空间进行始化。这里,有必给桥net_device应私区结构:struct net_bridge {
//读锁
spinlock_t lock; //端口列表
struct list_head port_list;
//网桥应虚拟设备
struct net_device *dev; //网桥应虚拟网卡统计数据
struct net_device_stats statistics;
//hash表锁
spinlock_t hash_lock; //MAC PORT应表,即CAM struct hlist_head hash[BR_HASH_SIZE];
struct list_head age_list; /* STP */
u16 root_port; rtnl_lock();
br->stp_enabled = 0; br_stp_timer_init(br); return dev; //stp 协议应数据
unsigned char stp_enabled; //由核确定接口名字,例如eth0 eth1等 br->designated_root = br->bridge_id; }
相关推荐: