前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >learning:gre tunnel plugins

learning:gre tunnel plugins

作者头像
dpdk-vpp源码解读
发布2024-01-09 15:47:59
2340
发布2024-01-09 15:47:59
举报
文章被收录于专栏:DPDK VPP源码分析DPDK VPP源码分析

GRE(Generic Routing Encapsulation,通用路由封装)协议用来对某种协议(如IP、MPLS、以太网)的数据报文进行封装,使这些被封装的数据报文能够在另一个网络(如IP)中传输。封装前后数据报文的网络层协议可以相同,也可以不同。封装后的数据报文在网络中传输的路径,称为GRE隧道。GRE隧道是一个虚拟的点到点的连接,其两端的设备分别对数据报文进行封装及解封装。

GRE封装后的报文包括如下几个部分:

· 净荷数据(Payload packet):需要封装和传输的数据报文。净荷数据的协议类型,称为乘客协议(Passenger Protocol)。乘客协议可以是任意的网络层协议。

· GRE头(GRE header):采用GRE协议对净荷数据进行封装所添加的报文头,包括封装层数、版本、乘客协议类型、校验和信息、Key信息等内容。添加GRE头后的报文称为GRE报文。对净荷数据进行封装的GRE协议,称为封装协议(Encapsulation Protocol)。

· 传输协议的报文头(Delivery header):在GRE报文上添加的报文头,以便传输协议对GRE报文进行转发处理。传输协议(Delivery Protocol或者Transport Protocol)是指负责转发GRE报文的网络层协议。设备支持IPv4和IPv6两种传输协议:当传输协议为IPv4时,GRE隧道称为GRE over IPv4隧道;当传输协议为IPv6时,GRE隧道称为GRE over IPv6隧道。传输协议使用IP头协议号 47 。

GRE头各字段说明:

GRE本身提供两种基本的安全机制:校验和验证,识别关键字(VPP目前不支持)。校验和验证是指对封装的报文进行端到端校验。若GRE报文头中的C位标识位置1,则校验和位有效。发送方将根据GRE头及Payload信息计算校验和,并将包含校验和的报文发送给对端。接收方对接收到的报文计算校验和,并与报文中的校验和比较,如果一致则对报文进一步处理,否则丢弃。隧道两端可以根据实际应用的需要决定配置校验和或禁止校验和。如果本端配置了校验和而对端没有配置,则本端将不会对接收到的报文进行校验和检查,但对发送的报文计算校验和;相反,如果本端没有配置校验和而对端已配置,则本端将对从对端发来的报文进行校验和检查,但对发送的报文不计算校验和。

识别关键字(Key)验证是指对Tunnel接口进行校验。通过这种弱安全机制,可以防止错误识别、接收其它地方来的报文。RFC1701中规定:若GRE报文头中的K位为1,则在GRE头中插入一个四字节长关键字字段,收发双方将进行识别关键字的验证。关键字的作用是标志隧道中的流量,属于同一流量的报文使用相同的关键字。在报文解封装时,GRE将基于关键字来识别属于相同流量的数据报文。只有Tunnel两端设置的识别关键字完全一致时才能通过验证,否则将报文丢弃。这里的“完全一致”是指两端都不设置识别关键字,或者两端都设置相同的关键字。

由于GRE协议并不具备检测链路状态的功能,如果对端接口不可达,隧道并不能及时关闭该Tunnel连接,这样会造成源端会不断的向对端转发数据,而对端却因隧道不通接收不到报文,由此就会形成数据空洞。GRE隧道增加Keepalive检测功能可以检测隧道状态,即检测隧道对端是否可达。如果对端不可达,隧道连接就会及时关闭,避免因对端不可达而造成的数据丢失,有效防止数据空洞,保证数据传输的可靠性。

本文基于vpp v24.02版本学习vpp gre隧道基本配置及业务转发流程。

下面是vpp1环境创建gre256接口相关配置(创建tap接口及路由配置可以参考文章,本文不再说明):

