0%

FRRouting

FRRouting(FRR)是一款提供 IP 路由服务的开源套件,支持 BGP、OSPF、RIP、IS-IS 等等路由协议。FRR 可以在网络栈中与其他路由器交换路由信息,做出路由策略决策,并将决策通知给其他层。

FRR 安装

Ubuntu 20.04 LTS 安装 FRR,且以 root 权限运行

安装依赖

1
2
3
4
5
6
7
8
9
sudo apt update
sudo apt-get install \
git autoconf automake libtool make libreadline-dev texinfo \
pkg-config libpam0g-dev libjson-c-dev bison flex \
libc-ares-dev python3-dev python3-sphinx \
install-info build-essential libsnmp-dev perl \
protobuf-c-compiler libprotobuf-c-dev \
libcap-dev libelf-dev libunwind-dev
apt-get install cmake libpcre2-dev

安装 libyang

1
2
3
4
5
6
7
8
git clone https://github.com/CESNET/libyang.git
cd libyang
git checkout v2.1.128
mkdir build; cd build
cmake --install-prefix /usr \
-D CMAKE_BUILD_TYPE:String="Release" ..
make
sudo make install

安装 FRR

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
git clone https://github.com/frrouting/frr.git frr
cd frr
./bootstrap.sh
./configure \
--prefix=/usr \
--includedir=\${prefix}/include \
--bindir=\${prefix}/bin \
--sbindir=\${prefix}/lib/frr \
--libdir=\${prefix}/lib/frr \
--libexecdir=\${prefix}/lib/frr \
--sysconfdir=/etc \
--localstatedir=/var \
--with-moduledir=\${prefix}/lib/frr/modules \
--enable-configfile-mask=0640 \
--enable-logfile-mask=0640 \
--enable-snmp=agentx \
--enable-multipath=64 \
--enable-user=root \
--enable-group=root \
--enable-vty-group=root \
--with-pkg-git-version \
--with-pkg-extra-version=-MyOwnFRRVersion
make
sudo make install

生成配置

1
2
3
4
5
6
sudo install -m 775 -o root -g root -d /var/log/frr
sudo install -m 775 -o root -g root -d /etc/frr
sudo install -m 640 -o root -g root tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf
sudo install -m 640 -o root -g root tools/etc/frr/frr.conf /etc/frr/frr.conf
sudo install -m 640 -o root -g root tools/etc/frr/daemons.conf /etc/frr/daemons.conf
sudo install -m 640 -o root -g root tools/etc/frr/daemons /etc/frr/daemons

启动服务

1
2
sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
sudo systemctl enable frr

