为了正确理解更复杂的配置,首先有必要解释一些概念。由于该主题的复杂性和相对较新,当人们实际上指的是同一件事时,会使用许多不同的词语。
以下内容大致基于draft-ietf-diffserv-model-06.txt,《Diffserv 路由器的非正式管理模型》。目前可以在 http://www.ietf.org/internet-drafts/draft-ietf-diffserv-model-06.txt 找到。
阅读它以了解所用术语的严格定义。
一种管理设备队列的算法,可以是入站 (ingress) 或出站 (egress)。
一种没有可配置内部细分的队列规则。
有类别队列规则包含多个类别。这些类别中的每一个都包含一个进一步的队列规则,它可能再次是有类别的,但不必如此。根据严格的定义,pfifo_fast *是* 有类别的,因为它包含三个频带,而这些频带实际上是类别。但是,从用户的配置角度来看,它是无类别的,因为无法使用 tc 工具触及这些类别。
有类别队列规则可以有许多类别,每个类别都是队列规则内部的。这些类别中的每一个都可以包含一个真实的队列规则。
每个有类别队列规则都需要确定它需要将数据包发送到哪个类别。这是使用分类器完成的。
可以使用过滤器执行分类。过滤器包含许多条件,如果匹配,则过滤器匹配。
队列规则可以借助分类器决定某些数据包需要比其他数据包更早地发出。此过程称为调度,例如由前面提到的 pfifo_fast 队列规则执行。调度也称为“重新排序”,但这会令人困惑。
在数据包发出之前延迟数据包以使流量符合配置的最大速率的过程。整形在出口 (egress) 上执行。通俗地说,丢弃数据包以减慢流量也经常被称为整形。
延迟或丢弃数据包以使流量保持在配置的带宽之下的过程。在 Linux 中,策略只能丢弃数据包而不能延迟它 - 没有“入口队列”。
如果数据包可用,则工作保持队列规则始终传递数据包。换句话说,如果网络适配器已准备好发送数据包(在出口队列规则的情况下),它永远不会延迟数据包。
某些队列,例如令牌桶过滤器,可能需要将数据包保留一段时间以限制带宽。这意味着即使它们有可用的数据包,有时也拒绝放弃数据包。
现在我们已经理清了术语,让我们看看所有这些东西在哪里。
Userspace programs ^ | +---------------+-----------------------------------------+ | Y | | -------> IP Stack | | | | | | | Y | | | Y | | ^ | | | | / ----------> Forwarding -> | | ^ / | | | |/ Y | | | | | | ^ Y /-qdisc1-\ | | | Egress /--qdisc2--\ | --->->Ingress Classifier ---qdisc3---- | -> | Qdisc \__qdisc4__/ | | \-qdiscN_/ | | | +----------------------------------------------------------+ |
大方框代表内核。最左边的箭头代表从网络进入您机器的流量。然后将其馈送到入口队列规则,该规则可以对数据包应用过滤器,并决定丢弃它。这称为“策略 (Policing)”。
这发生在非常早期的阶段,在它看到很多内核之前。因此,这是非常好的地方,可以尽早丢弃流量,而不会消耗大量 CPU 功率。
如果允许数据包继续,它可能会被定向到本地应用程序,在这种情况下,它会进入 IP 协议栈以便进行处理,并移交给用户空间程序。数据包也可能在不进入应用程序的情况下转发,在这种情况下,它被定向到出口分类器。用户空间程序也可能传递数据,然后对其进行检查并转发到出口分类器。
在那里,对其进行调查并排队到许多队列规则中的任何一个。在未配置的默认情况下,仅安装了一个出口队列规则,即 pfifo_fast,它始终接收数据包。这称为“排队 (enqueueing)”。
数据包现在位于队列规则中,等待内核要求它通过网络接口进行传输。这称为“出队 (dequeueing)”。
如果只有一个网络适配器,此图也适用 - 进入和离开内核的箭头不应被过于字面地理解。每个网络适配器都有入口和出口挂钩。