53、Linux 网络中的 IP 路由与服务质量控制

Linux 网络中的 IP 路由与服务质量控制

1. IP 路由概述

IP 路由的核心作用是为计算机之间的数据包传输确定最佳路径,这一过程由 IP 层负责处理。IP 路由主要具备两大功能:
- 数据包转发 :在路由器中对 IP 数据包进行转发操作。
- 最佳路径识别 :为每个数据包在网络间的传输找出最优路线。

Linux 系统借助以下几种表格来实现路由功能:
| 表格名称 | 功能描述 |
| — | — |
| 转发信息库(FIB) | 记录并跟踪所有已知的路由信息。 |
| 路由缓存 | 针对当前正在使用的目标地址提供快速缓存服务。 |
| 邻居表 | 跟踪与主机物理连接的计算机。 |

Linux 支持多种路由类型,包括基于策略的路由、多路径路由、源路由和记录路由。

2. Linux 中的 IP 服务质量(IP QoS)

IP 服务质量(IP QoS)在 Linux 中的基本功能是决定如何按顺序接收输入的网络数据包,确定合适的带宽速率,并规划输出网络数据包在队列中的排列方式以及在分配的带宽速率下进行传输的时间和方式,本质上是根据应用需求对带宽进行管理。

在 Linux 里,“qdisc”代表队列规则,默认附加到网络接口的队列规则是“pfifo_fast_qdisc”,不过可以根据需求替换为其他类型的队列规则。

Linux 支持的队列规则类型如下:
1. 先进先出(FIFO)
2. 优先先进先出(PFIFO)
3. 令牌桶流量(TBF)
4. 异步传输模式(ATM)
5. 随机早期检测(RED)
6. 随机公平队列(SFQ)
7. 基于类的队列规则(CBQ)
8. 广义随机早期检测(GED)
9. 差分服务标记(DS_MARK)
10. Clark – Shenker – Zhang(CSZ)

3. Linux 流量控制的基本组件

Linux 流量控制主要包含以下几个基本组件:
- 队列规则 :每个网络设备都有一个队列规则,用于控制网络数据包在传输前的入队和出队操作。
- :仅基于类的队列规则支持类的概念。可以根据过滤器(如 IP 地址、TCP/IP 端口等)将网络流量分类,在传输前划分成不同的类,每个类会根据优先级安排数据包的出队顺序。
- 过滤器/分类器 :根据特定参数(如 IP 地址、TCP/IP 端口等)将数据包组织到不同的类中。
- 策略 :在网络数据包入队后,可以对数据包进行策略控制,例如允许数据包通过、丢弃数据包或者标记数据包。

以下是 Linux 流量控制的流程 mermaid 图:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A([输入网络数据包]):::startend --> B(队列规则):::process
    B --> C(过滤器/分类器):::process
    C --> D(类):::process
    D --> E(策略):::process
    E --> F([输出网络数据包]):::startend
4. pfifo_fast 队列规则的 Linux 实现

pfifo_fast 队列规则是 Linux 系统中所有网络接口的默认队列规则,不过也可以替换为其他队列规则。

pfifo_fast 包含三个不同的 FIFO 队列(不同的带宽),根据数据包的优先级进行入队操作。优先级最高的数据包进入 FIFO 0,会在处理 FIFO 1 和 FIFO 2 中的数据包之前首先出队;同理,FIFO 1 中的数据包会在 FIFO 2 之前被处理。

pfifo_fast 队列规则是不可用户配置的,因为它默认是硬编码的。数据包的优先级由内核分配,并根据数据包的 TOS 八位字节(priomap)映射到相应的带宽(FIFO)。

对于数据包的入队和出队操作,pfifo_fast 队列规则使用 pfifo_fast_enqueue() pfifo_fast_dequeue() 函数。

TOS 四位的定义如下:
| 二进制 | 十进制 | 含义 |
| — | — | — |
| 1000 | 8 | 最小化延迟 |
| 0100 | 4 | 最大化吞吐量 |
| 0010 | 2 | 最大化可靠性 |
| 0001 | 1 | 最小化货币成本 |
| 0000 | 0 | 正常服务 |