查看安装完成的 FRR

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
root@ubuntu:/home/guoyi/frr/frr# systemctl status frr
● frr.service - FRRouting
Loaded: loaded (/etc/systemd/system/frr.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2024-10-16 05:46:16 PDT; 1s ago
Docs: https://frrouting.readthedocs.io/en/latest/setup.html
Process: 55748 ExecStart=/usr/lib/frr/frrinit.sh start (code=exited, status=0/SUCCESS)
Main PID: 55760 (watchfrr)
Status: "FRR Operational"
Tasks: 8 (limit: 4540)
Memory: 14.5M
CGroup: /system.slice/frr.service
├─55760 /usr/lib/frr/watchfrr -d -F traditional zebra mgmtd staticd
├─55771 /usr/lib/frr/zebra -d -F traditional -A 127.0.0.1 -s 90000000
├─55776 /usr/lib/frr/mgmtd -d -F traditional -A 127.0.0.1
└─55778 /usr/lib/frr/staticd -d -F traditional -A 127.0.0.1

Oct 16 05:46:16 ubuntu zebra[55771]: [VTVCM-Y2NW3] Configuration Read in Took: 00:00:00
Oct 16 05:46:16 ubuntu mgmtd[55776]: [VTVCM-Y2NW3] Configuration Read in Took: 00:00:00
Oct 16 05:46:16 ubuntu watchfrr[55760]: [VTVCM-Y2NW3] Configuration Read in Took: 00:00:00
Oct 16 05:46:16 ubuntu staticd[55778]: [VTVCM-Y2NW3] Configuration Read in Took: 00:00:00
Oct 16 05:46:16 ubuntu watchfrr[55760]: [QDG3Y-BY5TN] zebra state -> up : connect succeeded
Oct 16 05:46:16 ubuntu watchfrr[55760]: [QDG3Y-BY5TN] mgmtd state -> up : connect succeeded
Oct 16 05:46:16 ubuntu watchfrr[55760]: [QDG3Y-BY5TN] staticd state -> up : connect succeeded
Oct 16 05:46:16 ubuntu watchfrr[55760]: [KWE5Q-QNGFC] all daemons up, doing startup-complete notify
Oct 16 05:46:16 ubuntu frrinit.sh[55748]: * Started watchfrr
Oct 16 05:46:16 ubuntu systemd[1]: Started FRRouting.

安装问题

启动 frr 时报错

1
2
3
4
Oct 15 09:02:45 ubuntu systemd[1]: Starting FRRouting...
Oct 15 09:02:45 ubuntu frrinit.sh[28693]: * Starting watchfrr with command: ' /usr/lib/frr/watchfrr -d -F traditional zebra mgmtd staticd'
Oct 15 09:02:45 ubuntu frrinit.sh[28703]: /usr/lib/frr/watchfrr: error while loading shared libraries: libyang.so.2: cannot open shared object file: No such file or directory
Oct 15 09:02:45 ubuntu frrinit.sh[28693]: * Failed to start watchfrr!

查到 libyang 已安装

1
2
root@ubuntu:~/frr/libyang# ll /usr/local/lib/libyang.so
lrwxrwxrwx 1 root root 12 Oct 15 08:22 /usr/local/lib/libyang.so -> libyang.so.2

但 watchfrr 无法链接到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@ubuntu:~/frr/libyang# ldd /usr/lib/frr/watchfrr
linux-vdso.so.1 (0x00007fff64d68000)
libfrr.so.0 => /usr/lib/frr/libfrr.so.0 (0x00007f749a134000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f749a0f8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7499f06000)
libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007f7499efd000)
libunwind.so.8 => /lib/x86_64-linux-gnu/libunwind.so.8 (0x00007f7499ee0000)
libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f7499ea5000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7499e9d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7499d4e000)
libprotobuf-c.so.1 => /lib/x86_64-linux-gnu/libprotobuf-c.so.1 (0x00007f7499d43000)
libyang.so.2 => not found
libjson-c.so.4 => /lib/x86_64-linux-gnu/libjson-c.so.4 (0x00007f7499d31000)
/lib64/ld-linux-x86-64.so.2 (0x00007f749a387000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f7499d08000)

更新动态链接库

1
ldconfig

FRR 基础

Daemons 配置文件

Daemons 配置文件用来设置 FRR 的哪些 daemon 需要在 FRR 启动时被激活,并且设置 daemon 启动时的参数。

通常放在 /etc/frr/daemons,如果修改了里面的内容,需要重启 FRR 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# This file tells the frr package which daemons to start.
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/frr/examples/.
#
# ATTENTION:
#
# When activating a daemon for the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "frr", else
# the daemon will not be started by /etc/init.d/frr. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
#
# The watchfrr, zebra and staticd daemons are always started.
#
bgpd=no
ospfd=yes
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
pim6d=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=no
fabricd=no
vrrpd=no
pathd=no

#
# If this option is set the /etc/init.d/frr script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/frr if you intend to use "vtysh"!
#
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000"
mgmtd_options=" -A 127.0.0.1"
bgpd_options=" -A 127.0.0.1"
ospfd_options=" -A 127.0.0.1"
ospf6d_options=" -A ::1"
ripd_options=" -A 127.0.0.1"
ripngd_options=" -A ::1"
isisd_options=" -A 127.0.0.1"
pimd_options=" -A 127.0.0.1"
pim6d_options=" -A ::1"
ldpd_options=" -A 127.0.0.1"
nhrpd_options=" -A 127.0.0.1"
eigrpd_options=" -A 127.0.0.1"
babeld_options=" -A 127.0.0.1"
sharpd_options=" -A 127.0.0.1"
pbrd_options=" -A 127.0.0.1"
staticd_options="-A 127.0.0.1"
bfdd_options=" -A 127.0.0.1"
fabricd_options="-A 127.0.0.1"
vrrpd_options=" -A 127.0.0.1"
pathd_options=" -A 127.0.0.1"


