containerlab + FRRoutingでMPLS L3VPN step1
概要
FRRoutingを使ってMPLSのL3VPNを作ってみる。
Topology
topology.yml
name: mpls1
topology:
nodes:
cust1_ce1:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./cust1_ce1.log:/var/log/frr.log
- ./cust1_ce1.conf:/etc/frr/frr.conf
cust1_ce2:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./cust1_ce2.log:/var/log/frr.log
- ./cust1_ce2.conf:/etc/frr/frr.conf
cust2_ce1:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./cust2_ce1.log:/var/log/frr.log
- ./cust2_ce1.conf:/etc/frr/frr.conf
cust2_ce2:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./cust2_ce2.log:/var/log/frr.log
- ./cust2_ce2.conf:/etc/frr/frr.conf
pe1:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./pe1.log:/var/log/frr.log
- ./pe1.conf:/etc/frr/frr.conf
pe2:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./pe2.log:/var/log/frr.log
- ./pe2.conf:/etc/frr/frr.conf
pe3:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./pe3.log:/var/log/frr.log
- ./pe3.conf:/etc/frr/frr.conf
pe4:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./pe4.log:/var/log/frr.log
- ./pe4.conf:/etc/frr/frr.conf
p1:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./p1.log:/var/log/frr.log
- ./p1.conf:/etc/frr/frr.conf
p2:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./p2.log:/var/log/frr.log
- ./p2.conf:/etc/frr/frr.conf
p3:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./p3.log:/var/log/frr.log
- ./p3.conf:/etc/frr/frr.conf
p4:
kind: linux
image: quay.io/frrouting/frr
binds:
- ./daemons:/etc/frr/daemons
- ./p4.log:/var/log/frr.log
- ./p4.conf:/etc/frr/frr.conf
links:
- endpoints: ["cust1_ce1:eth1", "pe1:eth1"]
- endpoints: ["cust1_ce1:eth2", "pe2:eth1"]
- endpoints: ["cust2_ce1:eth1", "pe1:eth2"]
- endpoints: ["cust2_ce1:eth2", "pe2:eth2"]
- endpoints: ["pe1:eth3", "pe2:eth3"]
- endpoints: ["pe1:eth4", "p1:eth1"]
- endpoints: ["pe2:eth4", "p2:eth1"]
- endpoints: ["p1:eth2", "p2:eth2"]
- endpoints: ["p1:eth3", "p3:eth3"]
- endpoints: ["p2:eth3", "p4:eth3"]
- endpoints: ["cust1_ce2:eth1", "pe3:eth1"]
- endpoints: ["cust1_ce2:eth2", "pe4:eth1"]
- endpoints: ["cust2_ce2:eth1", "pe3:eth2"]
- endpoints: ["cust2_ce2:eth2", "pe4:eth2"]
- endpoints: ["pe3:eth3", "pe4:eth3"]
- endpoints: ["pe3:eth4", "p3:eth1"]
- endpoints: ["pe4:eth4", "p4:eth1"]
- endpoints: ["p3:eth2", "p4:eth2"]
母艦Linuxの準備
カーネルでMPLSを有効化
母艦Linuxでも準備が必用。
以下の通り準備する。
# こうなっていればOK
guest@vm-docker2:~/clab/mpls1$ lsmod | grep mpls
mpls_iptunnel 16384 0
mpls_gso 12288 0
mpls_router 45056 1 mpls_iptunnel
ip_tunnel 32768 1 mpls_router
guest@vm-docker2:~/clab/mpls1$
# なっていなければ以下を実行
modprobe mpls_router mpls_gso mpls_iptunnel
コンテナ側Linuxの準備
LinuxでMPLSを使う場合にはカーネルパラメータの調整が必要な場合がある。
今回使うdockerも調整が必用なので、パラメータの修正を行う。
MPLS以外のカーネルパラメータ設定変更
コンテナの中にshellモードで入り、以下設定を行う必要がある。
# Linuxをルータのようにパケット転送を有効化する
sysctl -w net.ipv4.ip_forward=1
# 受信パケットのリバース・パス・フィルタリングのソース検証を無効化する
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.lo.rp_filter=0
MPLS用のカーネルパラメータ設定変更
MPLS以外のカーネルパラメータと同様にshellモードで以下設定を行う必要がある。
# MPLSを有効化するインタフェースで
sysctl -w net.mpls.conf.lo.input=1
# 利用可能なラベル数を指定する
sysctl -w net.mpls.platform_labels=1048575
コマンドのスクリプト化
今回はMPLSを動作させるノードが8台あるので個別に実行するのは面倒。
ということで、以下シェルスクリプトを作ってdeploy後にMPLS設定をする準備を行う。
#!/bin/bash
lab=`ls | grep ^clab`
echo ${lab}
cat ./mpls.conf | while read l; do
host=`echo $l | awk -F"," '{print $1}'`
ifname=`echo $l | awk -F"," '{print $2}'`
sudo docker exec ${lab}-${host} bash -c 'sysctl -w net.mpls.conf.'${ifname}'.input=1'
done
cmds[0]="sysctl -w net.ipv4.ip_forward=1"
cmds[1]="systcl -w net.ipv4.conf.all.rp_filter=0"
cmds[2]="sysctl -w net.ipv4.conf.lo.rp_filter=0"
cmds[3]="sysctl -w net.mpls.conf.lo.input=1"
cmds[4]="sysctl -w net.mpls.platform_labels=1048575"
cat ./mpls.conf | awk -F"," '{print $1}' | sort | uniq | while read l; do
for cmd in "${cmds[@]}"; do
sudo docker exec ${lab}-${l} bash -c "${cmd}"
done
done
同じフォルダに"ノード名","インタフェース名"を書いたmpls.confを配置して上記スクリプトを実行すると必要な設定を投入してくれます。
所感
日ごろcontainerlab + FRRoutingでPoCを行う際の手順のようなものを書いてみました。
FRRoutingでMPLSを動かす場合はLinuxのカーネルパラメータの設定が必要と知らずに昔ハマったのでTipsとして残します。※SRv6でも事前にカーネルパラメータの設定が必用なので、いつか書きます。
次のステップではL3VPNを行うためにMPLS網内の設定を行っていこうと思います。