以下是一些应用对 TOS 位的使用示例:
| 应用程序 | TOS 位 | 说明 |
| — | — | — |
| TELNET | 1000 | 最小化延迟 |
| FTP 控制 | 1000 | 最小化延迟 |
| FTP 数据 | 0100 | 最大化吞吐量 |
| TFTP | 1000 | 最小化延迟 |
| SMTP 命令阶段 | 1000 | 最小化延迟 |
| SMTP 数据阶段 | 0100 | 最大化吞吐量 |
| 域名服务 UDP 查询 | 1000 | 最小化延迟 |
| 域名服务 TCP 查询 | 0000 | - |
| 域名服务区域传输 | 0100 | 最大化吞吐量 |
| NNTP | 0001 | 最小化货币成本 |
| ICMP 错误 | 0000 | - |
| ICMP 请求 | 0000(大部分情况) | - |
| ICMP 响应 | 与请求相同(大部分情况) | - |

5. 队列规则的数据结构
5.1 struct Qdisc
struct Qdisc {
    // 指向排队规则的入队函数的指针
    int (*enqueue)(struct sk_buff *skb, struct Qdisc *sch); 
    // 指向排队规则的出队函数的指针
    struct sk_buff *(*dequeue)(struct Qdisc *sch); 
    // 每个排队规则有一组控制其操作的函数
    struct Qdisc_ops *ops; 
    // 指向下一个排队规则的指针
    struct Qdisc *next; 
    // 排队规则的句柄,用于唯一标识
    u32 handle; 
    // 队列的头
    struct sk_buff_head q; 
    // 指向网络设备的指针
    struct net_device *dev; 
    // 统计信息,如入队字节数、数据包数、丢弃的数据包数等
    struct Qdisc_stats stats; 
    // 占位符,根据不同的排队规则指向不同的数据结构
    void *data; 
};

struct Qdisc 数据结构代表流量排队规则,它与网络设备相连,负责在将数据包发送到 Linux 系统的网络接口之前进行流量控制(数据包排队)。

  • enqueue :函数指针,指向排队规则的入队函数。如果未配置其他排队规则,默认函数是 pfifo_fast_enqueue() ,其主要目的是将 sk_buff 入队到调度器的适当队列中。
  • dequeue :函数指针,指向排队规则的出队函数,默认函数是 pfifo_fast_dequeue() ,主要目的是从最高优先级的非空队列中出队数据包。
  • ops :每个排队规则都有一组控制其操作的函数, Qdisc_ops 数据结构包含所有这些控制函数。
  • next :Linux 网络设备结构维护 qdisc_list 来链接用于设备排队的所有排队规则, next 指针指向设备支持的下一个排队规则。
  • handle :内核中有多个排队规则实例,每个实例由 32 位编号标识, handle 表示这个 32 位编号(由主编号和次编号组成,次编号始终为零)。
  • q :表示队列的头部。
  • dev :指向网络设备。
  • stats :表示统计信息,即入队字节数和数据包数、丢弃的数据包数等。
  • data :这是一个占位符。在默认的 pfifo_fast 情况下,它指向 sk_buff_head 结构的数组;对于 CBQ,它指向 cbq_sched_data 数据结构,该结构包含不同队列的类。
5.2 struct Qdisc_ops
struct Qdisc_ops {
    // 指向下一个 Qdisc_ops 的指针,用于链接所有已注册的排队规则操作
    struct Qdisc_ops *next; 
    // 类操作数据结构,提供特定类的一组函数
    struct Qdisc_class_ops *cl_ops; 
    // 排队规则的标识符,如 "pfifo", "cbq" 等
    char id[IFNAMSIZ]; 
    // 指向排队规则的入队函数的指针
    int (*enqueue)(struct sk_buff *skb, struct Qdisc *sch); 
    // 指向排队规则的出队函数的指针
    struct sk_buff *(*dequeue)(struct Qdisc *sch); 
    // 如果数据包出队发送失败,将其重新入队到原来的位置
    int (*requeue)(struct sk_buff *skb, struct Qdisc *sch); 
    // 从队列中移除并丢弃数据包
    int (*drop)(struct sk_buff *skb, struct Qdisc *sch); 
    // 将排队规则重置为初始状态
    void (*reset)(struct Qdisc *sch); 
    // 初始化新的排队规则
    int (*init)(struct Qdisc *sch, struct nlattr *opt); 
    // 销毁排队规则初始化期间使用的资源
    void (*destroy)(struct Qdisc *sch); 
    // 更改排队规则的参数值
    int (*change)(struct Qdisc *sch, struct nlattr *opt); 
    // 显示排队规则的统计信息
    int (*dump)(struct Qdisc *sch, struct sk_buff *skb); 
};

