关于网卡:网卡队列与发包

参考文献linux 网络子系统 DMA形式介绍https://cloud.tencent.com/developer/article/1628161网卡与DMA工作原理和流程https://zhuanlan.zhihu.com/p/553904728对收报、发包过程中网卡和网卡驱动工作流程有比拟具体的介绍https://www.cnblogs.com/jmilkfan-fanguiju/p/12789806.html#_50多队列网卡与网卡发包源码解读https://blog.csdn.net/tenfyguo/article/details/8777436这篇比拟全面具体: 对发包过程十分具体的形容,对波及到的函数有详细分析,很多图很直观https://zhuanlan.zhihu.com/p/373060740发送数据包流程dev_queue_xmit剖析https://blog.csdn.net/wdscq1234/article/details/51926808对网卡内存也就是RX TX FIFO有一个介绍,对收包流程也有介绍:https://www.jianshu.com/p/e6162bc984c8 意义当初问题大略都解决了,网卡有内存,但只是简略的RX TX FIFO,不起调度作用。多队列网卡应该接管时会有多个CPU能够并行处理,解决实现的程序和理论接管的程序可能不统一。我猜想:发送包的时候,应该也会有多个队列,每个队列绑定到一个CPU上,哪个CPU有空,就抢把锁去发送队列。这个队列存在主存还是网卡自带的什么存并不重要,要害的是这个队列和tc Qdisc是什么关系,一个包是如何进某个网卡队列的,是如何出队列被真正发送进来的,而后这些多个队列能并行发送吗?不过不能,那每次如何决定哪个队列出包发送呢?这些问题对于全部包的一个发送状况有着决定性的影响,然而如果我只思考单队列的网卡,或者说如果网卡的每一个队列下都有一个qdisc的话,因为网卡驱动是依据包的四元组进行HASH来决定到哪个队列的,那同一个流总还是到同一个队列的,那我只思考这一个队列上的所有流的一个调度状况即可,也就是说尽可能在这些流的一个时延束缚空间内找最大的吞吐率(或者某价值函数)。那这和单队列网卡的状况是一样的。因为对网卡多队列还须要破费一些工夫去理解、试验。所以当初先只思考单网卡队列状况。 网卡队列我看这个文章说的应该就是多个在内存中的RingBuffer,由网卡驱动程序在内存中创立:当初的服务器上的网卡个别都是反对多队列的。每一个队列上都是由一个 RingBuffer 示意的,开启了多队列当前的的网卡就会对应有多个 RingBuffer。网卡在启动时最重要的工作之一就是调配和初始化 RingBuffer我想多RingBuffer的益处应该就是能够施展多核CPU的劣势,能并行处理多个RingBuffer。只管网卡发包收报应该还是对packet一个接一个地进行。 问题网卡队列是个啥啊?packet是存在内存里,而后网卡以DMA的形式读取收回。还是说packet被copy到网卡的内存里,而后网卡读本人内存收回啊?网卡有内存吗?我还是没明确网卡多队列是怎么工作的。qdisc是搭载在队列上的吗?一个网卡队列上搭载一个qdisc?网卡队列是在内存上用网卡驱动创立实现的吗?还是说网卡硬件上自身就存在多个队列存储空间?但这如同不重要,比拟要害的是一个包是如何进某个网卡队列的,是如何出队列被真正发送进来的,而后这些多个队列能并行发送吗?不过不能,那每次如何决定哪个队列出包发送呢? 网卡DMA工作DMA 环形缓冲区建设在与处理器共享的内存中。每一个输出数据包被搁置在环形缓冲区中下一个可用缓冲区,而后收回中断。接着驱动程序将网络数据包传给内核的其它局部解决,并在环形缓冲区中搁置一个新的 DMA 缓冲区。 驱动程序在初始化时调配DMA缓冲区,并应用驱动程序直到进行运行。筹备工作: 系统启动时网卡(NIC)进行初始化,在内存中腾出空间给 Ring Buffer 。Ring Buffer 队列每个中的每个元素 Packet Descriptor指向一个sk_buff ,状态均为ready。 上图中虚线步骤的解释: 1.DMA 接口将网卡(NIC)接管的数据包(packet)一一写入 sk_buff ,被写入数据的 sk_buff 变为 used 状态。一个数据包可能占用多个 sk_buff , sk_buff读写程序遵循先入先出(FIFO)准则。2.DMA 写完数据之后,网卡(NIC)向网卡中断控制器(NIC Interrupt Handler)触发硬件中断请求。3.NIC driver 注册 poll 函数。4.poll 函数对数据进行查看,例如将几个 sk_buff 合并,因为可能同一个数据可能被扩散放在多个 sk_buff 中。5.poll 函数将 sk_buff 交付下层网络栈解决。后续解决: poll 函数清理 sk_buff,清理 Ring Buffer 上的 Descriptor 将其指向新调配的 sk_buff 并将状态设置为 ready。 网卡构造 没有内存网卡的组成: ...