# If you want to pass a common option to all daemons, you can use the
# "frr_global_options" variable.
#
#frr_global_options=""


# The list of daemons to watch is automatically generated by the init script.
# This variable can be used to pass options to watchfrr that will be passed
# prior to the daemon list.
#
# To make watchfrr create/join the specified netns, add the the "--netns"
# option here. It will only have an effect in /etc/frr/<somename>/daemons, and
# you need to start FRR with "/usr/lib/frr/frrinit.sh start <somename>".
#
#watchfrr_options=""


# configuration profile
#
#frr_profile="traditional"
#frr_profile="datacenter"


# This is the maximum number of FD's that will be available. Upon startup this
# is read by the control files and ulimit is called. Uncomment and use a
# reasonable value for your setup if you are expecting a large number of peers
# in say BGP.
#
#MAX_FDS=1024

# Uncomment this option if you want to run FRR as a non-root user. Note that
# you should know what you are doing since most of the daemons need root
# to work. This could be useful if you want to run FRR in a container
# for instance.
# FRR_NO_ROOT="yes"

# For any daemon, you can specify a "wrap" command to start instead of starting
# the daemon directly. This will simply be prepended to the daemon invocation.
# These variables have the form daemon_wrap, where 'daemon' is the name of the
# daemon (the same pattern as the daemon_options variables).
#
# Note that when daemons are started, they are told to daemonize with the `-d`
# option. This has several implications. For one, the init script expects that
# when it invokes a daemon, the invocation returns immediately. If you add a
# wrap command here, it must comply with this expectation and daemonize as
# well, or the init script will never return. Furthermore, because daemons are
# themselves daemonized with -d, you must ensure that your wrapper command is
# capable of following child processes after a fork() if you need it to do so.
#
# If your desired wrapper does not support daemonization, you can wrap it with
# a utility program that daemonizes programs, such as 'daemonize'. An example
# of this might look like:
#
# bgpd_wrap="/usr/bin/daemonize /usr/bin/mywrapper"
#
# This is particularly useful for programs which record processes but lack
# daemonization options, such as perf and rr.
#
# If you wish to wrap all daemons in the same way, you may set the "all_wrap"
# variable.
#
#all_wrap=""

crash 日志

FRR 各个 daemon 的 crash 日志储存在固定位置,即 /var/tmp/frr/<daemon>[-<instance>].<pid>/crashlog

日志配置

在 frr.conf 中可以配置日志文件输出

1
log file /var/log/frr/frr.log [logging_level]

vtysh

root 权限或者 frrvty 权限可以使用 vtysh 命令进入交互模式

show 命令

  • show ip ospf neighbor 查看 OSPF 邻居,其中
    • Neighbor ID:邻居的 Router ID
    • Pri:邻居的 Priority
    • State:邻居状态
1
2
3
4
568ade633bf9# show ip ospf neighbor

Neighbor ID Pri State Up Time Dead Time Address Interface RXmtL RqstL DBsmL
12.12.0.2 1 Full/Backup 22h48m43s 37.418s 11.11.0.3 eth1:11.11.0.2 0 0 0

FRR 和其他路由器交换路由信息、

支持北向grpc接口 或 vtysh 命令

进入配置模式

1
configure terminal

配置网卡

1
interface ens38

VIP是192.168.1.1/24,你要发布到OSPF区域0,且设置成本为10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vtysh
configure terminal
interface eth0
ip address 192.168.1.1/24
!
router ospf

network 192.168.1.0/24 area 0
!
interface eth0
ip ospf cost 10

end
write memory
1
2
3
4
5
6
7
8
9
10
vtysh
configure terminal
interface eth0
no ip address 192.168.1.1/24
!
router ospf 1
no network 192.168.1.0/24 area 0
!
interface eth0
ip ospf cost 10
1
show ip route ospf

查看 DR

1
show ip ospf neighbor

查看 ospf 路由

1
show ip ospf route

FRR 配置