struct Qdisc_ops 数据结构提供了用于对排队规则执行各种操作的一组控制函数。

  • next :指向 Qdisc_ops 链表中的下一个元素,用于链接所有已注册的排队规则操作。
  • cl_ops :这是一个类操作数据结构 Qdisc_class_ops ,为特定类提供一组函数。
  • id :字符数组,包含排队规则的标识符(例如, pfifo cbq 等)。
  • 以下是指向排队规则的函数指针:
  • enqueue() :指向排队规则的入队函数的指针。
  • dequeue() :指向排队规则的出队函数的指针。
  • requeue() :如果数据包出队但由于未知原因发送失败,此函数将数据包放回队列中的原位置。
  • drop() :从队列中移除数据包并丢弃它。
  • reset() :将排队规则重置回初始状态。
  • init() :初始化新的排队规则。
  • destroy() :销毁排队规则初始化期间使用的资源。
  • change() :更改排队规则的参数值。
  • dump() :显示排队规则的统计信息。
5.3 struct Qdisc_class_ops
struct Qdisc_class_ops {
    // 将新的排队规则附加到类,并返回先前附加的排队规则
    struct Qdisc *(*graft)(struct Qdisc *sch, struct Qdisc *new, u32 classid); 
    // 返回类的排队规则的指针
    struct Qdisc *(*leaf)(struct Qdisc *sch, u32 classid); 
    // 返回类的内部 ID
    u32 (*get)(struct Qdisc *sch, u32 classid); 
    // 当 get 函数返回的类被释放时调用
    void (*put)(struct Qdisc *sch, u32 classid); 
    // 更改类的属性,也用于创建新类
    int (*change)(struct Qdisc *sch, struct nlattr *opt, u32 classid); 
    // 删除类
    int (*delete)(struct Qdisc *sch, u32 classid); 
    // 遍历排队规则的所有类,用于获取所有类的诊断数据
    int (*walk)(struct Qdisc *sch, struct qdisc_walker *walker);
    // 返回类的过滤器列表的指针,用于操作过滤器列表
    struct tcf_chain *(*tcf_chain)(struct Qdisc *sch, u32 classid);
    // 将过滤器实例绑定到类
    int (*bind_tcf)(struct Qdisc *sch, struct tcf_proto *tp, u32 classid);
    // 从类中移除过滤器实例
    int (*unbind_tcf)(struct Qdisc *sch, struct tcf_proto *tp, u32 classid);
    // 返回类的统计信息
    int (*dump_class)(struct Qdisc *sch, struct sk_buff *skb, u32 classid);
};

struct Qdisc_class_ops 是一个类操作数据结构,为特定类提供一组控制函数。

  • graft :功能是将新的排队规则附加到类,并返回先前附加的排队规则。
  • leaf :返回类的排队规则的指针。
  • get :返回类的内部 ID。
  • put :当 get 返回的类被引用释放时调用。
  • change :更改类的属性,也用于创建新类。
  • delete :删除类。
  • walk :遍历排队规则的所有类,用于获取所有类的诊断数据。
  • tcf_chain :返回类的过滤器列表的指针,用于操作过滤器列表。
  • bind_tcf :将过滤器实例绑定到类。
  • unbind_tcf :从类中移除过滤器实例。
  • dump_class :返回类的统计信息。
5.4 struct cbq_class
struct cbq_class {
    // 指向类树中下一个类的指针(哈希表链接)
    struct cbq_class *next; 
    // 指向活动流量类列表中下一个有数据包积压的类的指针
    struct cbq_class *next_alive; 
    // 类的唯一标识符
    u32 classid; 
    // 类的优先级,用于调度
    u8 priority; 
    // 超过限制后使用的类优先级
    u8 priority2; 
    // 用于计算空闲时间的字段
    u32 ewma_log; 
    // 每次轮询时 qdisc 可以出队的字节数
    u32 allot; 
    // 基于类分配的带宽的加权轮询分配量
    u32 quantum; 
    // 类的权重,用于高带宽类在一轮中发送更多数据
    u32 weight; 
    // 指向 cbq_class 树的父节点的指针
    struct cbq_class *tparent; 
    // 指示子节点是否可以从父节点借用带宽
    struct cbq_class *borrow; 
    // 指向兄弟类的指针
    struct cbq_class *siblings; 
    // 指向子类的指针
    struct cbq_class *children; 
    // 类在类树中的级别
    u8 level; 
    // 用于轮询调度过程中的赤字值
    s32 deficit; 
};

