// 添加网桥设备
// 参数;
// name,需要全局唯一
// 调用路径:socket ioctl->br_add_bridge
// 函数主要任务:
// 1.创建一个新的网络设备
// 2.初始化网络设备的通用字段以及网桥设备的字段
// 3.向系统注册网络设备
1.1 int br_add_bridge(const char *name)
{
struct net_device *dev;//net_bridge->dev
int ret;
dev = new_bridge_dev(name);//创建一个新的网桥设备
if (!dev)
return -ENOMEM;
rtnl_lock();//获取rtnl锁
if (strchr(dev->name, '%')) {//名字中提供了通配符,通过系统递增网桥名中的%d
ret = dev_alloc_name(dev, dev->name);//由系统分配设备名
if (ret < 0)
goto err1;
}
ret = register_netdevice(dev);//注册网络设备设备
if (ret)
goto err2;
dev_hold(dev);//递增设备引用计数
rtnl_unlock();//由rtnl_unlock完成register_netdevice的下半部操作
ret = br_sysfs_addbr(dev);//初始化网桥相关的sysfs
dev_put(dev);
if (ret)
unregister_netdev(dev);
out:
return ret;
err2:
free_netdev(dev);
err1:
rtnl_unlock();
goto out;
}
// 分配网桥设备
// 网桥设备使用网络设备的通用控制块net_device
// 调用路径:br_add_bridge->new_bridge_dev
// 函数主要任务:
// 1.分配网络设备描述符
// 2.特定于网桥设备的初始化函数初始化设备描述符
// 3.初始化网桥id = [0x80,0x00,0x00 0x00 0x00 0x00 0x00 0x00],其中6字节的以太网地址部分,添加网桥端口时更新。
// 4.初始化网桥路径开销,拓扑变化,定时器等字段
// 5.初始化网桥定时器
1.2 static struct net_device *new_bridge_dev(const char *name)
{
struct net_bridge *br;
struct net_device *dev;
dev = alloc_netdev(sizeof(struct net_bridge), name,
br_dev_setup);//分配一个net_device,提供初始化函数
if (!dev)
return NULL;
br = netdev_priv(dev);//dev->priv为一个net_bridge结构
br->dev = dev;//回指指针
spin_lock_init(&br->lock);//初始化网桥的锁
INIT_LIST_HEAD(&br->port_list);//网桥的端口列表
spin_lock_init(&br->hash_lock);//转发数据库的表
br->bridge_id.prio[0] = 0x80;//网桥id中第一部分优先级
br->bridge_id.prio[1] = 0x00;
memset(br->bridge_id.addr, 0, ETH_ALEN);//网桥id中第二部分mac地址
br->stp_enabled = 0;//stp不使能
br->designated_root = br->bridge_id;///初始化时,根网桥id为自己的id
br->root_path_cost = 0;//到根网桥的最佳路径开销为0,因为初始化时,认为自己就是根网桥
br->root_port = 0;
网络子系统30_桥接子系统通用接口
最新推荐文章于 2023-11-08 14:23:30 发布
本文深入解析Linux内核网络子系统中的网桥操作,包括如何添加和删除网桥设备。`br_add_bridge`函数用于创建网桥,涉及分配网络设备、初始化和注册设备。`br_del_bridge`则负责删除网桥,需要先关闭设备。此外,还介绍了端口管理,如`br_add_if`用于添加端口,涉及混杂模式、STP和转发数据库,而`br_del_if`用于删除端口并重新计算网桥ID。
摘要由CSDN通过智能技术生成