VyOSのconfigureの出自

VyOSのconfigureの出自

VyOSはDebianベースにFRRoutingを中心に構成されたネットワークOSとのことだけでインタフェース周りがDebianと違うので調べました。 ついでにisoイメージのビルドがどうなっているか確認し実際に 1.4,1.3 でビルドしてみました。 久しぶりにLinuxの中をコマンドラインで探索する感じを思い出しました。

ソフトウェア バージョン
VyOS 1.4-rolling-202203080319

コマンドラインインタフェース

FRRのコマンドラインインタフェースは vtysh が有名です。VyOSにも入っているのですがログインシェルは vbash というBashです。

1
2
vyos@vysite1:~$ grep vyos /etc/passwd
vyos:x\:1002:100::/home/vyos:/bin/vbash

vbashvyatta-bash パッケージに入っています。ちなみに vtyshfrr に含まれています。

1
2
3
4
vyos@vysite1:~$ dpkg -S /bin/vbash
vyatta-bash: /bin/vbash
vyos@vysite1:~$ dpkg -S /usr/bin/vtysh
frr: /usr/bin/vtysh

vbashの設定を追っかける

vbashはほぼbashです。 configurevyos/vyatta-bash内で検索してもめぼしいものは見つからない。そこで bash を起動して何をしているか調べました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
vyos@vysite1:~$ alias | grep config
alias config='_vyatta_op_run config'
alias configu='_vyatta_op_run configu'
alias configur='_vyatta_op_run configur'
alias configure='_vyatta_op_run configure'
vyos@vysite1:~$ declare -f _vyatta_op_run
_vyatta_op_run ()
{
    if [[ "$1" == "set" && "$2" =~ ^(-|\+).* ]]; then
        set "${@:2}";
        return;
    fi;
    local -i estat;

定義箇所はここ。/opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-runvyatta-op パッケージで定義している。

1
2
vyos@vysite1:~$ dpkg -l | grep -E 'vyatta|vyos|frr|zebra' | awk '{ print $2 }' | xargs -I{} dpkg -L {} |  xargs grep '_vyatta_op_run' |& grep -v pyc | grep -v modules | grep -v directory | grep '()'
/opt/vyatta/share/vyatta-op/functions/interpreter/vyatta-op-run:_vyatta_op_run ()

これがどのように読まれるか気になった。

1
2
3
4
5
6
vyos@vysite1:~$ dpkg -l | grep -E 'vyatta|vyos|frr|zebra' | awk '{ print $2 }' | xargs -I{} dpkg -L {} |  xargs grep 'interpreter' |& grep -v pyc | grep -v modules | grep -v directory  | grep -v '.py:' | grep -v '.c:'
...
grep: /bin/vbash: binary file matches
/etc/bash_completion.d/vyatta-cfg:op_functions=( /opt/vyatta/share/vyatta-op/functions/interpreter/* )
/etc/bash_completion.d/vyatta-cfg:cfg_functions=( /opt/vyatta/share/vyatta-cfg/functions/interpreter/* )
...

VyOSに man コマンドはないけどDebianで man bash すると、/etc/bash_completion.d/* はBashが動的に読み込むよー、みたいな事が書いてある。

1
2
3
4
_completion_loader()
{
    . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
}

ということで configure モードに入る部分は vbash 上の関数を使って _vyatta_op_run configure として呼ばれることが確認できました。 この関数の動きを確認します。 declare -f _vyatta_op_run で開いてみます。

 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
_vyatta_op_run ()
{
    # なんか初期化色々やって
    # ディレクトリパスを取得してる
    local tpath=$vyatta_op_templates;
    # 引数でループ開始 (中でtpathを育てている)
    declare -a args;
    for arg in "$@";
    do
        local orig_arg=$arg;
        # なんか _vyatta_op_conv_node_path を使ってファイル名解決してる
        #     状況によって arg 書き換えてる
        # 曖昧かとかバリデーション検査してる
        # 対応するファイルがあるか確認してる
        if [ -f "$tpath/$arg/node.def" ]; then
            tpath+=/$arg; # ここでtpathが伸びる
        else
            if [ -f $tpath/node.tag/node.def ]; then
                tpath+=/node.tag; # ここでtpathが伸びる
            else
                echo -ne "\n  Invalid command: ${args[@]} [$arg]\n\n" 1>&2;
                eval $restore_shopts;
                return 1;
            fi;
        fi;
        # 
        if [[ "$arg" == "node.tag" ]]; then
            args[$i]=$orig_arg;
        else
            args[$i]=$arg;
        fi;
        let "i+=1";
    done;
    # 作ったtpathからファイルを特定してファイル内の `run` という項目をコマンドとして取得
    local run_cmd=$(_vyatta_op_get_node_def_field $tpath/node.def run);
    run_cmd=$(_vyatta_op_conv_run_cmd "$run_cmd");
    # showの時はページャーかましつつ実行(`eval "$run_cmd"`してる
    local ret=0;
    local cmd_regex="^(LESSOPEN=|less|pager|tail|/opt/vyatta/bin/vyatta-tshark-interface-port.pl).*";
    if [ -n "$run_cmd" ]; then
        eval $restore_shopts;
        if [[ -t 1 && "${args[1]}" == "show" && ! $run_cmd =~ $cmd_regex ]]; then
            eval "($run_cmd) | ${VYATTA_PAGER:-cat}";
        else
            eval "$run_cmd";
        fi;
    fi;
    return $ret
}

渡している引数から呼び出すコマンドを特定して最後に eval "$run_cmd" で実行していました。 詳細はコメントで中に注釈をつけてます。$vyatta_op_templatesの中身は /opt/vyatta/share/vyatta-op/templates です。

ということで show ip route がどう変換されるか確認してみます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
vyos@vysite1:~$ find /opt/vyatta/share/vyatta-op/templates/ -name node.def | grep show/ip/route | head
/opt/vyatta/share/vyatta-op/templates/show/ip/route/bgp/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/cache/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/cache/node.tag/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/connected/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/forward/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/forward/node.tag/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/isis/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/kernel/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/node.def
/opt/vyatta/share/vyatta-op/templates/show/ip/route/node.tag/longer-prefixes/node.def

vyos@vysite1:~$ cat /opt/vyatta/share/vyatta-op/templates/show/ip/route/node.def
help: Show IP routes
run: vtysh -c "show ip route"

となり vtysh -c "show ip route" が呼ばれるようです。実際に叩くと下のようになりました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
vyos@vysite1:~$  vtysh -c "show ip route"
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

S>* 0.0.0.0/0 [210/0] via 10.0.2.2, eth0, weight 1, 1d05h21m
C>* 10.0.2.0/24 is directly connected, eth0, 1d05h21m

無事 vbash から vtysh に変換されました。

ビルドについて

続いて上記のパッケージがどのようにisoイメージに含まれるか調べました。

ビルドについては丁寧にここに書かれています。 リポジトリはvyos/vyos-buildです。 ドキュメントによると make iso がビルド本体なので動きを確認します。 lb build してます。@scripts/…script/ ディレクトリ配下を呼びますよという話です。 lb コマンドはlive-build(7)のようです。 その前の prepare が大事そうです。インストールされるパッケージが指定される箇所を探していきます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
prepare:
	@set -e
	@echo "Starting VyOS ISO image build"

	rm -rf build/config/*
	mkdir -p build/config
	cp -r data/live-build-config/* build/config/
	@scripts/live-build-config
	@scripts/import-local-packages

	@scripts/make-version-file

	@scripts/build-flavour

.PHONY: iso
.ONESHELL:
iso: check_build_config clean prepare
	@echo "It's not like I'm building this specially for you or anything!"
	cd $(build_dir)
	set -o pipefail
	lb build 2>&1 | tee build.log; if [ $$? -ne 0 ]; then exit 1; fi
	cd ..
	@scripts/copy-image
	exit 0

ref. https://github.com/vyos/vyos-build/blob/current/Makefile#L15-L38

prepare の中で live-build-config/package-list/vyos-base.list.chroot をコピーしています。 この中にvyos-worldというメタパッケージが含まれていて、これを経由してvyatta-bash などがインストール対象になります。 これらのパッケージを取得するレジストリはscripts/live-build-configの中で指定しています。

1
2
3
4
5
vyos_repo_entry = "deb {0} {1} main\n".format(build_config['vyos_mirror'], build_config['vyos_branch'])
apt_file = os.path.join(build_config['build_dir'], defaults.VYOS_REPO_FILE)
# ...
with open(apt_file, 'w') as f:
    f.write(vyos_repo_entry)

ref. デフォルトのミラーはhttp://dev.packages.vyos.net/repositories/currentでした。

ビルドしてみる

公式ドキュメントに従えば 1.2 を除いて何も苦労せずに終わります。 なので特に書くことはありません。 1.4では vrf はトップレベルだが 1.3.x では protocol 配下にあり確認しやすかったです。

他に入っている主要なパッケージなど

 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
vyos@vysite1:~$ dpkg -l | grep -E 'vyatta|vyos|frr'
ii  frr                              8.1-0                          amd64        FRRouting suite of internet protocols (BGP, OSPF, IS-IS, ...)
ii  frr-pythontools                  8.1-0                          all          FRRouting suite - Python tools
ii  frr-rpki-rtrlib                  8.1-0                          amd64        FRRouting suite - BGP RPKI support (rtrlib)
ii  frr-snmp                         8.1-0                          amd64        FRRouting suite - SNMP support
ii  libvyatta-cfg1                   0.102.0+vyos2+current4         amd64        vyatta-cfg back-end library
ii  libvyosconfig0                   0.0.10                         amd64        VyConf config tree manipulation library
ii  linux-image-5.10.103-amd64-vyos  5.10.103-1                     amd64        Linux kernel, version 5.10.103-amd64-vyos
ii  live-boot                        1:20151213-vyos0               all          Live System Boot Components
ii  live-boot-initramfs-tools        1:20151213-vyos0               all          Live System Boot Components (initramfs-tools backend)
ii  udp-broadcast-relay              0.1+vyos3+equuleus1            amd64        UDP Broadcast Packet Relay
ii  vyatta-bash                      4.1-3+vyos2+current2           amd64        The VyOS Shell based on GNU bash
ii  vyatta-biosdevname               1:0.3.11+vyos2+current2        amd64        VyOS version of the biosdevname utility.
ii  vyatta-cfg                       0.102.0+vyos2+current4         amd64        VyOS configuration system
ii  vyatta-cfg-qos                   0.15.42+vyos2+current1         all          VyOS Qos configuration templates/scripts
ii  vyatta-cfg-system                0.20.44+vyos2+current22        amd64        VyOS system-level configuration
ii  vyatta-cluster                   0.11.25+vyos2+current1         all          VyOS configuration/operational commands for clustering
ii  vyatta-config-mgmt               0.34+vyos2+current2            all          VyOS commands for config-mgmt
ii  vyatta-op                        0.14.0+vyos2+current8          all          VyOS operational commands and completion scripts
ii  vyatta-op-qos                    0.12.27+vyos2+current1         all          VyOS operational commands for QOS
ii  vyatta-wanloadbalance            0.13.70+vyos2+current1         amd64        VyOS load balancing configuration system
ii  vyos-1x                          1.4dev0-2319-gf8b7846b         amd64        VyOS configuration scripts and data
ii  vyos-1x-smoketest                1.4dev0-2319-gf8b7846b         all          VyOS build sanity checking toolkit
ii  vyos-1x-vmware                   1.4dev0-2319-gf8b7846b         amd64        VyOS configuration scripts and data for VMware
ii  vyos-http-api-tools              0.2.0-1.1                      amd64        api tools for VyOS
ii  vyos-intel-qat                   1.7.L.4.14.0-00031-0           amd64        Vendor based driver for Intel QAT
ii  vyos-linux-firmware              20210716                       all          Binary firmware for various drivers in the Linux kernel
ii  vyos-user-utils                  1.4.0+vyos1+current            all          VyOS user utilities metapackage
ii  vyos-utils                       0.0.3                          amd64        VyOS utils for value validation and other things
ii  vyos-world                       1.4.0+vyos1+current            all          VyOS metapackage
ii  vyos-xe-guest-utilities          7.13.0+vyos1.3                 amd64        daemon for monitoring Xen Virtual machines

寄り道ですが、カーネルモジュールは下で確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
vyos@vysite1:~$ sudo kmod list
Module                  Size  Used by
binfmt_misc            24576  1
vxlan                  73728  0
ip6_udp_tunnel         16384  1 vxlan
udp_tunnel             20480  1 vxlan
af_packet              53248  2
nf_nat_tftp            16384  0
nf_conntrack_tftp      20480  1 nf_nat_tftp
...
...
e1000                 155648  0

カーネルモジュールについての一次情報を探したいときは modinfo, dpkg -S が便利です。 まずカーネルモジュールのファイルを探します。それから情報とパッケージを調べます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
vyos@vysite1:~$ grep vxlan /lib/modules/5.10.103-amd64-vyos/modules.dep
kernel/drivers/net/vxlan.ko: kernel/net/ipv6/ip6_udp_tunnel.ko kernel/net/ipv4/udp_tunnel.ko

vyos@vysite1:~$ modinfo  /lib/modules/5.10.103-amd64-vyos/kernel/drivers/net/vxlan.ko
filename:       /lib/modules/5.10.103-amd64-vyos/kernel/drivers/net/vxlan.ko
alias:          rtnl-link-vxlan
description:    Driver for VXLAN encapsulated traffic
author:         Stephen Hemminger <stephen@networkplumber.org>
version:        0.1
license:        GPL
srcversion:     A772666323B3A673FA6A7F1
depends:        udp_tunnel,ip6_udp_tunnel
retpoline:      Y
intree:         Y
name:           vxlan
vermagic:       5.10.103-amd64-vyos SMP mod_unload modversions
parm:           udp_port:Destination UDP port (ushort)
parm:           log_ecn_error:Log packets received with corrupted ECN (bool)

vyos@vysite1:~$ dpkg -S /lib/modules/5.10.103-amd64-vyos/kernel/drivers/net/vxlan.ko
linux-image-5.10.103-amd64-vyos: /lib/modules/5.10.103-amd64-vyos/kernel/drivers/net/vxlan.ko
comments powered by Disqus