見出し画像

containerlab + FRRoutingでMPLS L3VPN step1


概要

FRRoutingを使ってMPLSのL3VPNを作ってみる。

Topology

今回作る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網内の設定を行っていこうと思います。

いいなと思ったら応援しよう!