[linux][network]net bridge技术分析

前言: 对于作者这种没有在通信设备方面工作经验的人来说,理解网桥还是挺困难的。 二层之上的数据处理,协议分层,都是相对容易一些(尽管TCP协议复杂的一塌糊涂),毕竟在linux的协议栈代码中,逻辑层次都很清晰。 然后网桥却不同,它是一个二层逻辑。同时,它又不是一个具体的设备(具体的设备,有连接的物理的port口,插入网线就能通数据)。 在虚拟化场景下,虚拟机需要发送、接受数据,和外部交互,就需要有这样的设备。所以有必要深入了解一下网桥的具体的工作原理。 分析: 1,concept 网上的很多说法,网桥类似于交换机。交换机就是这样一个设备,它有若干个网口,并且这些网口是桥接起来的。于是,与交换机相连的若干主机就能够通过交换机的报文转发而互相通信。

如上图(选自网络):主机A发送的报文被送到交换机S1的eth0口,由于eth0与eth1、eth2桥接在一起,故而报文被复制到eth1和eth2,并且发送出去,然后被主机B和交换机S2接收到。而S2又会将报文转发给主机C、D。 当然,上述是物理的网桥的拓扑,我们说的网桥,是在本机中的一个虚拟设备。一种典型的应用场景就是:在本机中虚拟出来多块网卡,通过网桥,再通过物理网卡,和外界进行交互。 2,addbr brctl是一条常用的网桥操作命令。源代码在bridge-util中。作者大概翻了一下,比较简单,基本都是通过系统调用到内核中。所以下面的分析就不分析bridge-util了,直接分析kernel代码(主要逻辑在linux-4.4.61/net/bridge中实现)了。 在shell中敲命令创建网桥br0:brctl addbr br0 会继续进入到kernel中执行如下代码:

可见,bridge在linux中也一个是net device,它实现了自己的ops---br_link_ops。 在bridge的device中,有双链表指针port_list,bridge会把所有关联到bridge上的其他设备组织到port_list上。 3,addif 在shell中敲命令把eth0加入到br0中(想象一下,就是把一个网线插入到交换机的一个LAN口上):brctl addbr br0 eth0 作者截断了一部分检查逻辑的代码,把主要逻辑留下来:

首先,eth0在内核态中也是使用net device来管理的,这里的dev变量就是eth0的数据结构,它的rx被重载为br_handle_frame,也就是说,在eth0接收到数据的时候,会使用br_handle_frame来处理;其次,把eth0通过net_bridge_port数据结构组织到bridge的port list中;再通过br_fdb_insert加入到forward database中。 那么就是说,eth0收到数据,通过br_handle_frame交给bridge来处理。如果bridge发送数据给eth0,那么可以找到它;如果bridge想广播,那么就遍历port list。 4,br_dev_queue_push_xmit linux-4.4.61/net/bridge/br_forward.c中:

可见,bridge选择好了net device之后,就使用br_dev_queue_push_xmit (当然,更具体点就是通过dev_queue_xmit)发送数据了。 5,forward 为了便于分析网络过程,作者给vm配置了tap网卡,在虚拟机中发送数据包,然后抓到了这份backtrace。

backtrace从后向前看: a,首先看qemu使用tap发送包的进程。尽管这里的栈底不是syscall,但是qemu发送完数据包到这里是同步的。 b,使用__do_softirq处理网络包。 c,网络包的通用逻辑—net_rx_action->process_backlog->__netif_receive_skb->__netif_receive_skb_core。 d,调用到了3步注册的br_handle_frame。 e,继续deliver,再执行转发,最终使用br_dev_queue_push_xmi发送数据包。 6,br_handle_frame_finish 选择br_handle_frame_finish的关键逻辑:

a,如果是广播地址(当然,这里操作的地址都是MAC,并非IP地址),会使用flood的方式forward。当然,里面还需要检查vlan。具体逻辑下文展开。 b,如果是多播,则需要查询数据库(mdb是使用slab实现的),再进行多播。相比起代码,看协议更容易写。 c,查询forward db(也是使用slab实现的),在3步中br_fdb_insert已经把eth0加入到fdb中。 看到这里,大约也可以看到bridge的模型了:在二层网络上,广播,多播,转发,这几个是bridge的核心能力。至于mdb和fdb,都是辅助实现功能的方式。vlan可以算是一个扩展能力。 7,br_flood 广播的情况下,执行flood。逻辑比较简单,就是对bridge的port list进行遍历,逐个尝试发送数据包。

这里需要注意的是,在maybe_deliver中还是执行了vlan校验的,所以flood并不会跨vlan的。 8,fdb fdb的实现逻辑在linux-4.4.61/net/bridge/br_fdb.c。 使用slab,hash list等技术实现。需要注意的是在6步中用到的fdb查询函数---__br_fdb_get。

