linux DSA 开发(一)

linux DSA 开发(一)

本文主要是翻译,原文链接如下:https://www.kernel.org/doc/html/latest/networking/dsa/dsa.html

纲要

本文档描述了**分布式交换机架构 (DSA)**子系统的设计原则、限制、与其他子系统的交互、如何为该子系统开发驱动程序

设计原则

分布式交换机架构最少是用于支持使用 Linux 的 Marvell 以太网交换机的子系统(MV88E6xxx),但此后也发展为支持其他供应商。

这种设计背后的原始理念是能够使用未经修改的 Linux 工具(如bridge、iproute2、ifconfig)直接用来配置/查询交换机端口网络设备。

以太网交换机通常由多个前面板端口和一个或多个 CPU (管理) 端口组成。DSA 子系统目前依赖于管理端口的存在,管理端口连接到以太网控制器,该控制器能够从交换机接收以太网帧。对于小型家庭和办公产品中的各种以太网交换机来说,这是一种非常常见的设置:路由器、网关,甚至是机架式交换机。此主机以太网控制器稍后将在 DSA 术语和代码中称为“主控”和“cpu”。

DSA 中的 D 代表分布式(Distributed),因为该子系统的设计能够配置和管理级联交换机(上游和下游相互连接的多个交换机)。这些特定端口在 DSA 术语和代码中称为 dsa port。相互连接的多个交换机的集合称为“交换机树”(switch tree)

对于交换机每个前面板端口,DSA 将创建专门的网络设备( 对应于 lan*),用作 Linux 网络堆栈中的控制和数据流端点,这些专用网络接口在 DSA 术语和代码中被称为“slave”网络接口

使用 DSA 的理想情况是当以太网交换机支持“交换机标签(switch tag )”时,这是一种硬件功能,需要硬件支持。switch tag 用于使交换机为它从特定端口接收/发送的每个以太网帧插入一个特定的标签,以让管理接口知道:

  • 这个帧来自哪个端口
  • 这个帧被转发的原因是什么
  • 如何将 CPU 发起的流量发送到特定端口

该子系统确实支持无法插入/剥离标签的交换机,但在这种情况下,功能可能会受到轻微限制(流量分离依赖于基于端口的 VLAN ID)。

请注意,DSA 当前不会为“cpu”和“dsa”端口创建网络接口,因为:

  • “cpu”端口是管理控制器面向以太网交换机的一侧,创建的话您将获得同一管道的两个接口:master netdev和“cpu”netdev , 造成重复,这是不必要的
  • “dsa”端口只是两个或多个交换机之间的管道,因此不能真正用作适当的网络接口

switch-tag 协议

DSA 支持许多特定于供应商的标记协议、一种软件定义的标记协议以及一种无标记模式 ( DSA_TAG_PROTO_NONE)。

标签协议的确切格式是特定于供应商的,但总的来说,它们都包含以下内容:

  • 标识以太网帧来自/应该发送到哪个端口
  • 提供将此帧转发到管理接口的原因

所有的标记协议都在net/dsa/tag_*.c文件中,并实现了结构的方法,下面详述。struct dsa_device_ops

标记协议通常属于以下三类之一:

  1. switch-tag 位于 Ethernet header 之前,向右移动(从 DSA 主机的帧解析器的角度来看)MAC DA、MAC SA、EtherType 和整个 L2 有效载荷。
  2. switch-tag 位于 EtherType 之前,从 DSA 主机的角度来看,将 MAC DA 和 MAC SA 保持在适当的位置,但将“真实”的 EtherType 和 L2 有效载荷移到右侧。
  3. switch-tag 位于数据包的尾部,将所有帧头保持在适当的位置,并且不会改变 DSA 主机的帧解析器所拥有的数据包视图。

查看 switch-tag 协议类型

root@OpenWrt:/# cat /sys/class/net/eth0/dsa/tagging 
trailer

主控网络设备(master netdev )

