ifb的原理概述

和tun一样,ifb也是一个虚拟网卡,和tun一样,ifb也是在数据包来自的地方和去往的地方做文章。对于tun而言,数据包在xmit中发往字符设备,而从字符设备写下来的数据包则在tun网卡上模拟一个rx操作,对于ifb而言,情况和这类似。
       ifb驱动太简单,以至于很短的话就可以将其说清,然后上一幅全景图,最后留下一点如何使用它的技巧,本文就完了。

ifb驱动模拟一块虚拟网卡,它可以被看作是一个只有TC过滤功能的虚拟网卡,说它只有过滤功能,是因为它并不改变数据包的方向,即对于往外发的数据包被重定向到ifb之后,经过ifb的TC过滤之后,依然是通过重定向之前的网卡发出去,对于一个网卡接收的数据包,被重定向到ifb之后,经过ifb的TC过滤之后,依然被重定向之前的网卡继续进行接收处理,不管是从一块网卡发送数据包还是从一块网卡接收数据包,重定向到ifb之后,都要经过一个经由ifb虚拟网卡的dev_queue_xmit操作。说了这么多,看个图就明白了:

ingress队列

Linux TC是一个控发不控收的框架,然而这是对于TC所置于的位置而言的,而不是TC本身的限制,事实上,你完全可以自己在ingress点上实现一个队列机制,说TC控发不控收只是因为Linux TC目前的实现没有实现ingress队列而已。
       Linux的协议栈上有诸多的钩子点,Netfilter当然是最显然的了,它不但可以实现防火墙和NAT,也可以将一个数据包在PREROUTING钩子点上queue到一个队列,然后再将此队列的数据包发往一个虚拟网卡,虚拟网卡的xmit回调函数将数据包重新放回Netfilter将数据包STOLEN走的点上,在发往虚拟网卡的时候做发送流控从而变相地实现ingress队列,这就是IMQ的原理,它工作地不错,但是需要在skb中增加字段,使用起来也要牵扯到Netfilter的配置,不是那么纯粹,于是在这个思想的基础上实现了ifb驱动,这个驱动直接挂在TC本身的ingress钩子上,并不和Netfilter发生关系,但是由于TC的钩子机制并没有将一个数据包偷走再放回的机制,于是只有在做完ifb的流控后在ifb网卡的xmit函数中重新调用实际网卡的rx一次,这个实现和Linux Bridge的实现中完成local deliver的实现如出一辙。

Qdisc的多网卡共享

除了ingress队列之外,在多个网卡之间共享一个根Qdisc是ifb实现的另一个初衷,可以从文件头的注释中看出来。如果你有10块网卡,想在这10块网卡上实现相同的流控策略,你需要配置10遍吗?将相同的东西抽出来,实现一个ifb虚拟网卡,然后将这10块网卡的流量全部重定向到这个ifb虚拟网卡上,此时只需要在这个虚拟网卡上配置一个Qdisc就可以了。
性能问题
        也许你觉得,将多块网卡的流量重定向到一块ifb网卡,这岂不是要将所有的本属于不同的网卡队列被不同CPU处理的数据包排队到ifb虚拟网卡的一个队列被一个CPU处理吗?事实上,这种担心是多余的。
       是的,ifb虚拟网卡只有一个网卡接收队列和发送队列,但是这个队列并非被一个CPU处理的,而是被原来处理该数据包的CPU(只是尽量,但不能保证就是原来处理该数据包的那个CPU)继续处理,怎么做到的呢?事实上ifb采用了tasklet来对待数据包的发送和接收,在数据包进入fib的xmit函数之后,将数据包排入队列,然后在本CPU上,注意这个CPU就是原来处理数据包的那个CPU,在本CPU上调度一个tasklet,当tasklet被执行的时候,会取出队列中的数据包进行处理,如果是egress上被重定向到了ifb,就调用原始网卡的xmit,如果是ingress上被重定向到了ifb,就调用原始网卡的rx。当然,tasklet中只是在队列中取出第一个数据包,这个数据包不一定就是在这个CPU上被排入的,这也许会损失一点cache的高利用率带来的性能提升,但不管怎样,如果是多CPU系统,那么显然tasklet不会只在一个CPU上被调度执行。另外,开销还是有一点的,那就是操作单一队列时的自旋锁开销。
       优化方式是显然的,那就是将队列实现成“每CPU”的,这样不但可以保证cache的高利用率,也免去了操作单一队列的锁开销。

一个示例配置

# 加载ifb驱动并创建ifb网卡(使用ifconfig -a 如果看到已有则无需该步骤)
modprobe ifb numifbs=1
# up网卡
ip link set dev ifb0 up# 清除原有的根队列(根据实际情况操作,非必要)
tc qdisc del dev eth0 root 2>/dev/null
tc qdisc del dev eth0 ingress 2>/dev/null
tc qdisc del dev ifb0 root 2>/dev/null#  将eth0的ingress流量全部重定向到 ifb0 处理
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0# eth0的出向限速:eth0添加根队列,使用htb,添加1:1类,使用htb
tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65
tc class add dev eth0 parent 1: classid 1:1 htb rate 1000Mbit# eth0的入向限速:ifb0添加根队列,使用htb,添加1:1类,使用htb
tc qdisc add dev ifb0 root handle 1: htb r2q 625 default 65
tc class add dev ifb0 parent 1: classid 1:1 htb rate 1000Mbit# eth0的出向限速:eth0设备添加子类\对应的filter配置规则和子类的队列
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10Mbit
tc filter add dev eth0 parent 1: protocol all prio 1 u32 match ip dst 192.168.0.2 classid 1:10
tc qdisc add dev eth0 parent 1:10 handle 10: sfq# eth0的出向限速:eth0设备添加子类\对应的filter配置规则和子类的队列
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 20Mbit
tc filter add dev eth0 parent 1: protocol all prio 1 u32 match ip dst 192.168.0.3 classid 1:11
tc qdisc add dev eth0 parent 1:11 handle 11: sfq# eth0的入向限速:ifb0设备添加子类\对应的filter配置规则和子类的队列
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 10Mbit
tc filter add dev ifb0 parent 1: protocol all prio 1 u32 match ip src 192.168.0.2 classid 1:10
tc qdisc add dev ifb0 parent 1:10 handle 10: sfq# eth0的入向限速:ifb0设备添加子类\对应的filter配置规则和子类的队列
tc class add dev ifb0 parent 1:1 classid 1:11 htb rate 20Mbit
tc filter add dev ifb0 parent 1: protocol all prio 1 u32 match ip src 192.168.0.3 classid 1:11
tc qdisc add dev ifb0 parent 1:11 handle 11: sfq