这里进行了vlan id的检查,也就是常说的逻辑:vlan id不匹配,则网桥(或者说交换机)会拒绝转发数据包。 9,eth handle frame 再来看另外的一份backtrace,物理网卡收到数据包,然后到网桥的过程:

老习惯,从下向上分析。首先网卡产生了irq,kernel响应irq。然后softirq继续处理(原因就是网卡的处理流程可能会比较长,而irq需要尽快返回,所以先响应了irq,在用softirq继续处理)。把数据交给网卡的driver(作者使用的是e1000网卡,所以bt中有e1000_receive_skb这样的函数),driver处理完,数据交给通用的网络数据包处理逻辑。 相比于上面的5步的trace,前面触发的逻辑不同,但是后面处理的逻辑是相同的。换言之,就是不管网络数据,还是tap这种虚拟网卡的数据,它们接到bridge上之后,收到数据后都会把数据交给bridge,bridge决定数据包下一步的流向。 这里再多提到一句,如果网卡没有接入到bridge中,那么就会把数据包提交到三层上,例如ip,ip层上判断传输层协议,如果是udp,就组装包,交给udp协议栈。 10,tap write 既然虚拟机使用tap类型网卡,就在这里继续分析一下qemu对tap类型网卡的写操作: 抓到这份bt,可以看到:

a,qemu通过系统调用写tap设备。 b,vfs的通用处理逻辑—SyS_writev→vfs_writev→do_readv_writev→do_iter_readv_writev。 c,调用tap设备的write逻辑。 d,触发softirq。

继续分析softirq:

好吧,可以看到,这里已经接上了5步的最后一帧了---do_softirq_own_stack。 11,tap read

这里简单了很多,就是bridge向tap转发了数据包之后,qemu通过read系统调用,经过vfs最后到达了tap设备的driver,最终拿到了数据。 后记: qemu使用tap和外面建立桥接的这个过程,困扰了作者很长时间。“二层网络”这个概念,也让作者很迷惑。 这次代码的整体分析,了解了基本原理。 这当中,在交换机的概念理解和细节上,还请教过几次朋友。在这里感谢@吉普。

本文分享自微信公众号 - AlwaysGeek(gh_d0972b1eeb60)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-04-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开源优测

RFC2964 超文本传输协议(HTTP)状态管理的应用

14040
来自专栏黑泽君的专栏

BS和CS的区别有哪些?

1.5K20
来自专栏FreeBuf

挖洞经验 | 看我如何发现“小火车托马斯”智能玩具APP聊天应用漏洞

最近,我向智能玩具厂商ToyTalk提交了两个APP相关的漏洞并获得了$1750美金奖励,目前,漏洞已被成功修复,在此我打算公开详细的漏洞发现过程,以便其他AP...

26770
来自专栏静下来

Discuz论坛多功能工具1.0版本发布

Discuz论坛多功能工具(Summer版本)1.0发布。 软件是集合了之前单独工具的功能,增加了发帖的功能,这样也会更加方便点吧。但是没有进过大批量的测试,可...

47040
来自专栏逸鹏说道

[译]构建现代Web应用的安全指南

原文:Security for building modern web apps 译者:杰微刊—张迪 这篇文章的灵感来自于另一篇文章,它是关于“在今天,构建We...

29180
来自专栏Java学习网

网页打开时都发生了什么?我被吓着了

  在浏览器里输入网址或者点击链接,网页打开了……这是我们上网时再普通不过的一幕,但是如此简单的表象背后,却隐藏着无比复杂的技术流程。想涨涨知识吗?往下看吧。 ...

39560
来自专栏FreeBuf

挖洞经验 | 看我如何挖掘成人网站YouPorn的XSS并成功利用

事情开始变得有趣起来,使我不得不停下手中的工作。我很惊讶,这个问题之前竟然没有人能发现它。搜做表单中的XSS是最基本的情况之一,我和我的朋友都经常逛YouPor...

29550
来自专栏小白课代表

PDF有锁,不让复制?不让编辑?甚至不让打印?再见!

多年以来,PDF凭借着超级级级级级级级级好的兼容性,称霸了电子文档的世界,你不用担心自己辛辛苦苦做的Word、PPT、Excel发给别人看却成了乱七八糟的排版,...

2.6K30
来自专栏java一日一条

从输入 URL 到浏览器接收的过程中发生了什么事情?

首先是「输入 URL」,大部分人的第一反应会是键盘,不过为了与时俱进,这里将介绍触摸屏设备的交互。

15630
来自专栏月牙寂

Golang分布式设计模式之-----分层设计

第一时间获取文章,可以关注本人公众号 月牙寂道长 yueyajidaozhang      

42850

扫码关注云+社区

领取腾讯云代金券