struct cbq_class 数据结构代表 CBQ 排队规则的流量类,用于根据为类分配的带宽调度数据包。

  • next :指向类树中的下一个类(哈希表链接)。
  • next_alive :CBQ 调度算法维护一个活动流量类列表,用于根据优先级调度类,该字段指向活动类列表中下一个有数据包积压的类。
  • classid :CBQ 排队规则中的每个类都由一个 ID 表示,该字段包含 CBQ 类的唯一 ID。
  • priority :该字段包含用于调度 CBQ 类的类优先级。
  • priority2 :该字段包含超过限制后使用的类优先级。CBQ 类有三种类型:超过限制、未达到限制和达到限制。根据 CBQ 调度函数中类的使用情况,根据分配的带宽将类分类为超过限制、未达到限制和达到限制。
  • ewma_log :该字段用于计算 CBQ 调度函数中所需的空闲时间。
  • allot :指定 qdisc 在每一轮中可以出队的字节数,这是可重新配置的,取决于 cbq_class 结构的 weight 字段。
  • quantum :根据为类分配的带宽指定加权轮询的分配量。
  • weight :如果 cbq_class 比队列中的其他类具有更多带宽,则 weight 字段用于高带宽类在一轮中比其他类发送更多数据。
  • tparent :指向 cbq_class 树的父节点。
  • borrow :该字段指示子节点是否可以从父节点借用带宽。如果为 NULL ,则类的带宽受限,无法从父节点借用带宽。
  • siblings :指向兄弟类。
  • children :指向子类。
  • level :类在类树中的级别。
  • deficit :该字段用于调度的轮询过程中。如果在同一轮中未发送分配的字节数,则该字段包含保存的赤字值,该赤字值将用于下一轮。
6. tc 用户程序与内核实现细节

tc 是一个用户程序,用于覆盖和更新 Linux 中的默认排队规则。它使用 netlink 作为用户空间和内核之间的通信通道,可添加新的排队规则、流量类、过滤器等。

以添加 CBQ 排队规则为例,使用命令如下:

# tc qdisc add dev eth1 root handle 1: cbq bandwidth 10 Mbit cell 8 avpkt 1000 mpu 64

该命令添加了一个新的 CBQ 排队规则。下面详细介绍相关函数的实现:

6.1 tc_modify_qdisc()
1. 调用 dev_get_by_index() 函数查找网络接口设备,参数为 tcm->tcm_ifindex(在命令提示符中指定)。
2. 检查 tcm->tcm_parent 的值:
   - 如果不等于 TC_H_ROOT,调用 qdisc_lookup() 和 qdisc_leaf() 函数查找父排队规则和带宽排队规则。
   - 如果等于 TC_H_ROOT,带宽排队规则指向设备的 qdisc_sleeping。
3. 检查 tcm->tcm_handle 的值:
   - 如果不为空,调用 qdsic_lookup() 函数搜索带宽排队规则 q。
     - 如果未找到,跳转到 create_n_graft 标签。
     - 否则,跳转到 graft 标签。
4. 在 create_n_graft 标签处:
   - 检查 nlmsghdr->nlmsg_flags 的 NLM_F_CREATE 位是否为 1。
   - 如果为 1,在调用 qdisc_create() 之前检查 INGRESS 或 EGRESS,qdisc_create() 用于分配和初始化新的排队规则。
5. 在 graft 标签处:
   - 调用 qdisc_graft() 函数,将设备的 qdisc_sleeping 设置为新的排队规则,将 dev->qdisc 设置为 noop_qdisc,最后重新激活设备并返回旧的排队规则 oqdisc。
   - 如果没有错误,graft 最后调用 qdisc_notify() 函数并将消息(skb)发送到用户空间。
6.2 qdisc_create()
1. 根据参数 tca 中的 TCA_KIND - 1 项确定排队规则的类型,调用 qdisc_lookup_ops() 函数按名称搜索排队规则。
2. 为排队规则分配空间,大小为 Qdisc 的大小加上 Qdisc 私有数据结构的额外空间。
3. 调用 skb_queue_head() 函数初始化 Qdisc 队列。
4. 初始化 Qdisc 操作(sch->ops)指针,设置排队规则操作,如入队、出队和设备。
5. 调用 ops->init 函数指针,在这种情况下指向 cbq_init() 函数。
6.3 cbq_init()
1. 设置类的 classid、priority、siblings 链接等。
2. 调用 qdisc_create_dflt() 函数为排队规则创建默认的排队规则,默认类型为 pfifo。
6.4 qdisc_graft()
参数:dev, p, clid, q & old,其中 p 是父排队规则,clid 是类 ID,q 是带宽排队规则,old_q 是旧的排队规则并设置为 NULL。
1. 检查父排队规则 p 是否为空。
2. 根据 EGRESS 和 INGRESS 调用 dev_graft_qdisc() 函数;否则,调用父排队规则的类操作集的 get() 函数。
6.5 dev_graft_qdisc()
1. 调用 dev_deactivate() 函数停用设备。
2. 检查 INGRESS 或 EGRESS:
   - 如果是 EGRESS,将旧的 qdisc_sleeping 设置为 oqdisc 变量。
   - 检查提供的新排队规则是否为空。
     - 如果为空,将新的排队规则设置为 noop_qdisc。
   - 将设备的 qdisc_sleeping 设置为新的排队规则,将 dev->qdisc 设置为 noop_qdisc。