代码语言:javascript
复制
##创建GRE隧道接口
create gre tunnel src 192.168.100.113 dst 192.168.100.2 instance 256
set interface state gre256 up
#设置gre接口三层属性,复用物理接口ip
set interface unnumbered gre256 use GigabitEthernet0/6/0
#设置到PC2的路由,引入到gre接口
ip route add 192.168.110.0/24 via gre256

下面从PC2 ping PC1接口ip,抓取trace流程如下,为了验证gre接口feature使能配置,在gre接口上使能了tcp-mss-clamp功能。

代码语言:javascript
复制
#请求报文,gre解封装流程
07:20:42:286661: dpdk-input
  GigabitEthernet0/6/0 rx queue 0
  buffer 0x9b25b: current data 0, length 122, buffer-pool 0, ref-count 1, trace handle 0x0
                  ext-hdr-valid 
  PKT MBUF: port 0, nb_segs 1, pkt_len 122
    buf_len 2176, data_len 122, ol_flags 0x0, data_off 128, phys_addr 0xa00c9740
    packet_type 0x0 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0 
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
  IP4: 52:54:00:e3:1c:a6 -> 52:54:00:52:38:8b
  GRE: 192.168.100.2 -> 192.168.100.113
    tos 0x00, ttl 253, length 108, checksum 0x739e dscp CS0 ecn NON_ECN
    fragment id 0x0000
  GRE ip4
07:20:42:286665: ethernet-input
  frame: flags 0x1, hw-if-index 1, sw-if-index 1
  IP4: 52:54:00:e3:1c:a6 -> 52:54:00:52:38:8b
07:20:42:286669: ip4-input
  GRE: 192.168.100.2 -> 192.168.100.113
    tos 0x00, ttl 253, length 108, checksum 0x739e dscp CS0 ecn NON_ECN
    fragment id 0x0000
  GRE ip4
07:20:42:286670: ip4-lookup
  fib 0 dpo-idx 7 flow hash: 0x00000000
  GRE: 192.168.100.2 -> 192.168.100.113
    tos 0x00, ttl 253, length 108, checksum 0x739e dscp CS0 ecn NON_ECN
    fragment id 0x0000
  GRE ip4
07:20:42:286672: ip4-receive
    GRE: 192.168.100.2 -> 192.168.100.113
      tos 0x00, ttl 253, length 108, checksum 0x739e dscp CS0 ecn NON_ECN
      fragment id 0x0000
    GRE ip4
07:20:42:286672: gre4-input
  GRE: tunnel 4 len 108 src 192.168.100.2 dst 192.168.100.113
07:20:42:286674: ip4-input
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 63, length 84, checksum 0xdb8d dscp CS0 ecn NON_ECN
    fragment id 0xa8c5, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xb659 id 12
07:20:42:286675: tcp-mss-clamping-ip4-in
  max mss: 1100 clamped: 0
07:20:42:286676: ip4-lookup
  fib 0 dpo-idx 7 flow hash: 0x00000000
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 63, length 84, checksum 0xdb8d dscp CS0 ecn NON_ECN
    fragment id 0xa8c5, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xb659 id 12
07:20:42:286677: ip4-rewrite
  tx_sw_if_index 3 dpo-idx 7 : ipv4 via 192.168.200.2 tap100: mtu:9000 next:6 flags:[] 02feabb5b9d302fea94f68eb0800 flow hash: 0x00000000
  00000000: 02feabb5b9d302fea94f68eb080045000054a8c540003e01dc8dc0a86e02c0a8
  00000020: c8020800b659000c0001f4ba9b6500000000e6a50c00000000001011
07:20:42:286678: tap100-output
  tap100 flags 0x0018000d
  IP4: 02:fe:a9:4f:68:eb -> 02:fe:ab:b5:b9:d3
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 62, length 84, checksum 0xdc8d dscp CS0 ecn NON_ECN
    fragment id 0xa8c5, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xb659 id 12
07:20:42:286679: tap100-tx
    buffer 0x9b25b: current data 24, length 98, buffer-pool 0, ref-count 1, trace handle 0x0
                    ext-hdr-valid 
                    l2-hdr-offset 0 l3-hdr-offset 14 
  hdr-sz 0 l2-hdr-offset 24 l3-hdr-offset 14 l4-hdr-offset 0 l4-hdr-sz 0
  IP4: 02:fe:a9:4f:68:eb -> 02:fe:ab:b5:b9:d3
  ICMP: 192.168.110.2 -> 192.168.200.2
    tos 0x00, ttl 62, length 84, checksum 0xdc8d dscp CS0 ecn NON_ECN
    fragment id 0xa8c5, flags DONT_FRAGMENT
  ICMP echo_request checksum 0xb659 id 12

##回应报文,gre封装流程

07:20:42:286736: virtio-input
  virtio: hw_if_index 3 next-index 4 vring 0 len 98
    hdr: flags 0x00 gso_type 0x00 hdr_len 0 gso_size 0 csum_start 0 csum_offset 0 num_buffers 1
07:20:42:286737: ethernet-input
  frame: flags 0x1, hw-if-index 3, sw-if-index 3
  IP4: 02:fe:ab:b5:b9:d3 -> 02:fe:a9:4f:68:eb
07:20:42:286739: ip4-input
  ICMP: 192.168.200.2 -> 192.168.110.2
    tos 0x00, ttl 64, length 84, checksum 0x9879 dscp CS0 ecn NON_ECN
    fragment id 0x2ada
  ICMP echo_reply checksum 0xbe59 id 12
07:20:42:286739: ip4-lookup
  fib 0 dpo-idx 8 flow hash: 0x00000000
  ICMP: 192.168.200.2 -> 192.168.110.2
    tos 0x00, ttl 64, length 84, checksum 0x9879 dscp CS0 ecn NON_ECN
    fragment id 0x2ada
  ICMP echo_reply checksum 0xbe59 id 12
07:20:42:286740: ip4-midchain
  tx_sw_if_index 4 dpo-idx 8 : ipv4 [features] via 0.0.0.0 gre256: mtu:9000 next:7 flags:[features ] 45
00000000000000fe2f730ac0a86471c0a8640200000800
  stacked-on entry:15:
    [@2]: ipv4 via 192.168.100.2 GigabitEthernet0/6/0: mtu:9000 next:5 flags:[] 525400e31ca652540052388
b0800 flow hash: 0x00000000
  00000000: 4500006c00000000fe2f729ec0a86471c0a8640200000800450000542ada0000
  00000020: 3f019979c0a8c802c0a86e020000be59000c0001f4ba9b6500000000
07:20:42:286741: tcp-mss-clamping-ip4-out
  max mss: 1100 clamped: 0
07:20:42:286741: tunnel-output
  adj-midchain:[8]:ipv4 [features] via 0.0.0.0 gre256: mtu:9000 next:7 flags:[features ] 45000000000000
00fe2f730ac0a86471c0a8640200000800
  stacked-on entry:15:
    [@2]: ipv4 via 192.168.100.2 GigabitEthernet0/6/0: mtu:9000 next:5 flags:[] 525400e31ca652540052388
b0800
07:20:42:286742: ip4-rewrite
  tx_sw_if_index 1 dpo-idx 6 : ipv4 via 192.168.100.2 GigabitEthernet0/6/0: mtu:9000 next:5 flags:[] 52
5400e31ca652540052388b0800 flow hash: 0x00000000
  00000000: 525400e31ca652540052388b08004500006c00000000fd2f739ec0a86471c0a8
  00000020: 640200000800450000542ada00003f019979c0a8c802c0a86e020000
07:20:42:286743: GigabitEthernet0/6/0-output
  GigabitEthernet0/6/0 flags 0x00180005
  IP4: 52:54:00:52:38:8b -> 52:54:00:e3:1c:a6
  GRE: 192.168.100.113 -> 192.168.100.2
    tos 0x00, ttl 253, length 108, checksum 0x739e dscp CS0 ecn NON_ECN
    fragment id 0x0000
  GRE ip4
07:20:42:286743: GigabitEthernet0/6/0-tx
  GigabitEthernet0/6/0 tx queue 0
  buffer 0x9ea6b: current data -24, length 122, buffer-pool 0, ref-count 1, trace handle 0x1
                  l2-hdr-offset 0 l3-hdr-offset 14 
  PKT MBUF: port 65535, nb_segs 1, pkt_len 122
    buf_len 2176, data_len 122, ol_flags 0x0, data_off 104, phys_addr 0xa01a9b40
    packet_type 0x0 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0 
    rss 0x0 fdir.hi 0x0 fdir.lo 0x0
  IP4: 52:54:00:52:38:8b -> 52:54:00:e3:1c:a6
  GRE: 192.168.100.113 -> 192.168.100.2
    tos 0x00, ttl 253, length 108, checksum 0x739e dscp CS0 ecn NON_ECN
    fragment id 0x0000
  GRE ip4

vpp在隧道路由查找存在特殊处理adj-chain功能,减少了一次GRE封装之后查询路由。adj_midchain模块是用于处理中间链路路由的模块之一。中间链路路由是指数据包需要通过其他路由器进行转发的路由,而不是直接到达目的地。

adj_midchain模块的主要功能是管理和处理中间链路路由,包括添加、删除、修改路由表项等操作。它与VPP的其他模块一起协作,共同完成数据包的路由和转发。

1)路由表项的存储和管理:adj_midchain模块维护了一个路由表,用于存储中间链路路由的表项。每个表项包括目的网络地址、下一跳地址、出口接口等信息。通过查询和管理这个路由表,adj_midchain模块能够正确地转发经过其他路由器转发的数据包。

2)路由表的动态更新:adj_midchain模块支持动态更新路由表。当网络拓扑发生变化时,它可以接收来自其他模块的更新请求,并根据网络变化情况更新路由表。这样可以确保路由表的实时性和准确性,从而保证数据包的正确转发。

3)数据包的转发处理:当数据包进入VPP时,adj_midchain模块会根据数据包的源地址和目的地址查询路由表,确定下一跳地址和出口接口。然后,它将数据包转发到相应的出口接口,完成中间链路路由的处理。

下面是在PC1查询192.168.110.0/24网段路由,可以转发表中可以直接查询到外层路由信息,在vpp转发过程减少路由查找就接口node处理逻辑,加速了转发。

代码语言:javascript
复制
vpp# show ip fib 192.168.110.0/24
ipv4-VRF:0, fib_index:0, flow hash:[src dst sport dport proto flowlabel ] epoch:0 flags:none locks:[adjacency:1, default-route:1, ]
192.168.110.0/24 fib:0 index:17 locks:2
  CLI refs:1 entry-flags:attached, src-flags:added,contributing,active,
    path-list:[25] locks:2 flags:shared, uPRF-list:21 len:1 itfs:[4, ]
      path:[29] pl-index:25 ip4 weight=1 pref=0 attached:  oper-flags:resolved, cfg-flags:glean,
         gre256

 forwarding:   unicast-ip4-chain
  [@0]: dpo-load-balance: [proto:ip4 index:19 buckets:1 uRPF:21 to:[14787:1242108]]
    [0] [@6]: ipv4 [features] via 0.0.0.0 gre256: mtu:9000 next:7 flags:[features ] 4500000000000000fe2f730ac0a86471c0a8640200000800
        stacked-on entry:15:
          [@2]: ipv4 via 192.168.100.2 GigabitEthernet0/6/0: mtu:9000 next:5 flags:[] 525400e31ca652540052388b0800

gre-input解封之后,修改rx接口信息为gre接口,使能mss clamp功能之后,节点处理报文头指向原始报文ip头。但是gre封装流程是在adj-midchain节点完成gre头+外层ip头,切换tx接口为gre接口,在mss-clamp功能时,报文已经指向封装后报文。trace流程中tcp-mss-clamping-ip4-out节点并没有显示报文格式信息,我们可以通过pcap dispatch trace转包来查询。

版权归本公众号所有,如需转载请注明出处。 如果你觉得内容对你有帮助,欢迎转发、点赞、赞赏[1]

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DPDK VPP源码分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档