August 31, 2023 · 1 min · jiezi

配置Linux静态网卡远程连接MySQL问题

1、设置 Linux 为静态网络配置使用 VMWare 安装好 CentOS 后,将网络适配器设置为 NAT 模式。为了防止 IP 关机重启时候经常变动,需要将网卡信息设置为静态。修改 /etc/sysconfig/network-scripts 下的网卡配置文件 在此文件夹下我的网卡配置文件是 :ifcfg-ens33(一般都是 ifcfg-ensXX 文件,自己修改时候注意)。所以只需要使用 vi 命令编辑此文件即可,将文件信息修改为以下即可。TYPE="Ethernet"BOOTPROTO="static"IPADDR=192.168.197.129NETMASK=255.255.255.0GATEWAY=192.168.197.2DNS1=8.8.8.8DEFROUTE="yes"PEERDNS="yes"PEERROUTES="yes"IPV4_FAILURE_FATAL="no"IPV6INIT="yes"IPV6_AUTOCONF="yes"IPV6_DEFROUTE="yes"IPV6_PEERDNS="yes"IPV6_PEERROUTES="yes"IPV6_FAILURE_FATAL="no"IPV6_ADDR_GEN_MODE="stable-privacy"NAME="ens33"UUID="f50c1acb-829e-4c6c-a9d7-3d9c5e6ea0d5"DEVICE="ens33"ONBOOT="yes"上面主要配置信息解释如下(其他信息复制即可) 主要信息图中已经标识,切记网关地址一定要一致,否则不能上网。2、解决MySQL 远程连接错误:2003 - Cant't connect to MySQL server on 'ip'(10060 "Unknown error")问题描述: 使用 VMWare 搭建服务器后,然后安装好 MySQL ,成功启动。在本地尝试使用 Navicat 远程连接出现错误如下:2003 - Cant't connect to MySQL server on 'ip'(10060 "Unknown error")原因分析: 安装好的 MySQL 不允许远程登陆,所以需要 设置防火墙开放 MySQL 的 3306端口解决方法: 开放 3306 端口即可 : firewall-cmd --zone=public --add-port=3306/tcp --permanent。重启防火墙 (以下命令选择其中一个即可),重新连接即可 systemctl restart firewalld.service。 ...

November 4, 2019 · 1 min · jiezi

网卡也能虚拟化?网卡虚拟化技术 macvlan 详解