3. 重新激活设备并返回旧的排队规则 oqdisc。
7. 创建 CBQ 类层次结构的 tc 命令

可以使用以下 tc 命令创建 CBQ 类层次结构:

# tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10 Mbit rate 10 Mbit allot 1514 cell 8 weight 1 Mbit prio 8 maxburst 20 avpkt 1000

该命令为网络接口 eth0 添加了一个新的 CBQ 类。

通过以上介绍,我们详细了解了 Linux 网络中的 IP 路由和服务质量控制相关内容,包括 IP 路由的功能和使用的表格,Linux 中多种队列规则及其数据结构,以及 tc 用户程序和相关内核函数的实现,还有如何使用 tc 命令创建 CBQ 类层次结构。这些知识对于优化 Linux 系统的网络性能和流量管理非常重要。

Linux 网络中的 IP 路由与服务质量控制

8. 深入理解 CBQ 排队规则

CBQ(Class - Based Queueing Discipline)即基于类的排队规则,它在 Linux 网络流量控制中扮演着重要角色。CBQ 允许根据不同的流量特征将数据包分类到不同的类中,并为每个类分配特定的带宽和优先级。

8.1 CBQ 类的调度机制

CBQ 调度算法主要依据类的优先级和分配的带宽来决定数据包的出队顺序。在调度过程中,会维护一个活动流量类列表, next_alive 字段在这个列表中起着关键作用,它指向有数据包积压的下一个类。

当进行调度时,会优先处理优先级高的类。例如,如果一个类的 priority 字段值较高,那么该类中的数据包会更优先地被处理。同时, allot quantum 字段也会影响调度过程。 allot 指定了每次轮询时 qdisc 可以出队的字节数,而 quantum 则根据类分配的带宽指定加权轮询的分配量。

如果一个类在一轮中没有用完分配的带宽, deficit 字段会记录这个差值,并在后续的轮询中使用,以确保类能够充分利用其分配的带宽。

8.2 CBQ 类的配置示例

假设我们要为网络接口 eth0 配置一个复杂的 CBQ 类层次结构。以下是一个更详细的配置示例:

# 添加根 CBQ 排队规则
tc qdisc add dev eth0 root handle 1: cbq bandwidth 100Mbit cell 8 avpkt 1000 mpu 64

# 添加父类
tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 80Mbit rate 80Mbit allot 1514 cell 8 weight 1Mbit prio 8 maxburst 20 avpkt 1000

# 添加子类
tc class add dev eth0 parent 1:1 classid 1:10 cbq bandwidth 30Mbit rate 30Mbit allot 1000 cell 8 weight 0.5Mbit prio 6 maxburst 15 avpkt 800

在这个示例中,首先为 eth0 接口添加了一个根 CBQ 排队规则,总带宽为 100Mbit。然后创建了一个父类,分配了 80Mbit 的带宽,接着在父类下创建了一个子类,分配了 30Mbit 的带宽。

9. 过滤器在 Linux 流量控制中的应用

过滤器(Filter)在 Linux 流量控制中用于根据特定的参数将数据包组织到不同的类中。以下是过滤器在实际应用中的详细介绍:

9.1 过滤器的类型

Linux 支持多种类型的过滤器,常见的有:
1. IP 地址过滤器 :根据数据包的源 IP 地址或目的 IP 地址进行分类。例如,可以将来自特定 IP 段的数据包分配到一个特定的类中。
2. TCP/IP 端口过滤器 :根据数据包使用的 TCP 或 UDP 端口进行分类。比如,将所有访问 80 端口(HTTP 服务)的数据包分到一个类中。
3. TOS 过滤器 :根据数据包的服务类型(TOS)字段进行分类。前面我们已经介绍了 TOS 字段的不同含义,通过 TOS 过滤器可以根据数据包的延迟、吞吐量等需求进行分类。

