本文基于vpp 主线master分支版本号v24.02介绍当前vpp ipsec crypto框架。在公众号《DPDK与SPDK开源社区》中,有一篇文章介绍VPP的异步Crypto框架(链接在参考文章1中)。与当前版本框架相差不大。
VPP的crypto框架是VPP原生的一套数据加解密框架,其目的是为VPP框架中所有Graph node提供数据加密服务。VPP的Crypto框架包含一套为Graph node准备的用户API,包括创建、更新和删除密钥,以及处理加密工作等;该框架还包括一条逻辑简单且巧妙的crypto engine API,用于作为VPP Plugin的crypto engine来注册和上载回调函数,并根据每个crypto engine根据预设的优先级来决定某个算法的缺省engine回调函数。目前可用的VPP crypto engine有以下几个,可以通过命令行show crypto engines查询:
vpp# show crypto engines
Name Prio Description
ipsecmb 80 Intel(R) Multi-Buffer Crypto for IPsec Library 1.4.0
native 100 Native ISA Optimized Crypto
openssl 50 OpenSSL
sw_scheduler 100 SW Scheduler Async Engine
dpdk_cryptodev 100 DPDK Cryptodev Engine
因此,vpp crypto调度框架如下:
其中dpdk_cryptodev engine在虚拟环境或环境中未加载QAT卡是查询不到的 。我们可以启用dpdk加密设备PMD的openssl 及ipsec-mb PMD,具体设置如下两点:1、修改dpdk编译Makefile文件,将crypto的openssl及ipsec-mb的aesni_mb和aesni_gcm的PMD驱动打开,执行make install-ext-deps重新编译外部开发依赖库。2、在vpp的启动配置文件startup.conf文件设置虚拟crypto加密设备“crypto_openssl”和“crypto_aesni_mb0,socket_id=0”。修改内容如下:
#1、dpdk.mk修改
diff --git a/build/external/packages/dpdk.mk b/build/external/packages/dpdk.mk
index f15c9f79a..3705113b2 100644
--- a/build/external/packages/dpdk.mk
+++ b/build/external/packages/dpdk.mk
@@ -54,9 +54,6 @@ DPDK_DRIVERS_DISABLED := baseband/\*, \
crypto/ccp, \
crypto/cnxk, \
crypto/dpaa_sec, \
- crypto/openssl, \
- crypto/aesni_mb, \
- crypto/aesni_gcm, \
crypto/kasumi, \
crypto/snow3g, \
crypto/zuc, \
#2、在vpp startup配置文件设置设置虚拟crypto加密设备。
dpdk {
vdev crypto_openssl
#vdev crypto_aesni_mb0,socket_id=0
}
很不幸的是在实验过程中发现dpdk ipsec-mb pmd并没有生效,具体原因未知。目前怀疑是编译dpdk ipsec-mb pmd 驱动时未找到ipsec-mb库,后续再详细定位,有解决此问题的小伙伴欢迎公众号留言告知解决方法。
接下来可以通过show crypto handlers 查询加解密算法与加密引擎的关系。
vpp# show crypto handlers
vpp# show crypto handlers
Algo Type Simple Chained
(nil)
des-cbc encrypt openssl* openssl*
decrypt openssl* openssl*
3des-cbc encrypt openssl* openssl*
decrypt openssl* openssl*
aes-128-cbc encrypt ipsecmb native* openssl openssl*
decrypt ipsecmb native* openssl openssl*
aes-192-cbc encrypt ipsecmb native* openssl openssl*
decrypt ipsecmb native* openssl openssl*
aes-256-cbc encrypt ipsecmb native* openssl openssl*
decrypt ipsecmb native* openssl openssl*
aes-128-ctr encrypt ipsecmb* openssl openssl*
decrypt ipsecmb* openssl openssl*
aes-192-ctr encrypt ipsecmb* openssl openssl*
decrypt ipsecmb* openssl openssl*
aes-256-ctr encrypt ipsecmb* openssl openssl*
decrypt ipsecmb* openssl openssl*
aes-128-gcm aead-encrypt ipsecmb native* openssl ipsecmb* openssl
aead-decrypt ipsecmb native* openssl ipsecmb* openssl
aes-192-gcm aead-encrypt ipsecmb native* openssl ipsecmb* openssl
aead-decrypt ipsecmb native* openssl ipsecmb* openssl
aes-256-gcm aead-encrypt ipsecmb native* openssl ipsecmb* openssl
aead-decrypt ipsecmb native* openssl ipsecmb* openssl
aes-128-null-gmac aead-encrypt openssl* openssl*
aead-decrypt openssl* openssl*
aes-192-null-gmac aead-encrypt openssl* openssl*
aead-decrypt openssl* openssl*
aes-256-null-gmac aead-encrypt openssl* openssl*
aead-decrypt openssl* openssl*
chacha20-poly1305 aead-encrypt ipsecmb* openssl ipsecmb* openssl
aead-decrypt ipsecmb* openssl ipsecmb* openssl
hmac-md5 hmac openssl* openssl*
hmac-sha-1 hmac ipsecmb* openssl openssl*
hmac-sha-224 hmac ipsecmb* openssl openssl*
hmac-sha-256 hmac ipsecmb* openssl openssl*
hmac-sha-384 hmac ipsecmb* openssl openssl*
hmac-sha-512 hmac ipsecmb* openssl openssl*
sha-1 hash openssl* openssl*
sha-224 hash openssl* openssl*
sha-256 hash openssl* openssl*
sha-384 hash openssl* openssl*
sha-512 hash openssl* openssl*
Engine 名后的“*”代表其为该算法的缺省engine,这时我们可以将缺省aes-129-cbc的engine从native变成ipsec-mb,如下:
vpp# set crypto handler aes-128-cbc ipsecmb simple
vpp# show crypto handlers
Algo Type Simple Chained
(nil)
aes-128-cbc encrypt ipsecmb* native openssl openssl*
decrypt ipsecmb* native openssl openssl*
从命令行show crypto async handlers来dpdk_cryptodev只能工作在异步模式中。
vpp# show crypto async handlers
Algo Type Handler
(nil)
aes-128-gcm-aad8 async-encrypt sw_scheduler dpdk_cryptodev*
async-decrypt sw_scheduler dpdk_cryptodev*
aes-128-gcm-aad12 async-encrypt sw_scheduler dpdk_cryptodev*
async-decrypt sw_scheduler dpdk_cryptodev*
aes-192-gcm-aad8 async-encrypt sw_scheduler dpdk_cryptodev*
async-decrypt sw_scheduler dpdk_cryptodev*
aes-192-gcm-aad12 async-encrypt sw_scheduler dpdk_cryptodev*
async-decrypt sw_scheduler dpdk_cryptodev*
下面是dpdk crypto架构如下:
dpdk crypto相关PDF文档已放在github上面,链接: https://github.com/jin13417/dpdk-vpp-learning/tree/main/doc/dpdk/cryptodev
可以通ipsec命令行将ipsec 切换成异步模式:
vpp# set ipsec async mode on # 查询工作模式
vpp# show ipsec all
IPSec async mode: on
在strongswan+vpp实验阶段大概率遇到一个问题就是lcp创建的GigabitEthernet0/6/0接口mac地址52:54:00:52:38:8b与映射到内核接口eth0 mac地址7a:a1:93:35:a0:93不一致导致发送arp回应报文因mac地址与物理口mac地址不匹配而丢弃,ping不通。此问题实验环境中大概率复现,解决方案就是手动设置内核接口eth0 mac地址为52:54:00:52:38:8b解决。由此可见lcp插件产品化还是任重而道远。
1、vpp纳管物理接口mac地址,52:54:00:52:38:8b
###vppctl show hard GigabitEthernet0/6/0
Name Idx Link Hardware
GigabitEthernet0/6/0 1 up GigabitEthernet0/6/0
Link speed: unknown
RX Queues:
queue thread mode
0 main (0) polling
TX Queues:
TX Hash: [name: hash-eth-l34 priority: 50 description: Hash ethernet L34 headers]
queue shared thread(s)
0 no 0
Ethernet address 52:54:00:52:38:8b
2、内核查询lcp映射到内核接口eth0 mac 地址 7a:a1:93:35:a0:93
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9000
inet 192.168.100.113 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::5054:ff:fe52:388b prefixlen 64 scopeid 0x20<link>
ether 7a:a1:93:35:a0:93 txqueuelen 1000 (Ethernet)
RX packets 2 bytes 84 (84.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 271 bytes 11834 (11.8 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
3、解决方案,修改内核mac地址与vpp物理口mac地址一致
ifconfig eth0 hw ether 52:54:00:52:38:8b
至此,只是简单分析了vpp crypto框架及相关命令行操作。本人也是首次阅读相关代码,如有不当之处欢迎公众号留言交流。
参考文章: