zl程序教程

您现在的位置是:首页 >  其他

当前栏目

learning:vpp pipe interface

2023-02-19 12:21:04 时间

本文介绍pipe接口使用,此接口有点类似于内核veth-pair。总是成对出现的。此功能可以用于两个vrf之间进行通信。

简介

先看一下vpp代码中特性的描述信息:创建一个pipe设备接口,该接口可以将管道一端的数据包双向传递到另一端。虽然在行为上类似于unix pipe,但它不是基于主机的管道。目前代码就三个文件。主要命令行就2个,pipe接口的创建和删除。下面就分别来说明一下。

1、pipe创建
pipe create [instance <instance>]

支持用户指定实例ID,如果用户不支持,从0开始最大支持16K。创建完成后会生成三个接口,如下创建pipe0接口,会生成2个子接口pipe0.0,pipe0.1接口。pipe0接口无法使用,pipe0.0和pipe0.1是管道的两端。需要注意的是三个接口同时up才能转发报文。

vlearning_vpp1# show interface 
              Name               Idx    State  MTU (L3/IP4/IP6/MPLS)     Counter          Count     
GigabitEthernet13/0/0             2     down         9000/0/0/0     
GigabitEthernet1b/0/0             3     down         9000/0/0/0     
GigabitEthernetb/0/0              1     down         9000/0/0/0     
local0                            0     down          0/0/0/0       
pipe0                             4     down         9000/0/0/0     
pipe0.0                           5     down          0/0/0/0       
pipe0.1                           6     down          0/0/0/0       
2、pipe删除

pipe删除指定需要删除的接口名称即可。

pipe delete <interface>
3、相关结构体

pipe只涉及2个主要结构体,如下图所示:

pipe_main_t:pipe管理结构体,用于管理所有pipe接口的添加删除及转发查询动作。其中pipes就是描述pipe管道两端的信息。pipes是一个vector结构存储,下标是pipe创建的两个子接口索引(这里使用vector结构也能提升转发效率,降低cache miss)。

这里会不会有疑问,pipe接口删除的时候是如何查询到子接口索引,来清空pipes[sub_sw_if_index]信息的。这里使用主接口在创建子接口时,会保存子接口id和子接口索引hash关系,删除时遍历hash表即可。 hash_set (hi->sub_interface_sw_if_index_by_id, 0, pipe_sw_if_index[0]);

pipe_t: 具体pipe管道两端接口信息。

pipe验证

首先验证下面的组网设置:

发现存在问题,无法ping通(没有详细定位,暂时不知道原因)。提示错误如下:

learning_vpp1# ping 192.168.100.2 table-id 1
Failed: no source address for egress interface

通过创建一个2层bd域及loopback接口,pipe管道加入二层域中,具体组网及配置如下:

#创建vrf 1和2
ip table add 1
ip table add 1
#分别创建bd1和bd2
create bridge-domain 1 learn 1 forward 1 uu-flood 1 flood 1 arp-term 1
create bridge-domain 2 learn 1 forward 1 uu-flood 1 flood 1 arp-term 1
#创建loop接口
create loopback interface instance 0
create loopback interface instance 1
set interface state loop0 up
set interface state loop1 up
set interface l2 bridge loop0 1 bvi
set interface l2 bridge loop1 2 bvi
set interface ip table loop0 1
set interface ip table loop1 2
set interface ip address loop0 192.168.100.1/24
set interface ip address loop1 192.168.100.2/24
#创建pipe0接口并设置up
pipe create instance 0
set interface state pipe0 up
set interface state pipe0.0 up
set interface state pipe0.1 up

set interface ip table pipe0.0 1
set interface ip table pipe0.0 2
set interface l2 bridge pipe0.0 1
set interface l2 bridge pipe0.1 2

在vrf1中pingvrf2中loop1接口ip地址可以ping通.

learning_vpp1# ping 192.168.100.2 table-id 1
116 bytes from 192.168.100.2: icmp_seq=2 ttl=64 time=8.7647 ms
116 bytes from 192.168.100.2: icmp_seq=3 ttl=64 time=1.8757 ms

vpp中ping无法抓取trace,在bd1中加入一个物理口与内核接口相连,在内核上ping vrf2 loop接口ip,这样可以trace抓包。