9.2 配置过滤器的步骤

以下是配置一个简单的 IP 地址过滤器的步骤:
1. 创建类 :首先需要创建一个或多个类,用于接收过滤后的数据包。

# 创建一个类
tc class add dev eth0 parent 1:0 classid 1:2 cbq bandwidth 20Mbit rate 20Mbit allot 1200 cell 8 weight 0.8Mbit prio 7 maxburst 18 avpkt 900
  1. 创建过滤器 :使用 tc filter 命令创建过滤器,并将其关联到相应的类。
# 创建一个 IP 地址过滤器,将来自 192.168.1.0/24 网段的数据包导向类 1:2
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip src 192.168.1.0/24 flowid 1:2

在这个命令中, u32 表示使用 u32 过滤器, match ip src 192.168.1.0/24 表示匹配来自 192.168.1.0/24 网段的数据包, flowid 1:2 表示将匹配的数据包导向类 1:2。

10. 策略在 Linux 流量控制中的作用

策略(Policing)在网络数据包入队后对数据包进行控制,主要包括以下几种操作:

10.1 允许数据包通过

可以设置策略允许符合特定条件的数据包通过。例如,允许所有来自内部网络的数据包通过,而对外部网络的数据包进行更严格的控制。

# 允许来自内部网络 10.0.0.0/8 的数据包通过
tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip src 10.0.0.0/8 action pass
10.2 丢弃数据包

当数据包不符合某些规则时,可以选择丢弃这些数据包。比如,丢弃所有来自恶意 IP 地址的数据包。

# 丢弃来自恶意 IP 1.2.3.4 的数据包
tc filter add dev eth0 parent 1: protocol ip prio 3 u32 match ip src 1.2.3.4 action drop
10.3 标记数据包

标记数据包可以用于后续的处理,例如根据标记对数据包进行不同的调度。

# 标记来自特定端口 8080 的数据包
tc filter add dev eth0 parent 1: protocol ip prio 4 u32 match ip dport 8080 action mark set 1

在这个命令中, action mark set 1 表示将匹配的数据包标记为 1。

11. 优化 Linux 网络性能的综合建议

通过对 IP 路由、队列规则、过滤器和策略的了解,我们可以提出以下优化 Linux 网络性能的综合建议:

11.1 根据应用需求选择合适的队列规则

不同的应用对网络性能的要求不同,因此需要选择合适的队列规则。例如,对于实时性要求高的应用(如视频会议、语音通话),可以选择能够优先处理数据包的队列规则,如 pfifo_fast 。而对于对吞吐量要求高的应用(如文件下载),可以考虑使用基于类的队列规则(如 CBQ)来合理分配带宽。

11.2 合理配置类和过滤器

根据网络流量的特点,合理配置类和过滤器可以提高网络资源的利用率。例如,将不同类型的流量(如 HTTP 流量、FTP 流量)分到不同的类中,并为每个类分配适当的带宽和优先级。

11.3 定期监控和调整策略

网络流量是动态变化的,因此需要定期监控网络性能,并根据监控结果调整策略。例如,如果发现某个类的带宽利用率过高,可以适当增加该类的带宽分配;如果发现有大量恶意数据包,可以调整过滤规则来阻止这些数据包。

12. 总结

本文详细介绍了 Linux 网络中的 IP 路由和服务质量控制的相关内容。从 IP 路由的基本功能和使用的表格,到 Linux 中多种队列规则及其数据结构,再到 tc 用户程序和相关内核函数的实现,以及如何使用 tc 命令创建 CBQ 类层次结构、配置过滤器和策略等。

通过合理配置 IP 路由、队列规则、过滤器和策略,可以有效地优化 Linux 系统的网络性能,提高网络资源的利用率,满足不同应用对网络的需求。同时,定期监控和调整网络策略也是确保网络稳定运行的重要措施。

以下是整个 Linux 网络流量控制的流程 mermaid 图,包含了从数据包输入到输出的完整过程:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A([输入网络数据包]):::startend --> B(IP 路由):::process
    B --> C(队列规则):::process
    C --> D(过滤器/分类器):::process
    D --> E(类):::process
    E --> F(策略):::process
    F --> G([输出网络数据包]):::startend

通过这个流程图,我们可以更清晰地看到各个组件在 Linux 网络流量控制中的作用和相互关系。在实际应用中,我们可以根据具体需求对每个组件进行配置和优化,以实现最佳的网络性能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值