配置命令

  • 查看当前配置

    1
    show running-config
  • 进入配置模式

    1
    configure terminal

prefix-list 配置

prefix-list(前缀列表)用于匹配和过滤 IP 地址

定义 prefix-list

下面只是定义一条前缀列表规则,如未设置应用,不会起任何作用

1
ip prefix-list NAME [seq NUMBER] (permit|deny) PREFIX [le LEN] [ge LEN]
  • NAME:定义的该前缀列表的名字,用于唯一标识该 prefix-list
  • seq:规则序号,匹配的优先级,序号越小越先匹配,可自动设置,自动设置以 5 为增量
  • permit|deny:匹配到的前缀将被允许通过/被过滤掉
  • PREFIX:匹配的网络地址和前缀长度
  • le:匹配的最长子网掩码长度
  • ge:匹配的最短子网掩码长度

配置示例

1
2
3
4
5
6
// 定义一个命名为 PLIST-1 的 prefix-list,拒绝所有前缀
ip prefix-list PLIST-1 seq 5 deny 0.0.0.0/0 le 32

// 定义一个命名为 PLIST-2 的 prefix-list,接受前缀 IP 为 1.1.1.1 和 2.2.2.2 的前缀
ip prefix-list PLIST-2 seq 5 permit 1.1.1.1/32
ip prefix-list PLIST-2 seq 10 permit 2.2.2.2/32

前缀匹配规则

  1. 优先匹配 seq 小的规则,逐条检查匹配,如果匹配上,则后续条目无需再检查
  2. 如果未设置任何 prefix-list,则视为所有 prefix 都 permit
  3. 默认拒绝:如果设置有 prefix-list,但未匹配到任何一条规则,则默认拒绝该 prefix
  4. 匹配规则:
    1. 检查 prefix IP 是否匹配 network/prefix-length
    2. 如果有设置 gele,则检查 prefix 长度是否在 >=ge 以及 <=le 范围内
    3. 比如 192.168.1.0/24 ge 25 le 30
      • IP 匹配范围 192.168.1.0 ~ 192.168.1.255
      • 前缀长度在 25 ~ 30
      • 192.168.1.0/24 不匹配(前缀长度不匹配)、192.168.1.0/25 匹配、192.168.1.30/28 匹配

查看 prefix-list

1
show ip prefix-list

route-map 配置

用于匹配和过滤路由

定义 route-map

下面只是定义一条路由匹配规则,如未设置应用,不会起任何作用

1
2
3
route-map ROUTE-MAP-NAME (permit|deny) ORDER
match <conditions>
set <actions>
  • ROUTE-MAP-NAME:定义的该 route-map 的名字,用于唯一标识该 route-map
  • permit|deny :是否允许匹配的路由通过
  • ORDER:规则序号,匹配的优先级,序号越小越先匹配,可自动设置,自动设置以 10 为增量
  • match:匹配条件
  • set:设置动作,如果 match 匹配上了,则给该条路由执行设置动作

配置示例

1
2
3
4
5
6
7
route-map EXAMPLE permit 10
match ip address prefix-list LIST-1
set local-preference 200

route-map EXAMPLE permit 20
match ip address prefix-list LIST-2
set local-preference 100

match 匹配条件

路由匹配条件,只有全部满足才算匹配

  • match ip address prefix-list PREFIX_LIST
    • IP 地址被 prefix-list PREFIX_LIST 匹配并允许通过的路由则匹配

set 设置动作

路由匹配规则

  1. 优先匹配 order 小的 route map,逐条检查匹配,如果匹配上,则后续条目无需再检查
  2. 默认拒绝:如果所有的 route map 都没匹配上,则默认拒绝该路由
  3. 匹配规则:
    1. 检查是否匹配上 match 的匹配规则,如果是匹配 prefix-list,需要被 prefix-list permit 才算匹配上该 match

route-map 应用

OSPF 组网

搭建下面一个网络,使用 Docker 模拟出三台 FRR 路由器,并给其配网,其中有两个网段:Router 1 的 eth1 和 Router 2 的 eth1、Router 3 的 eth1 和 Router 2 的 eth2,使用 FRR 让 Router 1 和 Router 3 学习到到对方的路由。

