zoukankan      html  css  js  c++  java
  • 虚拟设备之linux网桥

    前言:网桥设备作为一个虚拟设备,用于连接多个端口,可以构建一个局域网。与之相似的是vlan设备,在linux中,vlan设备是为了处理802.1q的添加和去除TAG的问题,这和传统交换机中vlan的功能—划分局域网,不太一样,在这里仅仅是处理了消息头,只是实现了隔离功能,并未实现交换功能,如果需要vlan内的数据转发,可以把vlan子接口挂接在网桥设备下。

    网桥设备中添加的接口,在同一个二层域中。网桥在Linux中的实现如下:

    Bridge-utils工具的实现

    先查看一下Bridge-utils工具的工作原理,它是用于用户态配置网桥的工具,可以用于添加/删除网桥,往网桥添加/删除接口等操作。

    brctl.c的main()中,读取了参数列表,这里使用了getopt_long()函数,可以借鉴使用。之后进行br的初始化,主要就是创建一个socket接口,为之后IOCTL操作。然后调用command_lookup(),查找到参数命令,最后调用cmd->func(),执行命令。最后在内核中sock_ioctl()会收到,然后调用br_ioctl_hook(),从这里,就开始内核态的处理。

    网桥设备的初始化

    Br_init()br_init是注册到内核进行初始化的,module_init(br_init),在br_init中,主要做的事如下:

    注册stp(生成树协议),初始化转发表,注册network namespace(暂不知啥用),注册通知连,netlink的初始化,设置br_ioctl_hook

    网桥的建立和操作

    br_ioctl_hook调用开始,在br_init中注册的br_ioctl_hook

    br_ioctl_deviceless_stub,可以看到SIOCBRADDBR添加和删除网桥。添加网桥中alloc_netdev()分配了设备结构体,并进行了初始化设置br_dev_setup,在初始化设置的时候,就填充了netdev_ops->br_netdev_ops,这里就是对于设备的操作回调函数咯,重点关注br_dev_ioctl,在这里,会用添加和删除接口的操作。等再次添加从接口设备到网桥时,此时网桥设备已经存在,调用br_netdev_ops中的添加接口的回调函数,br_add_if中注册了接收数据的处理函数:netdev_rx_handler_register(dev, br_handle_frame, p);br_handle_frame就是处理函数咯。

    网桥的数据流程

    先附一张18摸公司的文章的图:

    发送流程:

    首先说一点是,网桥有自己的MAC地址,01:80:c2:00:00:0X,路由后发送函数dev_queue_xmit()发送数据出去,因为此时通过路由,skb->dev已经设置成为了br,所以,最后调用设备的发送回调ndo_start_xmit,在br初始化时,设置为br_dev_xmit,这样,最后的发送函数就是它咯。在发送中,确定目的地址是单播还是洪泛。

    接收流程:

    接收上,是从netif_receive_skb()中接收报文,因为只有在attach到网桥的从接口注册了rx_handle,即br_handle_frame,也就是只有这些接口才会把数据往网桥上送。接着调用br_handle_frame进行报文的处理,是consumed掉,还是转发等在这里完成。具体的代码就不分析咯。

    注意事项:

    网桥设备本身有自己的MAC,以及IP。发送和接收也正是通过路由后找到网桥接口的。
    加入网桥的接口,其本身的IP和MAC地址都已经不再有效,路由并不会使用其中的地址,而是使用网桥的。

  • 相关阅读:
    poj 2485 Highways 最小生成树
    hdu 3415 Max Sum of MaxKsubsequence
    poj 3026 Borg Maze
    poj 2823 Sliding Window 单调队列
    poj 1258 AgriNet
    hdu 1045 Fire Net (二分图匹配)
    poj 1789 Truck History MST(最小生成树)
    fafu 1181 割点
    减肥瘦身健康秘方
    人生的问题
  • 原文地址:https://www.cnblogs.com/yhp-smarthome/p/6910787.html
Copyright © 2011-2022 走看看