Linux 5.4内核Distributed Switch Architecture » Architecture翻译

原文地址:Distributed Switch Architecture » Architecture

体系架构

此文档描述了Distributed Switch Architecture (DSA)子系统的设计原则、限制、与其他子系统的交互
、及如何为DSA开发驱动,同时包含一个TODO供感兴趣的开发者一起参与。

1. 设计原则

DSA子系统最开始是为了Marvell以太网交换机(MV88E6xxx,即Linkstreet产品线)能使用Linux开发的,但是现在也发展到支持其他厂家。

设计背后的原始哲学是,当使用bridge,iproute2,ifconfig等工具配置或者查询网络设备时,这些工具不用关心它是一个交换机端口网络设备还是普通网络设备。

典型的以太网交换机包含多个前面板端口,及一个或者多个CPU或者管理口。DSA目前依赖存在连接到以太网控制器的,能够从交换机接收以太网帧的管理端口。这对于所有的家用、办公产品:路由器,网关,甚至架顶式的交换机,都是非常普遍的设置。在DSA的术语及代码中,这个主机以太网控制器被称为"master"和"cpu"。

DSA中的D表示分布式,因为此子系统能够用来配置和管理级联的交换机组群,组群里的交换机之间通过上行和下行以太网端口连接。这些特定的端口在DSA的术语及代码中叫做"dsa"端口。级联的一组交换机叫做一个"switch tree"。

对每个前面板端口,DSA都创建特定的网络设备,Linux网络栈使用此设备作为控制和数据流的端点。在DSA的术语及代码中,这些特定的网络接口被称为"slave"网络接口。

当以太网交换机支持"switch tag"硬件特性时,是使用DSA理想的场景。交换机通过"switch tag"给每个来自/去往特定端口的以太网帧都增加特定的tag,以协助管理接口了解如下信息:

  • 以太网帧来自哪个端口
  • 以太网帧转发的理由
  • CPU发出的数据如何发往指定的端口

DSA也支持无法插入/剥掉tag的交换机,但是此时功能会有一些限制(数据隔离依赖Port-based VLAN IDs)。

注意:DSA目前不为"cpu"和"dsa"端口创建网络接口,原因如下:

  • “cpu"端口是以太网交换机面向管理控制的一侧,因此,会创建功能的复本,因为同一个管道有两个接口:master netdev和"cpu” netdev。
  • dsa端口只是两个或者多个交换机之间的管道,因此不能用来作为网络接口,此模型下,只有最底层或者最上层的接口才合理。

1.1 交换机tagging协议

DSA目前运行5种tagging协议,外加一种无tag模式,协议在下列文件中实现:

  • net/dsa/tag_trailer.c: Marvell尾部4字节tag(已停产)
  • net/dsa/tag_dsa.c:Marvell初始DSA tag
  • net/dsa/tag_edsa.c:Marvell增强DSA tag
  • net/dsa/tag_brcm.c:博通4字节tag
  • net/dsa/tag_qca.c:高通2字节tag

tag协议的具体格式由厂家自定义,一般来说,包含如下信息:

  • 表明以太网帧来自或者发往哪个端口
  • 表明以太网帧为什么需要发往管理接口

1.2 Master网络设备

Master网络设备是原始的、用于CPU/管理以太网接口的Linux网络设备驱动。此驱动有时需要知道DSA是否被使能(比如:开启或者关闭特定的offload功能),但是DSA子系统已经在e1000e\mv643xx_eth等标准驱动上验证可用,并且不需要对驱动做修改。Master网络设备经常被看作conduit网络设备,因为他们是主处理器和硬件以太网交换机之间的管道。

1.3 网络栈hooks

当master netdev使用DSA,网络栈中有一个hook让DSA能够处理以太网交换机特定的tagging协议。DSA通过向网络栈注册一个特定(也是虚拟)的以太网类型(后来变成skb->protocol)来实现hook,也就是ptype或者packet_type。典型的以太网帧接收顺序如下:

Master网络设备(比如e1000e):

  1. 收包中断触发:
  • 收包函数被唤醒
  • 完成基本的包处理:获取长度、状态等
  • 以太网层通过调用eth_type_trans准备对包进行处理
  1. net/ethernet/eth.c:
eth_type_trans(skb, dev)
        if (dev->dsa_ptr != NULL)
                -> skb->protocol = ETH_P_XDSA
  1. drivers/net/ethernet/*:
netif_receive_skb(skb)
        -> iterate over registered packet_type
                -> invoke handler for ETH_P_XDSA, calls dsa_switch_rcv()
  1. net/dsa/dsa.c:
-> dsa_switch_rcv()
        -> invoke switch tag specific protocol handler in 'net/dsa/tag_*.c'
  1. net/dsa/tag_*.c:
  • 检查并批剥掉交换机tag协议来决定原始的端口
  • 获取每个端口的网络设备
  • 调用DSA slave网络设备的eth_type_trans()
  • 调用netif_receive_skb()

以上操作完成后,DSA slave网络设备收到能被网络栈处理的常规以太网帧。

1.4 slave网络设备

DSA创建的slave网络设备堆叠在对应的master网络设备上,每个网络接口是每个交换机前面板端口的控制及数据流端点。这些接口处理完成如下工作:

  • 当报文发往/来自交换机端口时,插入/剥掉交换机tag协议(如存在)
  • 支持交换机ethtool操作:统计,link状态,Wake-on-LAN,dump寄存器。。。
  • 外部/内部PHY管理:link,auto-negotiation等。

slave网络设备通过自定义的net_device_ops和ethtool_ops,在网络栈/ethtool和交换机驱动实现中间增加DSA这一层。

当salve网络设备发包时,DSA查找注册到网络设备的交换机tagging协议,然后调用相应的发包函数在以太网帧中增加相应的交换机tag。

然后这些帧通过master网络设备的ndo_start_xmit()函数加入发送队列,因为帧包含了特定的交换机tag,所以以太网交换机能够处理来自管理接口的帧,并且发往物理交换机端口。

1.5 图形表示

概括来说,下图表示从网络设备角度看到的DSA
在这里插入图片描述

1.6 slave MDIO总线

为了能操作交换机内置的PHY,DSA创建slave MDIO总线来支持交换机驱动转移和拦截MDIO对PHY的读写操作。在大部分MDIO连接的交换机中,这些函数使用直接或者间接的PHY寻址模式来返回内置PHY的标准MII寄存器,允许PHY返回link status,link partner pages,自协商结果等。

因为以太网交换机可能有外部和内部MDIO总线,所以多路复用器/解复用器MDIO利用slave MII总线读写交换机的内部或者外部MDIO设备,从而交换机可以连接:内部PHY,外部PHY,甚至外部交换机。

1.7 数据结构

DSA相关的数据结构定义在include/net/dsa.h和net/dsa/dsa_priv.h

  • dsa_chip_data:交换设备的平台数据配置,此结构体描述了交换设备的父设备,地址,端口的各种属性:names/labels,及路由表(当级联时)。
  • dsa_platform_data:平台设备配置数据,当多个交换机级联时,此结构体表示dsa_chip_data结构体的集合,switch tree的master网络设备使用dsa_platform_data来描述。
  • dsa_switch_tree:描述dsa_ptr中的master网络设备,此结构体包含dsa_platform_data指针,"switch tree"支持的tagging协议,收发包回调函数,直联的交换机信息(CPU端口),及用于描述树型结构中每个交换机的dsa_switch数组。
  • dsa_switch:描述"switch tree"中的一个交换设备,包含指向dsa_switch_tree的反向指针,slave网络设备,master网络设备及dsa_switch_ops指针。
  • dsa_switch_ops:函数指针结构体,请参考正文的详细描述。

2 设计限制

2.1 设备和端口数量限制

DSA目前"switch tree"中最大的交换机数是4(DSA_MAX_SWITCHES),每个交换机最大端口数为12(DSA_MAX_PORTS)。可以增大相应的值来扩展限制。

2.2 缺少CPU/DSA网络设备

按前面所述,DSA目前不为CPU或DSA端口创建slave网络设备。在下面的场景下可能是一个问题:

  • 无法通过ethtool获取交换机CPU口的统计,这使得很难通过xMII接口来调试MDIO交换机。
  • 无法基于以太网控制器的能力来配置CPU端口连接参数:net: dsa: Allow configuration of CPU & DSA port speeds/duplex
  • 当级联时,无法配置交换机之间的VLAN ID/trunking VLAN

2.3 使用DSA常见的坑

一旦master网络设备配置了DSA(dev->dsa_ptr不为NULL),那么它后面的交换机就会期望tagging协议,这个网络接口只能专门用作conduit接口。直接发往此接口的报文(比如:在接口上打开socket)将不会通过交换机tagging协议发送函数 ,从而对端的以太网交换机因为没有tag会丢弃报文。

slave网络设备up之前会检查确保master网络设备已经up。一个常见的配置错误就是没有最先让master网络设备up起来。

3 与其他模块的交互

DSA影响如下子系统:

  • MDIO/PHY驱动:drivers/net/phy/phy.c, mdio_bus.c
  • 交换设备:net/switchdev/*
  • 用于of_*函数的设备树

3.1 MDIO/PHY驱动:

DSA中的slave网络设备可以连接或者不连接PHY(定义在include/linux/phy.h中的struct phy_device),但是DSA子系统处理所有可能的组合:

  • 内部PHY设备,内置在以太网交换机硬件中
  • 外部PHY设备,通过内部或者外部MDIO总线连接
  • 内部PHY设备,通过内部MDIO总线连接
  • 特别的,非自协商或者非MDIO管理的PHY设备:SPF,MoCA;也就是固化PHY。

PHY配置由dsa_slave_phy_setup()函数实现,其基本逻辑如下:

  • 如果使用设备树,PHY设备通过标准的"phy-handle"属性来查找,找到之后,PHY设备通过of_phy_connect()创建和注册。
  • 如果使用设备树,并且PHY设备是"fixed"的,那么需要遵循Documentation/devicetree/bindings/net/fixed-link.txt中关于非MDIO管理PHY的定义。
  • 最后,如果PHY内置在交换机里,这对独立交换机很常见,PHY通过DSA创建的slave MII总线探测到。

3.2 SWITCHDEV

当连接bridge层时,DSA直接使用SWITCHDEV,更具体的,当在slave网络设备上配置了VLAN,使用它的VLAN filtering部分。因为DSA主要用于MDIO连接的交换机,但是并不仅限于此,SWITCHDEV的prepare/abort/commit阶段经常简化成,检查DSA交换机驱动是否支持操作的prepare阶段和应用修改的commit阶段。

从现在开始,DSA支持的SWITCHDEV对象是FDB和VLAN。

3.3 设备树

DSA功能在Documentation/devicetree/bindings/net/dsa/dsa.txt描述。PHY/MDIO驱动的辅助函数,比如of_get_phy_mode(), of_phy_connect()也用来查询PHY特定信息:接口连接,MDIO总线位置等。

4 驱动开发

DSA交换机驱动需要实现dsa_switch_ops结构体,它包含上述的所有成员。

register_switch_driver()向内部驱动列表注册用于probe的dsa_switch_ops。unregister_switch_driver()相反。

除非priv_size成员设置成不同的值,否则DSA不会分配任何驱动私有的空间。

4.1 交换机配置

  • tag_protocol:用于标明支持哪些tagging协议,根据枚举变量dsa_tag_protocol生成有效值。
  • probe:probe函数在DSA platform设备注册时被调用,用来检测交换机设备是否存在。对MDIO设备,建议通过交换机虚拟PHY读取内部寄存器,并返回设备是否被支持。对其他总线,返回非NULL字符串。
  • setup:交换机的setup函数 ,此函数负责设置dsa_switch_ops私有结构体中需要的操作:寄存器映射,中断,mutex,lock等。此函数同时配置交换机来区分每个网络接口,换句话说,这些接口需要物理上是隔离的,典型的,为每个端口创建一个Port-based VLAN ID,这样只允许CPU端口和相应的端口在转发表中。platform不用的端口需要被禁用。通过此函数,交换机已经被完全配置,并且做好处理各种请求的准备。推荐在setup函数中对交换机进行软复位,避免依赖之前通过bootloader/firmware配置的内容。

4.2 PHY设备和link管理

  • get_phy_flags:switch连接各种各样的以太网PHY,如果PHY自带的PHY驱动需要知道自己(比如来自switch寄存器)无法获取的信息,此函数应该返回32位bitmask的flags,这是switch驱动和以太网PHY驱动(drivers/net/phy/*)之间私有的。
  • phy_read:当要读取switch端口的MDIO寄存器时,由DSA slave MDIO总线调用。如果不可用,返回0xffff。对内置的switch以太网PHY,此函数应该支持读取link状态,自协商结果,link partner pages等。
  • phy_write:当要写入switch端口的MDIO寄存器时,由DSA slave MDIO总线调用。如果不可用,返回负数的错误码。
  • adjust_link:当一个slave网络设备关联到PHY设备时被PHY库调用。此函数负责配置switch端口的连接参数:speed,duplex,根据提供的phy_device进行pause。
  • fixed_link_update:专门被PHY库的fixedPHY驱动调用,用于向switch驱动请求link参数,这些参数不能是自协商的,或者通过MDIO读PHY寄存器获取的。对于QSGMII,MoCA或者其他非MDIO管理的PHY,此函数特别适合用来获取带外连接信息。

4.3 Ethtool操作

  • get_strings:用来查询驱动的字符串,一般用来返回统计字符串,私有flags字符串等。
  • get_ethtool_stats:用来查询每个端口的统计值并返回。DSA覆盖slave网络设备通用的统计值:网络设备的RX/TX统计,每个端口的switch驱动特定的统计。
  • get_sset_count:查询统计项的个数。
  • get_wol:获取每个端口的Wake-on-LAN配置,如果master网络设备开启了Wake-on-LAN,也可以用来查询它的Wake-on-LAN配置。
  • set_wol:配置每个端口的Wake-on-LAN设置,与get_wol限制相同。
  • set_eee:配置switch端口的EEE(Green Ethernet)设置,如果必要的话,也可以被PHY库调用在PHY层使能EEE。此函数应该在switch端口的MAC控制器和数据处理逻辑中使能EEE。
  • get_eee:查询switch端口的EEE配置,此函数返回switch端口MAC控制器和数据处理逻辑的EEE状态,同时查询PHY的当前EEE配置。
  • get_eeprom_len:返回switch的EEPROM长度(字节为单位)
  • get_eeprom:返回switch的EEPROM的内容
  • set_eeprom:配置switch的EEPROM
  • get_regs_len:返回switch寄存器的长度
  • get_regs:返回以太网switch内部寄存器的内容。此函数可能需要ethtool的用户态代码来格式化打印寄存器值和寄存器

4.4 电源管理

  • suspend:当系统挂起时,由DSA platform设备调用,停止所有的以太网switch活动,但是保持开启Wake-on-LAN功能及相应的唤醒逻辑正常工作。
  • resume:当系统恢复时,由DSA platform设备调用,恢复所有的以太网switch活动并且重新配置switch进入全功能状态。
  • port_enable:当端口up时,由DSA slave网络设备的ndo_open函数调用,此函数应该完全enable指定的switch端口。如果端口是桥成员,DSA标记端口为BR_STATE_BLOCKING,如果不是桥成员,标记为BR_STATE_FORWARDING,并且将这些变化传播到硬件。
  • port_disable:当端口down时,由DSA slave网络设备的ndo_close函数调用,此函数应该完全disable指定的switch端口。如果端口是桥成员,DSA标记端口为BR_STATE_DISABLED,并且将这些变化传播到硬件。

4.5 Bridge层

  • port_bridge_join:当switch端口加入bridge时被调用,此函数完成switch层的必要操作,来允许新join的端口,加入与bridge其他成员收发包的逻辑。
  • port_bridge_leave:当switch端口从bridge中删除时被调用,此函数完成switch层的必要操作,来拒绝新leaving的端口,离开与bridge其他成员收发包的逻辑。当端口留在bridge时,所有此端口后面的MAC地址都需要老化掉,然后switch重新学习。
  • port_stp_state_set:当switch端口的STP状态被bridge层计算完成时调用,并且需要传播到硬件来实现流量的forward/block/learn。switch驱动负责基于当前及请求的参数来计算STP状态变化,并且基于交叉的结果来进行相关的老化。

4.6 Bridge VLAN filtering

  • port_vlan_filtering:配置桥时用来打开或者关闭VLAN filtering。如果硬件层没什么操作,此回调可以不实现。当VLAN filtering打开时,硬件必须丢弃VLAN ID不在允许范围内的802.1Q帧。如果switch端口没有配置PVID,untagged帧也必须被丢弃。当VLAN filtering关闭时,switch必须接收所有VLAN的802.1Q报文,untagged帧也是允许的。
  • port_vlan_prepare:当bridge为指定端口准备VLAN配置时被调用。如果硬件不支持此操作,应该返回-EOPNOTSUPP通知bridge fallback到软件实现。此函数不需要进行实际的硬件配置。详细请参考port_vlan_add。
  • port_vlan_add:为指定switch端口配置VLAN(tagged或者untagged)时调用。
  • port_vlan_del:删除指定switch端口VLAN配置
  • port_vlan_dump:指定端口所属的所有VLAN调用switchdev回调函数时调用。switchdev对象用来保存VID和bridge flags。
  • port_fdb_add:当bridge需要增加FDB条目时调用,转发表中与指定VLAN ID相关的特定VLAN的特定MAC地址需要写入switch硬件。如果硬件不支持此操作,应该返回-EOPNOTSUPP通知bridge fallback到软件实现。
注意
VLAN 0相当于端口私有数据库,在DSA上下文中,是对应bridge设备的port-based VLAN
  • port_fdb_del:当bridge需要删除FDB条目时调用,转发表中指定VLAN ID的中的特定MAC地址需要从switch硬件中删除。
  • port_fdb_dump:指定端口背后的每个MAC地址调用switchdev回调函数时调用。switchdev对象用来保存VID和FDB信息。
  • port_mdb_prepare:当bridge为指定端口准备组播VLAN配置时被调用。如果硬件不支持此操作,应该返回-EOPNOTSUPP通知bridge fallback到软件实现。此函数不需要进行实际的硬件配置。详细请参考port_mdb_add。
  • port_mdb_add:当bridge需要增加组播条目时调用,转发表中与指定VLAN ID相关的特定VLAN的特定MAC地址需要写入switch硬件。
注意
VLAN 0相当于端口私有数据库,在DSA上下文中,是对应bridge设备的port-based VLAN
  • port_mdb_del:当bridge需要删除组播条目时调用,转发表中指定VLAN ID的中的特定MAC地址需要从switch硬件中删除。
  • port_mdb_dump:指定端口背后的每个MAC地址调用switchdev回调函数时调用。switchdev对象用来保存VID和MDB信息。

5 TODO

5.1 将SWITCHDEV和DSA合成一套代码

SWITCHDEV从支持offload的硬件中抽象网络栈,但并不强制实现一个严格的switch设备驱动模型。另一方面,DSA强制实现了相对严格的switch设备驱动模型,并且处理大部分switch规范。未来我们期望将两个系统合并,这样就两全其美了。

5.2 其他待办事项

  • switch端口数目完全动态变化,而不依赖DSA_MAX_PORTS
  • 允许多个CPU/管理接口:http://comments.gmane.org/gmane.linux.network/365657
  • 移植更多厂家的驱动:http://comments.gmane.org/gmane.linux.network/365510
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值