Learning VPP: OSPF routing protocol

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

前面文章:learning:vppsb router插件编译 介绍了vppsb router插件在Centos7内核版本3.10上的基于vpp 21.06版本的编译,并将修改后代码放在github上《链接https://github.com/jin13417/vppsb/tree/vpp_21.06》。本文主要参考博文《Learning VPP: OSPF routing protocol》学习使用vppsb的router插件搭建ospf学习环境。

基本环境

基础环境Centos7,内核版本3.10.0-957.21.3.el7.x86_64。分别下载并编译相关程序。 VPP VPPSB编译请参考:learning:vppsb router插件编译 frr编译及安装使用请参考:

http://docs.frrouting.org/projects/dev-guide/en/latest/building-frr-for-centos7.html?highlight=build 安装Frr参照上面链接:Centos7版本build说明即可,编译过程中没有任何报错。

组网及配置

目前vppsb中router插件使能tap-inject功能后,会把vpp所有接口映射到内核,提供给frr的ospf使用,组网设置如下所示:

首先分别在vpp1和vpp2环境上使能tap-inject功能,使能后通过进入vpp命令行模式查询,显示如下:

代码语言:javascript复制
learning_vpp1# show tap-inject 
GigabitEthernet13/0/0 -> vpp1 #对应内核的创建一个tap接口vpp1。
GigabitEthernet1b/0/0 -> vpp2
GigabitEthernetb/0/0 -> vpp0
#在linux系统上对vpp1进行进行操作,设置接口状态及配置ip地址。
#会通过netlink接口送到vpp进行处理,对应vpp接口设置ip地址。
ifconfig vpp1 up
ifconfig vpp1 192.168.100.2/24

show unix files命令行会显示tap inject后的tap 的socket,当缺少对应的描述信息,vppsb vpp_21.06已经加上。 learning_vpp1# show unix files FD Thread Read Write Error File Name Description 31 0 142 0 0 /dev/net/tun vpp1

对应的netlink处理接口函数如下:

代码语言:javascript复制
static void
netns_notify_cb (void * obj, netns_type_t type, u32 flags, uword opaque)
{
   /*接口设置ip地址*/
  if (type == NETNS_TYPE_ADDR)
    add_del_addr ((ns_addr_t *)obj, flags & NETNS_F_DEL);
  /*接口状态变化*/
  else if (type == NETNS_TYPE_LINK)
    add_del_link ((ns_link_t *)obj, flags & NETNS_F_DEL);
  /*arp或nd设置*/
  else if (type == NETNS_TYPE_NEIGH)
    add_del_neigh ((ns_neigh_t *)obj, flags & NETNS_F_DEL);
  /*路由添加或删除*/
  else if (type == NETNS_TYPE_ROUTE)
    add_del_route ((ns_route_t *)obj, flags & NETNS_F_DEL);
}

router 插件只提供了linux系统配置接口映射到vpp对应接口上,并没有提供vpp接口配置映射到内核的接口。

FRR基本配置参照博客中的介绍即可. 修改frr启动程序配置文件设置ospf程序启动及对应的配置文件 /etc/frr/daemons

代码语言:javascript复制
ospfd=yes
ospfd_options=" -A 127.0.0.1 -f /etc/frr/ospfd.conf"
Make the following changes to /etc/frr/ospfd.conf

设置ospf配置文件/etc/frr/ospfd.conf

代码语言:javascript复制
hostname ospfd
password zebra
log file /var/log/frr/ospfd.log informational
log stdout
!
router ospf
    ospf router-id 192.168.100.2
    network 192.168.100.2/24 area 0.0.0.0
    network 100.100.102.0/24 area 0.0.0.0
!
1、vpp1 环境配置
代码语言:javascript复制
#在内核上设置接口up及配置ip地址。
ifconfig vpp1 up
ifconfig vpp1 192.168.100.2/24
ifconfig vpp0 up
ifconfig vpp0 100.100.102.1/24
#配置frr
[root@jinsh11 frr]# cat /etc/frr/ospfd.conf
hostname ospfd
password zebra
log file /var/log/frr/ospfd.log informational
log stdout
!
router ospf
    ospf router-id 192.168.100.2
    network 192.168.100.2/24 area 0.0.0.0
    network 100.100.102.0/24 area 0.0.0.0
!
2、vpp2环境配置
代码语言:javascript复制
#在内核上设置接口up及配置ip地址。
ifconfig vpp1 up
ifconfig vpp1 192.168.100.1/24
ifconfig vpp0 up
ifconfig vpp0 100.100.100.1/24
#配置frr
[root@jinsh11 ~]# cat /etc/frr/ospfd.conf 
hostname ospfd
password zebra
log file /var/log/frr/ospfd.log informational
log stdout
!
router ospf
    ospf router-id 192.168.100.1
    network 192.168.100.1/24 area 0.0.0.0
    network 100.100.100.0/24 area 0.0.0.0
!

FRR ospf相关查询命令行

1、查询ospf路由信息
代码语言:javascript复制
jinsh11# show ip route ospf 
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

O   100.100.100.0/24 [110/10000] is directly connected, vpp0, weight 1, 02:35:16
O>* 100.100.102.0/24 [110/20000] via 192.168.100.2, vpp1, weight 1, 02:34:00
O   192.168.100.0/24 [110/10000] is directly connected, vpp1, weight 1, 02:35:50
2、查询ospf邻居建立信息
代码语言:javascript复制
jinsh11# show ip ospf neighbor 
Neighbor ID     Pri State           Dead Time Address         Interface                        RXmtL RqstL DBsmL
192.168.100.1     1 Full/DR           31.142s 192.168.100.1   vpp1:192.168.100.2                   0     0     0
3、查询ospf 路由信息
代码语言:javascript复制
jinsh11# show ip ospf route
============ OSPF network routing table ============
N    100.100.100.0/24      [20000] area: 0.0.0.0
                           via 192.168.100.1, vpp1
N    100.100.102.0/24      [10000] area: 0.0.0.0
                           directly attached to vpp0
N    192.168.100.0/24      [10000] area: 0.0.0.0
                           directly attached to vpp1
============ OSPF router routing table =============
============ OSPF external routing table ===========

vpp trace

在vpp1环境上ping vpp2 lan口ip地址,分别在vpp1抓包如下:

代码语言:javascript复制
learning_vpp1# show trace 
------------------- Start of thread 0 vpp_main -------------------
Packet 1

00:22:50:005780: dpdk-input
  GigabitEthernet13/0/0 rx queue 0
  buffer 0x9cc2f: current data 0, length 98, buffer-pool 0, ref-count 1, totlen-nifb 0, trace handle 0x0
                  ext-hdr-valid 
                  l4-cksum-computed l4-cksum-correct 
  PKT MBUF: port 1, nb_segs 1, pkt_len 98
    buf_len 2176, data_len 98, ol_flags 0x80, data_off 128, phys_addr 0x76130c40
    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:17:0a:44 -> 00:0c:29:63:94:30
  ICMP: 100.100.100.1 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0xe6d8 dscp CS0 ecn NON_ECN
    fragment id 0xa6c0
  ICMP echo_reply checksum 0xc61d id 2270
00:22:50:005837: ethernet-input
  frame: flags 0x1, hw-if-index 2, sw-if-index 2
  IP4: 00:0c:29:17:0a:44 -> 00:0c:29:63:94:30
00:22:50:005934: ip4-input
  ICMP: 100.100.100.1 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0xe6d8 dscp CS0 ecn NON_ECN
    fragment id 0xa6c0
  ICMP echo_reply checksum 0xc61d id 2270
00:22:50:005970: ip4-lookup
  fib 0 dpo-idx 7 flow hash: 0x00000000
  ICMP: 100.100.100.1 -> 192.168.100.2
    tos 0x00, ttl 64, length 84, checksum 0xe6d8 dscp CS0 ecn NON_ECN
    fragment id 0xa6c0
  ICMP echo_reply checksum 0xc61d id 2270
00:22:50:006011: ip4-local
    ICMP: 100.100.100.1 -> 192.168.100.2
      tos 0x00, ttl 64, length 84, checksum 0xe6d8 dscp CS0 ecn NON_ECN
      fragment id 0xa6c0
    ICMP echo_reply checksum 0xc61d id 2270

vpp1上只能显示icmp reply报文,request报文从linux内核vpp1->到达对应vpp的socket后,由tap-inject-rx节点从socket读取报文后直接从对应的物理接口发出。由于tap-inject-rx接口并没有设置trace。所以无法查询。后续打算增加一下。 上面trace流程中ip4-local后面的节点也无法显示报文的处理,可以通过命令行show ip local 来查询icmp协议对应的node节点tap-inject-tx,节点直接将报文通过socket发送内核。

代码语言:javascript复制
learning_vpp1# show ip local 
Protocols handled by ip4_local
ICMP: tap-inject-tx # 对应tap-inject=tx节点,直接发送到内核。
IGMP: igmp-input
TCP: tap-inject-tx
UDP: tap-inject-tx
IPSEC_ESP: ipsec4-tun-input
OSPF: tap-inject-tx
VRRP: vrrp4-input

对应节点代码都在tap-inject-node.c文件中,相应的处理也比较简单,感兴趣的可以自己阅读一下。

参考文章

1、learning-vpp-ospf-routing-protocol https://haryachyy.wordpress.com/2020/04/17/learning-vpp-ospf-routing-protocol/ 2、FRR Centos7 编译文档 http://docs.frrouting.org/projects/dev-guide/en/latest/building-frr-for-centos7.html?highlight=build 3、vppsb github路径 https://github.com/jin13417/vppsb

0 人点赞