linux内核DCB子系统

本文深入探讨Linux内核的DCB子系统如何处理网络流量的QoS需求,涉及LLDPAD应用、数据结构dcbnl_ops、DCB模块与驱动实现。DCB用于不同流量类型的QoS管理,如FCoE和TCP,通过lldpad配置DCB特性,驱动定义dcbnl_ops以与硬件交互。
摘要由CSDN通过智能技术生成

   q1. 网络设备是怎么利用linux内核的DCB子系统,来达到融合网络流量的各种各样的QoS需求的?

  q2.融合网卡或者存储流量是否也可以使用到DCB子系统,他们是怎样工作的?

     本文将对上面这两个问题进行解答;本文首先大体介绍了DCB机制和它的使用环境;然后介绍一个使用DCB的应用程序lldpad的例子;再然后介绍一个DCB子系统中重要的数据结构;最后介绍DCB内核模块和驱动的具体实现。

Overview

    首先,DCB是什么呢?
 

    整个DCB过程,是要把各种各样的流量,可能是FCoE流量,可能是一般的TCP流量,还可能是其他的视频流量等等,他们对于QoS的要求各不相同,有的要求不丢包,有的要求带宽保证等等,但是他们也许都需要从这一个网络接口发送到他们各自的目的地中去。由于意识到这个需求,在linux内核中,2.4?或者更早的版本中加入了TC(流量分类)模块,用来对不同的流量类型进行不同的处理。之前说到驱动模块是网络接口的agent,网络设备很可能也和内核一样,对于不同的流量类型也有不同的QoS处理,不过如果网络设备没有这个多队列和相关的处理,那么也不影响QoS的处理,只不过不能提速,在网卡这一块可能会成为瓶颈。使用了多个队列的网卡,在内部可能有一个处理器来进行这些复杂的多队列处理,然后驱动的DCB代码部分很可能需要完成TC映射的功能。但是如果说网卡没有多队列,内核的QoS任然可以发挥它的作用(当然要消耗CPU是必须的啦)。

 

    驱动是网卡的agent,就相当于网卡是个聋哑人,主机是不能和网卡说话的,通过驱动,网卡和主机能够进行交互。主机说要从这接口发送包出去,于是调用驱动的发送函数,把包发送出去。如果网卡物理层收到包,则通过驱动的中断函数来处理这些包(为了提高效率,现在也有可能使用到NAPI)。本来发送和接受都好说,当然是用最快的速度处理发包和收包就好。但是当流量类型渐渐复杂的时候,就要针对不同的流量进行不同的处理。比如说我们的主机上有飞机,坦克,自行车,当都必须经过这个接口出去时,我们按照飞机的优先级最高,自行车优先级最低,只有当飞机和坦克都过去了之后,自行车才能够通行(我们的主机内存很多,给飞机一个队,坦克一个队,自行车一个队)。如果这个接口很宽,我们还可以把这个接口设置几个队列,要出去的直接在接口上拍队(当然也是先通过内存的平滑缓冲)。道路上认为一次只能通过一个东西。

 

    用户的流量特征我们可以通过lldpad设置,设置了这个值,而且设置的而这些信息是要和对端交换机进行交互的,于是通过那个接口发出去,设置的这个值是要和内核交互的,当内核协议栈收到这些信息的时候,需要配置相应的队列和算法(同时还要获取硬件信息,如果有必要还要把tc队列映射到网卡队列),和驱动交互的另外一个原因很可能是因为dcb-lldp需要使用驱动本身要传递的网卡DCB信息和要求。

 

    关于存储流量,比如FCoE流量,是不会经过内核的Qdisc的,他经过的是FcoE模块,在FCoE模块中也是会使用DCB模块的额,从而达到和Qdisc一样的目的?

Q.FCoE模块为何也要用到dcb模块中的函数?

A.FCoE模块作为FCoE协议的处理模块,需要配置相应的FCoE类型和DCB类型的包的DCB参数。(这是不是假如它不再经过802.1p网络层次?)

Q.发挥了什么作用?

A.获取了FCoE和FIP类型的的优先级

Up(FCoE优先级);Fup(FIP优先级)

static void fcoe_dcb_create(struct fcoe_interface *fcoe)

