1.VPP 编译、源码安装、源码使用及插件开发注意事项
2.å¦ä½ä½¿ç¨git åpatch
3.关于vpp中dpdk接口注册流程解析
4.å¦ä½ä½¿ç¨Git åPatch
5.我用Realplayerv10.0播放VCD,源码但总提示需要下载新的剪辑才能播放文件,不知道为什么.
6.基于openstack网络模式的vlan分析
VPP 编译、安装、源码使用及插件开发注意事项
VPP(Vector Packet Processing)是源码一个由Cisco开发的开源可扩展框架,用于提供易于使用的源码绿色微盘源码高性能交换和路由功能。它通过使用各种插件(Plugin)来处理网络协议,源码这些插件可以在配置代码中指定其后续操作。源码插件间的源码处理逻辑通过返回的索引链接起来,形成一个处理流程。源码
VPP的源码核心在于其高性能处理机制,它将相同类型的源码包放在数组中,利用CPU缓存提高效率,源码并通过SSE、源码AVX指令加速(x平台)、源码NEON指令加速(ARM平台)或AltiVec技术加速(PowerPC平台)。Bihash实现了一个高效的检索表结构,支持读写分离。
VPP安装非常简单,无需编译步骤,直接从官方网站下载源代码,通过apt/yum更新后,执行apt/yum install vpp即可完成安装。智能网校源码不过需要注意的是,安装的版本可能较低。
在使用VPP时,新版本内置了DPDK,但默认情况下未启用高性能模式。默认运行方式可能为socket/af_packet,性能一般。如果你熟悉交换机指令,VPP的使用方式会很熟悉,具有自动补全、帮助和显示信息的功能。创建虚拟网口与VPP建立通信通常使用veth技术。
创建虚拟网口时,如需让VPP运行,通常需要通过命令创建网口并开启主机到VPP的通道。具体操作可参考以下示例:创建虚拟网口与VPP内部建立通讯。
VPP提供了一套完整的命令系统,允许用户进行详细的配置和调试。使用VPP指令时,通过ping .0.0.2检查网络连通性,同时VPP内部的show int命令可以显示统计数据的变化情况,而主机通过tcpdump工具可以抓取到包。源码部署homelande
编写插件时,可以参考src/examples/sample_plugin/sample中的示例代码。插件初始化代码在sample.c/sample_init函数中,其中VNET_FEATURE_INIT宏定义了前导节点及插入到哪个节点前面。默认位置为ethernet-input,即适配器输入的前面。vnet_feature_enable_disable函数用于激活节点,参数1通常包含前一步中定义的值。在插件命令执行时,如sample macswap,将调用相应的节点逻辑。
丢包操作可以通过在插件初始化时获取error_drop节点的全局索引,然后将需要丢弃的包存储到目标位置,并使用vlib_put_frame_to_node函数将包放入error_drop节点。实现时,可以使用vlib_get_next_frame获取目标包地址,然后使用put_frame函数将包放入指定位置。
编写和编译插件的流程相对标准,使用emacs进行编辑。VPP的源码编译相对简单,通常只需执行几条命令即可。需要注意的listview控件源码是,在编译过程中,可能会遇到如内存分配不足等问题,因此在虚拟机环境和图形界面下需进行相应的优化。同时,在特定版本和环境下,可能需要额外的依赖库和配置文件。
在安装和配置VPP时,可能会遇到一些常见的问题,例如无法打开日志文件、组vpp不存在等。这些问题通常可以通过调整配置文件或创建相关目录来解决。在某些版本和环境下,安装时可能需要额外的依赖包,如intel-ipsec-mb、dpdk、rdma-core、xdp-tools、quicly、meson等,确保在编译和安装过程中正确配置这些依赖。
最后,确保在安装和运行VPP时有足够的dev导入 源码磁盘空间,特别是在配置DPDK时,需要充足的内存资源。如果在HyperV下的Ubuntu.环境中遇到问题,可能需要额外的配置和优化。对于较新的Ubuntu版本,确保使用的是适合VPP版本的系统软件包,避免因版本不兼容导致的问题。
å¦ä½ä½¿ç¨git åpatch
å¤åpatchï¼å¤äº§çä¸äºå¥½çideaï¼æå¯ä»¥å¨open software communityä¸è¶æ··è¶å¥½ãé¦å é ç½®gitãè¿éæ两ç§é ç½®æ件ï¼ä¸ä¸ªæ¯å ¨å±çï¼å¨ç¨æ·çhomeç®å½ä¸ï¼ä¸ä¸ªæ¯ç¸åºgitä»åºçãå¦æä½ è®¾ç½®äºå ¨å±çï¼é£ä¹å¯ä»¥ç¨å¨å个gitä»åºä¸ãæ¥çä¸ä¸æå·²ç»é 置好çé ç½®æ件ï¼hacker@hacker:~/qemu-kvm$cat~/.gitconfig[user]name = Wanpeng Liemail = liwp@linux.vnet.ibm.com[sendemail]chainreplyto = falsesmtpserver=/usr/bin/msmtpæ们å¯ä»¥ä½¿ç¨å½ä»¤æ¥é ç½®ï¼$git config --global user.name 'Wanpeng Li'$git config --global user.name 'liwp@linux.vnet.ibm.com'$git config --global sendemail.chainreplyto false$git config --global sendemail.smtpserver/usr/bin/msmtpå¦ä¸ä¸ªéè¦é ç½®çå°±æ¯msmtpçé ç½®æ件ï¼å¦æ没æå®è£ msmtp使ç¨apt-get installå®è£ ãhacker@hacker:~/qemu-kvm$ cat ~/.msmtprcaccount defaulthost ap.relay.ibm.com#auth plainuser liwp@linux.vnet.ibm.compassword xxxxxfrom liwp@linux.vnet.ibm.comå½ä½ ä¿®æ¹æºç æ件åï¼ä½¿ç¨git commit -aå¯ä»¥ç»ä½ çpatchå ä¸äºæ³¨éï¼æ³¨æ第ä¸è¡æ·»å çæ¯patchçååï¼ç¶å空ä¸è¡ï¼ç¶åå¦å¯ä¸è¡æ·»å 对patchç注éã注æè¿patchçååå注éä¹åå¿ é¡»ç©ºä¸è¡ãç¶åæ·»å Signed-off-by: eg:Signed-off-by: Wanpeng Li <liwp@linux.vnet.ibm.comç¶åçæpatchæ件ï¼ä½¿ç¨å½ä»¤git format-patchï¼eg:$git format-patch originå¦æè§å¾è¿ä¸ªcommitä¸æ³è¦äºç¨git resetï¼$gitresetHEAD^ç¶ååéåºå»ï¼è¦ä½¿ç¨git-send-emailä¹åå è¦apt-get install git-email
关于vpp中dpdk接口注册流程解析
vpp 是一个高效的包处理转发框架,支持多种接口类型,其中应用最广泛的便是 dpdk。dpdk 通过接管网卡驱动实现内核旁路,提供报文收发加速机制。在 vpp 中,dpdk 作为插件实现,通过 make install-ext-deps 构建过程中自动集成 dpdk。
dpdk 初始化在 /src/plugins/dpdk/device/init.c 文件中,dpdk 的 eal 环境通过调用 rte_eal_init 函数实现。dpdk_config 函数负责参数解析,dpdk_config 函数通过宏 VLIB_CONFIG_FUNCTION 注入,vpp 启动时自动调用,将参数传递给 rte_eal_init 进行初始化。
vpp 的接口层分为硬件层和软件层,硬件层通过 device class 描述硬件驱动,软件层通过 interface class 描述链路层。硬件设备用 vnet_hw_interface_t 结构体描述,软件层接口用 vnet_sw_interface_t 描述。接口统一管理在 vnet_interface_main_t 结构体中,该结构体定义了硬件接口和软件接口的数组。
接口初始化在 vnet_interface_init 函数中进行,此函数除了初始化接口参数,还会将 dpdk 设备的 tx_function 赋值给 device class,决定后续的发包执行函数。
dpdk 接口初始化在 dpdk_lib_init 函数中完成,主要步骤包括初始化 dpdk_device_t 结构体,调用 ethernet_register_interface 注册接口,配置网卡参数,并为接口分配收包线程。
dpdk 收包通过 input node dpdk_input_node 实现,dpdk_device_input 函数完成实际的收包操作,通常将报文传递给下一个 node,如 ethernet_input node。
dpdk 发包逻辑相对复杂,dpdk 的发包并未直接在插件中实现专门的 output node,而是通过接口 tx_function 赋值,最终在 vpp 的发送流程中实现。在发送报文时,接口的 output node 和 tx node 会在 vnet_register_interface 注册接口时一同注册,其中 output node 的执行函数是 vnet_interface_output_node,tx node 的函数则由 vnet_device_class_t 定义。
发送流程以 ip4 报文为例,处理完 ip4 报文后,通常下一个节点为 ip4-lookup 进行路由查找。在 interface-output node 中,通过 buffer->sw_if_index[VNET_TX] 的值确定发送接口,并执行对应的 output node。
在 interface output node 的执行函数中,接口的 output node index 通过调用 vnet_per_buffer_interface_output_hw_interface_add_del 函数获得,该函数在 vpp 初始化过程中将接口的 output node 放置在 interface output node 后面,从而在执行函数中获取到接口 output node 的索引。
vpp 的设计遵循分层架构,逻辑清晰,但宏定义的大量使用增加了阅读难度。 版本源码调整了 node 注册方式,通过 VLIB_NODE_FN 宏实现不同优先级的 function 设置,但这一改动也给源码阅读带来不便。接口发送节点通过 vlib_register_node 函数定义,允许不同驱动共享一个函数,方便了接口的动态添加。
vpp 启动过程中的宏定义执行顺序影响代码结构,后续深入阅读源码时会进一步分析。如有需要,可参考相关学习资料、教学视频和交流群资源进行深入学习和交流。
å¦ä½ä½¿ç¨Git åPatch
æ¨å¥½ï¼å¾é«å ´è½å¸®å©æ¨
å¤åpatchï¼å¤äº§çä¸äºå¥½çideaï¼æå¯ä»¥å¨open software communityä¸è¶æ··è¶å¥½ã
é¦å é ç½®gitãè¿éæ两ç§é ç½®æ件ï¼ä¸ä¸ªæ¯å ¨å±çï¼å¨ç¨æ·çhomeç®å½ä¸ï¼ä¸ä¸ªæ¯ç¸åºgitä»åºçãå¦æä½ è®¾ç½®äºå ¨å±çï¼é£ä¹å¯ä»¥ç¨å¨å个gitä»åºä¸ãæ¥çä¸ä¸æå·²ç»é 置好çé ç½®æ件ï¼
hacker@hacker:~/qemu-kvm$cat~/.gitconfig[user]name = Wanpeng Li
email = liwp@linux.vnet.ibm.com
[sendemail]
chainreplyto = falsesmtpserver=/usr/bin/msmtp
æ们å¯ä»¥ä½¿ç¨å½ä»¤æ¥é ç½®ï¼$git config --global user.name 'Wanpeng Li'
$git config --global user.name 'liwp@linux.vnet.ibm.com'
$git config --global sendemail.
chainreplyto false
$git config --global sendemail.
smtpserver/usr/bin/msmtp
å¦ä¸ä¸ªéè¦é ç½®çå°±æ¯msmtpçé ç½®æ件ï¼å¦æ没æå®è£ msmtp使ç¨apt-get installå®è£ ã
hacker@hacker:~/qemu-kvm$ cat ~/.msmtprc
account default
host ap.relay.ibm.com
#auth plain
user liwp@linux.vnet.ibm.com
password xxxxx
from liwp@linux.vnet.ibm.com
å½ä½ ä¿®æ¹æºç æ件åï¼ä½¿ç¨git commit -aå¯ä»¥ç»ä½ çpatchå ä¸äºæ³¨éï¼æ³¨æ第ä¸è¡æ·»å çæ¯patchçååï¼ç¶å空ä¸è¡ï¼ç¶åå¦å¯ä¸è¡æ·»å 对patchç注éã注æè¿patchçååå注éä¹åå¿ é¡»ç©ºä¸è¡ãç¶åæ·»å Signed-off-by: eg:
Signed-off-by: Wanpeng Li <liwp@linux.vnet.ibm.com
ç¶åçæpatchæ件ï¼ä½¿ç¨å½ä»¤git format-patchï¼eg:
$git format-patch origin
å¦æè§å¾è¿ä¸ªcommitä¸æ³è¦äºç¨git resetï¼$gitresetHEAD^ç¶ååéåºå»ï¼
è¦ä½¿ç¨git-send-emailä¹åå è¦apt-get install git-email
ä½ çé纳æ¯æåè¿çå¨åï¼
è®°å¾å¥½è¯åé纳ï¼çé¢ä¸æï¼äºç¸å¸®å©ï¼
我用Realplayerv.0播放VCD,但总提示需要下载新的剪辑才能播放文件,不知道为什么.
这个是因为 Realplayerv.0的安装包里面没有支持播放 VCD 格式的插件,解决办法只有一个,按照提示一步一步的操作。
Realplayerv.0 长于播放RM格式的文件。在其他播放方面表现一般。如果你经常使用光牒,建议下载一个豪杰解霸
下载地址:ma separated list of VLAN ranges for the Neutron openvswitch
# plugin (eg. physnet1:1:,physnet2,physnet3::)
CONFIG_NEUTRON_OVS_VLAN_RANGES=
# A comma separated list of bridge mappings for the Neutron
# openvswitch plugin (eg. physnet1:br-eth1,physnet2:br-eth2,physnet3
# :br-eth3)
CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=
# A comma separated list of colon-separated OVS bridge:interface
# pairs. The interface will be added to the associated bridge.
CONFIG_NEUTRON_OVS_BRIDGE_IFACES=
(2)neutron配置文件(/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini)
复制代码
代码如下:
[ovs]
# (StrOpt) Type of network to allocate for tenant networks. The
# default value 'local' is useful only for single-box testing and
# provides no connectivity between hosts. You MUST either change this
# to 'vlan' and configure network_vlan_ranges below or change this to
# 'gre' or 'vxlan' and configure tunnel_id_ranges below in order for
# tenant networks to provide connectivity between hosts. Set to 'none'
# to disable creation of tenant networks.
#
tenant_network_type = local
RDO会根据answer.conf中local的配置将neutron中open vswitch配置文件中配置为local
2. vlan模式
大家对vlan可能比较熟悉,就不再赘述,直接看RDO和neutron的配置文件。
(1)RDO配置文件
复制代码
代码如下:
# Type of network to allocate for tenant networks (eg. vlan, local,
# gre)
CONFIG_NEUTRON_OVS_TENANT_NETWORK_TYPE=vlan //指定网络模式为vlan
# A comma separated list of VLAN ranges for the Neutron openvswitch
# plugin (eg. physnet1:1:,physnet2,physnet3::)
CONFIG_NEUTRON_OVS_VLAN_RANGES=physnet1:: //设置vlan ID value为~
# A comma separated list of bridge mappings for the Neutron
# openvswitch plugin (eg. physnet1:br-eth1,physnet2:br-eth2,physnet3
# :br-eth3)
CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=physnet1:br-eth1 //设置将br-int映射到桥br-eth1(会自动创建phy-br-eth1和int-br-eth1来连接br-int和br-eth1)
# A comma separated list of colon-separated OVS bridge:interface
# pairs. The interface will be added to the associated bridge.
CONFIG_NEUTRON_OVS_BRIDGE_IFACES=br-eth1:eth1 //设置eth0桥接到br-eth1上,即最后的网络流量从eth1流出 (会自动执行ovs-vsctl add br-eth1 eth1)
此配置描述的网桥与网桥之间,网桥与网卡之间的映射和连接关系具体可结合 《图1 vlan模式下计算节点的网络设备拓扑结构图》和 《图2 vlan模式下网络节点的网络设备拓扑结构图 》来理解。
思考:很多同学可能会碰到一场景:物理机只有一块网卡,或有两块网卡但只有一块网卡连接有网线
此时,可以做如下配置
(2)单网卡:
CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=physnet1:br-eth0 //设置将br-int映射到桥br-eth
复制代码
代码如下:
# A comma separated list of colon-separated OVS bridge:interface
# pairs. The interface will be added to the associated bridge
CONFIG_NEUTRON_OVS_BRIDGE_IFACES= //配置为空
这个配置的含义是将br-int映射到br-eth0,但是br-eth0并没有与真正的物理网卡绑定,这就需要你事先在所有的计算节点(或网络节点)上事先创建好br-eth0桥,并将eth0添加到br-eth0上,然后在br-eth0上配置好ip,那么RDO在安装的时候,只要建立好br-int与br-eth0之间的连接,整个网络就通了。
此时如果网络节点也是单网卡的话,可能就不能使用float ip的功能了。
(3)双网卡,单网线
复制代码
代码如下:
CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=physnet1:br-eth1 //设置将br-int映射到桥br-eth1
/pp# A comma separated list of colon-separated OVS bridge:interface
/pp# pairs. The interface will be added to the associated bridge.
/ppCONFIG_NEUTRON_OVS_BRIDGE_IFACES=eth1 //配置为空
还是默认都配置到eth1上,然后通过iptables将eth1的流量forward到eth0(没有试验过,不确定是否可行)
3. vlan网络模式详解
图1 vlan模式下计算节点的网络设备拓扑结构图
首先来分析下vlan网络模式下,计算节点上虚拟网络设备的拓扑结构。
(1)qbrXXX 等设备
前面已经讲过,主要是因为不能再tap设备vnet0上配置network ACL rules而增加的
(2)qvbXXX/qvoXXX等设备
这是一对veth pair devices,用来连接bridge device和switch,从名字猜测下:q-quantum, v-veth, b-bridge, o-open vswitch(quantum年代的遗留)。
(3) int-br-eth1和phy-br-eth1
这也是一对veth pair devices,用来连接br-int和br-eth1, 另外,vlan ID的转化也是在这执行的,比如从int-br-eth1进来的packets,其vlan id=会被转化成1,同理,从phy-br-eth1出去的packets,其vlan id会从1转化成
(4)br-eth1和eth1
packets要想进入physical network最后还得到真正的物理网卡eth1,所以add eth1 to br-eth1上,整个链路才完全打通
图2 vlan模式下网络节点的网络设备拓扑结构图
网络节点与计算节点相比,就是多了external network,L3 agent和dhcp agent。
(1)network namespace
每个L3 router对应一个private network,但是怎么保证每个private的ip address可以overlapping而又不相互影响呢,这就利用了linux kernel的network namespace
(2)qr-YYY和qg-VVV等设备 (q-quantum, r-router, g-gateway)
qr-YYY获得了一个internal的ip,qg-VVV是一个external的ip,通过iptables rules进行NAT映射。
思考:phy-br-ex和int-br-ex是干啥的?
坚持"所有packets必须经过物理的线路才能通"的思想,虽然 qr-YYY和qg-VVV之间建立的NAT的映射,归根到底还得通过一条物理链路,那么phy-br-ex和int-br-ex就建立了这条物理链路。