原文地址 blog.csdn.net @hhhhhyyyyy8 @4.15.1
¶前言
linux 内核源代码变动怎么这么大,handle_bridge 函数居然没有了,本来接着准备以 3.9.1 分析的,但发现和后面的又变了,还是以 4.15.1 现在电脑上用的版本分析吧。
linux kernel:4.15.1
best of best [link](https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg)
先看三张图片
tips: linux 内核版本不一样,流程函数会发生细微改变。
¶1. br_handle_frame()
作用:
对于需要转发的报文,调用
NF_BR_PRE_ROUTING处钩子函数,结束后,进入br_handle_frame_finish()函数;对于 STP 报文,调用
NF_BR_LOCAL_IN处钩子函数,结束后,进入br_handle_local_finish()函数,在br_handle_local_finish()函数中会调用br_pass_frame_up()函数。
1 | //linux/net/bridge/br_input.c |
相关函数
¶rx_handler_result_t 枚举类型
1 | enum rx_handler_result { |
¶is_valid_ether_addr()
1 |
|
¶br_handle_local_finish()
br_handle_local_finish() 函数中调用 br_pass_fame_up() 函数。
1 |
|
¶2. br_handle_frame_finish()
作用:
网桥设备是否处于混杂模式,如果是,则会发一份到本地进行处理
如果是广播包,则会进行广播洪泛,并会发一份到本地处理
如果是组播包,则根据组播表进行组播转发,并发一份数数包到本地处理
如果是单播包,发往本地的单播包则送到本地处理,在 fdb 表中可以找到转发表项的单播包则进行转发,未知单播包在广播域内进行洪泛
1 | //linux/net/bridge/br_input.c |
¶3.br_pass_frame_up
数据包的目的 MAC 是本地的单播报文,广播,组播和网桥处于混杂模式时,报文都会通过 br_pass_frame_up 函数交由上层处理。
作用:
调用 NF_BR_LOCAL_IN 处钩子函数,最后调用 br_netif_receive_skb 函数,绕一圈后,交友上层处理。
1 | //linux/net/bridge/br_input.c |
再次进入 netif_receive_skb,由于 skb-dev 被设置成了 bridge,而 bridge 设备的 rx_handler 函数是没有被设置的,所以就不会再次进入 bridge 逻辑,而直接进入了主机上层协议栈。
相关函数
¶br_netif_receive_skb()
可以看到在 br_netif_receive_skb() 函数中调用了 netif_receive_skb() 函数。
1 |
|
¶4. br_forward()
不是发往本地的数据包,但在 fdb 表中能找到对应的表项,则进行转发 br_forward(),若在 fdb 表中找不到对应表项就进行洪泛 br_blood().
作用:
主要是调用__br_forward() 转发报文
1 | //linux/net/bridge/br_forward.c |
¶5. __br_forward()
作用:
__br_forward() 函数根据数据包的来源(local_orig)分别进入不同的钩子点,如果数据包是从本地发出的,则进入 NF_BR_LOCAL_OUT,如果不是本地发出的,则进入 NF_BR_FORWARD 钩子,最后都进入 br_forward_finish() 函数。
1 | //linux/net/bridge/br_forward.c |
¶6. br_forward_finish()
br_forward_finish() 函数比较简单,调用 NF_BR_POST_ROUTING 处的钩子函数,最后进入 br_dev_queue_push_xmit 函数。
1 | //linux/net/bridge/br_forward.c |
¶7. br_dev_queue_push_xmit
在 br_dev_queue_push_xmit() 中,会先 skb_push(skb,ETH,HLEN); 将 data 指向二层头部,然后调用 dev_queue_xmit() 发送报文。
1 | //linux/net/bridge/br_forward.c |
¶8. br_flood
br_flood() 也是调用 __br_forward() 函数转发报文。
1 | //linux/net/bridge/br_forward.c |
¶9. br_mulicast_flood()
以后再分析,肚子饿了。
1 | //linux/net/bridge/br_forward.c |
¶参考
ebtables/iptables interaction on a Linux-based bridge @ebtables @2.4.x kernel
Iptables DNAT实现broadcast与unicast之间相互映射 @sxd2001 分析ebtables 的redirect 和 iptables 的redirect
Linux-4.20.8内核桥收包源码解析(七)--本地(br_pass_frame_up)or 转发(br_forward) @lw_yang @Linux-4.20.8
Linux 3.10 kernel bridge转发逻辑 @lvyilong316 @Linux 3.10 kernel
kernel 网桥代码分析 @海枫 @ 2.6.24.4
桥数据包处理函数——br_handle_frame_finish(七) @不留你的名字
Bridge实现 @SuperKing @linux 2.6.18
LInux下桥接模式详解三 @jack.chen @linux 3.10.1
协议栈报文接收之netif_receive_skb函数分析 @one_clouder @Linux4.1.12