01:37:15:975388: dpdk-input
  GigabitEthernetb/0/0 rx queue 0
  buffer 0x9b249: current data 0, length 98, buffer-pool 0, ref-count 1, totlen-nifb 0, trace handle 0x1000000
                  ext-hdr-valid 
                  l4-cksum-computed l4-cksum-correct 
  PKT MBUF: port 0, nb_segs 1, pkt_len 98
    buf_len 2176, data_len 98, ol_flags 0x80, data_off 128, phys_addr 0x3a2c92c0
    packet_type 0x91 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
    Packet Offload Flags
      PKT_RX_IP_CKSUM_GOOD (0x0080) IP cksum of RX pkt. is valid
    Packet Types
      RTE_PTYPE_L2_ETHER (0x0001) Ethernet packet
      RTE_PTYPE_L3_IPV4_EXT_UNKNOWN (0x0090) IPv4 packet with or without extension headers
  IP4: 00:0c:29:63:94:44 -> de:ad:00:00:00:01
  ICMP: 192.168.100.4 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0x1be8 dscp CS0 ecn NON_ECN
    fragment id 0xd569, flags DONT_FRAGMENT
  ICMP echo_request checksum 0x4a2b id 5000
01:37:15:975419: ethernet-input
  frame: flags 0x1, hw-if-index 1, sw-if-index 1
  IP4: 00:0c:29:63:94:44 -> de:ad:00:00:00:01
01:37:15:975436: l2-input
  l2-input: sw_if_index 1 dst de:ad:00:00:00:01 src 00:0c:29:63:94:44 [l2-learn l2-fwd l2-flood arp-term-l2bd l2-flood ]
01:37:15:975440: l2-learn
  l2-learn: sw_if_index 1 dst de:ad:00:00:00:01 src 00:0c:29:63:94:44 bd_index 1
01:37:15:975444: l2-fwd
  l2-fwd:   sw_if_index 1 dst de:ad:00:00:00:01 src 00:0c:29:63:94:44 bd_index 1 result [0x15a0000000006, 6] none
01:37:15:975449: l2-output
  l2-output: sw_if_index 6 dst de:ad:00:00:00:01 src 00:0c:29:63:94:44 data 08 00 45 00 00 54 d5 69 40 00 40 01
01:37:15:975452: pipe0-output
  pipe0.0 
  IP4: 00:0c:29:63:94:44 -> de:ad:00:00:00:01
  ICMP: 192.168.100.4 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0x1be8 dscp CS0 ecn NON_ECN
    fragment id 0xd569, flags DONT_FRAGMENT
  ICMP echo_request checksum 0x4a2b id 5000
01:37:15:975461: pipe-rx
  IP4: 00:0c:29:63:94:44 -> de:ad:00:00:00:01
01:37:15:975468: l2-input
  l2-input: sw_if_index 5 dst de:ad:00:00:00:01 src 00:0c:29:63:94:44 [l2-learn l2-fwd l2-flood arp-term-l2bd l2-flood ]
01:37:15:975469: l2-learn
  l2-learn: sw_if_index 5 dst de:ad:00:00:00:01 src 00:0c:29:63:94:44 bd_index 2
01:37:15:975470: l2-fwd
  l2-fwd:   sw_if_index 5 dst de:ad:00:00:00:01 src 00:0c:29:63:94:44 bd_index 2 result [0x700000008, 8] static age-not bvi 
01:37:15:975473: ip4-input
  ICMP: 192.168.100.4 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0x1be8 dscp CS0 ecn NON_ECN
    fragment id 0xd569, flags DONT_FRAGMENT
  ICMP echo_request checksum 0x4a2b id 5000
01:37:15:975479: ip4-lookup
  fib 2 dpo-idx 11 flow hash: 0x00000000
  ICMP: 192.168.100.4 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0x1be8 dscp CS0 ecn NON_ECN
    fragment id 0xd569, flags DONT_FRAGMENT
  ICMP echo_request checksum 0x4a2b id 5000
01:37:15:975499: ip4-local
    ICMP: 192.168.100.4 -> 192.168.100.2
      tos 0x00, ttl 64, length 84, checksum 0x1be8 dscp CS0 ecn NON_ECN
      fragment id 0xd569, flags DONT_FRAGMENT
    ICMP echo_request checksum 0x4a2b id 5000
01:37:15:975504: ip4-icmp-input
  ICMP: 192.168.100.4 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0x1be8 dscp CS0 ecn NON_ECN
    fragment id 0xd569, flags DONT_FRAGMENT
  ICMP echo_request checksum 0x4a2b id 5000
01:37:15:975507: ip4-icmp-echo-request
  ICMP: 192.168.100.4 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0x1be8 dscp CS0 ecn NON_ECN
    fragment id 0xd569, flags DONT_FRAGMENT
  ICMP echo_request checksum 0x4a2b id 5000
01:37:15:975515: ip4-load-balance
  fib 0 dpo-idx 7 flow hash: 0x00000000
  ICMP: 192.168.100.2 -> 192.168.100.4
    tos 0x00, ttl 64, length 84, checksum 0xb37d dscp CS0 ecn NON_ECN
    fragment id 0x3dd4, flags DONT_FRAGMENT
  ICMP echo_reply checksum 0x522b id 5000