本文首发于我的公众号 cloud_dev,专注于干货分享,号内有大量书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫。01 macvlan 简介前面的文章讲过了几种 Linux 虚拟网络设备:tap/tun、veth-pair、bridge,它们本质上是 Linux 系统 提供的网络虚拟化解决方案,今天要讲的 macvlan 也是其中的一种,准确说这是一种网卡虚拟化的解决方案。因为 macvlan 这种技术能将 一块物理网卡虚拟成多块虚拟网卡 ,相当于物理网卡施展了 多重影分身之术 ,由一个变多个。02 macvlan 的工作原理macvlan 是 Linux kernel 支持的新特性,支持的版本有 v3.9-3.19 和 4.0+,比较稳定的版本推荐 4.0+。它一般是以内核模块的形式存在,我们可以通过以下方法判断当前系统是否支持:# modprobe macvlan# lsmod | grep macvlanmacvlan 24576 0如果第一个命令报错,或者第二个命令没有返回,说明当前系统不支持 macvlan,需要升级内核。macvlan 这种技术听起来有点像 VLAN,但它们的实现机制是完全不一样的。macvlan 子接口和原来的主接口是完全独立的,可以单独配置 MAC 地址和 IP 地址,而 VLAN 子接口和主接口共用相同的 MAC 地址。VLAN 用来划分广播域,而 macvlan 共享同一个广播域。通过不同的子接口,macvlan 也能做到流量的隔离。macvlan 会根据收到包的目的 MAC 地址判断这个包需要交给哪个虚拟网卡,虚拟网卡再把包交给上层的协议栈处理。03 四种模式根据 macvlan 子接口之间的通信模式,macvlan 有四种网络模式:private 模式vepa(virtual ethernet port aggregator) 模式bridge 模式passthru 模式默认使用的是 vepa 模式。3.1 private这种模式下,同一主接口下的子接口之间彼此隔离,不能通信。即使从外部的物理交换机导流,也会被无情地丢掉。3.2 vepa这种模式下,子接口之间的通信流量需要导到外部支持 802.1Qbg/VPEA 功能的交换机上(可以是物理的或者虚拟的),经由外部交换机转发,再绕回来。注:802.1Qbg/VPEA 功能简单说就是交换机要支持 发夹(hairpin) 功能,也就是数据包从一个接口上收上来之后还能再扔回去。3.3 bridge这种模式下,模拟的是 Linux bridge 的功能,但比 bridge 要好的一点是每个接口的 MAC 地址是已知的,不用学习。所以,这种模式下,子接口之间就是直接可以通信的。3.4 passthru这种模式,只允许单个子接口连接主接口,且必须设置成混杂模式,一般用于子接口桥接和创建 VLAN 子接口的场景。3.5 mactap和 macvlan 相似的技术还有一种是 mactap。和 macvlan 不同的是,mactap 收到包之后不是交给协议栈,而是交给一个 tapX 文件,然后通过这个文件,完成和用户态的直接通信。04 实践在 Linux 系统下,创建 macvlan 的命令形式如下:ip link add link DEVICE name NAME type { macvlan | macvtap } mode { private | vepa | bridge | passthru [ nopromisc ] }通常,单独使用 macvlan 毫无意义,一般都是结合 VM 和容器来构建网络。下面我们就简单使用 namespace 来看看 Linux 是怎么使用 macvlan 的。实验拓扑如下:在我的系统中,以接口 enp0s8 为例创建两个 macvlan 子接口(使用 bridge 模式),配置 IP 并将其挂到两个 namespace 中,测试连通性。# 创建两个 macvlan 子接口ip link add link enp0s8 dev mac1 type macvlan mode bridgeip link add link enp0s8 dev mac2 type macvlan mode bridge# 创建两个 namespaceip netns add ns1ip netns add ns2# 将两个子接口分别挂到两个 namespace 中ip link set mac1 netns ns1ip link set mac2 netns ns2# 配置 IP 并启用ip netns exec ns1 ip a a 192.168.56.122/24 dev mac1ip netns exec ns1 ip l s mac1 upip netns exec ns1 ip a a 192.168.56.123/24 dev mac2ip netns exec ns2 ip l s mac2 up注:enp0s8 的 IP 是 192.168.56.110/24,配置的子接口 IP 也必须是同一网段的。完了两个子接口 ping 一下:root@ubuntu:# ip netns exec ns1 ip a show mac19: mac1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1 link/ether 2e:6e:d9:08:c5:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.56.122/24 scope global mac1 valid_lft forever preferred_lft forever inet6 fe80::2c6e:d9ff:fe08:c505/64 scope link valid_lft forever preferred_lft foreverroot@ubuntu:# ip netns exec ns1 ping 192.168.56.123PING 192.168.56.123 (192.168.56.123) 56(84) bytes of data.64 bytes from 192.168.56.123: icmp_seq=1 ttl=64 time=0.052 ms64 bytes from 192.168.56.123: icmp_seq=2 ttl=64 time=0.028 ms^C— 192.168.56.123 ping statistics —2 packets transmitted, 2 received, 0% packet loss, time 1000msrtt min/avg/max/mdev = 0.028/0.040/0.052/0.012 ms可以看到,能够 ping 通,如果把上面的 mode 换成其他模式就行不通了,这个就留给大家去实验了(默认是 vepa 模式)。另外,在 docker 中,macvlan 是一种较为重要的跨主机网络模型,这块的内容就留作下篇文章再做讲解了。05 总结macvlan 是一种网卡虚拟化技术,能够将一张网卡虚拟出多张网卡。macvlan 的四种通信模式,常用模式是 bridge。思考一下:macvlan bridge 和 bridge 的异同点还有一种类似的技术,多张虚拟网卡共享相同 MAC 地址,但有独立的 IP 地址,这是什么技术?这两个问题大家可以留言互动一下。我的公众号 cloud_dev,号内有大量书籍和视频资源,后台回复「1024」即可领取,分享的内容包括但不限于云计算虚拟化、容器、OpenStack、K8S、雾计算、网络、工具、SDN、OVS、DPDK、Linux、Go、Python、C/C++编程技术等内容,欢迎大家关注。 ...

April 2, 2019 · 2 min · jiezi