{

#ifdef CONFIG_DCB

     int dcbx;

   u8 fup, up;

   struct net_device *netdev = fcoe->realdev;

   struct fcoe_port *port = lport_priv(fcoe->ctlr.lp);

         struct dcb_app app = {

                                 .priority = 0,

                        .protocol = ETH_P_FCOE

                        };

    ...

                        app.selector = DCB_APP_IDTYPE_ETHTYPE;

                    up = dcb_getapp(netdev, &app);

                       app.protocol = ETH_P_FIP;

               fup = dcb_getapp(netdev, &app);

              }

                 port->priority = ffs(up) ? ffs(up) - 1 : 0;

fcoe->ctlr.priority = ffs(fup) ? ffs(fup) - 1 : port->priority;

 

除了DCB初始化函数,fcoe_dcb_create;内核提供了DCB,NET和CPU通知链注册/注销和工作队列的接口函数。


LLDPAD

这个应用程序是用来配置Intel网络设备的DCB特性的。

Listed below are the applicablestandards:

 Enhanced Transmission Selection: IEEE 802.1Qaz

 Lossless Traffic Class

   Priority Flow Control: IEEE 802.1Qbb

   Congestion Notification: IEEE 802.1Qau

 DCB Capability exchange protocol (DCBX): IEEE 802.1Qaz

那么怎么使用lldpad配置DCB特性呢?比如使用用户接口lldpad。

Dcbtool

Dcbtool可以用来查询和设置DCB以太网接口的DCB特性。通用的命令有gc, sc等。(对应的DCB模块的getset函数),主要可以参考https://github.com/jrfastab/lldpad
比如:<gc|go> dcbxgets the configured or operational version of the  DCB  capabilities  exchange  protocol.  
可以设置本地interface的配置特性。
sc <ifname> <feature> <args>
              sets the configuration of feature on interface ifname.
这些特性feature包括:
        dcb    DCB state of the port
 
       pg     priority groups
pgid:xxxxxxxx
Priority group ID for the 8  priorities.   From  left  to  right
(priorities  0-7),  x  is  the  corresponding  priority group ID
value, which can be 0-7 for priority groups with bandwidth allo-
cations  or f (priority group ID 15) for the unrestricted prior-
ity group.
 
 
       pfc    priority flow control(特殊的参数有pfcup: xxxxxxxx
x01,1指的是这个相应的优先级(总共有8个优先级0-7)使用传输的pause帧机制,0就表示不使用。
 
       app:<subtype> 特殊的参数是appcfg:xx xx是一个16进制的值代表一个8bitbitmap,某一位为1代表着这个subtype使用这个优先级。
 
              application specific data
       subtype can be:
       ---------------
       0|fcoe Fiber Channel over Ethernet (FCoE)
      
下面是dcbtool的使用例子:
达到的目的:使得PFC pause发生作用的传输优先级是3,并且将FCoE流量分配到这个第三优先级上。
       dcbtool sc eth2 pfc pfcup:00010000
       dcbtool sc eth2 app:0 appcfg:08
app:0是表示FcoE流量
 
另外带宽分配的部分就是pg:比如
       dcbtool sc eth2 pg pgid:0000111f pgpct:25,75,0,0,0,0,0,0

 

使用Netlink和内核DCB子系统交互

在net\netlink\af_netlink.c中:

 

static int __init netlink_proto_init(void)

        

         sock_register(&netlink_family_ops);

        

}

 

static const struct net_proto_familynetlink_family_ops = {

       .family = PF_NETLINK,

       .create = netlink_create,

       .owner    = THIS_MODULE, /* for consistency 8) */

};

 

 

 

netlink_create中调用

static int __netlink_create(struct net *net, struct socket *sock,

                         struct mutex *cb_mutex, int protocol)

{

       struct sock *sk;

       struct netlink_sock *nlk;

 

       sock->ops = &netlink_ops;

       sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto);

      

       …

}

 

static const struct proto_opsnetlink_ops= {

       .family = PF_NETLINK,

       .owner = THIS_MODULE,

       .release =      netlink_release,

       .bind =          netlink_bind,

       .connect =     netlink_connect,

       .socketpair = sock_no_socketpair,

       .accept =       sock_no_accept,

       .getname =    netlink_getname,

       .poll =           datagram_poll,

       .ioctl =   sock_no_ioctl,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值