OSPF实验拓扑

1. Docker 模拟 FRR 路由器

模拟 3 台 FRR 路由器 Docker

1
2
3
docker run -d --privileged --net=none --name frr-01 quay.io/frrouting/frr:10.0.0
docker run -d --privileged --net=none --name frr-02 quay.io/frrouting/frr:10.0.0
docker run -d --privileged --net=none --name frr-03 quay.io/frrouting/frr:10.0.0

查看 docker 进程

1
2
3
4
5
root@ubuntu:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6185c04f06d1 quay.io/frrouting/frr:10.0.0 "/sbin/tini -- /usr/…" 2 minutes ago Up 2 minutes frr-03
1681fd9bd374 quay.io/frrouting/frr:10.0.0 "/sbin/tini -- /usr/…" 3 minutes ago Up 3 minutes frr-02
568ade633bf9 quay.io/frrouting/frr:10.0.0 "/sbin/tini -- /usr/…" 24 hours ago Up 24 hours frr-01

2. OvS 配网

由于安装 docker 容器时使用 --net=none 无网络,需根据拓扑对容器配网

查看各个路由器的网卡,当前各 docker 容器无网卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
root@ubuntu:~# docker exec -it frr-01 ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

root@ubuntu:~# docker exec -it frr-02 ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

root@ubuntu:~# docker exec -it frr-03 ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

安装 OvS 虚拟交换机用来搭建容器网络

1
apt-get install openvswitch-switch

创建一个网桥交换机

1
ovs-vsctl add-br brConn

如需删除,使用 ovs-vsctl del-br brConn

查看创建好的网桥

1
2
3
4
5
6
7
root@ubuntu:~# ovs-vsctl show
cb63c817-8d63-4d1f-b599-9950b0aeb2eb
Bridge brConn
Port brConn
Interface brConn
type: internal
ovs_version: "2.13.8"

让三台 docker 路由器都连接到这个交换机,并配置 IP

1
2
3
4
ovs-docker add-port brConn eth1 frr-01 --ipaddress=11.11.0.2/24
ovs-docker add-port brConn eth1 frr-02 --ipaddress=11.11.0.3/24
ovs-docker add-port brConn eth2 frr-02 --ipaddress=12.12.0.2/24
ovs-docker add-port brConn eth1 frr-03 --ipaddress=12.12.0.3/24

再次查看网桥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@ubuntu:~# ovs-vsctl show
cb63c817-8d63-4d1f-b599-9950b0aeb2eb
Bridge brConn
Port brConn
Interface brConn
type: internal
Port "0021a5f25d344_l"
Interface "0021a5f25d344_l"
Port "1529171a9a294_l"
Interface "1529171a9a294_l"
Port df2bf7ec96bd4_l
Interface df2bf7ec96bd4_l
Port a67433ae00b04_l
Interface a67433ae00b04_l
ovs_version: "2.13.8"