01:37:15:975517: ip4-rewrite
  tx_sw_if_index 8 dpo-idx 7 : ipv4 via 192.168.100.4 loop1: mtu:9000 next:4 flags:[] 000c29639444dead000000010800 flow hash: 0x00000000
  00000000: 000c29639444dead000000010800450000543dd440004001b37dc0a86402c0a8
  00000020: 64040000522b1388001059c35d61000000001b450900000000001011
01:37:15:975521: loop1-output
  loop1 
  IP4: de:ad:00:00:00:01 -> 00:0c:29:63:94:44
  ICMP: 192.168.100.2 -> 192.168.100.4
    tos 0x00, ttl 64, length 84, checksum 0xb37d dscp CS0 ecn NON_ECN
    fragment id 0x3dd4, flags DONT_FRAGMENT
  ICMP echo_reply checksum 0x522b id 5000
01:37:15:975526: l2-input
  l2-input: sw_if_index 8 dst 00:0c:29:63:94:44 src de:ad:00:00:00:01 [l2-fwd l2-flood arp-term-l2bd l2-flood ]
01:37:15:975527: l2-fwd
  l2-fwd:   sw_if_index 8 dst 00:0c:29:63:94:44 src de:ad:00:00:00:01 bd_index 2 result [0x1600000000005, 5] none
01:37:15:975528: l2-output
  l2-output: sw_if_index 5 dst 00:0c:29:63:94:44 src de:ad:00:00:00:01 data 08 00 45 00 00 54 3d d4 40 00 40 01
01:37:15:975530: pipe0-output
  pipe0.1 
  IP4: de:ad:00:00:00:01 -> 00:0c:29:63:94:44
  ICMP: 192.168.100.2 -> 192.168.100.4
    tos 0x00, ttl 64, length 84, checksum 0xb37d dscp CS0 ecn NON_ECN
    fragment id 0x3dd4, flags DONT_FRAGMENT
  ICMP echo_reply checksum 0x522b id 5000
01:37:15:975532: pipe-rx
  IP4: de:ad:00:00:00:01 -> 00:0c:29:63:94:44
01:37:15:975533: l2-input
  l2-input: sw_if_index 6 dst 00:0c:29:63:94:44 src de:ad:00:00:00:01 [l2-learn l2-fwd l2-flood arp-term-l2bd l2-flood ]
01:37:15:975534: l2-learn
  l2-learn: sw_if_index 6 dst 00:0c:29:63:94:44 src de:ad:00:00:00:01 bd_index 1
01:37:15:975535: l2-fwd
  l2-fwd:   sw_if_index 6 dst 00:0c:29:63:94:44 src de:ad:00:00:00:01 bd_index 1 result [0x1600000000001, 1] none
01:37:15:975536: l2-output
  l2-output: sw_if_index 1 dst 00:0c:29:63:94:44 src de:ad:00:00:00:01 data 08 00 45 00 00 54 3d d4 40 00 40 01
01:37:15:975537: GigabitEthernetb/0/0-output
  GigabitEthernetb/0/0 
  IP4: de:ad:00:00:00:01 -> 00:0c:29:63:94:44
  ICMP: 192.168.100.2 -> 192.168.100.4
    tos 0x00, ttl 64, length 84, checksum 0xb37d dscp CS0 ecn NON_ECN
    fragment id 0x3dd4, flags DONT_FRAGMENT
  ICMP echo_reply checksum 0x522b id 5000
01:37:15:975541: GigabitEthernetb/0/0-tx
  GigabitEthernetb/0/0 tx queue 1
  buffer 0x9b249: current data 0, length 98, buffer-pool 0, ref-count 1, totlen-nifb 0, trace handle 0x1000000
                  ext-hdr-valid 
                  l4-cksum-computed l4-cksum-correct local l2-hdr-offset 0 l3-hdr-offset 14 
  PKT MBUF: port 0, nb_segs 1, pkt_len 98
    buf_len 2176, data_len 98, ol_flags 0x80, data_off 128, phys_addr 0x3a2c92c0
    packet_type 0x91 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
    Packet Offload Flags
      PKT_RX_IP_CKSUM_GOOD (0x0080) IP cksum of RX pkt. is valid
    Packet Types
      RTE_PTYPE_L2_ETHER (0x0001) Ethernet packet
      RTE_PTYPE_L3_IPV4_EXT_UNKNOWN (0x0090) IPv4 packet with or without extension headers
  IP4: de:ad:00:00:00:01 -> 00:0c:29:63:94:44
  ICMP: 192.168.100.2 -> 192.168.100.4
    tos 0x00, ttl 64, length 84, checksum 0xb37d dscp CS0 ecn NON_ECN
    fragment id 0x3dd4, flags DONT_FRAGMENT
  ICMP echo_reply checksum 0x522b id 5000

关键处理流程如下:

总结:

本文简单说明vpp pipe接口的配置使用及转发逻辑,代码实现比较简单,感兴趣的可以阅读一下。pipe接口使用场景还需要进一步研究分析。