learning:vnet/Packet Generator

2023-03-07 17:32:32 浏览数 (1)

本文内容来源于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文件,希望这个工具对你有所帮助。

0 人点赞