好久没有随笔了,帖下昨天的一部分笔记吧,现在在研究 linux bridge 部分,希望实现与硬件switch的完美结合。
以下是内核 bridge 模块初始化部分分析,内核版本是 2.6.23.9。只涉及到入口点,STP部分及其他细节部分没有在这里谈及。通过这些入口,大致可以了解 linux bridge部分的流程了。Hope its useful. Any comment is welcome.
1. 模块入口(br_init)
该函数初始化网桥模块及入口点函数。
1.1. 初始化
- br_fdb_init()
- br_netfilter_init()
- register_netdevice_notifier()
- br_netlink_init()
- brioctl_set(br_ioctl_deviceless_stub) bridge与用户态接口之一,另一个是dev_ioctl
- br_fdb_get_hook/br_fdb_put_hook 为其他内核模块提供的接口
1.2. 入口点流程
- br_stp_rcv
1 处理BPDU报文,如果STP是内核态,就交给内核STP协议栈处理。
- br_handle_frame
1 处理报文,包括br_stp_rcv没有处理的BPDU;
2 能进入这个函数一定是bridge上的一个port,也就是收到报文的是网桥的一个端点;
3 对于目标地址是802.1D规定的保留地址的报文并且STP开启,该函数执行NF_HOOK(NF_BR_LOCAL_IN),如果无人关心这个报文,即返回给上层函数,继续走流程,报文离开bridge。
4 对于3没有处理的报文,并且端点状态是转发或者学习状态的报文进行处理,处理将进入br_handle_frame_finish。
- br_handle_frame_finish
1 网桥处于混杂模式或者报文目标地址是组播地址,该报文会走br_pass_frame_up流程。
2 同时,如果报文目标地址不是本网桥上的某一端点(!dst->is_local),该报文可能将复制,并进行forward。
- br_pass_frame_up
1 注意到,该函数切换skb->dev,并执行NF_HOOK(NR_BR_LOCAL_IN, netif_receive_skb),相当于重新接收报文,但是skb->dev是br,非port,因此进不到bridge处理流程,果真是pass up。