主网络设备通常是常规以太网接口,无需对驱动做特殊修改。DSA 子系统已被证明可以与行业标准驱动程序一起使用: e1000e, mv643xx_eth等等,而无需对这些驱动程序进行修改。这种网络设备也经常被称为管道网络设备,因为它们充当主机处理器和硬件以太网交换机之间的管道。

网络协议栈中的钩子函数

当 master netdev 与 DSA 一起使用时,在网络堆栈中放置一个钩子函数,以便让 DSA 子系统处理以太网交换机特定的标记协议。典型的以太网帧接收序列如下所示:

主控网络设备(例如:e1000e):

  1. 接收中断触发:

    • 接收函数被调用
    • 完成基本的数据包处理:获取长度、状态等。
    • 数据包准备由以太网层通过调用 eth_type_trans
  2. net/ethernet/eth.c:

    eth_type_trans(skb, dev)
            if (dev->dsa_ptr != NULL)
                    -> skb->protocol = ETH_P_XDSA
    
  3. drivers/net/ethernet/*:

    netif_receive_skb(skb)
            -> iterate over registered packet_type
                    -> invoke handler for ETH_P_XDSA, calls dsa_switch_rcv()
    
  4. net/dsa/dsa.c:

    -> dsa_switch_rcv()
            -> invoke switch tag specific protocol handler in 'net/dsa/tag_*.c'
    
  5. net/dsa/tag_*.c:

    • inspect and strip switch tag protocol to determine originating port
    • locate per-port network device
    • invoke eth_type_trans() with the DSA slave network device
    • invoked netif_receive_skb()

到了这一步,DSA 的 slave netdev (lan*)会收到一个常规以太网帧。

从属网络设备 (slave netdev)

DSA 创建的从网络设备堆叠在其主网络设备的顶部( 例如 lan1@eth0),这些网络接口中负责作为交换机每个前面板端口的控制和数据流端点。这些接口专门用于:

  • 在向/从特定交换机端口发送/接收流量时插入/删除交换机标签协议
  • 查询交换机的 ethtool 操作:统计信息、链接状态、LAN 唤醒、register dumps …
  • 外部/内部 PHY 管理:链接、自动协商等。

这些从属网络设备具有自定义的 net_device_ops 和 ethtool_ops 函数指针,它们允许 DSA 在网络堆栈/ethtool 和交换机驱动程序实现之间引入一个分层级别。

在从这些从属网络设备传输帧时,DSA 将查找当前向这些网络设备注册的交换机标记协议,并调用特定的传输例程,负责在以太网帧中添加相关的交换机标记。

然后,这些帧将排队等待使用主网络设备ndo_start_xmit()功能进行传输 ,因为它们包含适当的交换机标签,以太网交换机将能够处理这些来自管理接口的传入帧,并将这些帧传送到物理交换机端口。

图示

总结一下,从网络设备的角度来看,DSA 基本上是这样子:

             Unaware application
           opens and binds socket
                    |  ^
                    |  |
        +-----------v--|--------------------+
        |+------+ +------+ +------+ +------+|
        || swp0 | | swp1 | | swp2 | | swp3 ||
        |+------+-+------+-+------+-+------+|
        |          DSA switch driver        |
        +-----------------------------------+
                      |        ^
         Tag added by |        | Tag consumed by
        switch driver |        | switch driver
                      v        |
        +-----------------------------------+
        | Unmodified host interface driver  | Software
--------+-----------------------------------+------------
        |       Host interface (eth0)       | Hardware
        +-----------------------------------+
                      |        ^
      Tag consumed by |        | Tag added by
      switch hardware |        | switch hardware
                      v        |
        +-----------------------------------+
        |               Switch              |
        |+------+ +------+ +------+ +------+|
        || swp0 | | swp1 | | swp2 | | swp3 ||
        ++------+-+------+-+------+-+------++

slave MDIO 总线

数据结构

DSA 数据结构在include/net/dsa.h以及 中定义net/dsa/dsa_priv.h

猜你喜欢

转载自blog.csdn.net/agave7/article/details/119321051
dsa