网络子系统大杂烩二

网桥


网桥属于一种虚拟设备,所以在使用之前需要先初始化和注册

网桥部分的初始化在/net/bridge/br.c中,通过初始化函数br_init函数实现

在br_init函数中通过brioctl_set(br_ioctl_deviceless_stub);来创建一个

网桥设备。brioctl_set(br_ioctl_deviceless_stub)->br_add_bridge->new_bridge_dev

最后通过new_bridge_dev创建出一个网桥设备。新创建的ops对应/net/bridge/br_device.c

中的br_netdev_ops。


值得一说的是new_bridge_dev函数返回的也是一个net_device结构,这个结构由new_bridge_dev

调用函数br_dev_setup进行初始化。但是这个net_device是包含在net_bridge中的数据结构,

属于net_bridge的netdev_pri(dev)。net_bridge和net_device的关系可一参考 网络技术内幕 的366页

的图片非常清楚。其链表上的每个net_device对应的才是一块真是的NIC,一块NIC对应一个端口。



网桥设备建立之后需要向网桥设备添加端口了,相当于将网卡对应的net_device绑定到net_bridge上。

没绑定端口的网桥当然是个废设备了。添加端口由函数br_add_if函数实现。br_add_if何时被调用的?

具体调用过程比较长,直接中中间截断开始分析,

从dev_ifsioc开始,具体如下:

dev_ifsioc->br_dev_ioctl

在br_dev_ioctl函数中有如下代码:    

... ...

            cmd == SIOCBONDCHANGEACTIVE ||
            cmd == SIOCGMIIPHY ||
            cmd == SIOCGMIIREG ||
            cmd == SIOCSMIIREG ||

            cmd == SIOCBRADDIF ||
            cmd == SIOCBRDELIF ||
            cmd == SIOCSHWTSTAMP ||
            cmd == SIOCWANDEV) {
            err = -EOPNOTSUPP;
            if (ops->ndo_do_ioctl) {
                if (netif_device_present(dev))
                    err = ops->ndo_do_ioctl(dev, ifr, cmd);
                else
                    err = -ENODEV;
            }

... ...

根据标红处的提示可以发现bridge add interface的时候会执行下面的代码

具体就是ops->ndo_do_ioctl

这会到时net_bridge中的net_device中的ops被执行。而这个ops在新建网桥设备的时候会

初始化为br_netdev_ops,其中的ndo_do_ioctl方法就是br_dev_ioctl

此处就是相当于执行br_dev_ioctl函数。

br_dev_ioctl->add_del_if->br_add_if

具体添加的端口就在br_add_if中完成了。


网桥新建或还需要通过open函数来启动,非常类似dm9000网卡设备。dm9000注册完毕后不是

直接就可以使用的,还需要调用dev_open函数来启动。在dm9000_open函数中还会做一些初始

化的操作,比如注册dm9000网卡中断处理函数等。网桥也一样,需要通过open方法,即br_dev_open

来启动了,并且在这个open方法中对网桥设备做些初始化操作,比如初始化端口等,更新端口状态等。

等所有这些操作执行完毕 网桥设备才可以启用。


网桥设备的帧处理函数br_handle_frame在br_add_if的时候已经通过函数

netdev_rx_handler_register(dev, br_handle_frame, p)注册到

net_bridge的net_device的rx_handler中了。

在L2的帧处理函数__netif_receive_skb中通过语句

rx_handler = rcu_dereference(skb->dev->rx_handler);

调用的就是bridge处理函数br_handle_frame了


你可能感兴趣的:(网络子系统大杂烩二)