此时上各个 Docker 可以看到已配好的网卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
root@ubuntu:~# docker exec -it frr-01 ifconfig
eth1 Link encap:Ethernet HWaddr 1A:CF:B4:C0:93:4B
inet addr:11.11.0.2 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::18cf:b4ff:fec0:934b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:165 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:13826 (13.5 KiB) TX bytes:3036 (2.9 KiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

root@ubuntu:~# docker exec -it frr-02 ifconfig
eth1 Link encap:Ethernet HWaddr DE:38:AD:91:D8:24
inet addr:11.11.0.3 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::dc38:adff:fe91:d824/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:200 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:16592 (16.2 KiB) TX bytes:3036 (2.9 KiB)

eth2 Link encap:Ethernet HWaddr E2:4D:1E:69:47:D2
inet addr:12.12.0.2 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::e04d:1eff:fe69:47d2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:190 errors:0 dropped:0 overruns:0 frame:0
TX packets:39 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:15768 (15.3 KiB) TX bytes:2798 (2.7 KiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

root@ubuntu:~# docker exec -it frr-03 ifconfig
eth1 Link encap:Ethernet HWaddr 16:47:A2:B7:F5:4F
inet addr:12.12.0.3 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::1447:a2ff:feb7:f54f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:182 errors:0 dropped:0 overruns:0 frame:0
TX packets:38 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:15112 (14.7 KiB) TX bytes:2756 (2.6 KiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

3. FRR 组网

由于 Router 1 eth1 和 Router 3 eth1 属于不同网段,在组网前两者间无路由,ping 不通

1
2
3
4
5
6
7
8
root@ubuntu:~# docker exec -it frr-01 bash
568ade633bf9:/# ping 12.12.0.3
PING 12.12.0.3 (12.12.0.3): 56 data bytes
ping: sendto: Network unreachable
568ade633bf9:/# route -ne
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
11.11.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
1
2
3
4
5
6
7
8
root@ubuntu:~# docker exec -it frr-03 bash
6185c04f06d1:/# ping 11.11.0.2
PING 11.11.0.2 (11.11.0.2): 56 data bytes
ping: sendto: Network unreachable
6185c04f06d1:/# route -ne
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
12.12.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1

通过配置 FRR 使得两个网段学习到对方的路由,实现 OSPF 组网

FRR 开启 OSPF 进程

  1. 编辑 /etc/frr/daemons

    1
    ospfd=yes
  2. 重启 FRR 服务

1
/etc/init.d/frr restart

vtysh 配置 FRR OSPF

1
2
3
4
--- frr-01 ---
568ade633bf9# configure
568ade633bf9(config)# router ospf
568ade633bf9(config-router)# network 11.11.0.2/24 area 0
1
2
3
4
5
--- frr-02 ---
1681fd9bd374# configure
1681fd9bd374(config)# router ospf
1681fd9bd374(config-router)# network 11.11.0.3/24 area 0
1681fd9bd374(config-router)# network 12.12.0.2/24 area 0
1
2
3
4
--- frr-03 ---
6185c04f06d1# configure
6185c04f06d1(config)# router ospf
6185c04f06d1(config-router)# network 12.12.0.3/24 area 0

配置完毕后,frr-01 和 frr-03 的 OSPF 便能学习到对方的路由,互相能 ping 通

1
2
3
4
5
6
7
8
9
10
11
--- frr-01 ---
568ade633bf9# show ip ospf route
============ OSPF network routing table ============
N 11.11.0.0/24 [10] area: 0.0.0.0
directly attached to eth1
N 12.12.0.0/24 [20] area: 0.0.0.0
via 11.11.0.3, eth1

============ OSPF router routing table =============

============ OSPF external routing table ===========
1
2
3
4
5
6
7
8
9
10
11
--- frr-01 ---
568ade633bf9:/# ping 12.12.0.3
PING 12.12.0.3 (12.12.0.3): 56 data bytes
64 bytes from 12.12.0.3: seq=0 ttl=63 time=0.725 ms
64 bytes from 12.12.0.3: seq=1 ttl=63 time=0.225 ms
64 bytes from 12.12.0.3: seq=2 ttl=63 time=0.128 ms
64 bytes from 12.12.0.3: seq=3 ttl=63 time=0.205 ms
^C
--- 12.12.0.3 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.128/0.320/0.725 ms
1
2
3
4
5
6
7
8
9
10
11
--- frr-03 ---
6185c04f06d1# show ip ospf route
============ OSPF network routing table ============
N 11.11.0.0/24 [20] area: 0.0.0.0
via 12.12.0.2, eth1
N 12.12.0.0/24 [10] area: 0.0.0.0
directly attached to eth1

============ OSPF router routing table =============

============ OSPF external routing table ===========
1
2
3
4
5
6
7
8
9
10
11
--- frr-03 ---
6185c04f06d1:/# ping 11.11.0.2
PING 11.11.0.2 (11.11.0.2): 56 data bytes
64 bytes from 11.11.0.2: seq=0 ttl=63 time=1.871 ms
64 bytes from 11.11.0.2: seq=1 ttl=63 time=0.236 ms
64 bytes from 11.11.0.2: seq=2 ttl=63 time=0.161 ms
64 bytes from 11.11.0.2: seq=3 ttl=63 time=0.151 ms
^C
--- 11.11.0.2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.151/0.604/1.871 ms

DR 竞选

参考