本文内容来源于vpp wiki文档中关于如何使用packet Generator及pacpket tracer的介绍。
参考链接:https://wiki.fd.io/view/VPP/How_To_Use_The_Packet_Generator_and_Packet_Tracer
在vpp源码src/scripts/vnet路径下存放很多模块的脚本,都是使用packet genertor工具实现自发包。pg工具应该是vpp单元测试框架重要的一个组件,用来构造流量。
代码语言:javascript复制root@jinsh:/home/jinsh/workspace/vpp-master/src/scripts/vnet# ls
arp4 ipsec lfib nat64_static tcp
arp4-mpls ipsec_spd mcast pcap tcp-test
arp6 ipsec_spd_vrf mpls-o-ethernet probe4 tf-ucs-1
bvi l2efpfilter mpls-o-gre probe6 udp
dhcp l2efpfilter_perf mpls-to-dot1ad rewrite uri
gre l2fib mpls-tunnel rightpeer urpf
gre-teb l2fib_perf nat44 rpf virl
icmp l2fib_xc nat44_det rtt-test vlan
icmp6 l2flood nat44_lb source_and_port_range_check
ige l2tp nat44_static speed
ip6 l3fwd nat44_static_with_port sr
ip6-hbh leftpeer nat64 srp
另外此目录下脚本中有很多模块的功能配置命令行,比如ipsec文件中,有ipsec基本命令行的配置,可以学习到ipsec配置方法:通过pipe模块实现在同一个vpp中实现跨vrf报文转发。这样通过vrf隔离可以构造出ipsec的两端,从而在一个vpp进程中实现ipsec隧道的创建及流量转发,来验证ipsec基本功能。下面我截取了一部分内容:
代码语言:javascript复制#1、创建2个pg接口
create packet-generator interface pg0
create packet-generator interface pg1
#创建pipe 及vrf2 将pg1级pipe接口的一端加入vrf 1
pipe create
ip table add 1
set int ip table pg1 1
set int ip table pipe0.1 1
#配置ip地址。
set int ip address pg0 192.168.0.1/24
set int ip address pg1 192.168.1.1/24
set int ip address pipe0.0 10.0.0.1/24
set int ip address pipe0.1 10.0.0.2/24
set int state pg0 up
set int state pg1 up
set int state pipe0 up
#配置ipsec
ipsec sa add 20 spi 200 crypto-key 6541686776336961656264656f6f6579 crypto-alg aes-cbc-128
ipsec sa add 30 spi 300 crypto-key 6541686776336961656264656f6f6579 crypto-alg aes-cbc-128
#手动创建ipsec隧道。并讲其中一条ipsec隧道加入vrf 1.
create ipip tunnel src 10.0.0.1 dst 10.0.0.2
create ipip tunnel src 10.0.0.2 dst 10.0.0.1 outer-table-id 1
ipsec tunnel protect ipip0 sa-in 20 sa-out 30
ipsec tunnel protect ipip1 sa-in 30 sa-out 20
set int state ipip0 up
set int unnum ipip0 use pg0
set int state ipip1 up
set int ip table ipip1 1
set int unnum ipip1 use pg1
#配置构造流量的响应路由表。
ip route add 192.168.1.0/24 via ipip0
set ip neighbor pg1 192.168.1.2 00:11:22:33:44:55
ip route add table 1 192.168.0.0/24 via ipip1
set ip neighbor pg0 192.168.0.2 00:11:22:33:44:66
trace add pg-input 100
下面是arp4脚本来介绍PG工具的使用,如下所示:创建一个名称为“x”的数据包生成器流,它在启用时发送单个 ipv4 icmp 回显请求。trace add命令设置跟踪以pg-input图形节点为起始的 100 个数据包。并创建两个loop接口,分别配置数据包流同网段。
代码语言:javascript复制root@jinsh:/home/jinsh/workspace/vpp-master/src/scripts/vnet# cat arp4
packet-generator new {
name x
limit 1
node ip4-input
size 64-64
data {
ICMP: 1.0.0.2 -> 2.0.0.2
ICMP echo_request
incrementing 100
}
}
trace add pg-input 100
loop create
loop create
set int state loop0 up
set int state loop1 up
set int ip address loop0 1.0.0.1/24
set int ip address loop1 2.0.0.1/24
在vpp命令行视图模式下,执行arp4脚本并查询pg相应的配置的如下:
代码语言:javascript复制#执行arp4脚本。需要注意一下,当前以vpp是以服务方式启动的,这里需要指定脚本的绝对路径
vpp# exec /home/jinsh/workspace/vpp-master/src/scripts/vnet/arp4
#查询名字为x的数据包生成器流内容。
vpp# show packet-generator verbose
Name Enabled Count Parameters
x No 0 limit 1, rate 0.00e0 pps, size 64-64, buffer-size 2048, worker 0,
hdr-size 20, offset 0,
hdr-size 4, offset 20, edit-function 0x7f8674c1e130,
hdr-size 40, offset 24,
#当前接口信息如下:
vpp# show interface addr
GigabitEthernet2/6/0 (up):
L3 192.168.100.1/24
local0 (dn):
loop0 (up):
L3 1.0.0.1/24
loop1 (up):
L3 2.0.0.1/24
pg-1 (up):
启动数据包生成器x,并显示跟踪查询转发流程。下面的跟踪中看到数据包在被丢弃之前经过“ip4-not-enabled”。这是因为用于注入数据包的接口(默认为 pg-1)没有 IPv4 配置,因此没有触发 ARP请求报文发送流程。
代码语言:javascript复制vpp# packet-generator enable-stream
vpp#
vpp# show trace
------------------- Start of thread 0 vpp_main -------------------
Packet 1
00:04:33:929094: pg-input
stream x, 64 bytes, sw_if_index 2
current data 0, length 64, buffer-pool 0, ref-count 1, trace handle 0x0
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:04:33:929115: ip4-input
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:04:33:929123: ip4-not-enabled
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:04:33:929127: error-drop
rx:pg-1
00:04:33:929129: drop
null-node: blackholed packets
接下我们设置接口pg-1复用loop0接口ip地址的,重新启用数据包生成器x,并跟踪trace流程。下面trace流程可以看到arp请求报文已经发送。
代码语言:javascript复制#pg-1 复用loop0接口ip地址
vpp# set interface unnumbered pg-1 use loop0
#使能数据流生成器
vpp# packet-generator enable-stream
vpp# clear trace
vpp# trace add pg-input 100
vpp# packet-generator enable-stream
vpp# show trace
------------------- Start of thread 0 vpp_main -------------------
Packet 1
00:12:54:202909: pg-input
stream x, 64 bytes, sw_if_index 2
current data 0, length 64, buffer-pool 0, ref-count 1, trace handle 0x0
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:12:54:202921: ip4-input
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:12:54:202926: ip4-lookup
fib 0 dpo-idx 5 flow hash: 0x00000000
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:12:54:202928: ip4-glean
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:12:54:202934: ip4-drop
ICMP: 1.0.0.2 -> 2.0.0.2
tos 0x00, ttl 64, length 64, checksum 0x77ba dscp CS0 ecn NON_ECN
fragment id 0x0000
ICMP echo_request checksum 0x7a6e id 1
00:12:54:202941: error-drop
rx:pg-1
00:12:54:202945: drop
ip4-glean: ARP requests sent
PG工具还支持回放pcap文件,下面我们通过vpp命令行创建一个tap0接口,并分别配置vpp接口ip(192.168.200.1)及内核tap0接口ip(192.168.200.2)。在内核设置抓包保存到1.pcap文件中。在vpp中ping 192.168.200.2 ip。抓取pcap文件内容如下:
代码语言:javascript复制root@jinsh:~# tcpdump -r 1.pcap -nnvv
reading from file 1.pcap, link-type EN10MB (Ethernet), snapshot length 262144
13:51:56.250850 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.200.2 tell 192.168.200.1, length 28
13:51:56.250892 ARP, Ethernet (len 6), IPv4 (len 4), Reply 192.168.200.2 is-at 02:fe:df:8d:a1:b6, length 28
13:51:57.249962 IP (tos 0x0, ttl 254, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 2, length 76
13:51:57.250158 IP (tos 0x0, ttl 64, id 4237, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 2, length 76
13:51:58.249974 IP (tos 0x0, ttl 254, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 3, length 76
13:51:58.250003 IP (tos 0x0, ttl 64, id 4360, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 3, length 76
13:51:59.249899 IP (tos 0x0, ttl 254, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 4, length 76
13:51:59.249931 IP (tos 0x0, ttl 64, id 4466, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 4, length 76
13:52:00.249953 IP (tos 0x0, ttl 254, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 5, length 76
13:52:00.250006 IP (tos 0x0, ttl 64, id 4517, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 5, length 76
13:52:02.458138 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.200.1 tell 192.168.200.2, length 28
13:52:02.458240 ARP, Ethernet (len 6), IPv4 (len 4), Reply 192.168.200.1 is-at 02:fe:18:21:1a:a2, length 28
下面我们指定数据包生成器s,指定回放上面抓取的pcap包,在内核接口打印tap0输出内容,看是否和pcap内容一致。
代码语言:javascript复制#1、首先创建一个pg0接口
create packet-generator interface pg0
#2、设置pg0接口状态up,并复用tap0接口ip
vpp# set interface state pg0 up
vpp# set interface unnumbered pg0 tap0
#3、查询接口信息
vpp# show interface addr
GigabitEthernet2/6/0 (up):
L3 192.168.100.1/24
local0 (dn):
pg0 (up):
unnumbered, use tap0
L3 192.168.200.1/24
tap0 (up):
L3 192.168.200.1/24
#4、设置PG 发包器S,并查询
vpp# packet-generator new pcap ~/1.pcap source pg0 name s
pp# show packet-generator verbose
Name Enabled Count Parameters
s No 0 limit 12, rate 0.00e0 pps, size 42-110, buffer-size 2048, worker 0,
#5、启动PG发包器S,在内核设置tap0抓包。
packet-generator enable-stream
~~~~~~~~~~~~~~~~~~~~~~~~~
root@jinsh:~# tcpdump -i tap0 -nnvv
tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
13:59:46.658092 IP (tos 0x0, ttl 253, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 2, length 76
13:59:46.658136 IP (tos 0x0, ttl 64, id 3496, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 2, length 76
13:59:46.658140 IP (tos 0x0, ttl 253, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 3, length 76
13:59:46.658142 IP (tos 0x0, ttl 64, id 3497, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 3, length 76
13:59:46.658143 IP (tos 0x0, ttl 253, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 4, length 76
13:59:46.658145 IP (tos 0x0, ttl 64, id 3498, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 4, length 76
13:59:46.658147 IP (tos 0x0, ttl 253, id 0, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.1 > 192.168.200.2: ICMP echo request, id 24497, seq 5, length 76
13:59:46.658149 IP (tos 0x0, ttl 64, id 3499, offset 0, flags [none], proto ICMP (1), length 96)
192.168.200.2 > 192.168.200.1: ICMP echo reply, id 24497, seq 5, length 76
13:59:51.706244 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.200.1 tell 192.168.200.2, length 28
13:59:51.706544 ARP, Ethernet (len 6), IPv4 (len 4), Reply 192.168.200.1 is-at 02:fe:18:21:1a:a2, length 28
至此我们介绍了pg功能基本使用方法,构造报文或者回放一个pcap文件,希望这个工具对你有所帮助。