前面文章: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命令行模式查询,显示如下:
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处理接口函数如下:
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
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
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
!
#在内核上设置接口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
!
#在内核上设置接口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
!
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
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
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 ===========
在vpp1环境上ping vpp2 lan口ip地址,分别在vpp1抓包如下:
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发送内核。
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