参考:https://blog.csdn.net/gdfhhj/article/details/83934931

linux使用TC并借助ifb实现入向限速(内附配置实例)相关推荐

  1. 技术干货|基于Apache Hudi 的CDC数据入湖「内附干货PPT下载渠道」

    简介: 阿里云技术专家李少锋(风泽)在Apache Hudi 与 Apache Pulsar 联合 Meetup 杭州站上的演讲整理稿件,本议题将介绍典型 CDC 入湖场景,以及如何使用 Pulsar ...

  2. linux 内核 三天吐血,编译安装——吐血经验,内附脚本

    程序包编译安装: 源码包:name-VERSION-release.src.rpm rpm由源码包安装后,使用rpmbuild命令制作成二进制格式的rpm包,而后再安装 源代码–> 预处理–&g ...

  3. 【Linux】软件包管理器yum和编辑器vim(内附动图)

    大家好我是沐曦希

  4. linux网卡限速tc,Linux使用tc对网络进行限速

    Linux使用tc对网络进行限速.md 一.限制向特定IP端的出流量outgoing tc qdisc del dev eth0 root 2>/dev/null tc qdisc add de ...

  5. Linux 下TC 以及netem队列的使用

    一:综述: linux系统中的流量控制器(TC)主要是在输出端口处建立一个队列进行流量控制. TC是一个可以根据数据包的任何一个部分的特征对其进行分类的工具,并且可以为各类数据提供不同带宽,从而控制他 ...

  6. Linux 下 TC 命令原理及详解<一>

    文章目录 1 前言 2 相关概念 3 使用TC 4 创建HTB队列 5 为根队列创建相应的类别 6 为各个类别设置过滤器 7 复杂的实例 Linux 下 TC 命令原理及详解<一> Lin ...

  7. Linux 下 TC 命令原理及详解

    众所周知,在互联网诞生之初都是各个高校和科研机构相互通讯,并没有网络流量控制方面的考虑和设计,IP协议的原则是尽可能好地为所有数据流服务,不同的数据流之间是平等的.然而多年的实践表明,这种原则并不是最 ...

  8. Linux使用tc模拟网络延迟和丢包

    1 模拟延迟传输简介 netem 与 tc: netem 是 Linux 2.6 及以上内核版本提供的一个网络模拟功能模块.该功能模块可以用来在性能良好的局域网中,模拟出复杂的互联网传输性能,诸如低带 ...

  9. linux服务器垃圾箱,如何将Linux rm命令删除的文件放入垃圾箱

    因为rm命令删除的文件是不会放入垃圾箱的,所以无法恢复.通过替换Linux rm命令的方法,从而将rm命令删除的文件放入垃圾箱,这样就能将误删的文件恢复,一起来学习下吧. 方法: 1. 在/home/ ...

最新文章

  1. 知识图谱如何让“人工智能”更智能?
  2. C#获取一些常用目录
  3. Android 获取当前的时间。年月日,时分秒,星期几
  4. 通通玩blend美工(8)——动态绘制路径动画,画出个萌妹子~
  5. 2012微软校园招聘笔试题
  6. Backbone.js入门学习资源
  7. 【Kibana】es 报错 all shards failed: [search_phase_execution_exception] all shards failed
  8. 绕开“陷阱“,阿里专家带你深入理解C++对象模型的特殊之处
  9. Java-static概述
  10. 常见职位的英文简称_英语面试常见的50大问题及应对技巧
  11. 备忘录模式-Memento
  12. android 壁纸服务,8.1 初识Android壁纸
  13. python元组定义_python定义元组
  14. 基于DES和RSA算法自动分配密钥的加密聊天程序
  15. ferguson博弈_组合博弈游戏
  16. 【纯净安装、免U盘】无视win11硬件要求,直接setup.exe安装win11
  17. json文件保存与读取
  18. 13.1 数状数组 ——【小朋友排队】
  19. CSS中的绝对定位和相对定位
  20. 计算机系给未来的自己写信,给未来的自己写信

热门文章

  1. 如何在电脑上安装虚拟机和系统。全网最全教程,不接受反驳。
  2. 玉米社:百度SEM竞价推广策略有哪些?
  3. 电脑文件备份到移动硬盘的方法
  4. 均值归一化_深度神经网络中的归一化技术
  5. 【iOS】Plist-XML-JSON数据解析
  6. ONLYOFFICE历史版本开发技术之二
  7. java锟斤拷锟斤拷锟_锟斤拷?UTF-8与GBK互转乱码问题
  8. python怎么变成竖行_用python实现古诗词横板竖版显示 【二维列表的使用】
  9. 哈工大计算机系统大作业:程序人生-Hello’s P2P
  10. R语言学习笔记三:两独立样本t检验