添加一个桥设备——br_add_bridge(二)
来源:互联网 发布:seo超级外链工具 编辑:程序博客网 时间:2024/06/06 16:37
上一节,讲述桥模式初始化时需要做的一些事情,这一节,我们一起来看看如何添加一个网桥设备。 我们先来看一个命令: **brctl addbr br1** 上节我们提到一个用来处理ioctl命令的函数br_ioctl_deviceless_stub通过调用brioctl_set, 将br_ioctl_deviceless_stub赋值给回调函数br_ioctl_hook,而br_ioctl_hook在sock_ioctl中使用。 这样通过在应用层调用socket的ioctl函数,就能够进行网桥的添加与删除了。 如果我们想增加新的ioctl,用于我们新开放的功能,就可以在该函数里增加新的case即可。 当我们输入上面命令时,就会触发br_ioctl_deviceless_stub函数来响应br_add_bridge函数,当命令执行完成以后, 使用brctl show命令就可以看见我们添加的br1这个网桥设备已经生成。
int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg){ switch (cmd) { case SIOCGIFBR: case SIOCSIFBR: return old_deviceless(net, uarg); case SIOCBRADDBR: case SIOCBRDELBR: { char buf[IFNAMSIZ]; if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) return -EPERM; if (copy_from_user(buf, uarg, IFNAMSIZ)) return -EFAULT; buf[IFNAMSIZ-1] = 0; if (cmd == SIOCBRADDBR) return br_add_bridge(net, buf);/*添加网桥设备的操作*/ return br_del_bridge(net, buf); } } return -EOPNOTSUPP;}
好!知道br_ioctl_deviceless_stub的功能后,我们来看看br_add_bridge,这个函数添加桥设备需要初始化哪些东西:
int br_add_bridge(struct net *net, const char *name){ struct net_device *dev; int res; /*为设备分配一块内存,并且调用br_dev_setup函数初始化*/ dev = alloc_netdev(sizeof(struct net_bridge), name, NET_NAME_UNKNOWN, br_dev_setup); if (!dev) return -ENOMEM; dev_net_set(dev, net); /*初始化dev的netlink链接通知操作函数*/ dev->rtnl_link_ops = &br_link_ops; /*注册一个网络设备*/ res = register_netdev(dev); if (res) free_netdev(dev); return res;}
br_dev_setup函数用来初始化桥设备所需要的基本数据,尤其是在br_netdev_ops,中指定了很多的设备函数, 包括启用,关闭网桥,修改mtu以及设备ioctl函数,添加或删除,桥下设备等等一系列函数,这些函数的具体作用我们会在后续的章节中继续讨论。
void br_dev_setup(struct net_device *dev){ struct net_bridge *br = netdev_priv(dev); eth_hw_addr_random(dev); ether_setup(dev); /*指定网络设备的管理钩子,关于各个钩子函数的作用以及用法, 请参见/linux/netdev.h中的net_device_ops结构体描述,这是很重要的一部分*/ dev->netdev_ops = &br_netdev_ops; /*可选netdev操作, 关于各个钩子函数的作用以及用法, 请参见/linux/ethtool.h中的ethtool_ops结构体描述*/ dev->destructor = br_dev_free; dev->ethtool_ops = &br_ethtool_ops; SET_NETDEV_DEVTYPE(dev, &br_type); /*IFF_EBRIDGE内核用来区别网桥设备和其他类型的设备*/ dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE; dev->features = COMMON_FEATURES | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; dev->vlan_features = COMMON_FEATURES; 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; br->bridge_id.prio[1] = 0x00; ether_addr_copy(br->group_addr, eth_reserved_addr_base); br->stp_enabled = BR_NO_STP; br->group_fwd_mask = BR_GROUPFWD_DEFAULT; br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT; br->designated_root = br->bridge_id; 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; /*老化时间初值默认为5分钟*/ br->ageing_time = BR_DEFAULT_AGEING_TIME; /*初始化该网桥的netfilter*/ br_netfilter_rtable_init(br); /*初始化网桥的各类定时器,hello定时器,垃圾回收定时器等等*/ br_stp_timer_init(br); /*多播初始化*/ br_multicast_init(br);}
在上面的函数中,除了br_netdev_ops需要注意以外还有一个需要注意的函数br_netfilter_rtable_init(br); 这个函数是用来初始化Bridging-Firewalling,在后续的章节中,可以看到Netfilter钩子(hook)在桥接程序用于处理入口和出口网络流量的主要位置。 另外,在编译内核时,选中: Networking support->Networking options->Networking packet filtering(replaces ipchains) -> Bridged IP/ARP packet filtering后, 内核就支持Bridging-Firewalling.Ethernel-Bridging-Tables选项(也就是ebtables).
以上就是,桥设备初始化的相关操作。
阅读全文
0 0
- 添加一个桥设备——br_add_bridge(二)
- MVC4入门(二)——添加一个控制器
- 学习笔记——《LINUX设备驱动程序(第三版)》Linux设备模型:内核添加、删除设备
- 设备驱动学习之字符设备驱动内核代码分析(二)——字符设备结构体cdev
- Linux块设备驱动(二)————块设备的体系架构
- IIC设备驱动程序(二)————IIC设备的硬件原理
- Linux 字符设备驱动结构(二)—— 自动创建设备节点
- Linux 字符设备驱动开发基础(二)—— 编写简单 PWM 设备驱动
- Linux 文件系统与设备文件系统 (二)—— sysfs 文件系统与Linux设备模型
- Linux 文件系统与设备文件系统 (二)—— sysfs 文件系统与Linux设备模型
- Linux 字符设备驱动开发基础(二)—— 编写简单 PWM 设备驱动
- Linux 字符设备驱动结构(二)—— 自动创建设备节点
- Linux 字符设备驱动结构(二)—— 自动创建设备节点
- linux 块设备驱动(二)——块设备数据结构
- Linux 字符设备驱动开发基础(二)—— 编写简单 PWM 设备驱动
- Ceph实战入门系列(二)——块设备
- 块设备(二)
- 设备驱动程序(二)
- button drawableLeft 加上动画效果
- Convert excel to xml
- exception in initAndListen: 29 Data directory /data/db not found., terminating
- 【MyBatis学习01】宏观上把握MyBatis框架
- 背景,尺寸及显示的相关属性
- 添加一个桥设备——br_add_bridge(二)
- 【二叉树】后序遍历【Add to List 145. Binary Tree Postorder Traversal】
- Jenkins+Tomcat + Gradle + Tinker + Walle + 360加固 + fir.im 持续集成,自动构建
- Kettle生成0到10随机数
- jquery动态添加删除div 新添加的为什么删不掉
- gets()和scanf的区别
- 程序员接私活儿注意事项
- Servlet Jsp三天速成大纲
- Scala基本语法(四)