Linux 3.10 kernel bridge 转发逻辑

前分析过linux kernel 2.6.32的bridge转发逻辑,下面分析一下linux kernel 3.10的bridge转发逻辑。这样正是CentOS 5和CentOS 7对应的内核。3.10 kernel中bridge逻辑的最大改变就是增加了vlan处理逻辑以及brdige入口函数的设置。

1. netdev_rx_handler_register

在分析之前首先要介绍一个重要函数:netdev_rx_handler_register,这个函数是2.6内核所没有的。

netdev_rx_handler_register

这个函数可以给设备(net_device)注册接收函数,然后在__netif_receive_skb函数中根据接收skb的设备接口,再调用这个被注册的接收函数。比如为网桥下的接口注册br_handle_frame函数,为bonding接口注册bond_handle_frame函数。这相对于老式的网桥处理更灵活,有了这个机制也可以在模块中自行注册处理函数。比如3.10中的openvswitch(OpenvSwitch在3.10已经合入了内核)创建netdev vport的函数netdev_create。

netdev_create

这个函数在创建netdev vport时将设备的接收函数设置为netdev_frame_hook函数,这也是整个openvswitch的入口函数,如果查看OpenvSwitch的源码可以看到当安装于2.6内核时这里是替换掉bridge的br_handle_frame_hook函数,从而由bridge逻辑进入OpenvSwitch逻辑。

2. Bridge转发逻辑分析

还是先从netif_receive_skb函数分析,这个函数算是进入协议栈的入口。

netif_receive_skb

netif_receive_skb只是对数据包进行了RPS的处理,然后调用__netif_receive_skb。

__netif_receive_skb并没有其他多余的处理逻辑,主要调用 __netif_receive_skb_core,这个函数才真正相当于2.6内核的netif_receive_skb。以下代码省略了和bridge无关的逻辑。

__netif_receive_skb_core

如果一个dev被添加到一个bridge(做为bridge的一个接口),的这个接口设备的rx_handler被设置为br_handle_frame函数,这是在br_add_if函数中设置的,而br_add_if (net/bridge/br_if.c)是在向网桥设备上添加接口时设置的。进入br_handle_frame也就进入了bridge的逻辑代码。

br_add_if

br_handle_frame

经过NF_BR_LOCAL_IN hook点会执行br_handle_local_finish函数。

br_handle_local_finish

经过NF_BR_PRE_ROUTING hook点会执行br_handle_frame_finish函数。

br_handle_frame_finish

我们先看发往本机协议栈的函数br_pass_frame_up。

br_pass_frame_up

再次进入netif_receive_skb,由于skb-dev被设置成了bridge,而bridge设备的rx_handler函数是没有被设置的,所以就不会再次进入bridge逻辑,而直接进入了主机上层协议栈。

下面看转发逻辑,转发逻辑主要在br_forward函数中,而br_forward主要调用__br_forward函数。

__br_forward

br_forward_finish

br_dev_queue_push_xmit

Skb进入dev_queue_xmit就会调用相应设备驱动的发送函数。也就出了bridge逻辑。所以整个3.10kernel的bridge转发逻辑如下图所示:

 

注意,和2.6kernel一样,bridge的OUTPUT hook点在bridge dev的发送函数中,这里不再分析列出。

打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

1 1 收藏 评论

关于作者:lvyilong316

linux爱好者 个人主页 · 我的文章 · 5

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部