Full Code of tinynetwork/tinet for AI

master 345f8b20042d cached
326 files
931.5 KB
353.0k tokens
179 symbols
1 requests
Download .txt
Showing preview only (1,020K chars total). Download the full file or copy to clipboard to get everything.
Repository: tinynetwork/tinet
Branch: master
Commit: 345f8b20042d
Files: 326
Total size: 931.5 KB

Directory structure:
gitextract_qbgpc9og/

├── .github/
│   ├── CODEOWNERS
│   ├── auto_assign.yml
│   └── workflows/
│       ├── pr-auto-assign.yaml
│       ├── release-master.yaml
│       ├── release-tag.yaml
│       └── test.yaml
├── .gitignore
├── .goreleaser.yml
├── Dockerfiles/
│   ├── centos7/
│   │   ├── Dockerfile
│   │   └── build.sh
│   ├── cloudvpn/
│   │   ├── Dockerfile
│   │   └── build.sh
│   ├── ebpf/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── build_and_attach.sh
│   │   ├── detach.sh
│   │   └── filter.c
│   ├── frr/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── daemons
│   ├── nginx/
│   │   ├── Dockerfile
│   │   └── Makefile
│   ├── pmacctd/
│   │   ├── Dockerfile
│   │   └── Makefile
│   └── trex/
│       ├── Dockerfile
│       └── Makefile
├── LICENSE
├── Makefile
├── README.md
├── cheatsheet.md
├── command_func.go
├── commands.go
├── configs/
│   └── spec_template.yaml
├── docs/
│   ├── command-line-usage-example.md
│   └── specification_yml.md
├── examples/
│   ├── bandwidth_tc/
│   │   └── spec.yaml
│   ├── basic_bfd/
│   │   └── spec.yaml
│   ├── basic_bgp/
│   │   ├── README.md
│   │   ├── bgp_clos_evpn_vxlan/
│   │   │   └── spec.yaml
│   │   ├── graceful_restart/
│   │   │   └── simple_ipv4_unicast/
│   │   │       ├── README.md
│   │   │       ├── r2/
│   │   │       │   └── r2-kill-bgpd.pcap
│   │   │       └── spec.yaml
│   │   ├── hv_bgp_dcn/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── hv_bgp_dcn_isol/
│   │   │   ├── Makefile
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── local_pref/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── mpbgp_ipv4_labeled_unicast/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── path_attr/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── route_reflector/
│   │   │   └── spec.yaml
│   │   ├── route_server/
│   │   │   └── spec.yaml
│   │   ├── route_server_multihop/
│   │   │   └── spec.yaml
│   │   ├── spec.yaml
│   │   ├── unnumbered/
│   │   │   ├── r1.pcap
│   │   │   └── spec.yaml
│   │   ├── vpnv4_mpls/
│   │   │   ├── README.md
│   │   │   ├── r1.pcap
│   │   │   ├── r2.pcap
│   │   │   └── spec.yaml
│   │   ├── vpnv4_srmpls/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── vpnv4_srmpls_interas_option-b/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── vpnv4_srv6/
│   │   │   ├── Makefile
│   │   │   ├── README.md
│   │   │   ├── frr.conf.srv6.R1
│   │   │   ├── frr.conf.srv6.R2
│   │   │   └── spec.yaml
│   │   ├── vpnv6_srv6_rs/
│   │   │   └── spec.yaml
│   │   └── vrf2vrf_rouet_leak/
│   │       ├── Makefile
│   │       └── spec.yaml
│   ├── basic_bond/
│   │   └── spec.yaml
│   ├── basic_bufferbloat/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_clos/
│   │   ├── README.md
│   │   ├── spec.v0.0.0.yaml
│   │   ├── spec.v0.0.1.yaml
│   │   ├── spec.v0.0.2.yaml
│   │   ├── spec.v0.0.3.yaml
│   │   └── spec.yaml
│   ├── basic_conntrack/
│   │   └── connection_sync/
│   │       ├── Makefile
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_coredns/
│   │   └── blacklist/
│   │       ├── Corefile.NS1
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_ebgp/
│   │   └── spec.yaml
│   ├── basic_ecmp/
│   │   ├── README.md
│   │   ├── scale.diff
│   │   └── spec.yaml
│   ├── basic_evpn/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_exabgp/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── daemons.R1
│   │   ├── exabgp.conf
│   │   ├── exabgp.conf.R2
│   │   ├── frr.conf.R1
│   │   └── spec.yaml
│   ├── basic_fq_codel/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_gcp_hv/
│   │   └── spec.yaml
│   ├── basic_geneve/
│   │   ├── in.pcap
│   │   └── spec.yaml
│   ├── basic_gre/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_haproxy/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_ipip/
│   │   ├── anycast_tunnel/
│   │   │   └── spec.yaml
│   │   └── simple/
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_ipsec/
│   │   ├── bgp/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── bgp_ha/
│   │   │   ├── in.pcap
│   │   │   └── spec.yaml
│   │   ├── mesh/
│   │   │   └── spec.yaml
│   │   ├── mesh_bgp/
│   │   │   └── spec.yaml
│   │   ├── simple/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── static_esp_tunnel_simple/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── with_vti/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   └── xfrm_interface/
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_iptables/
│   │   ├── napt/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── test/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   └── u32/
│   │       └── spec.yaml
│   ├── basic_isis/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_l3dsr/
│   │   └── dscp/
│   │       ├── Dockerfile
│   │       ├── spec.yaml
│   │       └── xdp.c
│   ├── basic_ldp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_mirror/
│   │   ├── local/
│   │   │   └── spec.yaml
│   │   └── remote/
│   │       └── spec.yaml
│   ├── basic_mpls/
│   │   └── spec.yaml
│   ├── basic_multipath/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_namespace/
│   │   ├── README.md
│   │   ├── spec.blue.yaml
│   │   └── spec.green.yaml
│   ├── basic_napt/
│   │   └── spec.yaml
│   ├── basic_netflow/
│   │   ├── README.md
│   │   ├── multipath/
│   │   │   ├── Makefile
│   │   │   └── spec.yaml
│   │   ├── netflow.pcap
│   │   └── simple/
│   │       └── spec.yaml
│   ├── basic_netns/
│   │   └── spec.yaml
│   ├── basic_nftables/
│   │   ├── masquerade/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   └── snat/
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_ospfv2_bird/
│   │   ├── README.md
│   │   ├── bird/
│   │   │   ├── R1_bird.conf
│   │   │   ├── R2_bird.conf
│   │   │   ├── R3_bird.conf
│   │   │   └── R4_bird.conf
│   │   └── spec.yaml
│   ├── basic_ospfv2_frr/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_ospfv3_bird_multiple_instance/
│   │   ├── R3_bird6.conf
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_ospfv3_frr/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_pbr/
│   │   └── spec.yaml
│   ├── basic_peer/
│   │   └── spec.yaml
│   ├── basic_pim/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_pim2/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_pppoe_WIP/
│   │   └── spec.yaml
│   ├── basic_rift/
│   │   ├── README.md
│   │   ├── ietf_rift_python/
│   │   │   ├── meta_topology_2c_2x2.yaml
│   │   │   ├── rift_leaf1.yaml
│   │   │   ├── rift_leaf2.yaml
│   │   │   ├── rift_spine1.yaml
│   │   │   └── rift_spine2.yaml
│   │   └── spec.yaml
│   ├── basic_rtbh/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_source_routing/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_srmpls/
│   │   └── spec.yaml
│   ├── basic_srv6/
│   │   ├── README.md
│   │   ├── linux/
│   │   │   ├── bgp_vpnv6/
│   │   │   │   └── spec.yaml
│   │   │   ├── binding_sid/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── end_bpf_WIP/
│   │   │   │   ├── Makefile
│   │   │   │   ├── bpf_helpers.h
│   │   │   │   ├── filter.c
│   │   │   │   └── spec.yaml
│   │   │   ├── hands_on/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── l2vpn/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── sfc/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── srv6_unaware/
│   │   │   │   ├── README.md
│   │   │   │   ├── function/
│   │   │   │   │   ├── Makefile
│   │   │   │   │   └── main.cc
│   │   │   │   ├── function1/
│   │   │   │   │   ├── Makefile
│   │   │   │   │   ├── edenman_chikuwa.cc
│   │   │   │   │   ├── main.cc
│   │   │   │   │   └── ntt_ipa.cc
│   │   │   │   └── spec.yaml
│   │   │   ├── transit/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v4_per_ce/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v4_per_vrf/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v6_per_ce/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v6_per_vrf/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   └── vrf_redirect/
│   │   │       ├── README.md
│   │   │       └── spec.yaml
│   │   └── vpp/
│   │       └── vpn4_per_ce/
│   │           ├── README.md
│   │           └── spec.yaml
│   ├── basic_sysctl/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_tc/
│   │   └── spec.yaml
│   ├── basic_tproxy/
│   │   ├── dns_interceptor/
│   │   │   ├── Corefile
│   │   │   ├── Dockerfile.coredns
│   │   │   ├── Dockerfile.dns-interceptor
│   │   │   ├── README.md
│   │   │   ├── go.mod
│   │   │   ├── go.sum
│   │   │   ├── main.go
│   │   │   ├── session-udp.go
│   │   │   └── spec.yaml
│   │   └── http_interceptor/
│   │       ├── Dockerfile
│   │       ├── README.md
│   │       ├── go.mod
│   │       ├── go.sum
│   │       ├── http_interceptor.go
│   │       └── spec.yaml
│   ├── basic_vpnv4/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_vpp/
│   │   ├── README.md
│   │   ├── nat.yaml
│   │   └── spec.yaml
│   ├── basic_vrf/
│   │   ├── README.md
│   │   ├── frr.spec.yaml
│   │   └── iproute2.spec.yaml
│   ├── basic_vrf2/
│   │   └── spec.yaml
│   ├── basic_vrrp/
│   │   ├── conntrack/
│   │   │   ├── keepalived.conf.R1
│   │   │   ├── keepalived.conf.R2
│   │   │   └── spec.yaml
│   │   └── simple/
│   │       └── spec.yaml
│   ├── basic_vxlan/
│   │   ├── vxlan_mcast.yaml
│   │   └── vxlan_ucast.yaml
│   ├── basic_vxlan_mcast_v6/
│   │   └── spec.yaml
│   ├── basic_vxlan_v6/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_xdp/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── filter.c
│   │   └── spec.yaml
│   ├── bgp_test/
│   │   ├── dut.conf
│   │   └── spec.yaml
│   ├── bgp_test2/
│   │   └── spec.yaml
│   ├── bridge_tc/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── flowspec/
│   │   └── spec.yaml
│   ├── gobgp-grpc/
│   │   ├── README.md
│   │   ├── add_path01.py
│   │   ├── add_path02.py
│   │   ├── gobgp01.conf
│   │   ├── gobgp02.conf
│   │   └── spec.yaml
│   ├── ovs_port_vlan/
│   │   └── spec.yaml
│   ├── simple/
│   │   └── topo2/
│   │       └── spec.yaml
│   ├── srmpls_l2vpn_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srmpls_l3vpnv4_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srmpls_l3vpnv4_static_vpp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l2vpn_static_linux_hack/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l2vpn_static_vpp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv4_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv4_static_linux_pseudo_dt4/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv4_static_vpp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv6_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   └── trex/
│       ├── dual_node_single_instance/
│       │   ├── README.md
│       │   ├── client.yaml
│       │   ├── server.yaml
│       │   ├── spec.yaml
│       │   ├── tcp_open.py
│       │   └── tcp_openclose.py
│       ├── simple/
│       │   ├── README.md
│       │   ├── cfg.yaml
│       │   ├── new_connection_test.py
│       │   ├── spec.yaml
│       │   ├── tcp_open.py
│       │   └── tcp_openclose.py
│       └── single_node_dual_instance/
│           ├── README.md
│           ├── client.yaml
│           ├── server.yaml
│           ├── spec.yaml
│           ├── tcp_open.py
│           └── tcp_openclose.py
├── go.mod
├── go.sum
├── internal/
│   └── pkg/
│       ├── shell/
│       │   ├── shell.go
│       │   └── shell_test.go
│       └── utils/
│           ├── utils.go
│           └── utils_test.go
└── main.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/CODEOWNERS
================================================
* @ak1ra24 @slankdev


================================================
FILE: .github/auto_assign.yml
================================================
# Set to true to add reviewers to pull requests
addReviewers: true

# Set to true to add assignees to pull requests
addAssignees: false

# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
  - slankdev
  - ak1ra24

# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 1

# A list of assignees, overrides reviewers if set
# assignees:
#   - assigneeA

# A number of assignees to add to the pull request
# Set to 0 to add all of the assignees.
# Uses numberOfReviewers if unset.
# numberOfAssignees: 2

# A list of keywords to be skipped the process that add reviewers if pull requests include it
skipKeywords:
  - wip


================================================
FILE: .github/workflows/pr-auto-assign.yaml
================================================
name: 'Auto Assign'
on: pull_request

jobs:
  add-reviews:
    runs-on: ubuntu-latest
    steps:
      - uses: kentaro-m/auto-assign-action@v1.1.0
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"
          configuration-path: ".github/auto_assign.yml"


================================================
FILE: .github/workflows/release-master.yaml
================================================
name: release-master
on:
  push:
    branches:
      - master

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
    - name: Set up Go 1.13
      uses: actions/setup-go@v2
      with:
        go-version: 1.13
      id: go

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2

    - name: Build
      env:
        GO111MODULE: on
        GOPATH: /home/runner/work/
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        go get -u github.com/tcnksm/ghr
        go get -u github.com/Songmu/ghch/cmd/ghch
        export TAGNAME=latest
        go build -ldflags="-s -w -X main.Version=$TAGNAME"
        mkdir -p dist/latest
        tar -zcvf dist/latest/tinet_latest_linux64_amd64.tar.gz tinet
        $GOPATH/bin/ghr -n=$TAGNAME -b="$($GOPATH/bin/ghch -F markdown --latest)" -replace $TAGNAME ./dist/$TAGNAME


================================================
FILE: .github/workflows/release-tag.yaml
================================================
name: release tag
on:
  push:
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"
permissions:
  contents: write
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: stable
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v5
        with:
          distribution: goreleaser
          version: v1.23.0
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/test.yaml
================================================
name: test

on: 
  push:
    branches:
    - "**"
  pull_request: {}

jobs:
  lint:
    name: lint
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go-version: [1.12.x, 1.13.x, 1.14.x, 1.15.x, 1.16.x, 1.17.x]
    steps:
      - uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
      - name: checkout
        uses: actions/checkout@v3
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v3
        with:
            version: v1.45.2

  test:
    name: go test
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go-version: [1.12.x, 1.13.x, 1.14.x, 1.15.x, 1.16.x, 1.17.x]
    steps:
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          version: ${{ matrix.go-version }}
      - name: checkout
        uses: actions/checkout@v3
      - name: Run go tests
        env:
          GO111MODULE: on
        run: |
          go test ./... -v


================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
/tinet
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
*.swp
*~


================================================
FILE: .goreleaser.yml
================================================
version: 1
before:
  hooks:
    - go mod tidy
builds:
  - env:
      - CGO_ENABLED=0
    ldflags:
      - -s -w
      - -X main.Version={{.Version}}
    goos:
      - linux
    goarch:
      - amd64
      - arm64
archives:
  - format: binary
    name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
changelog:
  sort: asc
  use: github-native


================================================
FILE: Dockerfiles/centos7/Dockerfile
================================================
FROM centos:centos7

RUN yum -y install git autoconf automake libtool make \
  readline-devel texinfo net-snmp-devel groff pkgconfig \
  json-c-devel pam-devel bison flex pytest c-ares-devel \
  python-devel systemd-devel python-sphinx libcap-devel \
	sudo iproute traceroute iputils bash-completion tcpdump \
	wireshark gdb wget vim libunwind libunwind-devel \
	iptables-services


================================================
FILE: Dockerfiles/centos7/build.sh
================================================
#!/bin/sh -xe
IMG=tinet/centos:centos7
docker build -t $IMG .


================================================
FILE: Dockerfiles/cloudvpn/Dockerfile
================================================
FROM tinet/centos:centos7

RUN yum -y install https://rpm.frrouting.org/repo/frr-stable-repo-1-0.el7.noarch.rpm \
 && yum -y install frr-7.3.1-01.el7.x86_64 frr-pythontools \
 && yum -y install https://download.libreswan.org/binaries/rhel/7/x86_64/libreswan-3.32-1.el7.x86_64.rpm


================================================
FILE: Dockerfiles/cloudvpn/build.sh
================================================
#!/bin/sh -xe
IMG=tinet/cloudvpn
docker build -t $IMG .


================================================
FILE: Dockerfiles/ebpf/Dockerfile
================================================
FROM ubuntu:rolling

ARG LIBBPF_VERSION="0.8.0"
ARG IPROUTE2_VERSION="5.18.0"
ARG BPFTOOL_VERSION="6.8.0"

RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \
	vim curl git gcc make flex bison clang-12 libbsd-dev libbfd-dev libcap-dev \
  libelf-dev gcc-multilib pkg-config linux-tools-`uname -r`

RUN ln -s /usr/bin/clang-12 /usr/bin/clang

WORKDIR /opt

ADD https://github.com/libbpf/libbpf/archive/refs/tags/v${LIBBPF_VERSION}.tar.gz .
RUN tar xvf v${LIBBPF_VERSION}.tar.gz
RUN cd libbpf-${LIBBPF_VERSION}/src && make install BUILD_STATIC_ONLY=1 && make install_pkgconfig
RUN rm -rf libbpf-${LIBBPF_VERSION} v${LIBBPF_VERSION}.tar.gz

ADD https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/snapshot/iproute2-${IPROUTE2_VERSION}.tar.gz .
RUN tar xvf iproute2-${IPROUTE2_VERSION}.tar.gz
RUN cd iproute2-${IPROUTE2_VERSION} && ./configure --libbpf_force=on --libbpf_dir=/ && make install
RUN rm -rf iproute2-${IPROUTE2_VERSION} iproute2-${IPROUTE2_VERSION}.tar.gz

ADD filter.c .
ADD build_and_attach.sh .
ADD detach.sh .


================================================
FILE: Dockerfiles/ebpf/Makefile
================================================
IMG=tinynetwork/ebpf:develop
build:
	docker build -t $(IMG) .
push:
	docker push $(IMG)
all: build push
run:
	docker run --rm -it $(IMG) bash


================================================
FILE: Dockerfiles/ebpf/README.md
================================================
# Usage

```
docker build -t demo:latest .
docker run -it --rm --privileged demo:latest bash
./build_and_attach.sh
bpftool map dump name pkt_counter_egr
bpftool map dump name pkt_counter_ing
bpftool map event_pipe name pkt_counter_eve
# make some traffic on eth0
```


================================================
FILE: Dockerfiles/ebpf/build_and_attach.sh
================================================
#!/bin/bash -xe

clang -target bpf -O3 -g -c filter.c
tc qdisc del dev eth0 clsact || true
tc qdisc add dev eth0 clsact
tc filter add dev eth0 ingress bpf obj filter.o section tc-ingress
tc filter add dev eth0 egress bpf obj filter.o section tc-egress


================================================
FILE: Dockerfiles/ebpf/detach.sh
================================================
#!/bin/bash -xe
tc qdisc del dev eth0 clsact


================================================
FILE: Dockerfiles/ebpf/filter.c
================================================
#include <linux/bpf.h>
#include <linux/pkt_cls.h>
#include <bpf/bpf_helpers.h>

struct {
  __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
  __uint(max_entries, 1);
  __type(key, int);
  __type(value, int);
} pkt_counter_ingress SEC(".maps");

struct {
  __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
  __uint(max_entries, 1);
  __type(key, int);
  __type(value, int);
} pkt_counter_egress SEC(".maps");

struct {
  __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
  __uint(key_size, sizeof(int));
  __uint(value_size, sizeof(int));
} pkt_counter_events SEC(".maps");

static __inline int
count_packets(struct __sk_buff *skb, void *map)
{
  int key = 0;
  int *val = bpf_map_lookup_elem(map, &key);
  if (val == NULL) {
    return TC_ACT_SHOT;
  }
  *val = *val + 1;

  int msg = 0xefbeadde;
  bpf_perf_event_output(skb, &pkt_counter_events, BPF_F_CURRENT_CPU, &msg, sizeof(msg));

  return TC_ACT_OK;
}

SEC("tc-ingress") int
count_packets_ingress(struct __sk_buff *skb)
{
  return count_packets(skb, &pkt_counter_ingress);
}

SEC("tc-egress") int
count_packets_egress(struct __sk_buff *skb)
{
  return count_packets(skb, &pkt_counter_egress);
}

char __license[] SEC("license") = "GPL";


================================================
FILE: Dockerfiles/frr/Dockerfile
================================================
FROM frr-ubuntu20:latest
USER root
RUN mkdir -p /etc/frr
COPY daemons /etc/frr/daemons
RUN apt install -y vim tcpdump


================================================
FILE: Dockerfiles/frr/Makefile
================================================
IMG=tinynetwork/frr:develop
build:
	docker build -t $(IMG) .
push:
	docker push $(IMG)
all: build push
run:
	docker run --rm -it --privileged $(IMG) bash


================================================
FILE: Dockerfiles/frr/daemons
================================================
zebra=yes
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=yes
pbrd=no
bfdd=no


================================================
FILE: Dockerfiles/nginx/Dockerfile
================================================
FROM nginx
RUN apt -y update -y && apt -y install iproute2
RUN apt update -y && apt install -y tcpdump netcat iperf3 watch file xxd psutils vim
ENTRYPOINT bash


================================================
FILE: Dockerfiles/nginx/Makefile
================================================
IMG=tinynetwork/nginx:develop
build:
	docker build -t $(IMG) .
push:
	docker push $(IMG)
all: build push
run:
	docker run --rm -it $(IMG) bash


================================================
FILE: Dockerfiles/pmacctd/Dockerfile
================================================
FROM peterevans/vegeta as vegeta
FROM pmacct/pmacctd:v1.7.6
RUN apt update -y && apt install -y tcpdump netcat iperf3 watch file xxd psutils vim
RUN apt install -y nfdump jq
RUN apt install -y curl
COPY --from=vegeta /bin/vegeta /bin/vegeta
ENTRYPOINT bash


================================================
FILE: Dockerfiles/pmacctd/Makefile
================================================
IMG=tinynetwork/pmacctd:develop
build:
	docker build -t $(IMG) .
push:
	docker push $(IMG)
all: build push
run:
	docker run --rm -it $(IMG) bash


================================================
FILE: Dockerfiles/trex/Dockerfile
================================================
FROM quay.io/centos/centos:stream8
ARG TREX_VERSION=3.04
ENV TREX_VERSION ${TREX_VERSION}

RUN dnf install -y --nodocs \
    git wget procps python3 vim python3-pip pciutils gettext \
    https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \
 && dnf clean all \
 && dnf install -y --nodocs \
    hostname iproute net-tools ethtool nmap iputils perf numactl \
    sysstat htop rdma-core-devel libibverbs libibverbs-devel net-tools \
 && dnf clean all

WORKDIR /opt/
RUN wget --no-check-certificate https://trex-tgn.cisco.com/trex/release/v${TREX_VERSION}.tar.gz && \
   tar -xzf v${TREX_VERSION}.tar.gz && \
   mv v${TREX_VERSION} trex && \
   rm v${TREX_VERSION}.tar.gz
WORKDIR /opt/trex


================================================
FILE: Dockerfiles/trex/Makefile
================================================
IMG=tinynetwork/trex:develop
build:
	docker build -t $(IMG) .
push:
	docker push $(IMG)
all: build push


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [2020] [ak1ra24]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Makefile
================================================
VERSION = $$(gobump show -r cmd)

export GO111MODULE=on

.PHONY: deps
deps:
	go get -u -d
	go mod tidy

.PHONY: devel-deps
devel-deps:
	go get -v \
	github.com/x-motemen/gobump/cmd/gobump \
	github.com/Songmu/ghch/cmd/ghch \
	github.com/Songmu/goxz/cmd/goxz \
	github.com/tcnksm/ghr \
	github.com/golangci/golangci-lint/cmd/golangci-lint

.PHONY: test
test:
	go test -v ./...

.PHONY: lint
lint: devel-deps
	golangci-lint run

.PHONY: build
build: deps
	go build -o tn

.PHONY: install
install: deps
	go install 

.PHONY: release
release: devel-deps
	echo ghr -n=v$(VERSION) -b="$($GOPATH/bin/ghch -F markdown --latest)" -draft v$(VERSION) ./dist/v$(VERSION)

.PHONY: crossbuild
crossbuild: devel-deps
	goxz -pv=$(VERSION) -os=linux -arch=amd64 -d=./dist/v$(VERSION)


================================================
FILE: README.md
================================================
# tinet

![test](https://github.com/tinynetwork/tinet/workflows/test/badge.svg) ![release](https://github.com/tinynetwork/tinet/workflows/release/badge.svg) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) [![Go Report Card](https://goreportcard.com/badge/github.com/tinynetwork/tinet)](https://goreportcard.com/report/github.com/tinynetwork/tinet)

An instant virtual network on your laptop with
light-weight virtualization. Here we introduce the
Container Network Simulation tools. Users can generate,
from the YAML configuration file, the script to build
the L2 container network. Quickstart guide is provided
in QUICKSTART.md. It is tested on Ubuntu 16.04 LTS and
later.

## Requirements
- Docker
- OpenvSwitch (optional)
- graphviz (optional)

## Quick Install

There is only linux_amd64 pre-built binary
```
curl -Lo /usr/bin/tinet https://github.com/tinynetwork/tinet/releases/download/v0.0.3/tinet.linux_amd64
chmod +x /usr/bin/tinet
tinet --version
```

for ubuntu user
```
sudo apt update
sudo apt install -y linux-image-extra-virtual
sudo reboot
```

upgrading the kernel
```
$ sudo apt list "linux-image-5.15.*-generic"
linux-image-5.15.0-33-generic/focal-updates,focal-security 5.15.0-33.34~20.04.1 amd64
$ sudo apt install linux-image-5.15.0-33-generic linux-modules-5.15.0-33-generic linux-modules-extra-5.15.0-33-generic
$ sudo reboot
```
```
$ sudo grep 'menuentry ' $(sudo find /boot -name "grub.cfg") | cut -f 2 -d "'" | nl -v 0
     0  Ubuntu
     1  Ubuntu, with Linux 5.15.0-33-generic
     2  Ubuntu, with Linux 5.15.0-33-generic (recovery mode)
     3  Ubuntu, with Linux 5.4.0-113-generic
     4  Ubuntu, with Linux 5.4.0-113-generic (recovery mode)
$ sudo grub-set-default 3
$ sudo reboot
```

## Build
```
git clone https://github.com/tinynetwork/tinet tinet && cd $_
docker run --rm -i -t -v $PWD:/v -w /v golang:1.12 go build
mv tinet /usr/local/bin
```

## Usage

```
tinet up -c spec.yaml | sudo sh -x
tinet conf -c spec.yaml | sudo sh -x
tinet test -c spec.yaml | sudo sh -x
tinet down -c spec.yaml | sudo sh -x
docker run -it --rm --privileged --net=container:R1 nicolaka/netshoot bash
```

## Command Options

```
# tinet
NAME:
   tinet - tinet: Tiny Network

USAGE:
   tinet [global options] command [command options] [arguments...]

VERSION:
   0.0.1 (rev:)

AUTHOR:
   ak1ra24 <marug4580@gmail.com>

COMMANDS:
   check    check config
   conf     configure Node from tinet config file
   down     Down Node from tinet config file
   exec     Execute Command on Node from tinet config file.
   img      visualize network topology by graphviz from tinet config file
   init     Generate tinet config template file
   ps       docker and netns process
   pull     Pull Node docker image from tinet config file
   reconf   Stop, remove, create, start and config
   reup     Stop, remove, create, start
   test     Execute test commands from tinet config file.
   up       create Node from tinet config file
   upconf   Create, start and config
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help (default: false)
   --version, -v  print the version (default: false)
```

## Contribute

Simply fork and create a pull-request. We'll try to respond in a timely fashion.

## Links

- [Command Line Usage Example](docs/command-line-usage-example.md)
- [YAML Format](docs/specification_yml.md)


================================================
FILE: cheatsheet.md
================================================
# Cheatsheet
## Linux Networking

```
# ip route add 10.0.0.0/24 encap seg6 mode encap segs a::,b::,c::,d:: via 2001:db8::1
# ip route add 10.0.0.0/24 encap seg6 mode l2encap segs a::,b::,c::,d:: via 2001:db8::1
# ip route add 10.0.0.0/24 encap seg6 mode inline segs a::,b::,c::,d:: via 2001:db8::1

# ip -6 route add fc00::1/128 encap seg6local \
    action End                    via 2001:db8::1
    action End.X   nh6 fc00::1:1  via 2001:db8::1
    action End.T   table 100      via 2001:db8::1
    action End.DX2 oif lxcbr0     via 2001:db8::1
    action End.DX4 nh4 10.0.3.254 via 2001:db8::1
    action End.DT4 vrftable 100   via 2001:db8::1
    action End.DX6 nh6 fc00::1:1  via 2001:db8::1
    action End.DT6 table 100      via 2001:db8::1
```

## VPP Networking
```
vpp> sr policy add bsid cafe::10 next fc00:2::10 fib-table 0
vpp> sr steer l3 192.168.1.0/24 via bsid cafe::10 fib-table 10
vpp> sr steer l2 host-net2 via bsid cafe::10

vpp> set sr encaps source addr fc00:1::
vpp> sr localsid address fc00:1::   behavior end
vpp> sr localsid address fc00:1::10 behavior end.dt4 10
vpp> sr localsid address fc00:1::10 behavior end.dx2 host-net2
```


================================================
FILE: command_func.go
================================================
package main

import (
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/emicklei/dot"
	"github.com/spf13/viper"
	"github.com/tinynetwork/tinet/internal/pkg/shell"
	"github.com/tinynetwork/tinet/internal/pkg/utils"
	"github.com/urfave/cli/v2"
)

type linkstatus struct {
	leftNodeName  string
	leftInfName   string
	leftIsSet     bool
	leftNodeType  string
	rightNodeName string
	rightInfName  string
	rightIsSet    bool
	rightNodeType string
}

func LoadCfg(c *cli.Context) (tnconfig shell.Tn, verbose bool, err error) {
	cfgFile := c.String("config")
	verbose = c.Bool("verbose")
	if cfgFile != "" {
		viper.SetConfigFile(cfgFile)
		viper.SetConfigType("yaml")

		if err = viper.ReadInConfig(); err != nil {
			return tnconfig, verbose, err
		}

		if err = viper.Unmarshal(&tnconfig); err != nil {
			return tnconfig, verbose, err
		}
	} else {
		err = fmt.Errorf("not set config file.")
		return tnconfig, verbose, err
	}

	return tnconfig, verbose, nil

}

func CmdBuild(c *cli.Context) error {

	tnconfig, _, err := LoadCfg(c)
	if err != nil {
		return err
	}
	nodes := tnconfig.Nodes

	for _, node := range nodes {
		buildCmd := node.BuildCmd()
		fmt.Fprint(os.Stdout, buildCmd)
	}

	return nil
}

func CmdCheck(c *cli.Context) error {

	tnconfig, _, err := LoadCfg(c)
	if err != nil {
		return err
	}

	nodes := tnconfig.Nodes
	bridges := tnconfig.Switches
	confmap := map[string]string{}

	for _, node := range nodes {
		for _, inf := range node.Interfaces {
			if inf.Type == "direct" {
				host := node.Name + ":" + inf.Name
				peer := strings.Split(inf.Args, "#")
				target := peer[0] + ":" + peer[1]
				confmap[host] = target
			} else if inf.Type == "bridge" {
				host := node.Name + ":" + inf.Name
				target := inf.Args + ":" + node.Name
				confmap[host] = target
			}
		}
	}

	for _, bridge := range bridges {
		for _, inf := range bridge.Interfaces {
			host := bridge.Name + ":" + inf.Args
			target := inf.Args + ":" + inf.Name
			confmap[host] = target
		}
	}

	var matchNum int
	falseConfigMap := map[string]string{}

	for key, value := range confmap {
		if confmap[key] == value && confmap[value] == key {
			matchNum++
		} else {
			falseConfigMap[key] = value
		}
	}

	if len(confmap) == matchNum {
		return nil
	} else {
		var errMsg string
		for key, value := range falseConfigMap {
			errMsg += fmt.Sprintf("%s<->%s\n", key, value)
		}
		return fmt.Errorf(errMsg)
	}
}

func CmdUp(c *cli.Context) error {

	tnconfig, verbose, err := LoadCfg(c)
	if err != nil {
		return err
	}

	if len(tnconfig.PreCmd) != 0 {
		for _, preCmds := range tnconfig.PreCmd {
			preExecCmds := shell.ExecCmd(preCmds.Cmds)
			utils.PrintCmds(os.Stdout, preExecCmds, verbose)
		}
	}
	if len(tnconfig.PreInit) != 0 {
		for _, preInitCmds := range tnconfig.PreInit {
			preExecInitCmds := shell.ExecCmd(preInitCmds.Cmds)
			utils.PrintCmds(os.Stdout, preExecInitCmds, verbose)
		}
	}
	for _, node := range tnconfig.Nodes {
		createNodeCmds := node.CreateNode()
		utils.PrintCmds(os.Stdout, createNodeCmds, verbose)

		if node.Type != "netns" {
			mountDockerNetnsCmds := node.Mount_docker_netns()
			utils.PrintCmds(os.Stdout, mountDockerNetnsCmds, verbose)
		}
	}

	if len(tnconfig.Switches) != 0 {
		for _, bridge := range tnconfig.Switches {
			createSwitchCmds := bridge.CreateSwitch()
			utils.PrintCmds(os.Stdout, createSwitchCmds, verbose)
		}
	}

	var links []linkstatus

	for _, node := range tnconfig.Nodes {
		for _, inf := range node.Interfaces {
			if inf.Type == "direct" {
				rNodeArgs := strings.Split(inf.Args, "#")
				rNodeName := rNodeArgs[0]
				rInfName := rNodeArgs[1]
				peerFound := false
				for _, link := range links {
					if !link.rightIsSet {
						nodecheck := link.leftNodeName == rNodeName
						infcheck := link.leftInfName == rInfName
						if nodecheck && infcheck {
							link.rightNodeName = node.Name
							link.rightInfName = inf.Name
							link.rightNodeType = node.Type
							link.rightIsSet = true
							peerFound = true
						}
					}
				}
				if !peerFound {
					link := linkstatus{leftNodeName: node.Name, leftInfName: inf.Name, rightNodeName: rNodeName, rightInfName: rInfName}
					link.leftNodeType = node.Type
					link.leftIsSet = true
					links = append(links, link)
					n2nLinkCmds := inf.N2nLink(node.Name)
					utils.PrintCmds(os.Stdout, n2nLinkCmds, verbose)
				}
				if len(inf.Addr) != 0 {
					addrSetCmd := inf.AddrSet(node.Name)
					utils.PrintCmd(os.Stdout, addrSetCmd, verbose)
				}
			} else if inf.Type == "bridge" {
				s2nLinkCmds := inf.S2nLink(node.Name)
				utils.PrintCmds(os.Stdout, s2nLinkCmds, verbose)
			} else if inf.Type == "veth" {
				v2cLinkCmds := inf.V2cLink(node.Name)
				utils.PrintCmds(os.Stdout, v2cLinkCmds, verbose)
			} else if inf.Type == "phys" {
				p2cLinkCmds := inf.P2cLink(node.Name)
				utils.PrintCmds(os.Stdout, p2cLinkCmds, verbose)
			} else {
				err := fmt.Errorf("not supported interface type: %s", inf.Type)
				log.Fatal(err)
			}
		}
	}

	// check
	err = CmdCheck(c)
	if err != nil {
		return err
	}

	for _, node := range tnconfig.Nodes {
		if node.Type == "docker" || node.Type == "" {
			delNsCmd := node.DelNsCmd()
			utils.PrintCmd(os.Stdout, delNsCmd, verbose)
			mountTmplCmd, err := node.MountTmpl()
			utils.PrintCmds(os.Stdout, mountTmplCmd, verbose)
			if err != nil {
				return err
			}
		}
	}

	if len(tnconfig.PostInit) != 0 {
		for _, postInitCmds := range tnconfig.PostInit {
			postExecInitCmds := shell.ExecCmd(postInitCmds.Cmds)
			utils.PrintCmds(os.Stdout, postExecInitCmds, verbose)
		}
	}

	return nil
}

func CmdConf(c *cli.Context) error {
	tnconfig, verbose, err := LoadCfg(c)
	if err != nil {
		return err
	}

	nodeinfo := map[string]string{}
	for _, node := range tnconfig.Nodes {
		nodeinfo[node.Name] = node.Type
	}

	if len(tnconfig.PreConf) != 0 {
		for _, preConf := range tnconfig.PreConf {
			preConfCmds := shell.ExecCmd(preConf.Cmds)
			utils.PrintCmds(os.Stdout, preConfCmds, verbose)
		}
	}

	for _, nodeConfig := range tnconfig.NodeConfigs {
		execConfCmds := nodeConfig.ExecConf(nodeinfo[nodeConfig.Name])
		for _, execConfCmd := range execConfCmds {
			utils.PrintCmd(os.Stdout, execConfCmd, verbose)
		}
	}

	return nil
}

func CmdUpConf(c *cli.Context) error {
	// create and start
	if err := CmdUp(c); err != nil {
		return err
	}

	// config
	if err := CmdConf(c); err != nil {
		return err
	}

	return nil
}

func CmdDown(c *cli.Context) error {

	tnconfig, verbose, err := LoadCfg(c)
	if err != nil {
		return err
	}

	for _, node := range tnconfig.Nodes {
		deleteNode := node.DeleteNode()
		utils.PrintCmds(os.Stdout, deleteNode, verbose)
	}
	for _, br := range tnconfig.Switches {
		delBrCmd := br.DeleteSwitch()
		utils.PrintCmd(os.Stdout, delBrCmd, verbose)
	}

	if len(tnconfig.PostFini) != 0 {
		for _, postFiniCmds := range tnconfig.PostFini {
			postExecFiniCmds := shell.ExecCmd(postFiniCmds.Cmds)
			utils.PrintCmds(os.Stdout, postExecFiniCmds, verbose)
		}
	}

	return nil
}

func CmdExec(c *cli.Context) error {

	tnconfig, verbose, err := LoadCfg(c)
	if err != nil {
		return err
	}

	execCmdArgs := c.Args().Slice()
	execCommand := tnconfig.Exec(execCmdArgs[0], execCmdArgs[1:])
	utils.PrintCmd(os.Stdout, execCommand, verbose)

	return nil

}

func CmdImg(c *cli.Context) error {
	format := c.String("format")
	tnconfig, _, err := LoadCfg(c)
	if err != nil {
		return err
	}

	g := dot.NewGraph(dot.Directed)
	for _, tnnode := range tnconfig.Nodes {
		nodeName := tnnode.Name
		fromNode := g.Node(nodeName)
		fromNode.Label(nodeName)
		ifaceInfos := tnnode.Interfaces
		for _, ifaceInfo := range ifaceInfos {
			var argsName string
			if ifaceInfo.Type == "direct" {
				argsName = strings.Split(ifaceInfo.Args, "#")[0]
				toNode := g.Node(argsName)
				findEdges := g.FindEdges(toNode, fromNode)
				if len(findEdges) == 0 {
					newEdge := g.Edge(fromNode, toNode)
					newEdge.Attr("arrowhead", "none")
					newEdge.Attr("labelfloat", "true")
					taillabel := ""
					if ifaceInfo.Label != "" {
						taillabel = fmt.Sprintf("%s(%s)", ifaceInfo.Name, ifaceInfo.Label)
					} else {
						taillabel = ifaceInfo.Name
					}
					newEdge.Attr("headlabel", strings.Split(ifaceInfo.Args, "#")[1])
					newEdge.Attr("taillabel", taillabel)
					newEdge.Attr("fontsize", "8")
				} else {
					edge := findEdges[0]
					if ifaceInfo.Label != "" {
						headlabel := fmt.Sprintf("%s(%s)", edge.GetAttr("headlabel"), ifaceInfo.Label)
						edge.Attr("headlabel", headlabel)
					}
				}
			} else if ifaceInfo.Type == "bridge" {
				argsName = ifaceInfo.Args
				toNode := g.Node(argsName)
				findEdges := g.FindEdges(toNode, fromNode)
				if len(findEdges) == 0 {
					newEdge := g.Edge(fromNode, toNode)
					newEdge.Attr("arrowhead", "none")
					newEdge.Attr("labelfloat", "true")
					newEdge.Attr("headlabel", argsName)
					taillabel := ""
					if ifaceInfo.Label != "" {
						taillabel = fmt.Sprintf("%s(%s)", ifaceInfo.Name, ifaceInfo.Label)
					} else {
						taillabel = ifaceInfo.Name
					}
					newEdge.Attr("taillabel", taillabel)
					newEdge.Attr("fontsize", "8")
				} else {
					edge := findEdges[0]
					if ifaceInfo.Label != "" {
						headlabel := fmt.Sprintf("%s(%s)", edge.GetAttr("headlabel"), ifaceInfo.Label)
						edge.Attr("headlabel", headlabel)
					}
				}
			}
		}
	}

	if format == "mermaid" {
		fmt.Println(dot.MermaidGraph(g, dot.MermaidTopToBottom))
	} else {
		fmt.Fprintln(os.Stdout, g.String())
	}

	return nil
}

func CmdInit(c *cli.Context) error {
	tnConf, err := shell.GenerateFile()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Fprintln(os.Stdout, tnConf)

	return nil

}

func CmdPs(c *cli.Context) error {

	all := c.Bool("all")
	fmt.Println("echo '---------------------------------------------------------------------------------'")
	fmt.Println("echo '                            Docker Status                                        '")
	fmt.Println("echo '---------------------------------------------------------------------------------'")
	dockerPsCmd := shell.DockerPs(all)
	fmt.Println(dockerPsCmd)
	fmt.Println("echo '---------------------------------------------------------------------------------'")
	fmt.Println("echo '                            IP NETNS LIST                                        '")
	fmt.Println("echo '---------------------------------------------------------------------------------'")
	netnsPsCmd := shell.NetnsPs()
	fmt.Println(netnsPsCmd)

	return nil
}

func CmdPull(c *cli.Context) error {
	tnconfig, verbose, err := LoadCfg(c)
	if err != nil {
		return err
	}
	pullCmds := shell.Pull(tnconfig.Nodes)

	utils.PrintCmds(os.Stdout, pullCmds, verbose)

	return nil
}

func CmdReConf(c *cli.Context) error {
	// stop, remove
	if err := CmdDown(c); err != nil {
		return err
	}

	// create and start
	if err := CmdUp(c); err != nil {
		return err
	}

	// config
	if err := CmdConf(c); err != nil {
		return err
	}

	return nil
}

func CmdReUp(c *cli.Context) error {
	// stop, remove
	if err := CmdDown(c); err != nil {
		return err
	}

	// create and start
	if err := CmdUp(c); err != nil {
		return err
	}

	return nil
}

func CmdTest(c *cli.Context) error {
	tnconfig, _, err := LoadCfg(c)
	if err != nil {
		return err
	}

	testName := c.Args().Get(0)

	var tnTestCmds []string

	if testName == "all" || testName == "" {
		for _, test := range tnconfig.Test {
			tnTestCmds = test.TnTestCmdExec()
		}
	} else {
		for _, test := range tnconfig.Test {
			if testName == test.Name {
				tnTestCmds = test.TnTestCmdExec()
			}
		}
	}

	if len(tnTestCmds) == 0 {
		return fmt.Errorf("not found test name\n")
	}

	fmt.Fprintln(os.Stdout, strings.Join(tnTestCmds, "\n"))

	return nil
}


================================================
FILE: commands.go
================================================
package main

import "github.com/urfave/cli/v2"

var commands = []*cli.Command{
	commandBuild,
	commandCheck,
	commandConf,
	commandDown,
	commandExec,
	commandImg,
	commandInit,
	commandPs,
	commandPull,
	commandReConf,
	commandReUp,
	commandTest,
	commandUp,
	commandUpConf,
}

var commandBuild = &cli.Command{
	Name:   "build",
	Usage:  "Build docker Image from tinet config file",
	Action: CmdBuild,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandUp = &cli.Command{
	Name:   "up",
	Usage:  "create Node from tinet config file",
	Action: CmdUp,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandConf = &cli.Command{
	Name:   "conf",
	Usage:  "configure Node from tinet config file",
	Action: CmdConf,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandUpConf = &cli.Command{
	Name:   "upconf",
	Usage:  "Create, start and config",
	Action: CmdUpConf,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandDown = &cli.Command{
	Name:   "down",
	Usage:  "Down Node from tinet config file",
	Action: CmdDown,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandExec = &cli.Command{
	Name:   "exec",
	Usage:  "Execute Command on Node from tinet config file.",
	Action: CmdExec,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandImg = &cli.Command{
	Name:   "img",
	Usage:  "visualize network topology by graphviz from tinet config file",
	Action: CmdImg,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.StringFlag{
			Name:    "format",
			Aliases: []string{"f"},
			Usage:   "Image output format",
			Value:   "graphviz",
		},
	},
}

var commandInit = &cli.Command{
	Name:   "init",
	Usage:  "Generate tinet config template file",
	Action: CmdInit,
}

var commandPs = &cli.Command{
	Name:   "ps",
	Usage:  "docker and netns process",
	Action: CmdPs,
	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "all",
			Aliases: []string{"a"},
			Usage:   "all docker and netns",
		},
	},
}

var commandPull = &cli.Command{
	Name:   "pull",
	Usage:  "Pull Node docker image from tinet config file",
	Action: CmdPull,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
	},
}

var commandReConf = &cli.Command{
	Name:   "reconf",
	Usage:  "Stop, remove, create, start and config",
	Action: CmdReConf,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandReUp = &cli.Command{
	Name:   "reup",
	Usage:  "Stop, remove, create, start",
	Action: CmdReUp,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
		&cli.BoolFlag{
			Name:    "verbose",
			Aliases: []string{"v"},
			Usage:   "Verbose",
		},
	},
}

var commandTest = &cli.Command{
	Name:   "test",
	Usage:  "Execute test commands from tinet config file.",
	Action: CmdTest,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
	},
}

var commandCheck = &cli.Command{
	Name:   "check",
	Usage:  "check config",
	Action: CmdCheck,
	Flags: []cli.Flag{
		&cli.StringFlag{
			Name:    "config",
			Aliases: []string{"c"},
			Usage:   "Specify the Config file.",
			Value:   "spec.yaml",
		},
	},
}


================================================
FILE: configs/spec_template.yaml
================================================
precmd:
- cmds:
  - cmd: ""
preinit:
- cmds:
  - cmd: ""
preconf:
- cmds:
  - cmd: ""
postinit:
- cmds:
  - cmd: ""
postfini:
- cmds:
  - cmd: ""
nodes:
- name: ""
  type: ""
  net_base: ""
  image: ""
  interfaces:
  - name: ""
    type: ""
    args: ""
    addr: ""
    label: ""
  sysctls: []
switches:
- name: ""
  interfaces:
  - name: ""
    type: ""
    args: ""
    addr: ""
node_configs:
- name: ""
  cmds:
  - cmd: ""
test:
- name: ""
  cmds:
  - cmd: ""


================================================
FILE: docs/command-line-usage-example.md
================================================
# Command Line Usage Example

## tn build
That hasn't been implemented yet.

## tn check
```
## Check link node to node
tn check -c spec.yaml
```

## tn conf
```
tn conf -c spec.yaml

## docker and netns exec config
tn conf -c spec.yaml | sudo sh -x
```

## tn down
```
tn down -c spec.yaml

## Remove docker container and netns
tn conf -c spec.yaml | sudo sh -x
```

## tn exec
That hasn't been implemented yet.

## tn help
```
tn help
tn -h
```

## tn img
```
## Output dot
tn img -c spec.yaml

## Generate img file
tn img -c spec.yaml | dot -Tpng > spec.png
```

## tn init
```
## Output tinet config template
tn init

## Generate Tinet config file
tn init > spec.yaml
```

## tn print
```
tn print -c spec.yaml
```

## tn ps
```
## Output docker and netns info cmd
tn ps -c spec.yaml

## Output docker and netns info
tn ps -c spec.yaml | sudo sh -x
```

## tn pull
```
tn pull -c spec.yaml

## Execute docker pull
tn pull -c spec.yaml | sudo sh -x
```

## tn reconf
```
tn reconf -c spec.yaml

## down, up, conf
tn reconf -c spec.yaml | sudo sh -x
```

## tn reup
```
tn reup -c spec.yaml

## down, up
tn reup -c spec.yaml | sudo sh -x
```

## tn up
```
tn up -c spec.yaml

## up
tn up -c spec.yaml | sudo sh -x
```

## tn upconf
```
tn upconf -c spec.yaml

## up, conf
tn upconf -c spec.yaml | sudo sh -x
```

## tn version
```
tn version
```


================================================
FILE: docs/specification_yml.md
================================================
# Yaml Format

## Node Definition

### Node type

- name: node name. It will be container-name or netns-name.
- type: node type (default: docker)
	- docker: node is docker container
	- netns: node is just network namespace
- image: specify docker-image
- sysctls: set sysctls
- mounts: mounts file/directory on the container
- dns: set DNS resolver
- dns_search: set DNS search domain


```
nodes:
  - name: Node0
    image: ubuntu:18.04
  - name: Node1
    type: netns
	- name: Node2
	  build: .
```

### Interface Definition

- type
	- direct: p2p connect to other container
	- bridge: bridge connection
	- phys  : host's network interface
- addr: specify mac address

```
nodes:
  - name: Node0
    image: ubuntu:18.04
    interfaces:
      - { name: net0, type: direct, args: R0#net1 }
      - { name: net0, type: bridge, args: B0 }
      - { name: eth0, type: phys }
      - { name: net0, type: direct, args: R1#net1, addr: 11:11:11:11:11:11 }
```

### Bridge Definition

If you use the bridge interface type, you need to
define the Bridge-Instance. It'll be created as a
linux bridge instance.

- name: interface name
- type: interface type, you must choose following.
	- docker: net-if of docker container
	- netns: net-if of network namespace
	- phys: host's network interface

```
bridges:
  - name: Bridge0
    interfaces:
      - { name: net0, type: docker, args: R0 }
      - { name: net0, type: netns, args: NS0 }
      - { name: eth0, type: phys }
```

## Config Definition
- name: node name
- cmds: shell command

```
node_configs:
  - name: Router1
    cmds:
      - cmd: ip addr add 10.255.0.10/32 dev lo
      - cmd: ip addr add 10.0.0.10/24 dev net0
			- copy: ./config.conf /usr/local/config.conf
  - name: Router0
    cmds:
      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'
      - cmd: /usr/lib/frr/frr start
      - cmd: ip addr add 10.255.0.1/32 dev lo
      - cmd: ip addr add 10.0.0.1/24 dev net0
      - cmd: ip addr add 10.1.0.1/24 dev net1
      - cmd: >-
          vtysh -c 'conf t'
          -c 'router bgp 100'
          -c ' bgp router-id 10.255.0.1'
          -c ' neighbor 10.0.0.10 remote-as 100'
          -c ' neighbor 10.0.0.20 remote-as 100'
          -c ' neighbor 10.0.0.30 remote-as 100'
```

## Test Definition

- name: test name, you can specify when you run `tn conf -n <name>`
- cmds: same format of config definition

```
test:
  - name: p2p
	  cmds:
    - cmd: docker exec S0 ping -c2 10.1.0.1
    - cmd: docker exec S1 ping -c2 192.168.0.1
    - cmd: docker exec S2 ping -c2 192.168.0.1
    - cmd: docker exec S3 ping -c2 192.168.0.1
  - name: remote
	  cmds:
    - cmd: docker exec S0 ping -c2 10.1.0.1
    - cmd: docker exec S1 ping -c2 192.168.0.1
    - cmd: docker exec S2 ping -c2 192.168.0.1
    - cmd: docker exec S3 ping -c2 192.168.0.1
```

## System Requirement Definition

```
require:
	- kernel_min: 4.11.0
	- kernel_max: 4.15.0
	- kmod: [ mpls_router, mpls_iptunnel, mpls_gso ]
  - kconfig: [ CONFIG_NET_L3_MASTER_DEV ]
```


================================================
FILE: examples/bandwidth_tc/spec.yaml
================================================
nodes:

  - name: C1
    image: ip6tables:test
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
  - name: C4
    image: ip6tables:test
    interfaces:
      - { name: net0, type: direct, args: R1#net3 }    
  - name: C2
    image: ip6tables:test
    interfaces:
      - { name: net0, type: direct, args: R1#net1 }
  - name: C3
    image: ip6tables:test
    interfaces:
      - { name: net0, type: direct, args: R1#net2 }    
  - name: R1
    image: ip6tables:test
    interfaces:
      - { name: net0, type: direct, args: C1#net0 }
      - { name: net1, type: direct, args: C2#net0 }
      - { name: net2, type: direct, args: C3#net0 }
      - { name: net3, type: direct, args: C4#net0 }  
  

node_configs:

  - name: C1
    cmds:
      - cmd: ip addr add 10.0.0.2/24 dev net0
      - cmd: ip route replace default via 10.0.0.1
  - name: C4
    cmds:
      - cmd: ip addr add 10.0.0.12/24 dev net0
      - cmd: ip route replace default via 10.0.0.1  
  - name: C2
    cmds:
      - cmd: ip addr add 10.1.0.2/24 dev net0
      - cmd: ip route replace default via 10.1.0.1
  - name: C3
    cmds:
      - cmd: ip addr add 10.2.0.2/24 dev net0
      - cmd: ip route replace default via 10.2.0.1  
  - name: R1
    cmds:
      - cmd: ip link add br0 type bridge
      - cmd: ip link set br0 up  
      - cmd: ip addr add 10.0.0.1/24 dev br0
      - cmd: ip addr add 10.1.0.1/24 dev net1
      - cmd: ip addr add 10.2.0.1/24 dev net2
      - cmd: ip link set net0 master br0
      - cmd: ip link set net3 master br0
      - cmd: tc qdisc add dev net0 root tbf limit 1Mb buffer 200Kb rate 1Mbps
      - cmd: tc qdisc add dev net2 root tbf limit 1Mb buffer 200Kb rate 1Mbps
      - cmd: ethtool -K net0 tso off gso off
      - cmd: ethtool -K net2 tso off gso off
      - cmd: tc qdisc replace dev net0 root netem delay 10ms
      - cmd: tc qdisc replace dev net1 root netem delay 10ms
      - cmd: tc qdisc replace dev net2 root netem delay 10ms
      - cmd: tc qdisc replace dev net3 root netem delay 10ms  
      - cmd: sysctl -w net.ipv4.ip_forward=1


================================================
FILE: examples/basic_bfd/spec.yaml
================================================
# http://www.asciiflow.com

nodes:
  - name: R1
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R2#net0 }
      - { name: net1, type: direct, args: R3#net0 }
  - name: R2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
      - { name: net1, type: direct, args: R4#net0 }
  - name: R3
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net1 }
      - { name: net1, type: direct, args: R4#net1 }
  - name: R4
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R2#net1 }
      - { name: net1, type: direct, args: R3#net1 }

node_configs:
  - name: R1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.1/32'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.1/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.5/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'router ospf'
          -c ' network 10.0.0.0/30 area 0'
          -c ' network 10.0.0.4/30 area 0'
          -c 'exit'
  - name: R2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.2/32'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.2/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.9/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'router ospf'
          -c ' network 10.0.0.0/30 area 0'
          -c ' network 10.0.0.8/30 area 0'
          -c 'exit'
  - name: R3
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.3/32'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.6/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.13/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'router ospf'
          -c ' network 10.0.0.4/30 area 0'
          -c ' network 10.0.0.12/30 area 0'
  - name: R4
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.4/32'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.10/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.14/30'
          -c ' ip ospf bfd'
          -c 'exit'
          -c 'router ospf'
          -c ' network 10.0.0.8/30 area 0'
          -c ' network 10.0.0.12/30 area 0'

test:
  - cmds:
    ## P2P Link test
    - cmd: docker exec R1 ping -c2 10.0.0.2
    - cmd: docker exec R1 ping -c2 10.0.0.6
    - cmd: docker exec R2 ping -c2 10.0.0.1
    - cmd: docker exec R2 ping -c2 10.0.0.10
    - cmd: docker exec R3 ping -c2 10.0.0.5
    - cmd: docker exec R3 ping -c2 10.0.0.14
    - cmd: docker exec R4 ping -c2 10.0.0.9
    - cmd: docker exec R4 ping -c2 10.0.0.13



================================================
FILE: examples/basic_bgp/README.md
================================================

# BGP Playground




================================================
FILE: examples/basic_bgp/bgp_clos_evpn_vxlan/spec.yaml
================================================
# ref: https://www.apresiatac.jp/blog/201903121016/

nodes:
  - name: Spine1
    image: akiranet24/frr
    interfaces:
      - { name: swp49, type: direct, args: Leaf1#swp49 }
      - { name: swp50, type: direct, args: Leaf2#swp49 }
    sysctls:
      - sysctl: net.ipv4.ip_forward=1
      - sysctl: net.ipv4.conf.all.rp_filter=0
      - sysctl: net.ipv4.conf.lo.rp_filter=0
      - sysctl: net.ipv6.conf.all.disable_ipv6=0
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.seg6_enabled=1
      - sysctl: net.ipv6.conf.default.seg6_enabled=1
      - sysctl: net.ipv4.fib_multipath_hash_policy=1
  - name: Spine2
    image: akiranet24/frr
    interfaces:
      - { name: swp49, type: direct, args: Leaf1#swp50 }
      - { name: swp50, type: direct, args: Leaf2#swp50 }
    sysctls:
      - sysctl: net.ipv4.ip_forward=1
      - sysctl: net.ipv4.conf.all.rp_filter=0
      - sysctl: net.ipv4.conf.lo.rp_filter=0
      - sysctl: net.ipv6.conf.all.disable_ipv6=0
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.seg6_enabled=1
      - sysctl: net.ipv6.conf.default.seg6_enabled=1
      - sysctl: net.ipv4.fib_multipath_hash_policy=1
  - name: Leaf1
    image: akiranet24/frr
    interfaces:
      - { name: swp49, type: direct, args: Spine1#swp49 }
      - { name: swp50, type: direct, args: Spine2#swp49 }
      - { name: swp1, type: direct, args: Vm1#net1 }
    sysctls:
      - sysctl: net.ipv4.ip_forward=1
      - sysctl: net.ipv4.conf.all.rp_filter=0
      - sysctl: net.ipv4.conf.lo.rp_filter=0
      - sysctl: net.ipv6.conf.all.disable_ipv6=0
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.seg6_enabled=1
      - sysctl: net.ipv6.conf.default.seg6_enabled=1
      - sysctl: net.ipv4.fib_multipath_hash_policy=1
  - name: Leaf2
    image: akiranet24/frr
    interfaces:
      - { name: swp49, type: direct, args: Spine1#swp50 }
      - { name: swp50, type: direct, args: Spine2#swp50 }
      - { name: swp1, type: direct, args: Vm2#net1 }
    sysctls:
      - sysctl: net.ipv4.ip_forward=1
      - sysctl: net.ipv4.conf.all.rp_filter=0
      - sysctl: net.ipv4.conf.lo.rp_filter=0
      - sysctl: net.ipv6.conf.all.disable_ipv6=0
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.seg6_enabled=1
      - sysctl: net.ipv6.conf.default.seg6_enabled=1
      - sysctl: net.ipv4.fib_multipath_hash_policy=1

  - name: Vm1
    image: akiranet24/frr
    interfaces: [ { name: net1, type: direct, args: Leaf1#swp1 } ]
    sysctls:
      - sysctl: net.ipv4.ip_forward=1
      - sysctl: net.ipv4.conf.all.rp_filter=0
      - sysctl: net.ipv4.conf.lo.rp_filter=0
      - sysctl: net.ipv6.conf.all.disable_ipv6=0
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.seg6_enabled=1
      - sysctl: net.ipv6.conf.default.seg6_enabled=1
      - sysctl: net.ipv4.fib_multipath_hash_policy=1
  - name: Vm2
    image: akiranet24/frr
    interfaces: [ { name: net1, type: direct, args: Leaf2#swp1 } ]
    sysctls:
      - sysctl: net.ipv4.ip_forward=1
      - sysctl: net.ipv4.conf.all.rp_filter=0
      - sysctl: net.ipv4.conf.lo.rp_filter=0
      - sysctl: net.ipv6.conf.all.disable_ipv6=0
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.forwarding=1
      - sysctl: net.ipv6.conf.all.seg6_enabled=1
      - sysctl: net.ipv6.conf.default.seg6_enabled=1
      - sysctl: net.ipv4.fib_multipath_hash_policy=1

node_configs:
  - name: Spine1
    cmds:
      - cmd: sed -i s/'#frr_profile="datacenter"'/'frr_profile="datacenter"'/ /etc/frr/daemons
      - cmd: /etc/init.d/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.0.0.1/32"
          -c "int swp49" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "int swp50" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "router bgp 65020"
          -c " bgp router-id 10.0.0.1"
          -c " bgp bestpath as-path multipath-relax"
          -c " neighbor FABRIC peer-group"
          -c " neighbor FABRIC remote-as external"
          -c " neighbor FABRIC bfd"
          -c " neighbor FABRIC capability extended-nexthop"
          -c " neighbor swp49 interface peer-group FABRIC"
          -c " neighbor swp50 interface peer-group FABRIC"
          -c " address-family ipv4 unicast"
          -c "  network 10.0.0.1/32"
          -c " exit-address-family"
          -c " address-family l2vpn evpn"
          -c "  neighbor FABRIC activate"
          -c " exit-address-family"
  - name: Spine2
    cmds:
      - cmd: sed -i s/'#frr_profile="datacenter"'/'frr_profile="datacenter"'/ /etc/frr/daemons
      - cmd: /etc/init.d/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.0.0.2/32"
          -c "int swp49" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "int swp50" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "router bgp 65020"
          -c " bgp router-id 10.0.0.2"
          -c " bgp bestpath as-path multipath-relax"
          -c " neighbor FABRIC peer-group"
          -c " neighbor FABRIC remote-as external"
          -c " neighbor FABRIC bfd"
          -c " neighbor FABRIC capability extended-nexthop"
          -c " neighbor swp49 interface peer-group FABRIC"
          -c " neighbor swp50 interface peer-group FABRIC"
          -c " address-family ipv4 unicast"
          -c "  network 10.0.0.2/32"
          -c " exit-address-family"
          -c " address-family l2vpn evpn"
          -c "  neighbor FABRIC activate"
          -c " exit-address-family"
  - name: Leaf1
    cmds:
      - cmd: sed -i s/'#frr_profile="datacenter"'/'frr_profile="datacenter"'/ /etc/frr/daemons
      - cmd: /etc/init.d/frr start
      - cmd: ip link add br0 type bridge vlan_filtering 1
      - cmd: ip link add link swp1 name swp1.100 type vlan id 100
      - cmd: ip link add vni-10100 type vxlan id 10100 local 10.0.0.11 remote 10.0.0.12 dstport 4789 nolearning
      - cmd: ip link set vni-10100 master br0
      - cmd: ip link set swp1.100 master br0
      - cmd: ip link set br0 up
      - cmd: ip link set vni-10100 up
      - cmd: ip link set swp1.100 up
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.0.0.11/32"
          -c "int swp49" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "int swp50" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "router bgp 65011"
          -c " bgp router-id 10.0.0.11"
          -c " bgp bestpath as-path multipath-relax"
          -c " neighbor FABRIC peer-group"
          -c " neighbor FABRIC remote-as external"
          -c " neighbor FABRIC bfd"
          -c " neighbor FABRIC capability extended-nexthop"
          -c " neighbor swp49 interface peer-group FABRIC"
          -c " neighbor swp50 interface peer-group FABRIC"
          -c " address-family ipv4 unicast"
          -c "  network 10.0.0.11/32"
          -c " exit-address-family"
          -c " address-family l2vpn evpn"
          -c "  neighbor FABRIC activate"
          -c "  advertise-all-vni"
          -c " exit-address-family"
  - name: Leaf2
    cmds:
      - cmd: sed -i s/'#frr_profile="datacenter"'/'frr_profile="datacenter"'/ /etc/frr/daemons
      - cmd: /etc/init.d/frr start
      - cmd: ip link add br0 type bridge vlan_filtering 1
      - cmd: ip link add link swp1 name swp1.100 type vlan id 100
      - cmd: ip link add vni-10100 type vxlan id 10100 local 10.0.0.12 remote 10.0.0.11 dstport 4789 nolearning
      - cmd: ip link set vni-10100 master br0
      - cmd: ip link set swp1.100 master br0
      - cmd: ip link set br0 up
      - cmd: ip link set vni-10100 up
      - cmd: ip link set swp1.100 up
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.0.0.12/32"
          -c "int swp49" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "int swp50" -c "ipv6 nd ra-interval 10" -c "no ipv6 nd suppress-ra"
          -c "router bgp 65012"
          -c " bgp router-id 10.0.0.12"
          -c " bgp bestpath as-path multipath-relax"
          -c " neighbor FABRIC peer-group"
          -c " neighbor FABRIC remote-as external"
          -c " neighbor FABRIC bfd"
          -c " neighbor FABRIC capability extended-nexthop"
          -c " neighbor swp49 interface peer-group FABRIC"
          -c " neighbor swp50 interface peer-group FABRIC"
          -c " address-family ipv4 unicast"
          -c "  network 10.0.0.12/32"
          -c " exit-address-family"
          -c " address-family l2vpn evpn"
          -c "  neighbor FABRIC activate"
          -c "  advertise-all-vni"
          -c " exit-address-family"
  - name: Vm1
    cmds:
      - cmd: /etc/init.d/frr start
      - cmd: ip link add link net1 name net1.100 type vlan id 100
      - cmd: ip addr add 172.16.100.10/24 dev net1.100
      - cmd: ip link set net1.100 up
  - name: Vm2
    cmds:
      - cmd: /etc/init.d/frr start
      - cmd: ip link add link net1 name net1.100 type vlan id 100
      - cmd: ip addr add 172.16.100.20/24 dev net1.100
      - cmd: ip link set net1.100 up

test:
  - cmds:
      - cmd: docker exec Vm1 ping -c2 172.16.100.20


================================================
FILE: examples/basic_bgp/graceful_restart/simple_ipv4_unicast/README.md
================================================
# Simple IPv4 unicast BGP-GR

```
$ tinet up -c spec.yaml | sudo sh
$ docker exec -it R2 bash
R2# tcpdump -nnli net0 # another shell
$ tinet conf -c spec.yaml | sudo sh 
$ docker exec R1 pkill -9 bgpd
```



================================================
FILE: examples/basic_bgp/graceful_restart/simple_ipv4_unicast/spec.yaml
================================================
nodes:
- name: C1
  image: alpine:latest
  interfaces:
  - { name: net1, type: direct, args: R1#net1 }
- name: R1
  image: frrouting/frr:v8.1.0
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R2#net0 }
  - { name: net1, type: direct, args: C1#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1
- name: R2
  image: frrouting/frr:v8.1.0
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R1#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1
node_configs:
- name: R1
  cmds:
  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c 'conf t'
      -c 'interface net0'
      -c ' ip address 10.255.0.1/16'
      -c '!'
      -c 'interface net1'
      -c ' ip address 192.168.10.1/16'
      -c '!'
      -c 'ip prefix-list PL1 permit 192.168.0.0/16'
      -c '!'
      -c 'route-map RM1 permit 10'
      -c ' match ip address prefix-list PL1'
      -c '!'
      -c 'router bgp 65001'
      -c ' no bgp ebgp-requires-policy'
      -c ' bgp router-id 10.255.0.1'
      -c ' bgp graceful-restart'
      -c ' bgp graceful-restart preserve-fw-state'
      -c ' bgp graceful-restart restart-time 1800'
      -c ' bgp graceful-restart stalepath-time 1800'
      -c ' neighbor 10.255.0.2 remote-as 65002'
      -c ' neighbor 10.255.0.2 route-map RM1 out'
      -c ' address-family ipv4 unicast'
      -c '  redistribute connected' 
      -c ' exit-address-family'
  - cmd: vtysh -c 'write mem'
- name: R2
  cmds:
  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c 'conf t'
      -c 'interface net0'
      -c ' ip address 10.255.0.2/16'
      -c '!'
      -c 'ip prefix-list PL1 permit 192.168.0.0/16'
      -c '!'
      -c 'route-map RM1 permit 10'
      -c ' match ip address prefix-list PL1'
      -c '!'
      -c 'router bgp 65002'
      -c ' no bgp ebgp-requires-policy'
      -c ' bgp router-id 10.255.0.2'
      -c ' bgp graceful-restart'
      -c ' bgp graceful-restart preserve-fw-state'
      -c ' bgp graceful-restart restart-time 1800'
      -c ' bgp graceful-restart stalepath-time 1800'
      -c ' neighbor 10.255.0.1 remote-as 65001'
      -c ' neighbor 10.255.0.1 route-map RM1 in'
  - cmd: vtysh -c 'write mem'
- name: C1
  cmds:
  - cmd: ip addr add 192.168.10.254/16 dev net1
  - cmd: route add default gw 192.168.10.1
test:
- cmds:
  - cmd: docker exec R1 ping -c2 192.168.10.254
  - cmd: docker exec R2 ping -c2 192.168.10.254


================================================
FILE: examples/basic_bgp/hv_bgp_dcn/README.md
================================================

# HV route advertisement study for BGP-DCN

- [GOOD reference about routing-info manupulation by @ukinau](https://engineering.linecorp.com/ja/blog/openstack-summit-vancouver-2018-recap-2-2/)
- [GOOD reference about proxy arp by @ukinau](https://qiita.com/ukinau/items/cb25588fb0c276a009dc)

![](topo.png)

```
docker exec TOR vtysh -c 'show bgp ipv4 unicast'
BGP table version is 4, local router ID is 10.255.0.99, vrf id 0
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 1.1.1.1/32       0.0.0.0                  0         32768 ?
*> 10.0.0.11/32     dn1                      0             0 65001 ?
*> 10.0.0.12/32     dn1                      0             0 65001 ?
*> 10.0.0.13/32     dn1                      0             0 65001 ?

Displayed  4 routes and 4 total paths
```



================================================
FILE: examples/basic_bgp/hv_bgp_dcn/spec.yaml
================================================

nodes:
  - name: TOR
    image: slankdev/frr
    interfaces:
      - { name: dn1, type: direct, args: HV1#up1 }
  - name: HV1
    image: slankdev/frr
    interfaces:
      - { name: up1, type: direct, args: TOR#dn1 }
      - { name: dn1, type: direct, args: VM1#net0 }
      - { name: dn2, type: direct, args: VM2#net0 }
      - { name: dn3, type: direct, args: VM3#net0 }
  - name: VM1
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: HV1#dn1 }
  - name: VM2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: HV1#dn2 }
  - name: VM3
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: HV1#dn3 }

node_configs:
  - name: TOR
    cmds:
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: ip addr add 1.1.1.1/32 dev lo
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface dn1'
          -c ' ipv6 nd ra-interval 3'
          -c ' no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65099'
          -c ' bgp router-id 10.255.0.99'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor dn1 interface peer-group PEER'
          -c '!'
          -c ' address-family ipv4 unicast'
          -c '  neighbor dn1 activate'
          -c '  redistribute connected'
          -c ' exit-address-family'

  - name: HV1
    cmds:
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: ip addr add 10.0.0.1/24 dev dn1
      - cmd: ip addr add 10.0.0.1/24 dev dn2
      - cmd: ip addr add 10.0.0.1/24 dev dn3
      - cmd: ip route add 10.0.0.11 dev dn1
      - cmd: ip route add 10.0.0.12 dev dn2
      - cmd: ip route add 10.0.0.13 dev dn3
      - cmd: sysctl -w net.ipv4.conf.dn1.proxy_arp=1
      - cmd: sysctl -w net.ipv4.conf.dn2.proxy_arp=1
      - cmd: sysctl -w net.ipv4.conf.dn3.proxy_arp=1
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface up1'
          -c ' ipv6 nd ra-interval 3'
          -c ' no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65001'
          -c ' bgp router-id 10.255.0.1'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor up1 interface peer-group PEER'
          -c ' !'
          -c ' address-family ipv4 unicast'
          -c '  redistribute kernel route-map TO_TOR'
          -c '  neighbor up1 route-map TO_TOR out'
          -c ' exit-address-family'
          -c '!'
          -c 'route-map TO_TOR permit 1'
          -c 'match ip address prefix-len 32'
          -c 'exit'

  - name: VM1
    cmds:
      - cmd: ip addr add 10.0.0.11/24 dev net0
      - cmd: ip route add default via 10.0.0.1
  - name: VM2
    cmds:
      - cmd: ip addr add 10.0.0.12/24 dev net0
      - cmd: ip route add default via 10.0.0.1
  - name: VM3
    cmds:
      - cmd: ip addr add 10.0.0.13/24 dev net0
      - cmd: ip route add default via 10.0.0.1



================================================
FILE: examples/basic_bgp/hv_bgp_dcn_isol/Makefile
================================================

sh:
	docker exec TOR vtysh -c 'show bgp ipv4 vpn'


================================================
FILE: examples/basic_bgp/hv_bgp_dcn_isol/README.md
================================================

# HV route advertisement study for BGP-DCN

- [GOOD reference about routing-info manupulation by @ukinau](https://engineering.linecorp.com/ja/blog/openstack-summit-vancouver-2018-recap-2-2/)
- [GOOD reference about proxy arp by @ukinau](https://qiita.com/ukinau/items/cb25588fb0c276a009dc)

![](topo.png)

```
docker exec TOR vtysh -c 'show bgp ipv4 unicast'
BGP table version is 4, local router ID is 10.255.0.99, vrf id 0
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 1.1.1.1/32       0.0.0.0                  0         32768 ?
*> 10.0.0.11/32     dn1                      0             0 65001 ?
*> 10.0.0.12/32     dn1                      0             0 65001 ?
*> 10.0.0.13/32     dn1                      0             0 65001 ?

Displayed  4 routes and 4 total paths
```



================================================
FILE: examples/basic_bgp/hv_bgp_dcn_isol/spec.yaml
================================================

nodes:
  - name: TOR
    # image: slankdev/frr-dev:latest
    image: slankdev/frr-dev:draft-ietf-bess-srv6-services
    interfaces:
      - { name: dn1, type: direct, args: HV1#up1 }
  - name: HV1
    # image: slankdev/frr-dev:latest
    image: slankdev/frr-dev:draft-ietf-bess-srv6-services
    interfaces:
      - { name: up1, type: direct, args: TOR#dn1 }
      - { name: dn1, type: direct, args: VM1#net0 }
      - { name: dn2, type: direct, args: VM2#net0 }
      - { name: dn3, type: direct, args: VM3#net0 }
  - name: VM1
    image: slankdev/ubuntu:18.04
    interfaces:
      - { name: net0, type: direct, args: HV1#dn1 }
  - name: VM2
    image: slankdev/ubuntu:18.04
    interfaces:
      - { name: net0, type: direct, args: HV1#dn2 }
  - name: VM3
    image: slankdev/ubuntu:18.04
    interfaces:
      - { name: net0, type: direct, args: HV1#dn3 }

node_configs:
  - name: TOR
    cmds:
      - cmd: sh -c "echo > /etc/frr/frr.conf"
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: ip addr add 1.1.1.1/32 dev lo
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface dn1'
          -c ' ipv6 nd ra-interval 3'
          -c ' no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65099'
          -c ' bgp router-id 10.255.0.99'
          -c ' no bgp default ipv4-unicast'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor dn1 interface peer-group PEER'
          -c '!'
          -c ' address-family ipv4 vpn'
          -c '  neighbor PEER activate'
          -c ' exit-address-family'

  - name: HV1
    cmds:
      - cmd: sh -c "echo > /etc/frr/frr.conf"
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: ip link add vrf1 type vrf table 10
      - cmd: ip link set vrf1 up
      - cmd: ip link set dn1 vrf vrf1
      - cmd: ip link set dn2 vrf vrf1
      - cmd: ip link set dn3 vrf vrf1
      - cmd: ip addr add 10.0.0.1/24 dev dn1 noprefixroute
      - cmd: ip addr add 10.0.0.1/24 dev dn2 noprefixroute
      - cmd: ip addr add 10.0.0.1/24 dev dn3 noprefixroute
      - cmd: ip route add 10.0.0.11 dev dn1 vrf vrf1
      - cmd: ip route add 10.0.0.12 dev dn2 vrf vrf1
      - cmd: ip route add 10.0.0.13 dev dn3 vrf vrf1
      - cmd: sysctl -w net.ipv4.conf.dn1.proxy_arp=1
      - cmd: sysctl -w net.ipv4.conf.dn2.proxy_arp=1
      - cmd: sysctl -w net.ipv4.conf.dn3.proxy_arp=1
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface up1'
          -c ' ipv6 nd ra-interval 3'
          -c ' no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65001'
          -c ' bgp router-id 10.255.0.1'
          -c ' no bgp default ipv4-unicast'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor up1 interface peer-group PEER'
          -c ' !'
          -c ' address-family ipv4 vpn'
          -c '  neighbor PEER activate'
          -c '  segment-routing-ipv6'
          -c ' exit-address-family'
          -c '!'
          -c 'router bgp 65001 vrf vrf1'
          -c ' bgp router-id 10.255.0.1'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' !'
          -c ' address-family ipv4 unicast'
          -c '  redistribute kernel'
          -c '  sid vpn export locator default'
          -c '  rd vpn export 65001:1'
          -c '  rt vpn both 100:1'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c '!'
          -c 'segment-routing-ipv6'
          -c ' encapsulation source-address 2001:1::'
          -c ' locator prefix 2001:1::/64'
          -c ' exit'
          -c '!'
          -c 'route-map TO_TOR permit 1'
          -c ' match ip address prefix-len 32'
          -c ' exit'

  - name: VM1
    cmds:
      - cmd: ip addr add 10.0.0.11/24 dev net0
      - cmd: ip route add default via 10.0.0.1
  - name: VM2
    cmds:
      - cmd: ip addr add 10.0.0.12/24 dev net0
      - cmd: ip route add default via 10.0.0.1
  - name: VM3
    cmds:
      - cmd: ip addr add 10.0.0.13/24 dev net0
      - cmd: ip route add default via 10.0.0.1



================================================
FILE: examples/basic_bgp/local_pref/README.md
================================================
![topology](topo.png "bgp")

================================================
FILE: examples/basic_bgp/local_pref/spec.yaml
================================================
nodes:
- name: R1
  image: frrouting/frr:latest
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R2#net0 }
  - { name: net1, type: direct, args: R3#net0 }
  - { name: net2, type: direct, args: R4#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1
- name: R2
  image: frrouting/frr:latest
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R1#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1
- name: R3
  image: frrouting/frr:latest
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R1#net1 }
  - { name: net1, type: direct, args: R5#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1  
- name: R4
  image: frrouting/frr:latest
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R1#net2 }
  - { name: net1, type: direct, args: R5#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1  
- name: R5
  image: frrouting/frr:latest
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R3#net1 }
  - { name: net1, type: direct, args: R4#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1    
node_configs:
  - name: R1
    cmds:
      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: ip addr add 10.0.0.1/24 dev net0
      - cmd: ip addr add 10.1.0.1/24 dev net1
      - cmd: ip addr add 10.2.0.1/24 dev net2
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 65001"
          -c "no bgp ebgp-requires-policy"
          -c ' bgp router-id 1.1.1.1'
          -c "neighbor 10.0.0.2 remote-as 65002"
          -c "neighbor 10.1.0.2 remote-as 65003"
          -c "neighbor 10.2.0.2 remote-as 65004"
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  neighbor 10.2.0.2 route-map LOCAL_PREF200 in'
          -c ' exit-address-family'
          -c 'access-list 1 permit 10.11.0.0/24'
          -c 'route-map LOCAL_PREF200 permit 10'
          -c ' match ip address 1'
          -c ' set local-preference 200'
          -c ' exit'
          -c 'route-map LOCAL_PREF200 permit 20'
          -c '!'
  - name: R2
    cmds:
      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: ip addr add 10.0.0.2/24 dev net0
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 65002"
          -c "no bgp ebgp-requires-policy"
          -c ' bgp router-id 1.1.1.2'
          -c "neighbor 10.0.0.1 remote-as 65001"
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'
  - name: R3
    cmds:
      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: ip addr add 10.1.0.2/24 dev net0
      - cmd: ip addr add 10.11.0.1/24 dev net1
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 65003"
          -c "no bgp ebgp-requires-policy"
          -c ' bgp router-id 1.1.1.3'
          -c "neighbor 10.1.0.1 remote-as 65001"
          -c "neighbor 10.11.0.2 remote-as 65005"
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'    
  - name: R4
    cmds:
      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: ip addr add 10.2.0.2/24 dev net0
      - cmd: ip addr add 10.12.0.1/24 dev net1
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 65004"
          -c "no bgp ebgp-requires-policy"
          -c ' bgp router-id 1.1.1.4'
          -c "neighbor 10.2.0.1 remote-as 65001"
          -c "neighbor 10.12.0.2 remote-as 65005"
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'       
  - name: R5
    cmds:
      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: ip addr add 10.11.0.2/24 dev net0
      - cmd: ip addr add 10.12.0.2/24 dev net1
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 65005"
          -c "no bgp ebgp-requires-policy"
          -c ' bgp router-id 1.1.1.5'
          -c "neighbor 10.11.0.1 remote-as 65003"
          -c "neighbor 10.12.0.1 remote-as 65004"
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'                       

================================================
FILE: examples/basic_bgp/mpbgp_ipv4_labeled_unicast/README.md
================================================

# MP-BGP labeled unicast example

```
     bgp unnumbered
ipv4-labeld-unicast enabled

 [R0]-----------------[R1]
 AS1                   AS2
```



================================================
FILE: examples/basic_bgp/mpbgp_ipv4_labeled_unicast/spec.yaml
================================================

precmd:
  - cmds:
    - cmd: export IMAGE=slankdev/frr:centos-7-stable-7.0

nodes:
  - name: R0
    image: $IMAGE
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
  - name: R1
    image: $IMAGE
    interfaces:
      - { name: net0, type: direct, args: R0#net0 }

node_configs:
  - name: R0
    cmds:
      - cmd: sh -c 'enable_seg6_router.py | sh'
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 1"
          -c " bgp router-id 1.1.1.1"
          -c " no bgp default ipv4-unicast"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor FABRIC peer-group"
          -c " neighbor FABRIC remote-as external"
          -c " neighbor FABRIC capability extended-nexthop"
          -c " neighbor net0 interface peer-group FABRIC"
          -c " !"
          -c " address-family ipv4 unicast"
          -c "  redistribute connected"
          -c "  redistribute kernel"
          -c " exit-address-family"
          -c " !"
          -c " address-family ipv4 labeled-unicast"
          -c "  neighbor FABRIC activate"
          -c " exit-address-family"
          -c "!"

  - name: R1
    cmds:
      - cmd: sh -c 'enable_seg6_router.py | sh'
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 2"
          -c " bgp router-id 2.2.2.2"
          -c " no bgp default ipv4-unicast"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor FABRIC peer-group"
          -c " neighbor FABRIC remote-as external"
          -c " neighbor FABRIC capability extended-nexthop"
          -c " neighbor net0 interface peer-group FABRIC"
          -c " !"
          -c " address-family ipv4 unicast"
          -c "  redistribute connected"
          -c "  redistribute kernel"
          -c " exit-address-family"
          -c " !"
          -c " address-family ipv4 labeled-unicast"
          -c "  neighbor FABRIC activate"
          -c " exit-address-family"
          -c "!"



================================================
FILE: examples/basic_bgp/path_attr/README.md
================================================

# BGP route-map playground (import-prefix-filter)

![](topo.png)

```
docker exec R3 vtysh -c 'show bgp ipv4 unicast'
BGP table version is 1, local router ID is 10.255.0.3, vrf id 0
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.2/32      net0                                   0 65001 65002 i

Displayed  1 routes and 1 total paths
```
```
docker exec R4 vtysh -c 'show bgp ipv4 unicast'
BGP table version is 3, local router ID is 10.255.0.4, vrf id 0
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.1/32      net0                                   0 65001 65002 i
*> 10.0.0.2/32      net0                                   0 65001 65002 i
*> 10.0.0.3/32      net0                                   0 65001 65002 i

Displayed  3 routes and 3 total paths
```



================================================
FILE: examples/basic_bgp/path_attr/spec.yaml
================================================

nodes:
  - name: R1
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R2#net0 }
      - { name: net1, type: direct, args: R3#net0 }
      - { name: net2, type: direct, args: R4#net0 }

  - name: R2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
  - name: R3
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net1 }
  - name: R4
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net2 }

node_configs:
  - name: R1
    cmds:
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'
          -c 'interface net1' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'
          -c 'interface net2' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65001'
          -c ' bgp router-id 10.255.0.1'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor net0 interface peer-group PEER'
          -c ' neighbor net1 interface peer-group PEER'
          -c ' neighbor net2 interface peer-group PEER'
          -c '!'
          -c ' address-family ipv4 unicast'
          -c '  neighbor net0 activate'
          -c ' exit-address-family'
          -c '!'
          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'
          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'
          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'

  - name: R2
    cmds:
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65002'
          -c ' bgp router-id 10.255.0.2'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor net0 interface peer-group PEER'
          -c ' !'
          -c ' address-family ipv4 unicast'
          -c '  network 10.0.0.1/32 route-map COM1'
          -c '  network 10.0.0.2/32 route-map COM2'
          -c '  network 10.0.0.3/32 route-map COM3'
          -c ' exit-address-family'
          -c '!'
          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'
          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'
          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'
          -c '!'
          -c 'route-map COM1 permit 1' -c 'set community 65002:1' -c 'exit'
          -c 'route-map COM2 permit 1' -c 'set community 65002:2' -c 'exit'
          -c 'route-map COM3 permit 1' -c 'set community 65002:3' -c 'exit'

  - name: R3
    cmds:
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65003'
          -c ' bgp router-id 10.255.0.3'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor net0 interface peer-group PEER'
          -c ' !'
          -c ' address-family ipv4 unicast'
          -c '  neighbor net0 route-map MAP1 in'
          -c ' exit-address-family'
          -c '!'
          -c 'route-map MAP1 permit 1'
          -c ' match ip address prefix-list PREF2'
          -c ' !match community 65002:2'
          -c ' exit'
          -c '!'
          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'
          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'
          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'

  - name: R4
    cmds:
      - cmd: sh -c "enable_seg6_router.py | sh"
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'
          -c '!'
          -c 'router bgp 65004'
          -c ' bgp router-id 10.255.0.4'
          -c ' bgp bestpath as-path multipath-relax'
          -c ' neighbor PEER peer-group'
          -c ' neighbor PEER remote-as external'
          -c ' neighbor net0 interface peer-group PEER'
          -c '!'
          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'
          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'
          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'



================================================
FILE: examples/basic_bgp/route_reflector/spec.yaml
================================================

# DESCRIPTION:
#    Basic iBGP RR test using and FRR
#    create reachability with loopback with OSPF
#
# INIT:
#    cns spec.yaml init | sudo sh
#    cns spec.yaml conf | sudo sh
#    cns spec.yaml test | sudo sh
# FINI:
#    cns spec.yaml fini | sudo sh
# TOPO:
#        10.0.0.0/24                             .1(net0)
#     B0----+-----------------+-----------------+------RR0(255.1.0.1)
#           |                 |                 |
#           |.10(net0)        |.11(net0)        |.12(net0)
#          R0(255.10.0.1)    R1(255.11.0.1)    R2(255.12.0.1)
#           |.1(net1)         |.1(net1)         |.1(net1)
#           |                 |                 |
#           |192.168.10.0/24  |192.168.11.0/24  |192.168.12.0/24
#           |                 |                 |
#           |.2(net0)         |.2(net0)         |.2(net0)
#          C0                C1                C2
#

nodes:
  - name: RR0
    image: slankdev/frr
    interfaces:
      - { name: net0, type: bridge, args: B0 }

  - name: R0
    image: slankdev/frr
    interfaces:
      - { name: net0, type: bridge, args: B0 }
      - { name: net1, type: direct, args: C0#net0 }
  - name: C0
    image: slankdev/ubuntu:16.04
    interfaces:
      - { name: net0, type: direct, args: R0#net1 }

  - name: R1
    image: slankdev/frr
    interfaces:
      - { name: net0, type: bridge, args: B0 }
      - { name: net1, type: direct, args: C1#net0 }
  - name: C1
    image: slankdev/ubuntu:16.04
    interfaces:
      - { name: net0, type: direct, args: R1#net1 }

  - name: R2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: bridge, args: B0 }
      - { name: net1, type: direct, args: C2#net0 }
  - name: C2
    image: slankdev/ubuntu:16.04
    interfaces:
      - { name: net0, type: direct, args: R2#net1 }

switches:
  - name: B0
    interfaces:
      - { name: net0, type: container, args: RR0 }
      - { name: net0, type: container, args: R0 }
      - { name: net0, type: container, args: R1 }
      - { name: net0, type: container, args: R2 }

node_configs:
  - name: RR0
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1

      - cmd: >-
          vtysh -c "conf t"
          -c "interface lo" -c "ip address 10.255.0.1/32" -c "exit"
          -c "interface net0" -c "ip address 10.0.0.1/24" -c "exit"
          -c "router ospf"
          -c "  network 10.255.0.1/32 area 0"
          -c "  network 10.0.0.0/24 area 0"
          -c "exit"
          -c "router bgp 100"
          -c "  bgp router-id 10.255.0.1"
          -c "  neighbor 10.255.0.10 remote-as 100"
          -c "  neighbor 10.255.0.10 update-source lo"
          -c "  neighbor 10.255.0.11 remote-as 100"
          -c "  neighbor 10.255.0.11 update-source lo"
          -c "  neighbor 10.255.0.12 remote-as 100"
          -c "  neighbor 10.255.0.12 update-source lo"
          -c "  address-family ipv4 unicast"
          -c "     neighbor 10.255.0.10 route-reflector-client"
          -c "     neighbor 10.255.0.11 route-reflector-client"
          -c "     neighbor 10.255.0.12 route-reflector-client"
          -c "  exit-address-family"
          -c "exit"

  - name: R0
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1

      - cmd: >-
          vtysh -c "conf t"
          -c "interface lo" -c "ip address 10.255.0.10/32" -c "exit"
          -c "interface net0" -c "ip address 10.0.0.10/24" -c "exit"
          -c "interface net1" -c "ip address 192.168.10.1/24" -c "exit"
          -c "router ospf"
          -c "  network 10.255.0.10/32 area 0"
          -c "  network 10.0.0.0/24 area 0"
          -c "exit"
          -c "router bgp 100"
          -c "  bgp router-id 10.255.0.10"
          -c "  neighbor 10.255.0.1 remote-as 100"
          -c "  neighbor 10.255.0.1 update-source lo"
          -c "  network 192.168.10.0/24"
          -c "exit"

  - name: R1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1

      - cmd: >-
          vtysh -c "conf t"
          -c "interface lo" -c "ip address 10.255.0.11/32" -c "exit"
          -c "interface net0" -c "ip address 10.0.0.11/24" -c "exit"
          -c "interface net1" -c "ip address 192.168.11.1/24" -c "exit"
          -c "router ospf"
          -c "  network 10.255.0.11/32 area 0"
          -c "  network 10.0.0.0/24 area 0"
          -c "exit"
          -c "router bgp 100"
          -c "  bgp router-id 10.255.0.11"
          -c "  neighbor 10.255.0.1 remote-as 100"
          -c "  neighbor 10.255.0.1 update-source lo"
          -c "  network 192.168.11.0/24"
          -c "exit"

  - name: R2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1

      - cmd: >-
          vtysh -c "conf t"
          -c "interface lo" -c "ip address 10.255.0.12/32" -c "exit"
          -c "interface net0" -c "ip address 10.0.0.12/24" -c "exit"
          -c "interface net1" -c "ip address 192.168.12.1/24" -c "exit"
          -c "router ospf"
          -c "  network 10.255.0.12/32 area 0"
          -c "  network 10.0.0.0/24 area 0"
          -c "exit"
          -c "router bgp 100"
          -c "  bgp router-id 10.255.0.12"
          -c "  neighbor 10.255.0.1 remote-as 100"
          -c "  neighbor 10.255.0.1 update-source lo"
          -c "  network 192.168.12.0/24"
          -c "exit"

  - name: C0
    cmds:
      - cmd: ip addr add 192.168.10.2/24 dev net0
      - cmd: ip route del default
      - cmd: ip route add default via 192.168.10.1
  - name: C1
    cmds:
      - cmd: ip addr add 192.168.11.2/24 dev net0
      - cmd: ip route del default
      - cmd: ip route add default via 192.168.11.1
  - name: C2
    cmds:
      - cmd: ip addr add 192.168.12.2/24 dev net0
      - cmd: ip route del default
      - cmd: ip route add default via 192.168.12.1

test:
  - cmds:
    - cmd: docker exec RR0 ping -c2 10.255.0.1
    - cmd: docker exec RR0 ping -c2 10.255.0.10
    - cmd: docker exec RR0 ping -c2 10.255.0.11
    - cmd: docker exec RR0 ping -c2 10.255.0.12
    - cmd: docker exec C0 ping -c2 192.168.10.1
    - cmd: docker exec C0 ping -c2 192.168.11.2
    - cmd: docker exec C0 ping -c2 192.168.12.2
    - cmd: docker exec C1 ping -c2 192.168.11.1
    - cmd: docker exec C1 ping -c2 192.168.10.2
    - cmd: docker exec C1 ping -c2 192.168.12.2
    - cmd: docker exec C2 ping -c2 192.168.12.1
    - cmd: docker exec C2 ping -c2 192.168.10.2
    - cmd: docker exec C2 ping -c2 192.168.11.2



================================================
FILE: examples/basic_bgp/route_server/spec.yaml
================================================
# DESCRIPTION: eBGP RS test
# TOPO:
#        10.0.0.0/24                             .1(net0)
#     B0----+-----------------+-----------------+------RS1(10.255.0.1)
#           |                 |                 |
#           |.10(net0)        |.11(net0)        |.12(net0)
#          R1                R2                R3
#           |.1(net1)         |.1(net1)         |.1(net1)
#           |                 |                 |
#           |192.168.1.0/24  |192.168.2.0/24  |192.168.3.0/24
#           |                 |                 |
#           |.2(net0)         |.2(net0)         |.2(net0)
#          C1                C2                C3

nodes:
- name: RS1
  image: slankdev/frr
  interfaces:
  - { name: net0, type: bridge, args: B0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

- name: R1
  image: slankdev/frr
  interfaces:
  - { name: net0, type: bridge, args: B0 }
  - { name: net1, type: direct, args: C1#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1
- name: C1
  image: slankdev/ubuntu:16.04
  interfaces:
  - { name: net0, type: direct, args: R1#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

- name: R2
  image: slankdev/frr
  interfaces:
  - { name: net0, type: bridge, args: B0 }
  - { name: net1, type: direct, args: C2#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1
- name: C2
  image: slankdev/ubuntu:16.04
  interfaces:
  - { name: net0, type: direct, args: R2#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

- name: R3
  image: slankdev/frr
  interfaces:
  - { name: net0, type: bridge, args: B0 }
  - { name: net1, type: direct, args: C3#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1
- name: C3
  image: slankdev/ubuntu:16.04
  interfaces:
  - { name: net0, type: direct, args: R3#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

switches:
- name: B0
  interfaces:
  - { name: net0, type: container, args: RS1 }
  - { name: net0, type: container, args: R1 }
  - { name: net0, type: container, args: R2 }
  - { name: net0, type: container, args: R3 }

node_configs:
- name: RS1
  cmds:
  - cmd: ip addr add 10.255.0.1/24 dev net0
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 1"
      -c " bgp router-id 10.255.0.1"
      -c " neighbor 10.255.0.11 remote-as 11"
      -c " neighbor 10.255.0.12 remote-as 12"
      -c " neighbor 10.255.0.13 remote-as 13"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  neighbor 10.255.0.11 route-server-client"
      -c "  neighbor 10.255.0.12 route-server-client"
      -c "  neighbor 10.255.0.13 route-server-client"
      -c "  !neighbor 10.255.0.11 next-hop-self"
      -c "  !neighbor 10.255.0.12 next-hop-self"
      -c "  !neighbor 10.255.0.13 next-hop-self"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  neighbor 10.255.0.11 activate"
      -c "  neighbor 10.255.0.12 activate"
      -c "  neighbor 10.255.0.13 activate"
      -c "  neighbor 10.255.0.11 route-server-client"
      -c "  neighbor 10.255.0.12 route-server-client"
      -c "  neighbor 10.255.0.13 route-server-client"
      -c " exit-address-family"
      -c "!"

- name: R1
  cmds:
  - cmd: ip addr add 10.255.0.11/24 dev net0
  - cmd: ip addr add 192.168.11.1/24 dev net1
  - cmd: ip -6 addr add 2001:11::1/64 dev net1
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 11"
      -c " bgp router-id 10.255.0.11"
      -c " neighbor 10.255.0.1 remote-as 1"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor 10.255.0.1 activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  redistribute connected"
      -c "  neighbor 10.255.0.1 activate"
      -c " exit-address-family"
      -c "!"

- name: R2
  cmds:
  - cmd: ip addr add 10.255.0.12/24 dev net0
  - cmd: ip addr add 192.168.12.1/24 dev net1
  - cmd: ip -6 addr add 2001:12::1/64 dev net1
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 12"
      -c " bgp router-id 10.255.0.12"
      -c " neighbor 10.255.0.1 remote-as 1"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor 10.255.0.1 activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  redistribute connected"
      -c "  neighbor 10.255.0.1 activate"
      -c " exit-address-family"
      -c "!"

- name: R3
  cmds:
  - cmd: ip addr add 10.255.0.13/24 dev net0
  - cmd: ip addr add 192.168.13.1/24 dev net1
  - cmd: ip -6 addr add 2001:13::1/64 dev net1
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 13"
      -c " bgp router-id 10.255.0.13"
      -c " neighbor 10.255.0.1 remote-as 1"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor 10.255.0.1 activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  redistribute connected"
      -c "  neighbor 10.255.0.1 activate"
      -c " exit-address-family"
      -c "!"

- name: C1
  cmds:
  - cmd: ip addr add 192.168.11.2/24 dev net0
  - cmd: ip route replace default via 192.168.11.1

- name: C2
  cmds:
  - cmd: ip addr add 192.168.12.2/24 dev net0
  - cmd: ip route replace default via 192.168.12.1

- name: C3
  cmds:
  - cmd: ip addr add 192.168.13.2/24 dev net0
  - cmd: ip route replace default via 192.168.13.1


================================================
FILE: examples/basic_bgp/route_server_multihop/spec.yaml
================================================
nodes:
- name: RS1
  image: slankdev/frr
  interfaces:
  - { name: net0, type: direct, args: S1#net0 }

- name: S1
  image: slankdev/frr
  interfaces:
  - { name: net0, type: direct, args: RS1#net0 }
  - { name: net1, type: direct, args: R1#net0 }
  - { name: net2, type: direct, args: R2#net0 }
  - { name: net3, type: direct, args: R3#net0 }

- name: R1
  image: slankdev/frr
  interfaces:
  - { name: net0, type: direct, args: S1#net1 }
  - { name: net1, type: direct, args: C1#net0 }

- name: R2
  image: slankdev/frr
  interfaces:
  - { name: net0, type: direct, args: S1#net2 }
  - { name: net1, type: direct, args: C2#net0 }
- name: R3
  image: slankdev/frr
  interfaces:
  - { name: net0, type: direct, args: S1#net3 }
  - { name: net1, type: direct, args: C3#net0 }

- name: C1
  image: slankdev/ubuntu:16.04
  interfaces:
  - { name: net0, type: direct, args: R1#net1 }
- name: C2
  image: slankdev/ubuntu:16.04
  interfaces:
  - { name: net0, type: direct, args: R2#net1 }
- name: C3
  image: slankdev/ubuntu:16.04
  interfaces:
  - { name: net0, type: direct, args: R3#net1 }

node_configs:
- name: RS1
  cmds:
  - cmd: ip addr add 10.255.1.1/24 dev net0
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 1"
      -c " bgp router-id 1.1.1.1"
      -c " neighbor 10.255.1.2 remote-as 100"
      -c " neighbor 10.255.11.1 remote-as 11"
      -c " neighbor 10.255.11.1 ebgp-multihop 64"
      -c " neighbor 10.255.12.1 remote-as 12"
      -c " neighbor 10.255.12.1 ebgp-multihop 64"
      -c " neighbor 10.255.13.1 remote-as 13"
      -c " neighbor 10.255.13.1 ebgp-multihop 64"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"

- name: S1
  cmds:
  - cmd: ip addr add 10.255.1.2/24 dev net0
  - cmd: ip addr add 10.255.11.2/24 dev net1
  - cmd: ip addr add 10.255.12.2/24 dev net2
  - cmd: ip addr add 10.255.13.2/24 dev net3
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 100"
      -c " bgp router-id 100.100.100.100"
      -c " neighbor 10.255.1.1 remote-as 1"
      -c " neighbor 10.255.11.1 remote-as 11"
      -c " neighbor 10.255.12.1 remote-as 12"
      -c " neighbor 10.255.13.1 remote-as 13"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"

- name: R1
  cmds:
  - cmd: ip addr add 10.255.11.1/24 dev net0
  - cmd: ip addr add 192.168.11.1/24 dev net1
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 11"
      -c " bgp router-id 11.11.11.11"
      -c " neighbor 10.255.11.2 remote-as 100"
      -c " neighbor 10.255.1.1 remote-as 1"
      -c " neighbor 10.255.1.1 ebgp-multihop 64"
      -c " neighbor 10.255.1.1 timer connect 1"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  neighbor 10.255.11.2 prefix-list core-out out"
      -c "  neighbor 10.255.11.2 prefix-list core-in in"
      -c "  neighbor 10.255.1.1 prefix-list rs-out out"
      -c "  neighbor 10.255.1.1 prefix-list rs-in in"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"
      -c "ip prefix-list core-out permit 10.255.0.0/16 le 32"
      -c "ip prefix-list core-in permit 10.255.0.0/16 le 32"
      -c "ip prefix-list rs-out permit 192.168.0.0/16 le 32"
      -c "ip prefix-list rs-in permit 192.168.0.0/16 le 32"


- name: R2
  cmds:
  - cmd: ip addr add 10.255.12.1/24 dev net0
  - cmd: ip addr add 192.168.12.1/24 dev net1
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 12"
      -c " bgp router-id 12.12.12.12"
      -c " neighbor 10.255.12.2 remote-as 100"
      -c " neighbor 10.255.1.1 remote-as 1"
      -c " neighbor 10.255.1.1 ebgp-multihop 64"
      -c " neighbor 10.255.1.1 timer connect 1"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  neighbor 10.255.12.2 prefix-list core-out out"
      -c "  neighbor 10.255.12.2 prefix-list core-in in"
      -c "  neighbor 10.255.1.1 prefix-list rs-out out"
      -c "  neighbor 10.255.1.1 prefix-list rs-in in"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"
      -c "ip prefix-list core-out permit 10.255.0.0/16 le 32"
      -c "ip prefix-list core-in permit 10.255.0.0/16 le 32"
      -c "ip prefix-list rs-out permit 192.168.0.0/16 le 32"
      -c "ip prefix-list rs-in permit 192.168.0.0/16 le 32"

- name: R3
  cmds:
  - cmd: ip addr add 10.255.13.1/24 dev net0
  - cmd: ip addr add 192.168.13.1/24 dev net1
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 13"
      -c " bgp router-id 13.13.13.13"
      -c " neighbor 10.255.13.2 remote-as 100"
      -c " neighbor 10.255.1.1 remote-as 1"
      -c " neighbor 10.255.1.1 ebgp-multihop 64"
      -c " neighbor 10.255.1.1 timer connect 1"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  neighbor 10.255.13.2 prefix-list core-out out"
      -c "  neighbor 10.255.13.2 prefix-list core-in in"
      -c "  neighbor 10.255.1.1 prefix-list rs-out out"
      -c "  neighbor 10.255.1.1 prefix-list rs-in in"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"
      -c "ip prefix-list core-out permit 10.255.0.0/16 le 32"
      -c "ip prefix-list core-in permit 10.255.0.0/16 le 32"
      -c "ip prefix-list rs-out permit 192.168.0.0/16 le 32"
      -c "ip prefix-list rs-in permit 192.168.0.0/16 le 32"

- name: C1
  cmds:
  - cmd: ip addr add 192.168.11.2/24 dev net0
  - cmd: ip route replace default via 192.168.11.1

- name: C2
  cmds:
  - cmd: ip addr add 192.168.12.2/24 dev net0
  - cmd: ip route replace default via 192.168.12.1

- name: C3
  cmds:
  - cmd: ip addr add 192.168.13.2/24 dev net0
  - cmd: ip route replace default via 192.168.13.1


================================================
FILE: examples/basic_bgp/spec.yaml
================================================

nodes:
  - name: R1
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R2#net0 }
  - name: R2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }

node_configs:
  - name: R1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: ip addr add 10.0.0.1/24 dev net0
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 65001"
          -c "bgp router-id 10.255.0.1"
          -c "neighbor 10.0.0.2 remote-as 65002"
  - name: R2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: ip addr add 10.0.0.2/24 dev net0
      - cmd: >-
          vtysh -c "conf t"
          -c "router bgp 65002"
          -c "bgp router-id 10.255.0.2"
          -c "neighbor 10.0.0.1 remote-as 65001"



================================================
FILE: examples/basic_bgp/unnumbered/spec.yaml
================================================
nodes:
- name: R1
  image: frrouting/frr:v8.1.0
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R2#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1
- name: R2
  image: frrouting/frr:v8.1.0
  docker_run_extra_args: --entrypoint bash
  interfaces:
  - { name: net0, type: direct, args: R1#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv4.ip_forward=1

node_configs:
- name: R1
  cmds:
  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c 'conf t'
      -c 'interface net0'
      -c ' ipv6 nd ra-interval 3'
      -c ' no ipv6 nd suppress-ra'
      -c '!'
      -c 'router bgp 65001'
      -c ' bgp router-id 10.255.0.1'
      -c ' bgp bestpath as-path multipath-relax'
      -c ' no bgp ebgp-requires-policy'
      -c ' neighbor PEER peer-group'
      -c ' neighbor PEER remote-as external'
      -c ' neighbor net0 interface peer-group PEER'
      -c ' !'
      -c ' address-family ipv4 unicast'
      -c '  redistribute connected'
      -c ' exit-address-family'

- name: R2
  cmds:
  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c 'conf t'
      -c 'interface net0'
      -c ' ipv6 nd ra-interval 3'
      -c ' no ipv6 nd suppress-ra'
      -c '!'
      -c 'router bgp 65002'
      -c ' bgp router-id 10.255.0.2'
      -c ' bgp bestpath as-path multipath-relax'
      -c ' no bgp ebgp-requires-policy'
      -c ' neighbor PEER peer-group'
      -c ' neighbor PEER remote-as external'
      -c ' neighbor net0 interface peer-group PEER'
      -c ' !'
      -c ' address-family ipv4 unicast'
      -c '  redistribute connected'
      -c ' exit-address-family'


================================================
FILE: examples/basic_bgp/vpnv4_mpls/README.md
================================================

# MP-BGP VPNv4 per-VRF w/ MPLS

![](./topo.png)

references: configure example of vpnv4 as small set.
https://gist.github.com/hkwi/5c116f05667a3abf43c7456fae32a529

setup
```
$ tn upconf | sudo sh
```

check vpn routes on R1
```
$ docker exec R1 vtysh -c 'show bgp ipv4 vpn'
BGP table version is 1, local router ID is 10.255.0.1, vrf id 0
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 65001:1
*> 20.1.0.0/24      0.0.0.0@6<         0         32768 ?
    UN=0.0.0.0 EC{100:1} label=80 type=bgp, subtype=5
Route Distinguisher: 65001:2
*> 20.3.0.0/24      0.0.0.0@7<         0         32768 ?
    UN=0.0.0.0 EC{100:2} label=81 type=bgp, subtype=5
Route Distinguisher: 65001:3
*> 20.5.0.0/24      0.0.0.0@8<         0         32768 ?
    UN=0.0.0.0 EC{100:1} label=82 type=bgp, subtype=5
Route Distinguisher: 65002:1
*> 20.2.0.0/24      10.0.0.2         0             0 65002 ?
    UN=10.0.0.2 EC{100:1} label=80 type=bgp, subtype=0
Route Distinguisher: 65002:2
*> 20.4.0.0/24      10.0.0.2         0             0 65002 ?
    UN=10.0.0.2 EC{100:2} label=81 type=bgp, subtype=0
Route Distinguisher: 65002:3
*> 20.6.0.0/24      10.0.0.2         0             0 65002 ?
    UN=10.0.0.2 EC{100:2} label=82 type=bgp, subtype=0

Displayed  6 routes and 6 total paths
```

check vrf's route on VRF1 on R1 (VPNv4 rt100:1)
```
docker exec R1 vtysh -c 'show ip route vrf vrf1'
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, D - SHARP,
       F - PBR,
       > - selected route, * - FIB route


VRF vrf1:
C>* 20.1.0.0/24 is directly connected, net1, 00:01:37
B>* 20.2.0.0/24 [200/0] via 10.0.0.2, net0(vrf Default-IP-Routing-Table), label 80, 00:01:30
B>* 20.5.0.0/24 [200/0] is directly connected, net3(vrf vrf3), 00:01:37
```



================================================
FILE: examples/basic_bgp/vpnv4_mpls/spec.yaml
================================================

nodes:
  - name: R1
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R2#net0 }
      - { name: net1, type: direct, args: C1#net0 }
      - { name: net2, type: direct, args: C3#net0 }
      - { name: net3, type: direct, args: C5#net0 }
  - name: R2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
      - { name: net1, type: direct, args: C2#net0 }
      - { name: net2, type: direct, args: C4#net0 }
      - { name: net3, type: direct, args: C6#net0 }
  - name: C1
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]
  - name: C2
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]
  - name: C3
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]
  - name: C4
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]
  - name: C5
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R1#net3 } ]
  - name: C6
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R2#net3 } ]

node_configs:
  - name: R1
    cmds:
      - cmd: sh -c 'echo 100000 > /proc/sys/net/mpls/platform_labels'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net0/input'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net1/input'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net2/input'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net3/input'
      - cmd: ip link add vrf1 type vrf table 10
      - cmd: ip link set vrf1 up
      - cmd: ip link add vrf2 type vrf table 20
      - cmd: ip link set vrf2 up
      - cmd: ip link add vrf3 type vrf table 30
      - cmd: ip link set vrf3 up
      - cmd: ip link set net1 vrf vrf1
      - cmd: ip link set net2 vrf vrf2
      - cmd: ip link set net3 vrf vrf3
      - cmd: tcpdump -ni net0 -w /tmp/R1.in.pcap &

      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf te'
          -c 'int net0'
          -c ' ip address 10.0.0.1/24'
          -c '!'
          -c 'int net1 vrf vrf1'
          -c ' ip address 20.1.0.1/24'
          -c '!'
          -c 'int net2 vrf vrf2'
          -c ' ip address 20.3.0.1/24'
          -c '!'
          -c 'int net3 vrf vrf3'
          -c ' ip address 20.5.0.1/24'
          -c '!'
          -c 'router bgp 65001'
          -c ' bgp router-id 10.255.0.1'
          -c ' neighbor 10.0.0.2 remote-as 65002'
          -c ' !'
          -c ' address-family ipv4 unicast'
          -c '  neighbor 10.0.0.2 activate'
          -c '  redistribute connected'
          -c '  redistribute static'
          -c ' exit-address-family'
          -c ' !'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.0.0.2 activate'
          -c ' exit-address-family'
          -c '!'
          -c 'router bgp 65001 vrf vrf1'
          -c ' address-family ipv4'
          -c '  export vpn'
          -c '  import vpn'
          -c '  rd vpn export 65001:1'
          -c '  rt vpn both 100:1'
          -c '  label vpn export auto'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'
          -c 'router bgp 65001 vrf vrf2'
          -c ' address-family ipv4'
          -c '  export vpn'
          -c '  import vpn'
          -c '  rd vpn export 65001:2'
          -c '  rt vpn both 100:2'
          -c '  label vpn export auto'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'
          -c 'router bgp 65001 vrf vrf3'
          -c ' address-family ipv4'
          -c '  export vpn'
          -c '  import vpn'
          -c '  rd vpn export 65001:3'
          -c '  rt vpn both 100:1'
          -c '  label vpn export auto'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'

  - name: R2
    cmds:
      - cmd: sh -c 'echo 100000 > /proc/sys/net/mpls/platform_labels'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net0/input'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net1/input'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net2/input'
      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net3/input'
      - cmd: ip link add vrf1 type vrf table 10
      - cmd: ip link set vrf1 up
      - cmd: ip link add vrf2 type vrf table 20
      - cmd: ip link set vrf2 up
      - cmd: ip link add vrf3 type vrf table 30
      - cmd: ip link set vrf3 up
      - cmd: ip link set net1 vrf vrf1
      - cmd: ip link set net2 vrf vrf2
      - cmd: ip link set net3 vrf vrf3
      - cmd: tcpdump -ni net0 -w /tmp/R2.in.pcap &

      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c 'conf te'
          -c 'int net0'
          -c ' ip address 10.0.0.2/24'
          -c '!'
          -c 'int net1 vrf vrf1'
          -c ' ip address 20.2.0.1/24'
          -c '!'
          -c 'int net2 vrf vrf2'
          -c ' ip address 20.4.0.1/24'
          -c '!'
          -c 'int net3 vrf vrf3'
          -c ' ip address 20.6.0.1/24'
          -c '!'
          -c 'router bgp 65002'
          -c ' bgp router-id 10.255.0.2'
          -c ' neighbor 10.0.0.1 remote-as 65001'
          -c ' !'
          -c ' address-family ipv4'
          -c '  neighbor 10.0.0.1 activate'
          -c '  redistribute connected'
          -c '  redistribute static'
          -c ' exit-address-family'
          -c ' !'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.0.0.1 activate'
          -c ' exit-address-family'
          -c '!'
          -c 'router bgp 65002 vrf vrf1'
          -c ' address-family ipv4'
          -c '  export vpn'
          -c '  import vpn'
          -c '  rd vpn export 65002:1'
          -c '  rt vpn both 100:1'
          -c '  label vpn export auto'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'
          -c 'router bgp 65002 vrf vrf2'
          -c ' address-family ipv4'
          -c '  export vpn'
          -c '  import vpn'
          -c '  rd vpn export 65002:2'
          -c '  rt vpn both 100:2'
          -c '  label vpn export auto'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'
          -c 'router bgp 65002 vrf vrf3'
          -c ' address-family ipv4'
          -c '  export vpn'
          -c '  import vpn'
          -c '  rd vpn export 65002:3'
          -c '  rt vpn both 100:2'
          -c '  label vpn export auto'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c '!'

  - name: C1
    cmds:
      - cmd: ip addr replace 20.1.0.2/24 dev net0
      - cmd: ip route replace default via 20.1.0.1
  - name: C2
    cmds:
      - cmd: ip addr replace 20.2.0.2/24 dev net0
      - cmd: ip route replace default via 20.2.0.1
  - name: C3
    cmds:
      - cmd: ip addr replace 20.3.0.2/24 dev net0
      - cmd: ip route replace default via 20.3.0.1
  - name: C4
    cmds:
      - cmd: ip addr replace 20.4.0.2/24 dev net0
      - cmd: ip route replace default via 20.4.0.1
  - name: C5
    cmds:
      - cmd: ip addr replace 20.5.0.2/24 dev net0
      - cmd: ip route replace default via 20.5.0.1
  - name: C6
    cmds:
      - cmd: ip addr replace 20.6.0.2/24 dev net0
      - cmd: ip route replace default via 20.6.0.1

test:
  - name: p2p
    cmds:
    - cmd: echo slankdev slankdev
    - cmd: echo slankdev slankdev



================================================
FILE: examples/basic_bgp/vpnv4_srmpls/README.md
================================================
# MP-BGP VPNv4 per-VRF w/ SR-MPLS

![](./topo.png)

setup
```
$ tn upconf | sudo sh
```


================================================
FILE: examples/basic_bgp/vpnv4_srmpls/spec.yaml
================================================
preinit:
  - cmds:
    - cmd: modprobe mpls_router
    - cmd: modprobe mpls_gso
    - cmd: modprobe mpls_iptunnel

nodes:
  - name: R1
    image: frrouting/frr:v7.5.1
    docker_run_extra_args: --entrypoint bash
    interfaces:
    - { name: net0, type: direct, args: R2#net0 }
    - { name: net1, type: direct, args: R4#net0 }
    - { name: net2, type: direct, args: HostA1#net0 }
    - { name: net3, type: direct, args: HostB1#net0 }
  - name: R2
    image: frrouting/frr:v7.5.1
    docker_run_extra_args: --entrypoint bash
    interfaces:
    - { name: net0, type: direct, args: R1#net0 }
    - { name: net1, type: direct, args: R3#net0 }
    - { name: net2, type: direct, args: R4#net1 }
  - name: R3
    image: frrouting/frr:v7.5.1
    docker_run_extra_args: --entrypoint bash
    interfaces:
    - { name: net0, type: direct, args: R2#net1 }
    - { name: net1, type: direct, args: R4#net2 }
    - { name: net2, type: direct, args: HostA2#net0 }
    - { name: net3, type: direct, args: HostB2#net0 }
  - name: R4
    image: frrouting/frr:v7.5.1
    docker_run_extra_args: --entrypoint bash
    interfaces:
    - { name: net0, type: direct, args: R1#net1 }
    - { name: net1, type: direct, args: R2#net2 }
    - { name: net2, type: direct, args: R3#net1 }
  - name: HostA1
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: R1#net2 }
  - name: HostA2
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: R3#net2 }
  - name: HostB1
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: R1#net3 }
  - name: HostB2
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: R3#net3 }

node_configs:
  - name: R1
    cmds:
      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
      - cmd: sed -i -e 's/ospfd=no/ospfd=yes/g' /etc/frr/daemons
      - cmd: sed -i -e 's/pimd=no/pimd=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575

      - cmd: ip link add CUST-A type vrf table 10
      - cmd: ip link add CUST-B type vrf table 20
      - cmd: ip link set CUST-A up
      - cmd: ip link set CUST-B up
      - cmd: ip link set net2 master CUST-A
      - cmd: ip link set net3 master CUST-B

      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.1/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.1/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.9/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net2'
          -c ' ip address 192.168.0.1/24'
          -c 'exit'
          -c 'interface net3'
          -c ' ip address 192.168.0.1/24'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.1'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.1'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.1/32 index 1001'
          -c 'exit'
          -c 'router bgp 65000'
          -c ' neighbor 10.255.0.3 remote-as 65000'
          -c ' neighbor 10.255.0.3 update-source 10.255.0.1'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.255.0.3 activate'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-A'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:10'
          -c '  rt vpn both 65000:10'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-B'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:20'
          -c '  rt vpn both 65000:20'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
  - name: R2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.conf.net2.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.2/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.2/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.5/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net2'
          -c ' ip address 10.0.0.13/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.2'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.2'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.2/32 index 1002'
          -c 'exit'
  - name: R3
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575

      - cmd: ip link add CUST-A type vrf table 10
      - cmd: ip link add CUST-B type vrf table 20
      - cmd: ip link set CUST-A up
      - cmd: ip link set CUST-B up
      - cmd: ip link set net2 master CUST-A
      - cmd: ip link set net3 master CUST-B

      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.3/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.6/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.17/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net2'
          -c ' ip address 192.168.1.1/24'
          -c 'exit'
          -c 'interface net3'
          -c ' ip address 192.168.1.1/24'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.3'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.3'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.3/32 index 1003'
          -c 'exit'
          -c 'router bgp 65000'
          -c ' neighbor 10.255.0.1 remote-as 65000'
          -c ' neighbor 10.255.0.1 update-source 10.255.0.3'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.255.0.1 activate'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-A'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:10'
          -c '  rt vpn both 65000:10'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-B'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:20'
          -c '  rt vpn both 65000:20'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
  - name: R4
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.conf.net2.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.4/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.10/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.14/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net2'
          -c ' ip address 10.0.0.18/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.4'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.4'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.4/32 index 1004'
          -c 'exit'
  - name: HostA1
    cmds:
      - cmd: ip addr add 192.168.0.2/24 dev net0
      - cmd: ip route add default via 192.168.0.1
  - name: HostA2
    cmds:
      - cmd: ip addr add 192.168.1.2/24 dev net0
      - cmd: ip route add default via 192.168.1.1
  - name: HostB1
    cmds:
      - cmd: ip addr add 192.168.0.2/24 dev net0
      - cmd: ip route add default via 192.168.0.1
  - name: HostB2
    cmds:
      - cmd: ip addr add 192.168.1.2/24 dev net0
      - cmd: ip route add default via 192.168.1.1

test:
  - cmds:
    ## SR-MPLS Operation
    - cmd: docker exec R1 ip route add 10.255.0.3/32 encap mpls 17004/17003 via 10.0.0.2
    - cmd: docker exec R3 ip route add 10.255.0.1/32 encap mpls 17002/17001 via 10.0.0.18
    ## SR-MPLS Test
    - cmd: docker exec HostA1 ping -c2 192.168.1.2


================================================
FILE: examples/basic_bgp/vpnv4_srmpls_interas_option-b/README.md
================================================
# MP-BGP VPNv4 per-VRF Inter-AS Option B w/ SR-MPLS

![](./topo.png)

setup
```
$ tn upconf | sudo sh
```


================================================
FILE: examples/basic_bgp/vpnv4_srmpls_interas_option-b/spec.yaml
================================================
preinit:
  - cmds:
    - cmd: modprobe mpls_router
    - cmd: modprobe mpls_gso
    - cmd: modprobe mpls_iptunnel

nodes:
  ## AS65000
  - name: ASBR1
    image: frrouting/frr:v7.5.1
    interfaces:
    - { name: net0, type: direct, args: ASBR2#net0 }
    - { name: net1, type: direct, args: P1#net0 }
  - name: P1
    image: frrouting/frr:v7.5.1
    interfaces:
    - { name: net0, type: direct, args: ASBR1#net1 }
    - { name: net1, type: direct, args: PE1#net0 }
  - name: PE1
    image: frrouting/frr:v7.5.1
    interfaces:
    - { name: net0, type: direct, args: P1#net1 }
    - { name: net1, type: direct, args: HostA1#net0 }
    - { name: net2, type: direct, args: HostB1#net0 }
  - name: HostA1
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: PE1#net1 }
  - name: HostB1
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: PE1#net2 }
  ## AS65001
  - name: ASBR2
    image: frrouting/frr:v7.5.1
    interfaces:
    - { name: net0, type: direct, args: ASBR1#net0 }
    - { name: net1, type: direct, args: P2#net0 }
  - name: P2
    image: frrouting/frr:v7.5.1
    interfaces:
    - { name: net0, type: direct, args: ASBR2#net1 }
    - { name: net1, type: direct, args: PE2#net0 }
  - name: PE2
    image: frrouting/frr:v7.5.1
    interfaces:
    - { name: net0, type: direct, args: P2#net1 }
    - { name: net1, type: direct, args: HostA2#net0 }
    - { name: net2, type: direct, args: HostB2#net0 }
  - name: HostA2
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: PE2#net1 }
  - name: HostB2
    image: slankdev/ubuntu:18.04
    interfaces:
    - { name: net0, type: direct, args: PE2#net2 }

node_configs:
  - name: ASBR1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575

      - cmd: ip link add CUST-A type vrf table 10
      - cmd: ip link add CUST-B type vrf table 20
      - cmd: ip link set CUST-A up
      - cmd: ip link set CUST-B up

      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.1/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 172.16.0.1/30'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.1/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.1'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.1'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.1/32 index 1001'
          -c 'exit'
          -c 'router bgp 65000'
          -c ' neighbor 10.255.0.3 remote-as 65000'
          -c ' neighbor 10.255.0.3 update-source 10.255.0.1'
          -c ' neighbor 172.16.0.2 remote-as 65001'
          -c ' neighbor 172.16.0.2 update-source 172.16.0.1'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.255.0.3 activate'
          -c '  neighbor 10.255.0.3 next-hop-self'
          -c '  neighbor 172.16.0.2 activate'
          -c '  neighbor 172.16.0.2 route-map AS65001-IN in'
          -c '  neighbor 172.16.0.2 route-map AS65001-OUT out'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-A'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:10'
          -c '  rt vpn both 65000:10'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-B'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:20'
          -c '  rt vpn both 65000:20'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'bgp extcommunity-list 1 seq 1 permit rt 65000:10'
          -c 'bgp extcommunity-list 2 seq 1 permit rt 65000:20'
          -c 'route-map AS65001-IN permit 1'
          -c 'route-map AS65001-OUT permit 1'
          -c ' match extcommunity 1'
          -c ' set extcommunity rt 65001:10'
          -c 'route-map AS65001-OUT permit 2'
          -c ' match extcommunity 2'
          -c ' set extcommunity rt 65001:20'

  - name: P1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.2/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.2/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.0.5/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.2'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.2'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.2/32 index 1002'
          -c 'exit'

  - name: PE1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575

      - cmd: ip link add CUST-A type vrf table 10
      - cmd: ip link add CUST-B type vrf table 20
      - cmd: ip link set CUST-A up
      - cmd: ip link set CUST-B up
      - cmd: ip link set net1 master CUST-A
      - cmd: ip link set net2 master CUST-B

      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.3/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.0.6/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 192.168.0.1/24'
          -c 'exit'
          -c 'interface net2'
          -c ' ip address 192.168.0.1/24'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.3'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.3'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.3/32 index 1003'
          -c 'exit'
          -c 'router bgp 65000'
          -c ' neighbor 10.255.0.1 remote-as 65000'
          -c ' neighbor 10.255.0.1 update-source 10.255.0.3'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.255.0.1 activate'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-A'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:10'
          -c '  rt vpn both 65000:10'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65000 vrf CUST-B'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65000:20'
          -c '  rt vpn both 65000:20'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'

  - name: ASBR2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575

      - cmd: ip link add CUST-A type vrf table 10
      - cmd: ip link add CUST-B type vrf table 20
      - cmd: ip link set CUST-A up
      - cmd: ip link set CUST-B up

      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.1/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 172.16.0.2/30'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.1.1/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.1'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.1'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.1/32 index 1001'
          -c 'exit'
          -c 'router bgp 65001'
          -c ' neighbor 10.255.0.3 remote-as 65001'
          -c ' neighbor 10.255.0.3 update-source 10.255.0.1'
          -c ' neighbor 172.16.0.1 remote-as 65000'
          -c ' neighbor 172.16.0.1 update-source 172.16.0.2'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.255.0.3 activate'
          -c '  neighbor 10.255.0.3 next-hop-self'
          -c '  neighbor 172.16.0.1 activate'
          -c '  neighbor 172.16.0.1 route-map AS65000-IN in'
          -c '  neighbor 172.16.0.1 route-map AS65000-OUT out'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65001 vrf CUST-A'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65001:10'
          -c '  rt vpn both 65001:10'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65001 vrf CUST-B'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65001:20'
          -c '  rt vpn both 65001:20'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'bgp extcommunity-list 1 seq 1 permit rt 65001:10'
          -c 'bgp extcommunity-list 2 seq 1 permit rt 65001:20'
          -c 'route-map AS65000-IN permit 1'
          -c 'route-map AS65000-OUT permit 1'
          -c ' match extcommunity 1'
          -c ' set extcommunity rt 65000:10'
          -c 'route-map AS65000-OUT permit 2'
          -c ' match extcommunity 2'
          -c ' set extcommunity rt 65000:20'

  - name: P2
    cmds:
      - cmd: /usr/lib/fro/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.conf.net1.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575
      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.2/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.1.2/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 10.0.1.5/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.2'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.2'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.2/32 index 1002'
          -c 'exit'

  - name: PE2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons
      - cmd: /usr/lib/frr/frrinit.sh restart
      - cmd: sysctl -w net.ipv4.ip_forward=1
      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0
      - cmd: sysctl -w net.mpls.conf.lo.input=1
      - cmd: sysctl -w net.mpls.conf.net0.input=1
      - cmd: sysctl -w net.mpls.platform_labels=1048575

      - cmd: ip link add CUST-A type vrf table 10
      - cmd: ip link add CUST-B type vrf table 20
      - cmd: ip link set CUST-A up
      - cmd: ip link set CUST-B up
      - cmd: ip link set net1 master CUST-A
      - cmd: ip link set net2 master CUST-B

      - cmd: >-
          vtysh -c 'conf t'
          -c 'interface lo'
          -c ' ip address 10.255.0.3/32'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net0'
          -c ' ip address 10.0.1.6/30'
          -c ' ip ospf area 0.0.0.0'
          -c 'exit'
          -c 'interface net1'
          -c ' ip address 192.168.1.1/24'
          -c 'exit'
          -c 'interface net2'
          -c ' ip address 192.168.1.1/24'
          -c 'exit'
          -c 'router ospf'
          -c ' ospf router-id 10.255.0.3'
          -c ' router-info area 0.0.0.0'
          -c ' passive-interface lo'
          -c ' capability opaque'
          -c ' mpls-te on'
          -c ' mpls-te router-address 10.255.0.3'
          -c ' segment-routing on'
          -c ' segment-routing global-block 16000 19999'
          -c ' segment-routing node-msd 8'
          -c ' segment-routing prefix 10.255.0.3/32 index 1003'
          -c 'exit'
          -c 'router bgp 65001'
          -c ' neighbor 10.255.0.1 remote-as 65001'
          -c ' neighbor 10.255.0.1 update-source 10.255.0.3'
          -c ' address-family ipv4 vpn'
          -c '  neighbor 10.255.0.1 activate'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65001 vrf CUST-A'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65001:10'
          -c '  rt vpn both 65001:10'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'
          -c 'router bgp 65001 vrf CUST-B'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c '  label vpn export auto'
          -c '  rd vpn export 65001:20'
          -c '  rt vpn both 65001:20'
          -c '  export vpn'
          -c '  import vpn'
          -c ' exit-address-family'
          -c 'exit'

  - name: HostA1
    cmds:
      - cmd: ip addr add 192.168.0.2/24 dev net0
      - cmd: ip route add default via 192.168.0.1
  - name: HostA2
    cmds:
      - cmd: ip addr add 192.168.1.2/24 dev net0
      - cmd: ip route add default via 192.168.1.1
  - name: HostB1
    cmds:
      - cmd: ip addr add 192.168.0.2/24 dev net0
      - cmd: ip route add default via 192.168.0.1
  - name: HostB2
    cmds:
      - cmd: ip addr add 192.168.1.2/24 dev net0
      - cmd: ip route add default via 192.168.1.1

test:
  - cmds:
    ## SR-MPLS Test
    - cmd: docker exec HostA1 ping -c2 192.168.1.2


================================================
FILE: examples/basic_bgp/vpnv4_srv6/Makefile
================================================

help:
	@echo help

build:
	make -C /home/vagrant/git/frr.slankdev
	sudo make -C /home/vagrant/git/frr.slankdev install

install:
	docker exec R1 rm -rf /usr/lib/frr
	docker cp /usr/lib/frr R1:/usr/lib/frr
	docker cp /usr/bin/vtysh R1:/usr/bin/vtysh
	\
	docker exec R2 rm -rf /usr/lib/frr
	docker cp /usr/lib/frr R2:/usr/lib/frr
	docker cp /usr/bin/vtysh R2:/usr/bin/vtysh

config_srv6_only:
	docker cp frr.conf.srv6.R1 R1:/etc/frr/frr.conf
	docker cp frr.conf.srv6.R2 R2:/etc/frr/frr.conf

stop:
	docker exec R1 /usr/lib/frr/frrinit.sh stop
	docker exec R2 /usr/lib/frr/frrinit.sh stop

start:
	docker exec R1 /usr/lib/frr/frrinit.sh start
	docker exec R2 /usr/lib/frr/frrinit.sh start

restart:
	docker exec R1 /usr/lib/frr/frrinit.sh restart
	docker exec R2 /usr/lib/frr/frrinit.sh restart

capture:
	docker exec R1 pkill tcpdump | true
	docker exec R2 pkill tcpdump | true
	docker exec -d R1 tcpdump -ni net0 -w /tmp/r1.pcap
	docker exec -d R2 tcpdump -ni net0 -w /tmp/r2.pcap

nocapture:
	docker exec R1 pkill tcpdump | true
	docker exec R2 pkill tcpdump | true
	docker cp R1:/tmp/r1.pcap /vagrant/r1.pcap
	docker cp R2:/tmp/r2.pcap /vagrant/r2.pcap

rere:
	make -C . build
	make -C . install
	make -C . reload

taillog_R1:
	while :; do \
		docker exec -it R1 touch /tmp/frr.log; \
		docker exec -it R1 chown frr.frr /tmp/frr.log; \
		docker exec -it R1 tail -f /tmp/frr.log -n0; \
		sleep 1 ; done
taillog_R2:
	while :; do \
		docker exec -it R2 touch /tmp/frr.log; \
		docker exec -it R2 chown frr.frr /tmp/frr.log; \
		docker exec -it R2 tail -f /tmp/frr.log -n0; \
		sleep 1 ; done

tn_reconf:
	tn reconf | sudo sh
	make -C . install
	make -C . config_srv6_only

sh_route_vrfs:
	@echo -e '\n[[R1-glb]]'
	@docker exec R1 ip route list
	@docker exec R1 ip -6 route list
	@echo -e '\n[[R1-vrf1]]'
	@docker exec R1 ip route list vrf vrf1
	@echo -e '\n[[R1-vrf2]]'
	@docker exec R1 ip route list vrf vrf2
	@echo -e '\n[[R1-vrf3]]'
	@docker exec R1 ip route list vrf vrf3
	@echo -e '\n[[R2-glb]]'
	@docker exec R2 ip route list
	@docker exec R2 ip -6 route list
	@echo -e '\n[[R2-vrf1]]'
	@docker exec R2 ip route list vrf vrf1
	@echo -e '\n[[R2-vrf2]]'
	@docker exec R2 ip route list vrf vrf2
	@echo -e '\n[[R2-vrf3]]'
	@docker exec R2 ip route list vrf vrf3
	@echo



================================================
FILE: examples/basic_bgp/vpnv4_srv6/README.md
================================================

# FRR meets BGP-SRv6-VPNv4

MP-BGP VPNv4 per-VRF w/ SRv6..?

![](./topo.png)

```
$ make sh_route_vrfs

[[R1-glb]]
169.254.99.10 dev vrf1 scope link
169.254.99.20 dev vrf2 scope link
169.254.99.30 dev vrf3 scope link
1:1::  encap seg6local action End.DX4 nh4 169.254.99.10 dev net0 metric 1024 pref medium
1:2::  encap seg6local action End.DX4 nh4 169.254.99.20 dev net0 metric 1024 pref medium
1:3::  encap seg6local action End.DX4 nh4 169.254.99.30 dev net0 metric 1024 pref medium
2:1:: via 2001::2 dev net0 metric 1024 pref medium
2:2:: via 2001::2 dev net0 metric 1024 pref medium
2:3:: via 2001::2 dev net0 metric 1024 pref medium
2001::/64 dev net0 proto kernel metric 256 pref medium
fe80::/64 dev net0 proto kernel metric 256 pref medium

[[R1-vrf1]]
30.1.0.0/24 dev net1 proto kernel scope link src 30.1.0.1
30.2.0.0/24  encap seg6 mode encap segs 1 [ 2:1:: ] dev net0 scope link

[[R1-vrf2]]
30.3.0.0/24 dev net2 proto kernel scope link src 30.3.0.1
30.4.0.0/24  encap seg6 mode encap segs 1 [ 2:2:: ] dev net0 scope link

[[R1-vrf3]]
30.5.0.0/24 dev net3 proto kernel scope link src 30.5.0.1
30.6.0.0/24  encap seg6 mode encap segs 1 [ 2:3:: ] dev net0 scope link

[[R2-glb]]
169.254.99.10 dev vrf1 scope link
169.254.99.20 dev vrf2 scope link
169.254.99.30 dev vrf3 scope link
1:1:: via 2001::1 dev net0 metric 1024 pref medium
1:2:: via 2001::1 dev net0 metric 1024 pref medium
1:3:: via 2001::1 dev net0 metric 1024 pref medium
2:1::  encap seg6local action End.DX4 nh4 169.254.99.10 dev net0 metric 1024 pref medium
2:2::  encap seg6local action End.DX4 nh4 169.254.99.20 dev net0 metric 1024 pref medium
2:3::  encap seg6local action End.DX4 nh4 169.254.99.30 dev net0 metric 1024 pref medium
2001::/64 dev net0 proto kernel metric 256 pref medium
fe80::/64 dev net0 proto kernel metric 256 pref medium

[[R2-vrf1]]
30.1.0.0/24  encap seg6 mode encap segs 1 [ 1:1:: ] dev net0 scope link
30.2.0.0/24 dev net1 proto kernel scope link src 30.2.0.1

[[R2-vrf2]]
30.3.0.0/24  encap seg6 mode encap segs 1 [ 1:2:: ] dev net0 scope link
30.4.0.0/24 dev net2 proto kernel scope link src 30.4.0.1

[[R2-vrf3]]
30.5.0.0/24  encap seg6 mode encap segs 1 [ 1:3:: ] dev net0 scope link
30.6.0.0/24 dev net3 proto kernel scope link src 30.6.0.1
```



================================================
FILE: examples/basic_bgp/vpnv4_srv6/frr.conf.srv6.R1
================================================
hostname R1
log file /tmp/frr.log
!
debug bgp vpn label
debug bgp vpn leak-from-vrf
debug bgp vpn leak-to-vrf
debug bgp vpn rmap-event
debug bgp vpn adv-prefix-sid
!
int net0
 ipv6 address 2001::1/64
!
int net1 vrf vrf1
 ip address 30.1.0.1/24
!
int net2 vrf vrf2
 ip address 30.3.0.1/24
!
int net3 vrf vrf3
 ip address 30.5.0.1/24
!
router bgp 65001
 bgp router-id 10.255.0.1
 neighbor 2001::2 remote-as 65002
 !
 address-family ipv4 unicast
  redistribute connected
  redistribute static
 exit-address-family
 !
 address-family ipv4 srv6-vpn
  neighbor 2001::2 activate
 exit-address-family
!
router bgp 65001 vrf vrf1
 bgp router-id 10.255.0.1
 !
 address-family ipv4 unicast
  redistribute connected
  sid srv6-vpn export 1:1::
  rd srv6-vpn export 65001:1
  rt srv6-vpn both 100:1
  export srv6-vpn
  import srv6-vpn
 exit-address-family
!
router bgp 65001 vrf vrf2
 bgp router-id 10.255.0.1
 !
 address-family ipv4 unicast
  redistribute connected
  sid srv6-vpn export 1:2::
  rd srv6-vpn export 65001:2
  rt srv6-vpn both 100:2
  export srv6-vpn
  import srv6-vpn
 exit-address-family
!
router bgp 65001 vrf vrf3
 bgp router-id 10.255.0.1
 !
 address-family ipv4 unicast
  redistribute connected
  sid srv6-vpn export 1:3::
  rd srv6-vpn export 65001:3
  rt srv6-vpn both 100:3
  export srv6-vpn
  import srv6-vpn
 exit-address-family
!
line vty
!


================================================
FILE: examples/basic_bgp/vpnv4_srv6/frr.conf.srv6.R2
================================================
hostname R2
log file /tmp/frr.log
!
debug bgp vpn label
debug bgp vpn leak-from-vrf
debug bgp vpn leak-to-vrf
debug bgp vpn rmap-event
debug bgp vpn adv-prefix-sid
!
int net0
 ipv6 address 2001::2/64
!
int net1 vrf vrf1
 ip address 30.2.0.1/24
!
int net2 vrf vrf2
 ip address 30.4.0.1/24
!
int net3 vrf vrf3
 ip address 30.6.0.1/24
!
router bgp 65002
 bgp router-id 10.255.0.2
 neighbor 2001::1 remote-as 65001
 !
 address-family ipv4 unicast
  redistribute connected
  redistribute static
 exit-address-family
 !
 address-family ipv4 srv6-vpn
  neighbor 2001::1 activate
 exit-address-family
!
router bgp 65002 vrf vrf1
 bgp router-id 10.255.0.2
 !
 address-family ipv4 unicast
  redistribute connected
  sid srv6-vpn export 2:1::
  rd srv6-vpn export 65002:1
  rt srv6-vpn both 100:1
  export srv6-vpn
  import srv6-vpn
 exit-address-family
!
router bgp 65002 vrf vrf2
 bgp router-id 10.255.0.2
 !
 address-family ipv4 unicast
  redistribute connected
  sid srv6-vpn export 2:2::
  rd srv6-vpn export 65002:2
  rt srv6-vpn both 100:2
  export srv6-vpn
  import srv6-vpn
 exit-address-family
!
router bgp 65002 vrf vrf3
 bgp router-id 10.255.0.2
 !
 address-family ipv4 unicast
  redistribute connected
  sid srv6-vpn export 2:3::
  rd srv6-vpn export 65002:3
  rt srv6-vpn both 100:3
  export srv6-vpn
  import srv6-vpn
 exit-address-family
!
line vty
!


================================================
FILE: examples/basic_bgp/vpnv4_srv6/spec.yaml
================================================

nodes:

  - name: R1
    image: slankdev/frr-7.3:slankdev-support-mpbgp-vpnv4-srv6-cplane
    interfaces:
      - { name: net0, type: direct, args: R2#net0 }
      - { name: net1, type: direct, args: C1#net0 }
      - { name: net2, type: direct, args: C3#net0 }
      - { name: net3, type: direct, args: C5#net0 }

  - name: R2
    image: slankdev/frr-7.3:slankdev-support-mpbgp-vpnv4-srv6-cplane
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
      - { name: net1, type: direct, args: C2#net0 }
      - { name: net2, type: direct, args: C4#net0 }
      - { name: net3, type: direct, args: C6#net0 }

  - name: C1
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]
  - name: C2
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]
  - name: C3
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]
  - name: C4
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]
  - name: C5
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R1#net3 } ]
  - name: C6
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: R2#net3 } ]

node_configs:
  - name: R1
    cmds:
      - cmd: bash -c "enable_seg6_router.py | sh"
      - cmd: touch /etc/frr/frr.conf

      - cmd: ip link add vrf1 type vrf table 10
      - cmd: ip link set vrf1 up
      - cmd: ip link set net1 vrf vrf1
      - cmd: ip route add 169.254.99.10 dev vrf1

      - cmd: ip link add vrf2 type vrf table 20
      - cmd: ip link set vrf2 up
      - cmd: ip link set net2 vrf vrf2
      - cmd: ip route add 169.254.99.20 dev vrf2

      - cmd: ip link add vrf3 type vrf table 30
      - cmd: ip link set vrf3 up
      - cmd: ip link set net3 vrf vrf3
      - cmd: ip route add 169.254.99.30 dev vrf3

  - name: R2
    cmds:
      - cmd: bash -c "enable_seg6_router.py | sh"
      - cmd: touch /etc/frr/frr.conf

      - cmd: ip link add vrf1 type vrf table 10
      - cmd: ip link set vrf1 up
      - cmd: ip link set net1 vrf vrf1
      - cmd: ip route add 169.254.99.10 dev vrf1

      - cmd: ip link add vrf2 type vrf table 20
      - cmd: ip link set vrf2 up
      - cmd: ip link set net2 vrf vrf2
      - cmd: ip route add 169.254.99.20 dev vrf2

      - cmd: ip link add vrf3 type vrf table 30
      - cmd: ip link set vrf3 up
      - cmd: ip link set net3 vrf vrf3
      - cmd: ip route add 169.254.99.30 dev vrf3

  - name: C1
    cmds:
      - cmd: ip addr replace 30.1.0.2/24 dev net0
      - cmd: ip route replace default via 30.1.0.1
  - name: C2
    cmds:
      - cmd: ip addr replace 30.2.0.2/24 dev net0
      - cmd: ip route replace default via 30.2.0.1
  - name: C3
    cmds:
      - cmd: ip addr replace 30.3.0.2/24 dev net0
      - cmd: ip route replace default via 30.3.0.1
  - name: C4
    cmds:
      - cmd: ip addr replace 30.4.0.2/24 dev net0
      - cmd: ip route replace default via 30.4.0.1
  - name: C5
    cmds:
      - cmd: ip addr replace 30.5.0.2/24 dev net0
      - cmd: ip route replace default via 30.5.0.1
  - name: C6
    cmds:
      - cmd: ip addr replace 30.6.0.2/24 dev net0
      - cmd: ip route replace default via 30.6.0.1



================================================
FILE: examples/basic_bgp/vpnv6_srv6_rs/spec.yaml
================================================
nodes:
- name: RS1
  image: tinynetwork/frr:develop
  interfaces:
  - { name: net0, type: direct, args: S1#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

- name: S1
  image: slankdev/frr
  interfaces:
  - { name: net0, type: direct, args: RS1#net0 }
  - { name: net1, type: direct, args: R1#net0 }
  - { name: net2, type: direct, args: R2#net0 }
  - { name: net3, type: direct, args: R3#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

- name: R1
  image: tinynetwork/frr:develop
  interfaces:
  - { name: net0, type: direct, args: S1#net1 }
  - { name: net1, type: direct, args: C1#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1
- name: R2
  image: tinynetwork/frr:develop
  interfaces:
  - { name: net0, type: direct, args: S1#net2 }
  - { name: net1, type: direct, args: C2#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1
- name: R3
  image: tinynetwork/frr:develop
  interfaces:
  - { name: net0, type: direct, args: S1#net3 }
  - { name: net1, type: direct, args: C3#net0 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

- name: C1
  image: tinynetwork/frr:develop
  interfaces:
  - { name: net0, type: direct, args: R1#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1
- name: C2
  image: tinynetwork/frr:develop
  interfaces:
  - { name: net0, type: direct, args: R2#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1
- name: C3
  image: tinynetwork/frr:develop
  interfaces:
  - { name: net0, type: direct, args: R3#net1 }
  sysctls:
  - sysctl: net.ipv6.conf.all.disable_ipv6=0
  - sysctl: net.ipv6.conf.default.disable_ipv6=0
  - sysctl: net.ipv6.conf.all.forwarding=1

node_configs:
- name: RS1
  cmds:
  - cmd: ip addr add 10.255.0.1/32 dev lo
  - cmd: ip addr add 2001:db8:e:1::0/128 dev lo
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 1"
      -c " bgp router-id 1.1.1.1"
      -c " no bgp ebgp-requires-policy"
      -c " !"
      -c " neighbor PEER peer-group"
      -c " neighbor PEER remote-as external"
      -c " neighbor net0 interface peer-group PEER"
      -c " !"
      -c " neighbor PE peer-group"
      -c " neighbor PE remote-as external"
      -c " neighbor PE ebgp-multihop 255"
      -c " bgp listen range 2001:db8:e::/48 peer-group PE"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  neighbor PEER activate"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 vpn"
      -c "  neighbor PE activate"
      -c " exit-address-family"
      -c "!"

- name: S1
  cmds:
  - cmd: ip addr add 10.255.0.100/32 dev lo
  - cmd: /usr/lib/frr/frr start
  - cmd: >-
      vtysh -c "conf t"
      -c "router bgp 100"
      -c " bgp router-id 100.100.100.100"
      -c " !"
      -c " neighbor PEER peer-group"
      -c " neighbor PEER remote-as external"
      -c " neighbor net0 interface peer-group PEER"
      -c " neighbor net1 interface peer-group PEER"
      -c " neighbor net2 interface peer-group PEER"
      -c " neighbor net3 interface peer-group PEER"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  neighbor PEER activate"
      -c "  network 0::/0"
      -c " exit-address-family"
      -c "!"

- name: R1
  cmds:
  - cmd: ip addr add 10.255.0.11/32 dev lo
  - cmd: ip addr add 2001:db8:e:11::0/128 dev lo
  - cmd: ip link add vrf1 type vrf table 1001
  - cmd: ip link set vrf1 up
  - cmd: ip link set net1 master vrf1
  - cmd: ip -6 addr add 2001:11::1/64 dev net1
  - cmd: ip sr tunsrc set 2001:db8:f:1::0
  - cmd: ip -6 rule add to 2001:db8::/32 pref 1 table main
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c "conf t"
      -c "segment-routing"
      -c " srv6"
      -c "  locators"
      -c "   locator default"
      -c "     prefix 2001:db8:f:1::/64"
      -c "   !"
      -c "  !"
      -c " !"
      -c "!"
      -c "ipv6 route 2001:db8:f:1::/64 Null0"
      -c "!"
      -c "router bgp 11"
      -c " bgp router-id 11.11.11.11"
      -c " no bgp ebgp-requires-policy"
      -c " !"
      -c " neighbor PEER peer-group"
      -c " neighbor PEER remote-as external"
      -c " neighbor net0 interface peer-group PEER"
      -c " !"
      -c " neighbor PE peer-group"
      -c " neighbor PE remote-as external"
      -c " neighbor PE ebgp-multihop 255"
      -c " neighbor 2001:db8:e:1:: peer-group PE"
      -c " !"
      -c " segment-routing srv6"
      -c "  locator default"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  redistribute connected"
      -c "  network 2001:db8:f:1::/64"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 vpn"
      -c "  neighbor PE activate"
      -c " exit-address-family"
      -c "!"
      -c "router bgp 11 vrf vrf1"
      -c " bgp router-id 11.11.11.11"
      -c " no bgp ebgp-requires-policy"
      -c " neighbor 2001:11::2 remote-as external"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  neighbor 2001:11::2 activate"
      -c "  sid vpn export auto"
      -c "  rd vpn export 11:1001"
      -c "  rt vpn export 1:1001"
      -c "  rt vpn import 1:1001"
      -c "  import vpn"
      -c "  export vpn"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"

- name: R2
  cmds:
  - cmd: ip addr add 10.255.0.12/32 dev lo
  - cmd: ip addr add 2001:db8:e:12::0/128 dev lo
  - cmd: ip link add vrf1 type vrf table 1001
  - cmd: ip link set vrf1 up
  - cmd: ip link set net1 master vrf1
  - cmd: ip -6 addr add 2001:12::1/64 dev net1
  - cmd: ip sr tunsrc set 2001:db8:f:2::0
  - cmd: ip -6 rule add to 2001:db8::/32 pref 1 table main
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c "conf t"
      -c "segment-routing"
      -c " srv6"
      -c "  locators"
      -c "   locator default"
      -c "     prefix 2001:db8:f:2::/64"
      -c "   !"
      -c "  !"
      -c " !"
      -c "!"
      -c "ipv6 route 2001:db8:f:2::/64 Null0"
      -c "!"
      -c "router bgp 12"
      -c " bgp router-id 12.12.12.12"
      -c " no bgp ebgp-requires-policy"
      -c " !"
      -c " neighbor PEER peer-group"
      -c " neighbor PEER remote-as external"
      -c " neighbor net0 interface peer-group PEER"
      -c " !"
      -c " neighbor PE peer-group"
      -c " neighbor PE remote-as external"
      -c " neighbor PE ebgp-multihop 255"
      -c " neighbor 2001:db8:e:1:: peer-group PE"
      -c " !"
      -c " segment-routing srv6"
      -c "  locator default"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  redistribute connected"
      -c "  network 2001:db8:f:2::/64"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 vpn"
      -c "  neighbor PE activate"
      -c " exit-address-family"
      -c "!"
      -c "router bgp 12 vrf vrf1"
      -c " bgp router-id 12.12.12.12"
      -c " no bgp ebgp-requires-policy"
      -c " neighbor 2001:12::2 remote-as external"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  neighbor 2001:12::2 activate"
      -c "  sid vpn export auto"
      -c "  rd vpn export 12:1001"
      -c "  rt vpn export 1:1001"
      -c "  rt vpn import 1:1001"
      -c "  import vpn"
      -c "  export vpn"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"

- name: R3
  cmds:
  - cmd: ip addr add 10.255.0.13/32 dev lo
  - cmd: ip addr add 2001:db8:e:13::0/128 dev lo
  - cmd: ip link add vrf1 type vrf table 1001
  - cmd: ip link set vrf1 up
  - cmd: ip link set net1 master vrf1
  - cmd: ip -6 addr add 2001:13::1/64 dev net1
  - cmd: ip sr tunsrc set 2001:db8:f:3::0
  - cmd: ip -6 rule add to 2001:db8::/32 pref 1 table main
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c "conf t"
      -c "segment-routing"
      -c " srv6"
      -c "  locators"
      -c "   locator default"
      -c "     prefix 2001:db8:f:3::/64"
      -c "   !"
      -c "  !"
      -c " !"
      -c "!"
      -c "ipv6 route 2001:db8:f:3::/64 Null0"
      -c "!"
      -c "router bgp 13"
      -c " bgp router-id 13.13.13.13"
      -c " no bgp ebgp-requires-policy"
      -c " !"
      -c " neighbor PEER peer-group"
      -c " neighbor PEER remote-as external"
      -c " neighbor net0 interface peer-group PEER"
      -c " !"
      -c " neighbor PE peer-group"
      -c " neighbor PE remote-as external"
      -c " neighbor PE ebgp-multihop 255"
      -c " neighbor 2001:db8:e:1:: peer-group PE"
      -c " !"
      -c " segment-routing srv6"
      -c "  locator default"
      -c " !"
      -c " address-family ipv4 unicast"
      -c "  redistribute connected"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  redistribute connected"
      -c "  network 2001:db8:f:3::/64"
      -c "  neighbor PEER activate"
      -c " exit-address-family"
      -c " !"
      -c " address-family ipv6 vpn"
      -c "  neighbor PE activate"
      -c " exit-address-family"
      -c "!"
      -c "router bgp 13 vrf vrf1"
      -c " bgp router-id 13.13.13.13"
      -c " no bgp ebgp-requires-policy"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  sid vpn export auto"
      -c "  rd vpn export 13:1001"
      -c "  rt vpn export 1:1001"
      -c "  rt vpn import 1:1001"
      -c "  import vpn"
      -c "  export vpn"
      -c "  redistribute connected"
      -c " exit-address-family"
      -c "!"

- name: C1
  cmds:
  - cmd: ip -6 addr add 2001:11::2/64 dev net0
  - cmd: ip -6 route replace default via 2001:11::1
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c "conf t"
      -c "ipv6 route 0::/0 Null0"
      -c "!"
      -c "router bgp 101"
      -c " bgp router-id 101.101.101.101"
      -c " no bgp ebgp-requires-policy"
      -c " neighbor 2001:11::1 remote-as external"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  neighbor 2001:11::1 activate"
      -c "  network 0::/0"
      -c " exit-address-family"
- name: C2
  cmds:
  - cmd: ip -6 addr add 2001:12::2/64 dev net0
  - cmd: ip -6 route replace default via 2001:12::1
  - cmd: /usr/lib/frr/frrinit.sh start
  - cmd: >-
      vtysh -c "conf t"
      -c "ipv6 route 0::/0 Null0"
      -c "!"
      -c "router bgp 102"
      -c " bgp router-id 102.102.102.102"
      -c " no bgp ebgp-requires-policy"
      -c " neighbor 2001:12::1 remote-as external"
      -c " !"
      -c " address-family ipv6 unicast"
      -c "  neighbor 2001:12::1 activate"
      -c "  network 0::/0"
      -c " exit-address-family"
- name: C3
  cmds:
  - cmd: ip -6 addr add 2001:13::2/64 dev net0
  - cmd: ip -6 route replace default via 2001:13::1
  - cmd: /usr/lib/frr/frrinit.sh start


================================================
FILE: examples/basic_bgp/vrf2vrf_rouet_leak/Makefile
================================================

sh:
	docker exec R1 ip route list
	@echo
	docker exec R1 ip route list vrf red
	@echo
	docker exec R1 ip route list vrf blu
	@echo
	docker exec R1 ip route list vrf grn


================================================
FILE: examples/basic_bgp/vrf2vrf_rouet_leak/spec.yaml
================================================

nodes:
  - name: R1
    image: slankdev/frr-dev:latest
    interfaces:
      - { name: net0, type: direct, args: R2#net0 }
  - name: R2
    image: slankdev/frr-dev:latest
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }


node_configs:
  - name: R1
    cmds:
      - cmd: ip link add red type vrf table 10
      - cmd: ip link add blu type vrf table 20
      - cmd: ip link add grn type vrf table 30
      - cmd: ip link set red up
      - cmd: ip link set blu up
      - cmd: ip link set grn up
      - cmd: ip link set net0 vrf red
      - cmd: /usr/lib/frr/frrinit.sh start
      - cmd: >-
          vtysh -c 'conf t'
          -c 'int net0' -c 'ip addr 10.0.0.1/24' -c 'exit'
          -c 'router bgp 1 vrf red'
          -c ' bgp router-id 1.1.1.1'
          -c ' address-family ipv4 unicast'
          -c '  redistribute connected'
          -c ' exit-address-family'
          -c 'router bgp 2 vrf blu'
          -c ' bgp router-id 2.2.2.2'
          -c ' address-family ipv4 unicast'
          -c '  import vrf red'
          -c ' exit-address-family'
          -c 'router bgp 3 vrf grn'
          -c ' bgp router-id 3.3.3.3'
          -c ' address-family ipv4 unicast'
          -c '  import vrf blu'
          -c ' exit-address-family'



================================================
FILE: examples/basic_bond/spec.yaml
================================================

precmd:
  - cmds:
      - cmd: export IMAGE=slankdev/frr
      - cmd: export IMAGE=slankdev/gobgp
      - cmd: export IMAGE=slankdev/ubuntu:18.04

nodes:
  - name: R1
    image: $IMAGE
    interfaces:
      - { name: net0, type: direct, args: R2#net0 }
      - { name: net1, type: direct, args: R2#net1 }
  - name: R2
    image: $IMAGE
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
      - { name: net1, type: direct, args: R1#net1 }

node_configs:
  - name: R1
    cmds:
      - cmd: ip link add bond0 type bond miimon 100 mode active-backup
      - cmd: ip link set bond0 up
      - cmd: ip link set net0 down
      - cmd: ip link set net1 down
      - cmd: ip link set net0 master bond0
      - cmd: ip link set net1 master bond0
      - cmd: ip addr add 10.0.0.1/24 dev bond0
  - name: R2
    cmds:
      - cmd: ip link add bond0 type bond miimon 100 mode active-backup
      - cmd: ip link set bond0 up
      - cmd: ip link set net0 down
      - cmd: ip link set net1 down
      - cmd: ip link set net0 master bond0
      - cmd: ip link set net1 master bond0
      - cmd: ip addr add 10.0.0.2/24 dev bond0

test:
  - name: p2p
    cmds:
    - cmd: echo slankdev slankdev
    - cmd: echo slankdev slankdev



================================================
FILE: examples/basic_bufferbloat/README.md
================================================
# Bufferbloat demonstration

Simple demonstration of the [bufferbloat](https://www.bufferbloat.net/projects/) problem.

![](./topo.png)


================================================
FILE: examples/basic_bufferbloat/spec.yaml
================================================
nodes:
- name: R1
  image: nicolaka/netshoot
  interfaces:
  - { name: net0, type: direct, args: R2#net0 }
  - { name: net1, type: direct, args: C1#net0 }
  - { name: net2, type: direct, args: C2#net0 }
- name: R2
  image: nicolaka/netshoot
  interfaces:
  - { name: net0, type: direct, args: R1#net0 }
  - { name: net1, type: direct, args: C3#net0 }
  - { name: net2, type: direct, args: C4#net0 }
- name: C1
  image: nicolaka/netshoot
  interfaces:
  - { name: net0, type: direct, args: R1#net1 }
- name: C2
  image: nicolaka/netshoot
  interfaces:
  - { name: net0, type: direct, args: R1#net2 }
- name: C3
  image: nicolaka/netshoot
  interfaces:
  - { name: net0, type: direct, args: R2#net1 }
- name: C4
  image: nicolaka/netshoot
  interfaces:
  - { name: net0, type: direct, args: R2#net2 }
node_configs:
- name: R1
  cmds:
  - cmd: ip addr add 10.0.0.1/24 dev net1
  - cmd: ip addr add 10.0.1.1/24 dev net2
  - cmd: ip addr add 10.0.2.1/24 dev net0
  - cmd: ip route add default via 10.0.2.2
  - cmd: tc qdisc add dev net0 root netem rate 500mbit
- name: R2
  cmds:
  - cmd: ip addr add 10.0.2.2/24 dev net0
  - cmd: ip addr add 10.0.3.1/24 dev net1
  - cmd: ip addr add 10.0.4.1/24 dev net2
  - cmd: ip route add default via 10.0.2.1
  - cmd: tc qdisc add dev net0 root netem rate 500mbit
- name: C1
  cmds:
  - cmd: ip addr add 10.0.0.2/24 dev net0
  - cmd: ip route add default via 10.0.0.1
- name: C2
  cmds:
  - cmd: ip addr add 10.0.1.2/24 dev net0
  - cmd: ip route add default via 10.0.1.1
- name: C3
  cmds:
  - cmd: ip addr add 10.0.3.2/24 dev net0
  - cmd: ip route add default via 10.0.3.1
- name: C4
  cmds:
  - cmd: ip addr add 10.0.4.2/24 dev net0
  - cmd: ip route add default via 10.0.4.1
test:
  - cmds:
    - cmd: echo "=========================================="
    - cmd: echo "iperf from C1 to C3"
    - cmd: echo "=========================================="
    - cmd: docker exec C3 iperf -s -i 1 &
    - cmd: sleep 3
    - cmd: docker exec C1 iperf -c 10.0.3.2 2>&1 > /dev/null
    - cmd: docker exec C3 pkill iperf
    - cmd: echo "=========================================="
    - cmd: echo "ping from C2 to C4"
    - cmd: echo "=========================================="
    - cmd: docker exec C2 ping -c 10 10.0.4.2
    - cmd: echo "=========================================="
    - cmd: echo "ping from C2 to C4 while iperf-ing from C1 to C3"
    - cmd: echo "=========================================="
    - cmd: docker exec C3 iperf -s 2>&1 > /dev/null &
    - cmd: sleep 3
    - cmd: docker exec C1 iperf -c 10.0.3.2 -t 60 2>&1 > /dev/null &
    - cmd: sleep 3
    - cmd: docker exec C2 ping -c 10 10.0.4.2
    - cmd: docker exec C1 pkill iperf
    - cmd: sleep 3
    - cmd: docker exec C3 pkill iperf


================================================
FILE: examples/basic_clos/README.md
================================================

# CLOS Topology

Practice of designing DCN. Following are principle of Design.
- using modernaized technology (such as BGP-unnumbered.)

Version
- 0.0.0: basic CLOS-network ([yaml](./spec.v0.0.0.yaml))
- 0.0.1: using BGP-unnumbered ([yaml](./spec.v0.0.1.yaml))
- 0.0.2: using ECMP anycast ([yaml](./spec.v0.0.2.yaml))
- 0.0.3: add VM and ToR nodes ([yaml](./spec.v0.0.3.yaml))
- 0.0.4: support multi-tenancy ([yaml](./spec.v0.0.4.yaml)) (**currentry version**)
- 0.0.5: support SRv6 network slicing ([yaml](./spec.v0.0.5.yaml))

**version v0.0.3**
![](./topo.v0.0.3.png)

**version v0.0.2**
![](./topo.v0.0.2.png)

**version v0.0.1**
![](./topo.v0.0.1.png)

**version v0.0.0**
![](./topo.v0.0.0.png)

references
- LINE-SRv6-DCN ENOG55 http://enog.jp/wp-content/uploads/2018/12/05_20190222_ENOG55_LINE.pdf
- Large Scale DC Network Design https://www.slideshare.net/MasayukiKobayashi/dc-66865243
- Good TiNET examples by MIYA-kun https://github.com/mi2428/netben
- LINE DCN Overview by Kobayashi-san 2018.10 https://www.slideshare.net/linecorp/ss-116867631
- About designing the LINE-NW from scrach by Kobayashi-san 2019.01 https://www.janog.gr.jp/meeting/janog43/application/files/7915/4823/1858/janog43-line-kobayashi.pdf
- OpenStack Summit Vancouver 2018 Recap LINE-verda https://engineering.linecorp.com/ja/blog/openstack-summit-vancouver-2018-recap-2-2

operation performance
```
v0.0.3 sh -c 'tn up | sudo sh'
real    0m29.151s
user    0m6.945s
sys     0m4.472s

v0.0.3 sh -c 'tn conf | sudo sh' frr-all
real    1m25.104s
user    0m6.110s
sys     0m4.263s

v0.0.3 sh -c 'tn conf | sudo sh' frr-zebra,bgpd
real    1m13.867s
user    0m6.239s
sys     0m4.143s
```


================================================
FILE: examples/basic_clos/spec.v0.0.0.yaml
================================================

nodes:
  - name: Ext1
    image: slankdev/frr
    interfaces:
      # - { name: net0, type: direct, args: Internet#net0 }
      - { name: net1, type: direct, args: Spine1#up1 }
      - { name: net2, type: direct, args: Spine2#up1 }
  - name: Spine1
    image: slankdev/frr
    interfaces:
      - { name: up1, type: direct, args: Ext1#net1 }
      - { name: dn1, type: direct, args: Leaf1#up1 }
      - { name: dn2, type: direct, args: Leaf2#up1 }
      - { name: dn3, type: direct, args: Leaf3#up1 }
      - { name: dn4, type: direct, args: Leaf4#up1 }
  - name: Spine2
    image: slankdev/frr
    interfaces:
      - { name: up1, type: direct, args: Ext1#net2 }
      - { name: dn1, type: direct, args: Leaf1#up2 }
      - { name: dn2, type: direct, args: Leaf2#up2 }
      - { name: dn3, type: direct, args: Leaf3#up2 }
      - { name: dn4, type: direct, args: Leaf4#up2 }
  - name: Leaf1
    image: slankdev/frr
    interfaces:
      - { name: up1, type: direct, args: Spine1#dn1 }
      - { name: up2, type: direct, args: Spine2#dn1 }
      - { name: dn1, type: direct, args: Serv1#net0 }
      - { name: dn2, type: direct, args: Serv2#net0 }
  - name: Leaf2
    image: slankdev/frr
    interfaces:
      - { name: up1, type: direct, args: Spine1#dn2 }
      - { name: up2, type: direct, args: Spine2#dn2 }
      - { name: dn1, type: direct, args: Serv3#net0 }
      - { name: dn2, type: direct, args: Serv4#net0 }
  - name: Leaf3
    image: slankdev/frr
    interfaces:
      - { name: up1, type: direct, args: Spine1#dn3 }
      - { name: up2, type: direct, args: Spine2#dn3 }
      - { name: dn1, type: direct, args: Serv5#net0 }
      - { name: dn2, type: direct, args: Serv6#net0 }
  - name: Leaf4
    image: slankdev/frr
    interfaces:
      - { name: up1, type: direct, args: Spine1#dn4 }
      - { name: up2, type: direct, args: Spine2#dn4 }
      - { name: dn1, type: direct, args: Serv7#net0 }
      - { name: dn2, type: direct, args: Serv8#net0 }
  - name: Serv1
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf1#dn1 } ]
  - name: Serv2
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf1#dn2 } ]
  - name: Serv3
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf2#dn1 } ]
  - name: Serv4
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf2#dn2 } ]
  - name: Serv5
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf3#dn1 } ]
  - name: Serv6
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf3#dn2 } ]
  - name: Serv7
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf4#dn1 } ]
  - name: Serv8
    image: slankdev/frr
    interfaces: [ { name: net0, type: direct, args: Leaf4#dn2 } ]

node_configs:
  - name: Ext1
    cmds:
      - cmd: echo slankdev slankdev
  - name: Spine1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.1/32"
          -c "int dn1" -c "ip addr 10.0.0.1/30"
          -c "int dn2" -c "ip addr 10.0.0.5/30"
          -c "int dn3" -c "ip addr 10.0.0.9/30"
          -c "int dn4" -c "ip addr 10.0.0.13/30"
          -c "router bgp 65001"
          -c " bgp router-id 10.255.0.1"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 10.0.0.2 remote-as 65011"
          -c " neighbor 10.0.0.6 remote-as 65012"
          -c " neighbor 10.0.0.10 remote-as 65013"
          -c " neighbor 10.0.0.14 remote-as 65014"
  - name: Spine2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.2/32"
          -c "int dn1" -c "ip addr 10.0.0.17/30"
          -c "int dn2" -c "ip addr 10.0.0.21/30"
          -c "int dn3" -c "ip addr 10.0.0.25/30"
          -c "int dn4" -c "ip addr 10.0.0.29/30"
          -c "router bgp 65002"
          -c " bgp router-id 10.255.0.2"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 10.0.0.18 remote-as 65011"
          -c " neighbor 10.0.0.22 remote-as 65012"
          -c " neighbor 10.0.0.26 remote-as 65013"
          -c " neighbor 10.0.0.30 remote-as 65014"
  - name: Leaf1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.11/32"
          -c "int up1" -c "ip addr 10.0.0.2/30"
          -c "int up2" -c "ip addr 10.0.0.18/30"
          -c "int dn1" -c "ip addr 20.0.0.1/30"
          -c "int dn2" -c "ip addr 20.0.0.5/30"
          -c "router bgp 65011"
          -c " bgp router-id 10.255.0.11"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 10.0.0.1 remote-as 65001"
          -c " neighbor 10.0.0.17 remote-as 65002"
          -c " neighbor 20.0.0.2 remote-as 65021"
          -c " neighbor 20.0.0.6 remote-as 65022"
  - name: Leaf2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.12/32"
          -c "int up1" -c "ip addr 10.0.0.6/30"
          -c "int up2" -c "ip addr 10.0.0.22/30"
          -c "int dn1" -c "ip addr 20.0.0.9/30"
          -c "int dn2" -c "ip addr 20.0.0.13/30"
          -c "router bgp 65012"
          -c " bgp router-id 10.255.0.12"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 10.0.0.5 remote-as 65001"
          -c " neighbor 10.0.0.21 remote-as 65002"
          -c " neighbor 20.0.0.10 remote-as 65023"
          -c " neighbor 20.0.0.14 remote-as 65024"
  - name: Leaf3
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.13/32"
          -c "int up1" -c "ip addr 10.0.0.10/30"
          -c "int up2" -c "ip addr 10.0.0.26/30"
          -c "int dn1" -c "ip addr 20.0.0.17/30"
          -c "int dn2" -c "ip addr 20.0.0.21/30"
          -c "router bgp 65013"
          -c " bgp router-id 10.255.0.13"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 10.0.0.9 remote-as 65001"
          -c " neighbor 10.0.0.25 remote-as 65002"
          -c " neighbor 20.0.0.18 remote-as 65025"
          -c " neighbor 20.0.0.22 remote-as 65026"
  - name: Leaf4
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.14/32"
          -c "int up1" -c "ip addr 10.0.0.14/30"
          -c "int up2" -c "ip addr 10.0.0.30/30"
          -c "int dn1" -c "ip addr 20.0.0.25/30"
          -c "int dn2" -c "ip addr 20.0.0.29/30"
          -c "router bgp 65014"
          -c " bgp router-id 10.255.0.14"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 10.0.0.13 remote-as 65001"
          -c " neighbor 10.0.0.29 remote-as 65002"
          -c " neighbor 20.0.0.26 remote-as 65027"
          -c " neighbor 20.0.0.30 remote-as 65028"
  - name: Serv1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.21/32"
          -c "int net0" -c "ip addr 20.0.0.2/30"
          -c "router bgp 65021"
          -c " bgp router-id 10.255.0.21"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.1 remote-as external"
          -c " network 20.0.0.2/30"
  - name: Serv2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.22/32"
          -c "int net0" -c "ip addr 20.0.0.6/30"
          -c "router bgp 65022"
          -c " bgp router-id 10.255.0.22"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.5 remote-as external"
          -c " network 20.0.0.6/30"
  - name: Serv3
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.23/32"
          -c "int net0" -c "ip addr 20.0.0.10/30"
          -c "router bgp 65023"
          -c " bgp router-id 10.255.0.23"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.9 remote-as external"
          -c " network 20.0.0.10/30"
  - name: Serv4
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.24/32"
          -c "int net0" -c "ip addr 20.0.0.14/30"
          -c "router bgp 65024"
          -c " bgp router-id 10.255.0.24"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.13 remote-as external"
          -c " network 20.0.0.14/30"
  - name: Serv5
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.25/32"
          -c "int net0" -c "ip addr 20.0.0.18/30"
          -c "router bgp 65025"
          -c " bgp router-id 10.255.0.25"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.17 remote-as external"
          -c " network 20.0.0.18/30"
  - name: Serv6
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.26/32"
          -c "int net0" -c "ip addr 20.0.0.22/30"
          -c "router bgp 65026"
          -c " bgp router-id 10.255.0.26"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.21 remote-as external"
          -c " network 20.0.0.22/30"
  - name: Serv7
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.27/32"
          -c "int net0" -c "ip addr 20.0.0.26/30"
          -c "router bgp 65027"
          -c " bgp router-id 10.255.0.27"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.25 remote-as external"
          -c " network 20.0.0.26/30"
  - name: Serv8
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: >-
          vtysh -c "conf t"
          -c "int lo" -c "ip addr 10.255.0.28/32"
          -c "int net0" -c "ip addr 20.0.0.30/30"
          -c "router bgp 65028"
          -c " bgp router-id 10.255.0.28"
          -c " bgp bestpath as-path multipath-relax"
          -c " bgp bestpath compare-routerid"
          -c " neighbor 20.0.0.29 remote-as external"
          -c " network 20.0.0.30/30"

test:
  - name: p2p
    cmds:
    - cmd: docker exec Ext1 echo slank
    - cmd: echo slankdev slankdev



================================================
FILE: examples/basic_clos
Download .txt
gitextract_qbgpc9og/

├── .github/
│   ├── CODEOWNERS
│   ├── auto_assign.yml
│   └── workflows/
│       ├── pr-auto-assign.yaml
│       ├── release-master.yaml
│       ├── release-tag.yaml
│       └── test.yaml
├── .gitignore
├── .goreleaser.yml
├── Dockerfiles/
│   ├── centos7/
│   │   ├── Dockerfile
│   │   └── build.sh
│   ├── cloudvpn/
│   │   ├── Dockerfile
│   │   └── build.sh
│   ├── ebpf/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── build_and_attach.sh
│   │   ├── detach.sh
│   │   └── filter.c
│   ├── frr/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   └── daemons
│   ├── nginx/
│   │   ├── Dockerfile
│   │   └── Makefile
│   ├── pmacctd/
│   │   ├── Dockerfile
│   │   └── Makefile
│   └── trex/
│       ├── Dockerfile
│       └── Makefile
├── LICENSE
├── Makefile
├── README.md
├── cheatsheet.md
├── command_func.go
├── commands.go
├── configs/
│   └── spec_template.yaml
├── docs/
│   ├── command-line-usage-example.md
│   └── specification_yml.md
├── examples/
│   ├── bandwidth_tc/
│   │   └── spec.yaml
│   ├── basic_bfd/
│   │   └── spec.yaml
│   ├── basic_bgp/
│   │   ├── README.md
│   │   ├── bgp_clos_evpn_vxlan/
│   │   │   └── spec.yaml
│   │   ├── graceful_restart/
│   │   │   └── simple_ipv4_unicast/
│   │   │       ├── README.md
│   │   │       ├── r2/
│   │   │       │   └── r2-kill-bgpd.pcap
│   │   │       └── spec.yaml
│   │   ├── hv_bgp_dcn/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── hv_bgp_dcn_isol/
│   │   │   ├── Makefile
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── local_pref/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── mpbgp_ipv4_labeled_unicast/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── path_attr/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── route_reflector/
│   │   │   └── spec.yaml
│   │   ├── route_server/
│   │   │   └── spec.yaml
│   │   ├── route_server_multihop/
│   │   │   └── spec.yaml
│   │   ├── spec.yaml
│   │   ├── unnumbered/
│   │   │   ├── r1.pcap
│   │   │   └── spec.yaml
│   │   ├── vpnv4_mpls/
│   │   │   ├── README.md
│   │   │   ├── r1.pcap
│   │   │   ├── r2.pcap
│   │   │   └── spec.yaml
│   │   ├── vpnv4_srmpls/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── vpnv4_srmpls_interas_option-b/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── vpnv4_srv6/
│   │   │   ├── Makefile
│   │   │   ├── README.md
│   │   │   ├── frr.conf.srv6.R1
│   │   │   ├── frr.conf.srv6.R2
│   │   │   └── spec.yaml
│   │   ├── vpnv6_srv6_rs/
│   │   │   └── spec.yaml
│   │   └── vrf2vrf_rouet_leak/
│   │       ├── Makefile
│   │       └── spec.yaml
│   ├── basic_bond/
│   │   └── spec.yaml
│   ├── basic_bufferbloat/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_clos/
│   │   ├── README.md
│   │   ├── spec.v0.0.0.yaml
│   │   ├── spec.v0.0.1.yaml
│   │   ├── spec.v0.0.2.yaml
│   │   ├── spec.v0.0.3.yaml
│   │   └── spec.yaml
│   ├── basic_conntrack/
│   │   └── connection_sync/
│   │       ├── Makefile
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_coredns/
│   │   └── blacklist/
│   │       ├── Corefile.NS1
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_ebgp/
│   │   └── spec.yaml
│   ├── basic_ecmp/
│   │   ├── README.md
│   │   ├── scale.diff
│   │   └── spec.yaml
│   ├── basic_evpn/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_exabgp/
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── daemons.R1
│   │   ├── exabgp.conf
│   │   ├── exabgp.conf.R2
│   │   ├── frr.conf.R1
│   │   └── spec.yaml
│   ├── basic_fq_codel/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_gcp_hv/
│   │   └── spec.yaml
│   ├── basic_geneve/
│   │   ├── in.pcap
│   │   └── spec.yaml
│   ├── basic_gre/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_haproxy/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_ipip/
│   │   ├── anycast_tunnel/
│   │   │   └── spec.yaml
│   │   └── simple/
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_ipsec/
│   │   ├── bgp/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── bgp_ha/
│   │   │   ├── in.pcap
│   │   │   └── spec.yaml
│   │   ├── mesh/
│   │   │   └── spec.yaml
│   │   ├── mesh_bgp/
│   │   │   └── spec.yaml
│   │   ├── simple/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── static_esp_tunnel_simple/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── with_vti/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   └── xfrm_interface/
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_iptables/
│   │   ├── napt/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   ├── test/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   └── u32/
│   │       └── spec.yaml
│   ├── basic_isis/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_l3dsr/
│   │   └── dscp/
│   │       ├── Dockerfile
│   │       ├── spec.yaml
│   │       └── xdp.c
│   ├── basic_ldp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_mirror/
│   │   ├── local/
│   │   │   └── spec.yaml
│   │   └── remote/
│   │       └── spec.yaml
│   ├── basic_mpls/
│   │   └── spec.yaml
│   ├── basic_multipath/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_namespace/
│   │   ├── README.md
│   │   ├── spec.blue.yaml
│   │   └── spec.green.yaml
│   ├── basic_napt/
│   │   └── spec.yaml
│   ├── basic_netflow/
│   │   ├── README.md
│   │   ├── multipath/
│   │   │   ├── Makefile
│   │   │   └── spec.yaml
│   │   ├── netflow.pcap
│   │   └── simple/
│   │       └── spec.yaml
│   ├── basic_netns/
│   │   └── spec.yaml
│   ├── basic_nftables/
│   │   ├── masquerade/
│   │   │   ├── README.md
│   │   │   └── spec.yaml
│   │   └── snat/
│   │       ├── README.md
│   │       └── spec.yaml
│   ├── basic_ospfv2_bird/
│   │   ├── README.md
│   │   ├── bird/
│   │   │   ├── R1_bird.conf
│   │   │   ├── R2_bird.conf
│   │   │   ├── R3_bird.conf
│   │   │   └── R4_bird.conf
│   │   └── spec.yaml
│   ├── basic_ospfv2_frr/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_ospfv3_bird_multiple_instance/
│   │   ├── R3_bird6.conf
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_ospfv3_frr/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_pbr/
│   │   └── spec.yaml
│   ├── basic_peer/
│   │   └── spec.yaml
│   ├── basic_pim/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_pim2/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_pppoe_WIP/
│   │   └── spec.yaml
│   ├── basic_rift/
│   │   ├── README.md
│   │   ├── ietf_rift_python/
│   │   │   ├── meta_topology_2c_2x2.yaml
│   │   │   ├── rift_leaf1.yaml
│   │   │   ├── rift_leaf2.yaml
│   │   │   ├── rift_spine1.yaml
│   │   │   └── rift_spine2.yaml
│   │   └── spec.yaml
│   ├── basic_rtbh/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_source_routing/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_srmpls/
│   │   └── spec.yaml
│   ├── basic_srv6/
│   │   ├── README.md
│   │   ├── linux/
│   │   │   ├── bgp_vpnv6/
│   │   │   │   └── spec.yaml
│   │   │   ├── binding_sid/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── end_bpf_WIP/
│   │   │   │   ├── Makefile
│   │   │   │   ├── bpf_helpers.h
│   │   │   │   ├── filter.c
│   │   │   │   └── spec.yaml
│   │   │   ├── hands_on/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── l2vpn/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── sfc/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── srv6_unaware/
│   │   │   │   ├── README.md
│   │   │   │   ├── function/
│   │   │   │   │   ├── Makefile
│   │   │   │   │   └── main.cc
│   │   │   │   ├── function1/
│   │   │   │   │   ├── Makefile
│   │   │   │   │   ├── edenman_chikuwa.cc
│   │   │   │   │   ├── main.cc
│   │   │   │   │   └── ntt_ipa.cc
│   │   │   │   └── spec.yaml
│   │   │   ├── transit/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v4_per_ce/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v4_per_vrf/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v6_per_ce/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   ├── vpn_v6_per_vrf/
│   │   │   │   ├── README.md
│   │   │   │   └── spec.yaml
│   │   │   └── vrf_redirect/
│   │   │       ├── README.md
│   │   │       └── spec.yaml
│   │   └── vpp/
│   │       └── vpn4_per_ce/
│   │           ├── README.md
│   │           └── spec.yaml
│   ├── basic_sysctl/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_tc/
│   │   └── spec.yaml
│   ├── basic_tproxy/
│   │   ├── dns_interceptor/
│   │   │   ├── Corefile
│   │   │   ├── Dockerfile.coredns
│   │   │   ├── Dockerfile.dns-interceptor
│   │   │   ├── README.md
│   │   │   ├── go.mod
│   │   │   ├── go.sum
│   │   │   ├── main.go
│   │   │   ├── session-udp.go
│   │   │   └── spec.yaml
│   │   └── http_interceptor/
│   │       ├── Dockerfile
│   │       ├── README.md
│   │       ├── go.mod
│   │       ├── go.sum
│   │       ├── http_interceptor.go
│   │       └── spec.yaml
│   ├── basic_vpnv4/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_vpp/
│   │   ├── README.md
│   │   ├── nat.yaml
│   │   └── spec.yaml
│   ├── basic_vrf/
│   │   ├── README.md
│   │   ├── frr.spec.yaml
│   │   └── iproute2.spec.yaml
│   ├── basic_vrf2/
│   │   └── spec.yaml
│   ├── basic_vrrp/
│   │   ├── conntrack/
│   │   │   ├── keepalived.conf.R1
│   │   │   ├── keepalived.conf.R2
│   │   │   └── spec.yaml
│   │   └── simple/
│   │       └── spec.yaml
│   ├── basic_vxlan/
│   │   ├── vxlan_mcast.yaml
│   │   └── vxlan_ucast.yaml
│   ├── basic_vxlan_mcast_v6/
│   │   └── spec.yaml
│   ├── basic_vxlan_v6/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── basic_xdp/
│   │   ├── Dockerfile
│   │   ├── Makefile
│   │   ├── filter.c
│   │   └── spec.yaml
│   ├── bgp_test/
│   │   ├── dut.conf
│   │   └── spec.yaml
│   ├── bgp_test2/
│   │   └── spec.yaml
│   ├── bridge_tc/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── flowspec/
│   │   └── spec.yaml
│   ├── gobgp-grpc/
│   │   ├── README.md
│   │   ├── add_path01.py
│   │   ├── add_path02.py
│   │   ├── gobgp01.conf
│   │   ├── gobgp02.conf
│   │   └── spec.yaml
│   ├── ovs_port_vlan/
│   │   └── spec.yaml
│   ├── simple/
│   │   └── topo2/
│   │       └── spec.yaml
│   ├── srmpls_l2vpn_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srmpls_l3vpnv4_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srmpls_l3vpnv4_static_vpp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l2vpn_static_linux_hack/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l2vpn_static_vpp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv4_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv4_static_linux_pseudo_dt4/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv4_static_vpp/
│   │   ├── README.md
│   │   └── spec.yaml
│   ├── srv6_l3vpnv6_static_linux/
│   │   ├── README.md
│   │   └── spec.yaml
│   └── trex/
│       ├── dual_node_single_instance/
│       │   ├── README.md
│       │   ├── client.yaml
│       │   ├── server.yaml
│       │   ├── spec.yaml
│       │   ├── tcp_open.py
│       │   └── tcp_openclose.py
│       ├── simple/
│       │   ├── README.md
│       │   ├── cfg.yaml
│       │   ├── new_connection_test.py
│       │   ├── spec.yaml
│       │   ├── tcp_open.py
│       │   └── tcp_openclose.py
│       └── single_node_dual_instance/
│           ├── README.md
│           ├── client.yaml
│           ├── server.yaml
│           ├── spec.yaml
│           ├── tcp_open.py
│           └── tcp_openclose.py
├── go.mod
├── go.sum
├── internal/
│   └── pkg/
│       ├── shell/
│       │   ├── shell.go
│       │   └── shell_test.go
│       └── utils/
│           ├── utils.go
│           └── utils_test.go
└── main.go
Download .txt
SYMBOL INDEX (179 symbols across 27 files)

FILE: Dockerfiles/ebpf/filter.c
  function count_packets (line 25) | static __inline int
  function count_packets_ingress (line 41) | int
  function count_packets_egress (line 47) | int

FILE: command_func.go
  type linkstatus (line 16) | type linkstatus struct
  function LoadCfg (line 27) | func LoadCfg(c *cli.Context) (tnconfig shell.Tn, verbose bool, err error) {
  function CmdBuild (line 50) | func CmdBuild(c *cli.Context) error {
  function CmdCheck (line 66) | func CmdCheck(c *cli.Context) error {
  function CmdUp (line 122) | func CmdUp(c *cli.Context) error {
  function CmdConf (line 236) | func CmdConf(c *cli.Context) error {
  function CmdUpConf (line 264) | func CmdUpConf(c *cli.Context) error {
  function CmdDown (line 278) | func CmdDown(c *cli.Context) error {
  function CmdExec (line 304) | func CmdExec(c *cli.Context) error {
  function CmdImg (line 319) | func CmdImg(c *cli.Context) error {
  function CmdInit (line 395) | func CmdInit(c *cli.Context) error {
  function CmdPs (line 407) | func CmdPs(c *cli.Context) error {
  function CmdPull (line 424) | func CmdPull(c *cli.Context) error {
  function CmdReConf (line 436) | func CmdReConf(c *cli.Context) error {
  function CmdReUp (line 455) | func CmdReUp(c *cli.Context) error {
  function CmdTest (line 469) | func CmdTest(c *cli.Context) error {

FILE: examples/basic_l3dsr/dscp/xdp.c
  function __always_inline (line 13) | static __always_inline __u16 csum_fold_helper(__u64 csum) {
  function __always_inline (line 23) | static __always_inline void ipv4_csum(void *data_start, int data_size,  ...
  function __always_inline (line 28) | static __always_inline int process_ipv4(struct xdp_md* ctx,
  function __always_inline (line 63) | static __always_inline int process_eth(struct xdp_md* ctx) {
  function entry (line 80) | int entry(struct xdp_md *ctx) {

FILE: examples/basic_srv6/linux/end_bpf_WIP/bpf_helpers.h
  type sk_buff (line 66) | struct sk_buff
  type bpf_map_def (line 77) | struct bpf_map_def {

FILE: examples/basic_srv6/linux/end_bpf_WIP/filter.c
  function filter (line 13) | int filter(struct __sk_buff *skb)

FILE: examples/basic_srv6/linux/srv6_unaware/function/main.cc
  type policy (line 23) | struct policy {
  function process_packet (line 33) | static void
  function forward_frame (line 59) | static void
  function open_raw_sock (line 100) | static int
  function main (line 144) | int

FILE: examples/basic_srv6/linux/srv6_unaware/function1/edenman_chikuwa.cc
  type policy (line 23) | struct policy {
  function process_packet (line 32) | static int
  function forward_frame (line 66) | static void
  function open_raw_sock (line 115) | static int
  function main (line 159) | int

FILE: examples/basic_srv6/linux/srv6_unaware/function1/main.cc
  type policy (line 23) | struct policy {
  function process_packet (line 33) | static int
  function forward_frame (line 67) | static void
  function open_raw_sock (line 116) | static int
  function main (line 160) | int

FILE: examples/basic_srv6/linux/srv6_unaware/function1/ntt_ipa.cc
  type policy (line 23) | struct policy {
  function process_packet (line 32) | static int
  function forward_frame (line 66) | static void
  function open_raw_sock (line 115) | static int
  function main (line 159) | int

FILE: examples/basic_tproxy/dns_interceptor/main.go
  function setupTransparentSocket (line 17) | func setupTransparentSocket(network, address string, c syscall.RawConn) ...
  type DNSInterceptor (line 49) | type DNSInterceptor struct
    method NewFQDNFirewall (line 52) | func (di *DNSInterceptor) NewFQDNFirewall() {
    method ServeDNS (line 55) | func (di *DNSInterceptor) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
  function main (line 88) | func main() {

FILE: examples/basic_tproxy/dns_interceptor/session-udp.go
  type SessionUDPFactory (line 31) | type SessionUDPFactory struct
    method SetSocketOptions (line 119) | func (f *SessionUDPFactory) SetSocketOptions(conn *net.UDPConn) error {
    method InitPool (line 145) | func (f *SessionUDPFactory) InitPool(msgSize int) {
    method ReadRequest (line 156) | func (f *SessionUDPFactory) ReadRequest(conn *net.UDPConn) ([]byte, dn...
  type sessionUDP (line 43) | type sessionUDP struct
    method Discard (line 176) | func (s *sessionUDP) Discard() {
    method RemoteAddr (line 187) | func (s *sessionUDP) RemoteAddr() net.Addr { return s.raddr }
    method LocalAddr (line 190) | func (s *sessionUDP) LocalAddr() net.Addr { return s.laddr }
    method WriteResponse (line 193) | func (s *sessionUDP) WriteResponse(b []byte) (int, error) {
    method controlMessage (line 272) | func (s *sessionUDP) controlMessage(src *net.UDPAddr) []byte {
  function transparentSetsockopt (line 59) | func transparentSetsockopt(fd int, ipv4, ipv6 bool) error {
  function listenConfig (line 82) | func listenConfig(mark int, ipv4, ipv6 bool) *net.ListenConfig {
  function bindUDP (line 103) | func bindUDP(addr string, ipv4, ipv6 bool) *net.IPConn {
  function parseDstFromOOB (line 223) | func parseDstFromOOB(oob []byte) (*net.UDPAddr, error) {

FILE: examples/basic_tproxy/http_interceptor/http_interceptor.go
  function setupTransparentSocket (line 14) | func setupTransparentSocket(network, address string, c syscall.RawConn) ...
  function dialContextWithTransparentSocket (line 41) | func dialContextWithTransparentSocket(ctx context.Context, network, addr...
  type HTTPInterceptor (line 47) | type HTTPInterceptor struct
    method ServeHTTP (line 50) | func (hi *HTTPInterceptor) ServeHTTP(w http.ResponseWriter, req *http....
  function main (line 92) | func main() {

FILE: examples/basic_xdp/filter.c
  function filter (line 8) | int filter(struct xdp_md *ctx)

FILE: examples/gobgp-grpc/add_path01.py
  function run (line 16) | def run():

FILE: examples/gobgp-grpc/add_path02.py
  function run (line 16) | def run():

FILE: examples/trex/dual_node_single_instance/tcp_open.py
  class Prof1 (line 5) | class Prof1():
    method __init__ (line 6) | def __init__(self):
    method create_profile (line 9) | def create_profile(self, cps):
    method get_profile (line 33) | def get_profile(self, tunables, **kwargs):
  function register (line 42) | def register():

FILE: examples/trex/dual_node_single_instance/tcp_openclose.py
  class Prof1 (line 5) | class Prof1():
    method __init__ (line 6) | def __init__(self):
    method create_profile (line 9) | def create_profile(self, cps):
    method get_profile (line 32) | def get_profile(self, tunables, **kwargs):
  function register (line 41) | def register():

FILE: examples/trex/simple/new_connection_test.py
  class Prof1 (line 12) | class Prof1():
    method create_profile (line 13) | def create_profile(self, cps):
  function dig (line 53) | def dig(d, keys):

FILE: examples/trex/simple/tcp_open.py
  class Prof1 (line 5) | class Prof1():
    method __init__ (line 6) | def __init__(self):
    method create_profile (line 9) | def create_profile(self, cps):
    method get_profile (line 33) | def get_profile(self, tunables, **kwargs):
  function register (line 42) | def register():

FILE: examples/trex/simple/tcp_openclose.py
  class Prof1 (line 5) | class Prof1():
    method __init__ (line 6) | def __init__(self):
    method create_profile (line 9) | def create_profile(self, cps):
    method get_profile (line 32) | def get_profile(self, tunables, **kwargs):
  function register (line 41) | def register():

FILE: examples/trex/single_node_dual_instance/tcp_open.py
  class Prof1 (line 5) | class Prof1():
    method __init__ (line 6) | def __init__(self):
    method create_profile (line 9) | def create_profile(self, cps):
    method get_profile (line 33) | def get_profile(self, tunables, **kwargs):
  function register (line 42) | def register():

FILE: examples/trex/single_node_dual_instance/tcp_openclose.py
  class Prof1 (line 5) | class Prof1():
    method __init__ (line 6) | def __init__(self):
    method create_profile (line 9) | def create_profile(self, cps):
    method get_profile (line 32) | def get_profile(self, tunables, **kwargs):
  function register (line 41) | def register():

FILE: internal/pkg/shell/shell.go
  type Tn (line 19) | type Tn struct
    method Exec (line 188) | func (tnconfig *Tn) Exec(nodeName string, Cmds []string) (execCommand ...
  type PreCmd (line 32) | type PreCmd struct
  type PreInit (line 38) | type PreInit struct
  type PreConf (line 43) | type PreConf struct
  type PostInit (line 48) | type PostInit struct
  type PostFini (line 53) | type PostFini struct
  type Node (line 58) | type Node struct
    method BuildCmd (line 122) | func (node *Node) BuildCmd() (buildCmd string) {
    method DeleteNode (line 160) | func (node *Node) DeleteNode() (deleteNodeCmds []string) {
    method CreateNode (line 436) | func (node *Node) CreateNode() (createNodeCmds []string) {
    method Mount_docker_netns (line 607) | func (node *Node) Mount_docker_netns() (mountDockerNetnsCmds []string) {
    method DelNsCmd (line 629) | func (node *Node) DelNsCmd() (delNsCmd string) {
    method MountTmpl (line 637) | func (node *Node) MountTmpl() (mountTmplCmd []string, err error) {
  type Interface (line 79) | type Interface struct
    method AddrSet (line 528) | func (inf *Interface) AddrSet(nodeName string) (addrSetCmd string) {
    method N2nLink (line 548) | func (inf *Interface) N2nLink(nodeName string) (n2nLinkCmds []string) {
    method S2nLink (line 563) | func (inf *Interface) S2nLink(nodeName string) (s2nLinkCmds []string) {
    method V2cLink (line 579) | func (inf *Interface) V2cLink(nodeName string) (v2cLinkCmds []string) {
    method P2cLink (line 593) | func (inf *Interface) P2cLink(nodeName string) (p2cLinkCmds []string) {
  type Sysctl (line 88) | type Sysctl struct
  type Template (line 92) | type Template struct
  type Switch (line 99) | type Switch struct
    method DeleteSwitch (line 180) | func (br *Switch) DeleteSwitch() (deleteBrCmd string) {
    method CreateSwitch (line 536) | func (bridge *Switch) CreateSwitch() (createSwitchCmds []string) {
  type NodeConfig (line 105) | type NodeConfig struct
    method ExecConf (line 137) | func (nodeConfig *NodeConfig) ExecConf(nodeType string) (execConfCmds ...
  type Cmd (line 111) | type Cmd struct
  type Test (line 116) | type Test struct
    method TnTestCmdExec (line 416) | func (t *Test) TnTestCmdExec() (tnTestCmds []string) {
  function GenerateFile (line 224) | func GenerateFile() (genContent string, err error) {
  function DockerPs (line 377) | func DockerPs(all bool) (dockerPsCmd string) {
  function NetnsPs (line 389) | func NetnsPs() (netnsListCmd string) {
  function Pull (line 397) | func Pull(nodes []Node) (pullCmds []string) {
  function ExecCmd (line 426) | func ExecCmd(cmds []Cmd) (execCmds []string) {
  function HostLinkUp (line 513) | func HostLinkUp(linkName string) (linkUpCmd string) {
  function NetnsLinkUp (line 521) | func NetnsLinkUp(netnsName string, linkName string) (netnsLinkUpCmd stri...
  function GetContainerPid (line 621) | func GetContainerPid(nodename string) (getpidCmd string) {

FILE: internal/pkg/shell/shell_test.go
  function TestNodeConfig_ExecConf (line 8) | func TestNodeConfig_ExecConf(t *testing.T) {
  function TestNode_DeleteNode (line 90) | func TestNode_DeleteNode(t *testing.T) {
  function TestSwitch_DeleteSwitch (line 180) | func TestSwitch_DeleteSwitch(t *testing.T) {
  function TestTn_Exec (line 228) | func TestTn_Exec(t *testing.T) {
  function TestGenerateFile (line 272) | func TestGenerateFile(t *testing.T) {
  function TestDockerPs (line 294) | func TestDockerPs(t *testing.T) {
  function TestNetnsPs (line 327) | func TestNetnsPs(t *testing.T) {
  function TestPull (line 346) | func TestPull(t *testing.T) {
  function TestExecCmd (line 381) | func TestExecCmd(t *testing.T) {
  function TestNode_CreateNode (line 414) | func TestNode_CreateNode(t *testing.T) {
  function TestHostLinkUp (line 679) | func TestHostLinkUp(t *testing.T) {
  function TestNetnsLinkUp (line 705) | func TestNetnsLinkUp(t *testing.T) {
  function TestSwitch_CreateSwitch (line 733) | func TestSwitch_CreateSwitch(t *testing.T) {
  function TestInterface_N2nLink (line 776) | func TestInterface_N2nLink(t *testing.T) {
  function TestInterface_S2nLink (line 820) | func TestInterface_S2nLink(t *testing.T) {
  function TestInterface_V2cLink (line 864) | func TestInterface_V2cLink(t *testing.T) {
  function TestInterface_P2cLink (line 908) | func TestInterface_P2cLink(t *testing.T) {
  function TestNode_Mount_docker_netns (line 952) | func TestNode_Mount_docker_netns(t *testing.T) {
  function TestGetContainerPid (line 1008) | func TestGetContainerPid(t *testing.T) {
  function TestNode_DelNsCmd (line 1034) | func TestNode_DelNsCmd(t *testing.T) {
  function TestNode_BuildCmd (line 1094) | func TestNode_BuildCmd(t *testing.T) {
  function TestTest_TnTestCmdExec (line 1166) | func TestTest_TnTestCmdExec(t *testing.T) {

FILE: internal/pkg/utils/utils.go
  function Exists (line 11) | func Exists(name string) bool {
  function RemoveDuplicatesString (line 17) | func RemoveDuplicatesString(elements []string) []string {
  function PrintCmd (line 34) | func PrintCmd(w io.Writer, cmd string, verbose bool) {
  function PrintCmds (line 43) | func PrintCmds(w io.Writer, cmds []string, verbose bool) {

FILE: internal/pkg/utils/utils_test.go
  function TestExists (line 9) | func TestExists(t *testing.T) {
  function TestRemoveDuplicatesString (line 35) | func TestRemoveDuplicatesString(t *testing.T) {
  function TestPrintCmd (line 61) | func TestPrintCmd(t *testing.T) {
  function TestPrintCmds (line 99) | func TestPrintCmds(t *testing.T) {

FILE: main.go
  constant name (line 11) | name        = "tinet"
  constant description (line 12) | description = "tinet: Tiny Network"
  function main (line 19) | func main() {
  function newApp (line 26) | func newApp() *cli.App {
Condensed preview — 326 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,026K chars).
[
  {
    "path": ".github/CODEOWNERS",
    "chars": 21,
    "preview": "* @ak1ra24 @slankdev\n"
  },
  {
    "path": ".github/auto_assign.yml",
    "chars": 708,
    "preview": "# Set to true to add reviewers to pull requests\naddReviewers: true\n\n# Set to true to add assignees to pull requests\naddA"
  },
  {
    "path": ".github/workflows/pr-auto-assign.yaml",
    "chars": 269,
    "preview": "name: 'Auto Assign'\non: pull_request\n\njobs:\n  add-reviews:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: kentaro-m"
  },
  {
    "path": ".github/workflows/release-master.yaml",
    "chars": 862,
    "preview": "name: release-master\non:\n  push:\n    branches:\n      - master\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n  "
  },
  {
    "path": ".github/workflows/release-tag.yaml",
    "chars": 603,
    "preview": "name: release tag\non:\n  push:\n    tags:\n      - \"v[0-9]+.[0-9]+.[0-9]+\"\npermissions:\n  contents: write\njobs:\n  release:\n"
  },
  {
    "path": ".github/workflows/test.yaml",
    "chars": 947,
    "preview": "name: test\n\non: \n  push:\n    branches:\n    - \"**\"\n  pull_request: {}\n\njobs:\n  lint:\n    name: lint\n    runs-on: ubuntu-l"
  },
  {
    "path": ".gitignore",
    "chars": 285,
    "preview": "# Binaries for programs and plugins\n/tinet\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.tes"
  },
  {
    "path": ".goreleaser.yml",
    "chars": 358,
    "preview": "version: 1\nbefore:\n  hooks:\n    - go mod tidy\nbuilds:\n  - env:\n      - CGO_ENABLED=0\n    ldflags:\n      - -s -w\n      - "
  },
  {
    "path": "Dockerfiles/centos7/Dockerfile",
    "chars": 381,
    "preview": "FROM centos:centos7\n\nRUN yum -y install git autoconf automake libtool make \\\n  readline-devel texinfo net-snmp-devel gro"
  },
  {
    "path": "Dockerfiles/centos7/build.sh",
    "chars": 62,
    "preview": "#!/bin/sh -xe\nIMG=tinet/centos:centos7\ndocker build -t $IMG .\n"
  },
  {
    "path": "Dockerfiles/cloudvpn/Dockerfile",
    "chars": 280,
    "preview": "FROM tinet/centos:centos7\n\nRUN yum -y install https://rpm.frrouting.org/repo/frr-stable-repo-1-0.el7.noarch.rpm \\\n && yu"
  },
  {
    "path": "Dockerfiles/cloudvpn/build.sh",
    "chars": 56,
    "preview": "#!/bin/sh -xe\nIMG=tinet/cloudvpn\ndocker build -t $IMG .\n"
  },
  {
    "path": "Dockerfiles/ebpf/Dockerfile",
    "chars": 1055,
    "preview": "FROM ubuntu:rolling\n\nARG LIBBPF_VERSION=\"0.8.0\"\nARG IPROUTE2_VERSION=\"5.18.0\"\nARG BPFTOOL_VERSION=\"6.8.0\"\n\nRUN apt-get u"
  },
  {
    "path": "Dockerfiles/ebpf/Makefile",
    "chars": 142,
    "preview": "IMG=tinynetwork/ebpf:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker run"
  },
  {
    "path": "Dockerfiles/ebpf/README.md",
    "chars": 267,
    "preview": "# Usage\n\n```\ndocker build -t demo:latest .\ndocker run -it --rm --privileged demo:latest bash\n./build_and_attach.sh\nbpfto"
  },
  {
    "path": "Dockerfiles/ebpf/build_and_attach.sh",
    "chars": 252,
    "preview": "#!/bin/bash -xe\n\nclang -target bpf -O3 -g -c filter.c\ntc qdisc del dev eth0 clsact || true\ntc qdisc add dev eth0 clsact\n"
  },
  {
    "path": "Dockerfiles/ebpf/detach.sh",
    "chars": 45,
    "preview": "#!/bin/bash -xe\ntc qdisc del dev eth0 clsact\n"
  },
  {
    "path": "Dockerfiles/ebpf/filter.c",
    "chars": 1173,
    "preview": "#include <linux/bpf.h>\n#include <linux/pkt_cls.h>\n#include <bpf/bpf_helpers.h>\n\nstruct {\n  __uint(type, BPF_MAP_TYPE_PER"
  },
  {
    "path": "Dockerfiles/frr/Dockerfile",
    "chars": 118,
    "preview": "FROM frr-ubuntu20:latest\nUSER root\nRUN mkdir -p /etc/frr\nCOPY daemons /etc/frr/daemons\nRUN apt install -y vim tcpdump\n"
  },
  {
    "path": "Dockerfiles/frr/Makefile",
    "chars": 154,
    "preview": "IMG=tinynetwork/frr:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker run "
  },
  {
    "path": "Dockerfiles/frr/daemons",
    "chars": 137,
    "preview": "zebra=yes\nbgpd=yes\nospfd=no\nospf6d=no\nripd=no\nripngd=no\nisisd=no\npimd=no\nldpd=no\nnhrpd=no\neigrpd=no\nbabeld=no\nsharpd=yes"
  },
  {
    "path": "Dockerfiles/nginx/Dockerfile",
    "chars": 160,
    "preview": "FROM nginx\nRUN apt -y update -y && apt -y install iproute2\nRUN apt update -y && apt install -y tcpdump netcat iperf3 wat"
  },
  {
    "path": "Dockerfiles/nginx/Makefile",
    "chars": 143,
    "preview": "IMG=tinynetwork/nginx:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker ru"
  },
  {
    "path": "Dockerfiles/pmacctd/Dockerfile",
    "chars": 257,
    "preview": "FROM peterevans/vegeta as vegeta\nFROM pmacct/pmacctd:v1.7.6\nRUN apt update -y && apt install -y tcpdump netcat iperf3 wa"
  },
  {
    "path": "Dockerfiles/pmacctd/Makefile",
    "chars": 145,
    "preview": "IMG=tinynetwork/pmacctd:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker "
  },
  {
    "path": "Dockerfiles/trex/Dockerfile",
    "chars": 707,
    "preview": "FROM quay.io/centos/centos:stream8\nARG TREX_VERSION=3.04\nENV TREX_VERSION ${TREX_VERSION}\n\nRUN dnf install -y --nodocs \\"
  },
  {
    "path": "Dockerfiles/trex/Makefile",
    "chars": 104,
    "preview": "IMG=tinynetwork/trex:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\n"
  },
  {
    "path": "LICENSE",
    "chars": 11342,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "Makefile",
    "chars": 767,
    "preview": "VERSION = $$(gobump show -r cmd)\n\nexport GO111MODULE=on\n\n.PHONY: deps\ndeps:\n\tgo get -u -d\n\tgo mod tidy\n\n.PHONY: devel-de"
  },
  {
    "path": "README.md",
    "chars": 3408,
    "preview": "# tinet\n\n![test](https://github.com/tinynetwork/tinet/workflows/test/badge.svg) ![release](https://github.com/tinynetwor"
  },
  {
    "path": "cheatsheet.md",
    "chars": 1157,
    "preview": "# Cheatsheet\n## Linux Networking\n\n```\n# ip route add 10.0.0.0/24 encap seg6 mode encap segs a::,b::,c::,d:: via 2001:db8"
  },
  {
    "path": "command_func.go",
    "chars": 11653,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/emicklei/dot\"\n\t\"github.com/spf13/viper\"\n\t\"github.com"
  },
  {
    "path": "commands.go",
    "chars": 4910,
    "preview": "package main\n\nimport \"github.com/urfave/cli/v2\"\n\nvar commands = []*cli.Command{\n\tcommandBuild,\n\tcommandCheck,\n\tcommandCo"
  },
  {
    "path": "configs/spec_template.yaml",
    "chars": 465,
    "preview": "precmd:\n- cmds:\n  - cmd: \"\"\npreinit:\n- cmds:\n  - cmd: \"\"\npreconf:\n- cmds:\n  - cmd: \"\"\npostinit:\n- cmds:\n  - cmd: \"\"\npost"
  },
  {
    "path": "docs/command-line-usage-example.md",
    "chars": 1348,
    "preview": "# Command Line Usage Example\n\n## tn build\nThat hasn't been implemented yet.\n\n## tn check\n```\n## Check link node to node\n"
  },
  {
    "path": "docs/specification_yml.md",
    "chars": 2999,
    "preview": "# Yaml Format\n\n## Node Definition\n\n### Node type\n\n- name: node name. It will be container-name or netns-name.\n- type: no"
  },
  {
    "path": "examples/bandwidth_tc/spec.yaml",
    "chars": 2067,
    "preview": "nodes:\n\n  - name: C1\n    image: ip6tables:test\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - n"
  },
  {
    "path": "examples/basic_bfd/spec.yaml",
    "chars": 3273,
    "preview": "# http://www.asciiflow.com\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: dire"
  },
  {
    "path": "examples/basic_bgp/README.md",
    "chars": 20,
    "preview": "\n# BGP Playground\n\n\n"
  },
  {
    "path": "examples/basic_bgp/bgp_clos_evpn_vxlan/spec.yaml",
    "chars": 9491,
    "preview": "# ref: https://www.apresiatac.jp/blog/201903121016/\n\nnodes:\n  - name: Spine1\n    image: akiranet24/frr\n    interfaces:\n "
  },
  {
    "path": "examples/basic_bgp/graceful_restart/simple_ipv4_unicast/README.md",
    "chars": 206,
    "preview": "# Simple IPv4 unicast BGP-GR\n\n```\n$ tinet up -c spec.yaml | sudo sh\n$ docker exec -it R2 bash\nR2# tcpdump -nnli net0 # a"
  },
  {
    "path": "examples/basic_bgp/graceful_restart/simple_ipv4_unicast/spec.yaml",
    "chars": 2757,
    "preview": "nodes:\n- name: C1\n  image: alpine:latest\n  interfaces:\n  - { name: net1, type: direct, args: R1#net1 }\n- name: R1\n  imag"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn/README.md",
    "chars": 1052,
    "preview": "\n# HV route advertisement study for BGP-DCN\n\n- [GOOD reference about routing-info manupulation by @ukinau](https://engin"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn/spec.yaml",
    "chars": 3129,
    "preview": "\nnodes:\n  - name: TOR\n    image: slankdev/frr\n    interfaces:\n      - { name: dn1, type: direct, args: HV1#up1 }\n  - nam"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn_isol/Makefile",
    "chars": 51,
    "preview": "\nsh:\n\tdocker exec TOR vtysh -c 'show bgp ipv4 vpn'\n"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn_isol/README.md",
    "chars": 1052,
    "preview": "\n# HV route advertisement study for BGP-DCN\n\n- [GOOD reference about routing-info manupulation by @ukinau](https://engin"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn_isol/spec.yaml",
    "chars": 4320,
    "preview": "\nnodes:\n  - name: TOR\n    # image: slankdev/frr-dev:latest\n    image: slankdev/frr-dev:draft-ietf-bess-srv6-services\n   "
  },
  {
    "path": "examples/basic_bgp/local_pref/README.md",
    "chars": 27,
    "preview": "![topology](topo.png \"bgp\")"
  },
  {
    "path": "examples/basic_bgp/local_pref/spec.yaml",
    "chars": 5169,
    "preview": "nodes:\n- name: R1\n  image: frrouting/frr:latest\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net"
  },
  {
    "path": "examples/basic_bgp/mpbgp_ipv4_labeled_unicast/README.md",
    "chars": 147,
    "preview": "\n# MP-BGP labeled unicast example\n\n```\n     bgp unnumbered\nipv4-labeld-unicast enabled\n\n [R0]-----------------[R1]\n AS1 "
  },
  {
    "path": "examples/basic_bgp/mpbgp_ipv4_labeled_unicast/spec.yaml",
    "chars": 2137,
    "preview": "\nprecmd:\n  - cmds:\n    - cmd: export IMAGE=slankdev/frr:centos-7-stable-7.0\n\nnodes:\n  - name: R0\n    image: $IMAGE\n    i"
  },
  {
    "path": "examples/basic_bgp/path_attr/README.md",
    "chars": 1312,
    "preview": "\n# BGP route-map playground (import-prefix-filter)\n\n![](topo.png)\n\n```\ndocker exec R3 vtysh -c 'show bgp ipv4 unicast'\nB"
  },
  {
    "path": "examples/basic_bgp/path_attr/spec.yaml",
    "chars": 4686,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      -"
  },
  {
    "path": "examples/basic_bgp/route_reflector/spec.yaml",
    "chars": 6900,
    "preview": "\n# DESCRIPTION:\n#    Basic iBGP RR test using and FRR\n#    create reachability with loopback with OSPF\n#\n# INIT:\n#    cn"
  },
  {
    "path": "examples/basic_bgp/route_server/spec.yaml",
    "chars": 6241,
    "preview": "# DESCRIPTION: eBGP RS test\n# TOPO:\n#        10.0.0.0/24                             .1(net0)\n#     B0----+-------------"
  },
  {
    "path": "examples/basic_bgp/route_server_multihop/spec.yaml",
    "chars": 5871,
    "preview": "nodes:\n- name: RS1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: S1#net0 }\n\n- name: S1\n  ima"
  },
  {
    "path": "examples/basic_bgp/spec.yaml",
    "chars": 774,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - nam"
  },
  {
    "path": "examples/basic_bgp/unnumbered/spec.yaml",
    "chars": 1935,
    "preview": "nodes:\n- name: R1\n  image: frrouting/frr:v8.1.0\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net"
  },
  {
    "path": "examples/basic_bgp/vpnv4_mpls/README.md",
    "chars": 2130,
    "preview": "\n# MP-BGP VPNv4 per-VRF w/ MPLS\n\n![](./topo.png)\n\nreferences: configure example of vpnv4 as small set.\nhttps://gist.gith"
  },
  {
    "path": "examples/basic_bgp/vpnv4_mpls/spec.yaml",
    "chars": 7403,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      -"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srmpls/README.md",
    "chars": 88,
    "preview": "# MP-BGP VPNv4 per-VRF w/ SR-MPLS\n\n![](./topo.png)\n\nsetup\n```\n$ tn upconf | sudo sh\n```\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srmpls/spec.yaml",
    "chars": 11318,
    "preview": "preinit:\n  - cmds:\n    - cmd: modprobe mpls_router\n    - cmd: modprobe mpls_gso\n    - cmd: modprobe mpls_iptunnel\n\nnodes"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srmpls_interas_option-b/README.md",
    "chars": 106,
    "preview": "# MP-BGP VPNv4 per-VRF Inter-AS Option B w/ SR-MPLS\n\n![](./topo.png)\n\nsetup\n```\n$ tn upconf | sudo sh\n```\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srmpls_interas_option-b/spec.yaml",
    "chars": 16833,
    "preview": "preinit:\n  - cmds:\n    - cmd: modprobe mpls_router\n    - cmd: modprobe mpls_gso\n    - cmd: modprobe mpls_iptunnel\n\nnodes"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/Makefile",
    "chars": 2271,
    "preview": "\nhelp:\n\t@echo help\n\nbuild:\n\tmake -C /home/vagrant/git/frr.slankdev\n\tsudo make -C /home/vagrant/git/frr.slankdev install\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/README.md",
    "chars": 2255,
    "preview": "\n# FRR meets BGP-SRv6-VPNv4\n\nMP-BGP VPNv4 per-VRF w/ SRv6..?\n\n![](./topo.png)\n\n```\n$ make sh_route_vrfs\n\n[[R1-glb]]\n169."
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/frr.conf.srv6.R1",
    "chars": 1356,
    "preview": "hostname R1\nlog file /tmp/frr.log\n!\ndebug bgp vpn label\ndebug bgp vpn leak-from-vrf\ndebug bgp vpn leak-to-vrf\ndebug bgp "
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/frr.conf.srv6.R2",
    "chars": 1356,
    "preview": "hostname R2\nlog file /tmp/frr.log\n!\ndebug bgp vpn label\ndebug bgp vpn leak-from-vrf\ndebug bgp vpn leak-to-vrf\ndebug bgp "
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/spec.yaml",
    "chars": 3231,
    "preview": "\nnodes:\n\n  - name: R1\n    image: slankdev/frr-7.3:slankdev-support-mpbgp-vpnv4-srv6-cplane\n    interfaces:\n      - { nam"
  },
  {
    "path": "examples/basic_bgp/vpnv6_srv6_rs/spec.yaml",
    "chars": 12065,
    "preview": "nodes:\n- name: RS1\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: S1#net0 }\n  sysc"
  },
  {
    "path": "examples/basic_bgp/vrf2vrf_rouet_leak/Makefile",
    "chars": 170,
    "preview": "\nsh:\n\tdocker exec R1 ip route list\n\t@echo\n\tdocker exec R1 ip route list vrf red\n\t@echo\n\tdocker exec R1 ip route list vrf"
  },
  {
    "path": "examples/basic_bgp/vrf2vrf_rouet_leak/spec.yaml",
    "chars": 1267,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr-dev:latest\n    interfaces:\n      - { name: net0, type: direct, args: R2#net"
  },
  {
    "path": "examples/basic_bond/spec.yaml",
    "chars": 1234,
    "preview": "\nprecmd:\n  - cmds:\n      - cmd: export IMAGE=slankdev/frr\n      - cmd: export IMAGE=slankdev/gobgp\n      - cmd: export I"
  },
  {
    "path": "examples/basic_bufferbloat/README.md",
    "chars": 136,
    "preview": "# Bufferbloat demonstration\n\nSimple demonstration of the [bufferbloat](https://www.bufferbloat.net/projects/) problem.\n\n"
  },
  {
    "path": "examples/basic_bufferbloat/spec.yaml",
    "chars": 2747,
    "preview": "nodes:\n- name: R1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: n"
  },
  {
    "path": "examples/basic_clos/README.md",
    "chars": 1666,
    "preview": "\n# CLOS Topology\n\nPractice of designing DCN. Following are principle of Design.\n- using modernaized technology (such as "
  },
  {
    "path": "examples/basic_clos/spec.v0.0.0.yaml",
    "chars": 11104,
    "preview": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0"
  },
  {
    "path": "examples/basic_clos/spec.v0.0.1.yaml",
    "chars": 15846,
    "preview": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0"
  },
  {
    "path": "examples/basic_clos/spec.v0.0.2.yaml",
    "chars": 18445,
    "preview": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0"
  },
  {
    "path": "examples/basic_clos/spec.v0.0.3.yaml",
    "chars": 59767,
    "preview": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0"
  },
  {
    "path": "examples/basic_clos/spec.yaml",
    "chars": 59767,
    "preview": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0"
  },
  {
    "path": "examples/basic_conntrack/connection_sync/Makefile",
    "chars": 171,
    "preview": "\nNAME=N1\nlog_N1:\n\twhile :; do \\\n\t\tdocker exec $(NAME) vtysh -c 'conf te' -c 'log file /tmp/frr.log'; \\\n\t\tdocker exec -it"
  },
  {
    "path": "examples/basic_conntrack/connection_sync/README.md",
    "chars": 377,
    "preview": "\n# Connection Sync with conntrackd and keepalived\n\n```\ntn upconf | sudo sh\n```\n\n<!-- docker exec -it S1 tcpdump -ni net0"
  },
  {
    "path": "examples/basic_conntrack/connection_sync/spec.yaml",
    "chars": 5678,
    "preview": "\nnodes:\n\n  - name: C1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: S"
  },
  {
    "path": "examples/basic_coredns/blacklist/Corefile.NS1",
    "chars": 182,
    "preview": ".:53 {\n  errors\n  log\n  forward . 8.8.8.8\n}\n\nichihara.org {\n  etcd ichihara.org {\n    path /dns-server01\n    endpoint ht"
  },
  {
    "path": "examples/basic_coredns/blacklist/README.md",
    "chars": 345,
    "preview": "\n# CoreDNS example (very simple blacklist)\n\n![](topo.png)\n\n- Blacklisted\n\t-\temacs.org\n\t- sublimetext.com\n\n```\ndocker exe"
  },
  {
    "path": "examples/basic_coredns/blacklist/spec.yaml",
    "chars": 2443,
    "preview": "\npostinit:\n  - cmds:\n      - cmd: docker cp Corefile.NS1 NS1:/Corefile\n      # - cmd: docker cp Corefile.NS2 NS2:/Corefi"
  },
  {
    "path": "examples/basic_ebgp/spec.yaml",
    "chars": 3814,
    "preview": "\n# DESCRIPTION: BGP network using FRR\n#\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#   "
  },
  {
    "path": "examples/basic_ecmp/README.md",
    "chars": 16,
    "preview": "\n![](topo.jpeg)\n"
  },
  {
    "path": "examples/basic_ecmp/scale.diff",
    "chars": 1695,
    "preview": "diff --git a/examples/basic_ecmp/spec.yaml b/examples/basic_ecmp/spec.yaml\nindex c2c0bd2..79ab538 100644\n--- a/examples/"
  },
  {
    "path": "examples/basic_ecmp/spec.yaml",
    "chars": 5057,
    "preview": "# http://www.asciiflow.com\n\nnodes:\n  - name: S0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: dire"
  },
  {
    "path": "examples/basic_evpn/README.md",
    "chars": 26,
    "preview": "\n# EVPN\n\n![](./topo.png)\n\n"
  },
  {
    "path": "examples/basic_evpn/spec.yaml",
    "chars": 9395,
    "preview": "\nnodes:\n  - name: RR\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n\n  - name"
  },
  {
    "path": "examples/basic_exabgp/Makefile",
    "chars": 225,
    "preview": "\nexabgp:\n\texabgp ./exabgp.conf\n\nPCAP_PATH=/vagrant\ngetcapture:\n\ttcpdump -ni net0 -w $(PCAP_PATH)/in.pcap &\n\texabgp ./exa"
  },
  {
    "path": "examples/basic_exabgp/README.md",
    "chars": 166,
    "preview": "\n# ExaBGP test\n\n```\ntn upconf | sudo sh\ndocker_mount_netns R2 ns0\nip netns exec ns0 bash\nmake       //execute exabgp\nmak"
  },
  {
    "path": "examples/basic_exabgp/daemons.R1",
    "chars": 2330,
    "preview": "# This file tells the frr package which daemons to start.\n#\n# Sample configurations for these daemons can be found in\n# "
  },
  {
    "path": "examples/basic_exabgp/exabgp.conf",
    "chars": 939,
    "preview": "neighbor 10.0.0.1 {\n\trouter-id 2.2.2.2;\n\tlocal-address 10.0.0.2;\n\tlocal-as 2;\n\tpeer-as 1;\n\n\t#capability {\n\t#\tnexthop tru"
  },
  {
    "path": "examples/basic_exabgp/exabgp.conf.R2",
    "chars": 227,
    "preview": "neighbor 10.0.0.1 {\n        router-id 2.2.2.2;\n        local-address 10.0.0.2;\n        local-as 2;\n        peer-as 1;\n  "
  },
  {
    "path": "examples/basic_exabgp/frr.conf.R1",
    "chars": 364,
    "preview": "hostname R1\nlog file /tmp/frr.log\n!\nint net0\n ip address 10.0.0.1/24\n no shutdown\n!\nrouter bgp 1\n bgp router-id 1.1.1.1\n"
  },
  {
    "path": "examples/basic_exabgp/spec.yaml",
    "chars": 729,
    "preview": "\npostinit:\n  - cmds:\n    - cmd: docker cp daemons.R1 R1:/etc/frr/daemons\n    - cmd: docker cp frr.conf.R1 R1:/etc/frr/fr"
  },
  {
    "path": "examples/basic_fq_codel/README.md",
    "chars": 346,
    "preview": "# FQ-Codel demonstration\n\nSimple demonstration of the [FQ-Codel](https://www.bufferbloat.net/projects/codel/wiki/) that "
  },
  {
    "path": "examples/basic_fq_codel/spec.yaml",
    "chars": 3038,
    "preview": "nodes:\n- name: R1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: n"
  },
  {
    "path": "examples/basic_gcp_hv/spec.yaml",
    "chars": 1045,
    "preview": "---\nnodes:\n- name: HV1\n  image: slankdev/frr\n  interfaces:\n  - { name: tap1, type: direct, args: VM1#net0 }\n  - { name: "
  },
  {
    "path": "examples/basic_geneve/spec.yaml",
    "chars": 1268,
    "preview": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - {"
  },
  {
    "path": "examples/basic_gre/README.md",
    "chars": 232,
    "preview": "\n# GRE\n\n![](topo.jpeg)\n\n```\nmodprobe ip_gre\nip tunnel add <IF_NAME> mode gre remote <REMOTE_IPV4_ADDR> local <LOCAL_IPV4"
  },
  {
    "path": "examples/basic_gre/spec.yaml",
    "chars": 6488,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      -"
  },
  {
    "path": "examples/basic_haproxy/README.md",
    "chars": 495,
    "preview": "# HAProxy demonstration\n\n![](./topo.png)\n\n**How to test**<br>\nP1 is configured HAProxy container as-a TCP proxy.\nYou can"
  },
  {
    "path": "examples/basic_haproxy/spec.yaml",
    "chars": 3561,
    "preview": "\nnodes:\n  - name: C1\n    image: slankdev/sandbox\n    interfaces:\n      - { name: net0, type: direct, args: P1#net0 }\n  -"
  },
  {
    "path": "examples/basic_ipip/anycast_tunnel/spec.yaml",
    "chars": 7879,
    "preview": "\npostinit:\n  - cmds:\n    - cmd: docker cp /root/dotfiles/bin/linkstat.py CLOS:/usr/bin/linkstat.py\n    - cmd: docker cp "
  },
  {
    "path": "examples/basic_ipip/simple/README.md",
    "chars": 31,
    "preview": "\n# IPIP tunnel\n\n![](topo.png)\n\n"
  },
  {
    "path": "examples/basic_ipip/simple/spec.yaml",
    "chars": 1013,
    "preview": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n- nam"
  },
  {
    "path": "examples/basic_ipsec/bgp/README.md",
    "chars": 84,
    "preview": "## References\n\nhttps://gist.github.com/Manouchehri/de3adfb02c5b55f3edc2da9e8ee59fae\n"
  },
  {
    "path": "examples/basic_ipsec/bgp/spec.yaml",
    "chars": 4480,
    "preview": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: "
  },
  {
    "path": "examples/basic_ipsec/bgp_ha/spec.yaml",
    "chars": 8959,
    "preview": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: "
  },
  {
    "path": "examples/basic_ipsec/mesh/spec.yaml",
    "chars": 10620,
    "preview": "---\nnodes:\n- name: R1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1,"
  },
  {
    "path": "examples/basic_ipsec/mesh_bgp/spec.yaml",
    "chars": 13390,
    "preview": "---\nnodes:\n- name: R1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1,"
  },
  {
    "path": "examples/basic_ipsec/simple/README.md",
    "chars": 380,
    "preview": "\n## IPsec Example\n\n- libreswan\n\n```bash\n> docker exec R1 ipsec status | grep \"Total IPsec connections\" -A5\n000 Total IPs"
  },
  {
    "path": "examples/basic_ipsec/simple/spec.yaml",
    "chars": 2841,
    "preview": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"vpn1\"\n      EOF\n  - cmd: |\n      cat"
  },
  {
    "path": "examples/basic_ipsec/static_esp_tunnel_simple/README.md",
    "chars": 2591,
    "preview": "# Simple statically-configured ESP tunnel mode example just works\n\nEstablish SA bidirectionally between R0 and R1. Apply"
  },
  {
    "path": "examples/basic_ipsec/static_esp_tunnel_simple/spec.yaml",
    "chars": 3941,
    "preview": "nodes:\n- name: C0\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - name: net0\n    type: direct\n    args: R0#net0\n- na"
  },
  {
    "path": "examples/basic_ipsec/with_vti/README.md",
    "chars": 380,
    "preview": "\n## IPsec Example\n\n- libreswan\n\n```bash\n> docker exec R1 ipsec status | grep \"Total IPsec connections\" -A5\n000 Total IPs"
  },
  {
    "path": "examples/basic_ipsec/with_vti/spec.yaml",
    "chars": 3433,
    "preview": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"vpn1\"\n      EOF\n  - cmd: |\n      cat"
  },
  {
    "path": "examples/basic_ipsec/xfrm_interface/README.md",
    "chars": 286,
    "preview": "# Simple statically-configured ESP tunnel with XFRM Interface\n\nEstablish SA bidirectionally between R0 and R1. Apply xfr"
  },
  {
    "path": "examples/basic_ipsec/xfrm_interface/spec.yaml",
    "chars": 2713,
    "preview": "---\nnodes:\n- name: C0\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net0, type: direct, args: R0#net0 }\n- "
  },
  {
    "path": "examples/basic_iptables/napt/README.md",
    "chars": 305,
    "preview": "\n# Managed NAPT example\n\n```\ntn upconf | sudo sh\ndocker exec -it S1 tcpdump -ni net0 -Qin '(tcp[tcpflags] & tcp-syn)' !="
  },
  {
    "path": "examples/basic_iptables/napt/spec.yaml",
    "chars": 1951,
    "preview": "\n# DESCRIPTION: NAPT network using FRR\n#\n# TOPO:\n#                    S0\n#            (net0).2|\n#                    |\n#"
  },
  {
    "path": "examples/basic_iptables/test/README.md",
    "chars": 1658,
    "preview": "\n# iptables study\n\n```\nroot@R2:/# iptables -L\nChain INPUT (policy ACCEPT)\ntarget     prot opt source               desti"
  },
  {
    "path": "examples/basic_iptables/test/spec.yaml",
    "chars": 750,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/sandbox\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  -"
  },
  {
    "path": "examples/basic_iptables/u32/spec.yaml",
    "chars": 2221,
    "preview": "nodes:\n- name: C1_1\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net1_1, type: direct, args: C2#net1_1 }\n"
  },
  {
    "path": "examples/basic_isis/README.md",
    "chars": 116,
    "preview": "\n# ISIS\n\n![](topo.png)\n\n```\ntn upconf | sudo sh\n```\n\n## Reference\n\n- http://docs.frrouting.org/en/latest/isisd.html\n"
  },
  {
    "path": "examples/basic_isis/spec.yaml",
    "chars": 6473,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      -"
  },
  {
    "path": "examples/basic_l3dsr/dscp/Dockerfile",
    "chars": 97,
    "preview": "\nFROM ubuntu:22.04\n\nRUN apt update \\\n && apt install -y libc6-dev-i386 clang libbpf-dev iproute2\n"
  },
  {
    "path": "examples/basic_l3dsr/dscp/spec.yaml",
    "chars": 2363,
    "preview": "preinit:\n  - cmds:\n    - cmd: docker build -t xdptmp .\n\nnodes:\n  - name: R1\n    image: xdptmp\n    interfaces:\n      - { "
  },
  {
    "path": "examples/basic_l3dsr/dscp/xdp.c",
    "chars": 1913,
    "preview": "#include <linux/bpf.h>\n#include <linux/if_ether.h>\n#include <linux/icmp.h>\n#include <linux/ip.h>\n#include <linux/in.h>\n#"
  },
  {
    "path": "examples/basic_ldp/README.md",
    "chars": 324,
    "preview": "\n# LDP Example\n\ncreate basic mpls backbone-network\n![](./topo.png)\n\n```\nhost# modprobe mpls_router\nhost# modprobe mpls_i"
  },
  {
    "path": "examples/basic_ldp/spec.yaml",
    "chars": 2054,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - nam"
  },
  {
    "path": "examples/basic_mirror/local/spec.yaml",
    "chars": 2913,
    "preview": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n- nam"
  },
  {
    "path": "examples/basic_mirror/remote/spec.yaml",
    "chars": 2322,
    "preview": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n- nam"
  },
  {
    "path": "examples/basic_mpls/spec.yaml",
    "chars": 7720,
    "preview": "# DESCRIPTION: Basic MPLS Traffic Engneering\n# TEST:\n#    docker exec C0 ping 192.168.1.2 -I 192.168.0.2 &\n#    docker e"
  },
  {
    "path": "examples/basic_multipath/README.md",
    "chars": 749,
    "preview": "# Multipath Configuration\n\ndiagram\n```\n+-----------+\n|    R1     |\n+-----------+\n(net0) (net1)\n  |      |\n(net0) (net0)\n"
  },
  {
    "path": "examples/basic_multipath/spec.yaml",
    "chars": 2204,
    "preview": "---\nnodes:\n- name: R1\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2 }\n  - "
  },
  {
    "path": "examples/basic_namespace/README.md",
    "chars": 813,
    "preview": "\n# Namespace Isolation\n\n![](./topo.png)\n\n```\ncd path/to/here\ntn -f spec.blue.yaml upconf | sudo sh\ntn -f spec.green.yaml"
  },
  {
    "path": "examples/basic_namespace/spec.blue.yaml",
    "chars": 416,
    "preview": "\nmeta:\n  namespace: blue_\n\nnodes:\n  - name: R1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, ty"
  },
  {
    "path": "examples/basic_namespace/spec.green.yaml",
    "chars": 417,
    "preview": "\nmeta:\n  namespace: green_\n\nnodes:\n  - name: R1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, t"
  },
  {
    "path": "examples/basic_napt/spec.yaml",
    "chars": 1708,
    "preview": "\n# DESCRIPTION: NAPT network using FRR\n#\n# TOPO:\n#                    S0\n#            (net0).2|\n#                    |\n#"
  },
  {
    "path": "examples/basic_netflow/README.md",
    "chars": 653,
    "preview": "# NetFlow/IPFIX using pmacctd\n\n## pmacct\nref: https://github.com/linsomniac/pmacct/blob/master/EXAMPLES\n\n```\npmacctd -P "
  },
  {
    "path": "examples/basic_netflow/multipath/Makefile",
    "chars": 1250,
    "preview": "linkstats:\n\t@echo -n \"R1:net0  \"\n\t@docker exec -it R1 sh -c \"ip -j -s link show dev net0 | jq '.[0] | [.stats64.rx.packe"
  },
  {
    "path": "examples/basic_netflow/multipath/spec.yaml",
    "chars": 4487,
    "preview": "---\nnodes:\n- name: R1\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: bridge, args: B1 }\n  - "
  },
  {
    "path": "examples/basic_netflow/simple/spec.yaml",
    "chars": 1019,
    "preview": "---\nnodes:\n- name: R1\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }"
  },
  {
    "path": "examples/basic_netns/spec.yaml",
    "chars": 798,
    "preview": "\nnodes:\n  - name: H0\n    type: netns\n    interfaces:\n      - { name: net0, type: direct, args: C0#net0 }\n      - { name:"
  },
  {
    "path": "examples/basic_nftables/masquerade/README.md",
    "chars": 430,
    "preview": "\n# nftables study (MASQ)\n\ncheck nft is enabled (m is OK)\n```\n# cat /boot/config-`uname -r` | grep CONFIG_NF_TABLES\nCONFI"
  },
  {
    "path": "examples/basic_nftables/masquerade/spec.yaml",
    "chars": 1227,
    "preview": "\npostinit:\n  - cmds:\n      - cmd: docker cp ../../../tools/http_server.py R3:/usr/bin\n      - cmd: docker cp ../../../to"
  },
  {
    "path": "examples/basic_nftables/snat/README.md",
    "chars": 430,
    "preview": "\n# nftables study (SNAT)\n\ncheck nft is enabled (m is OK)\n```\n# cat /boot/config-`uname -r` | grep CONFIG_NF_TABLES\nCONFI"
  },
  {
    "path": "examples/basic_nftables/snat/spec.yaml",
    "chars": 1227,
    "preview": "\npostinit:\n  - cmds:\n      - cmd: docker cp ../../../tools/http_server.py R3:/usr/bin\n      - cmd: docker cp ../../../to"
  },
  {
    "path": "examples/basic_ospfv2_bird/README.md",
    "chars": 65,
    "preview": "\n# Multiple OSPFv3 Instance using Bird\n\n![](./topo.png)\n\n```\n```\n"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R1_bird.conf",
    "chars": 389,
    "preview": "router id 10.255.0.1;\n\nprotocol device {\n}\n\nprotocol kernel {\n\tlearn;\n\texport all;\n\timport all;\n}\n\nprotocol ospf instanc"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R2_bird.conf",
    "chars": 326,
    "preview": "router id 10.255.0.2;\n\nprotocol device {\n}\n\nprotocol kernel {\n\tlearn;\n\texport all;\n\timport all;\n}\n\nprotocol ospf instanc"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R3_bird.conf",
    "chars": 390,
    "preview": "router id 10.255.0.3;\n\nprotocol device {\n}\n\nprotocol kernel {\n\tlearn;\n\texport all;\n\timport all;\n}\n\nprotocol ospf instanc"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R4_bird.conf",
    "chars": 390,
    "preview": "router id 10.255.0.4;\n\nprotocol device {\n}\n\nprotocol kernel {\n\tlearn;\n\texport all;\n\timport all;\n}\n\nprotocol ospf instanc"
  },
  {
    "path": "examples/basic_ospfv2_bird/spec.yaml",
    "chars": 3789,
    "preview": "\npostinit:\n  - cmds:\n    - cmd: docker cp bird/R1_bird.conf R1:/etc/bird/bird.conf\n    - cmd: docker cp bird/R2_bird.con"
  },
  {
    "path": "examples/basic_ospfv2_frr/README.md",
    "chars": 39,
    "preview": "\n# OSPFv2 using FRR\n\n![](./topo.png)\n\n\n"
  },
  {
    "path": "examples/basic_ospfv2_frr/spec.yaml",
    "chars": 3889,
    "preview": "\n# DESCRIPTION: OSPF network using FRR\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#    "
  },
  {
    "path": "examples/basic_ospfv3_bird_multiple_instance/R3_bird6.conf",
    "chars": 955,
    "preview": "router id 10.255.0.3;\n\nprotocol device dev0 {\n}\n\nprotocol kernel ker0 {\n\tlearn;\n\texport all;\n\timport all;\n}\n\ntable red;\n"
  },
  {
    "path": "examples/basic_ospfv3_bird_multiple_instance/README.md",
    "chars": 154,
    "preview": "\n# OSPFv3 Multiple Instance(VRF) using Bird\n\n![](./topo.png)\n\n- the tmp image should include **bird-1.6.6**\n- also kerne"
  },
  {
    "path": "examples/basic_ospfv3_bird_multiple_instance/spec.yaml",
    "chars": 3092,
    "preview": "\npostinit:\n  - cmds:\n    - cmd: docker exec R3 mkdir -p /etc/bird\n    - cmd: docker cp R3_bird6.conf R3:/etc/bird/bird6."
  },
  {
    "path": "examples/basic_ospfv3_frr/README.md",
    "chars": 39,
    "preview": "\n# OSPFv3 using FRR\n\n![](./topo.png)\n\n\n"
  },
  {
    "path": "examples/basic_ospfv3_frr/spec.yaml",
    "chars": 5017,
    "preview": "\n# DESCRIPTION: OSPF network using FRR\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#    "
  },
  {
    "path": "examples/basic_pbr/spec.yaml",
    "chars": 1018,
    "preview": "postinit:\n- cmds:\n  - cmd: |\n      cat <<EOF > /tmp/Corefile\n      .:53 {\n        forward . 8.8.8.8\n        log\n        "
  },
  {
    "path": "examples/basic_peer/spec.yaml",
    "chars": 1719,
    "preview": "\nprecmd:\n  - cmds:\n    - cmd: export IMAGE=slankdev/frr:centos-7-stable-7.0\n\nnodes:\n  - name: R0\n    image: $IMAGE\n    i"
  },
  {
    "path": "examples/basic_pim/README.md",
    "chars": 1800,
    "preview": "\n# PIM Multicast Test\n\nmulticast test\n```\niperf -u -s -B 239.1.1.5 -i 1\niperf -u -c 239.1.1.5 -i <interval> -T <ttl> -t "
  },
  {
    "path": "examples/basic_pim/spec.yaml",
    "chars": 2879,
    "preview": "# http://www.asciiflow.com\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: dire"
  },
  {
    "path": "examples/basic_pim2/README.md",
    "chars": 667,
    "preview": "\n# PIM Multicast Test\n\n![](topo.jpeg)\n\ndebug commands (vtysh)\n```\nshow ip mroute\nshow ip pim neighbor\nshow ip pim join\ns"
  },
  {
    "path": "examples/basic_pim2/spec.yaml",
    "chars": 8414,
    "preview": "# http://www.asciiflow.com\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: dire"
  },
  {
    "path": "examples/basic_pppoe_WIP/spec.yaml",
    "chars": 1926,
    "preview": "# http://www.asciiflow.com\n\nnodes:\n  - name: R0\n    image: tmp\n    interfaces:\n      - { name: net0, type: bridge, args:"
  },
  {
    "path": "examples/basic_rift/README.md",
    "chars": 1823,
    "preview": "\n# RIFT: Routing In Fat Tree\n\nThis is evaluation of rift-python powered by IETF.\n\n- draft-ietf-rift-rift-03 https://tool"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/meta_topology_2c_2x2.yaml",
    "chars": 51,
    "preview": "nr-leaf-nodes-per-pod: 2\nnr-spine-nodes-per-pod: 2\n"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_leaf1.yaml",
    "chars": 400,
    "preview": "shards:\n  - id: 0\n    nodes:\n      - name: Leaf1\n        level: 0\n        systemid: 1001\n        interfaces:\n          -"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_leaf2.yaml",
    "chars": 400,
    "preview": "shards:\n  - id: 0\n    nodes:\n      - name: Leaf2\n        level: 0\n        systemid: 1002\n        interfaces:\n          -"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_spine1.yaml",
    "chars": 304,
    "preview": "shards:\n  - id: 0\n    nodes:\n      - name: Spine1\n        level: 1\n        systemid: 101\n        interfaces:\n          -"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_spine2.yaml",
    "chars": 304,
    "preview": "shards:\n  - id: 0\n    nodes:\n      - name: Spine2\n        level: 1\n        systemid: 102\n        interfaces:\n          -"
  },
  {
    "path": "examples/basic_rift/spec.yaml",
    "chars": 3116,
    "preview": "\npostinit:\n  - cmds:\n    - cmd: docker cp ietf_rift_python/rift_spine1.yaml Spine1:/root/config.yaml\n    - cmd: docker c"
  },
  {
    "path": "examples/basic_rtbh/README.md",
    "chars": 2408,
    "preview": "\n# RTBH: Remotely-Triggered Black Hole Routing\n\n![](./topo.png)\n\ncreate test traffic\n```\nhost# docker exec -it C2 ping 1"
  },
  {
    "path": "examples/basic_rtbh/spec.yaml",
    "chars": 2674,
    "preview": "\nnodes:\n  ## AS65001\n  - name: R1\n    type: docker\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: d"
  },
  {
    "path": "examples/basic_source_routing/README.md",
    "chars": 464,
    "preview": "\n# Source Routing\n\n![](topo.jpeg)\n\nnetwork operation\n```\ndocker exec R1 ip rule add from 192.168.1.2 table 10\ndocker exe"
  },
  {
    "path": "examples/basic_source_routing/spec.yaml",
    "chars": 3393,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      -"
  },
  {
    "path": "examples/basic_srmpls/spec.yaml",
    "chars": 7464,
    "preview": "# http://www.asciiflow.com\n\npreinit:\n  - cmds:\n    - cmd: modprobe mpls_router\n    - cmd: modprobe mpls_gso\n    - cmd: m"
  },
  {
    "path": "examples/basic_srv6/README.md",
    "chars": 5927,
    "preview": "\n# Segment Routing IPv6 Examples\n\n- **vpn-v4-per-ce**: IPv4 L3VPN [T.Encaps, End, End.DX4]\n- **vpn-v6-per-ce**: IPv6 L3V"
  },
  {
    "path": "examples/basic_srv6/linux/bgp_vpnv6/spec.yaml",
    "chars": 6721,
    "preview": "postinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/daemons\n      zebra=yes\n      bgpd=yes\n      sharpd=yes\n      EOF\n  -"
  },
  {
    "path": "examples/basic_srv6/linux/binding_sid/README.md",
    "chars": 228,
    "preview": "\n# VRF Redirect\n- Hiroki Shirokura <slankdev@coe.ad.jp>\n- 2018.12.31\n\n![](topo.jpeg)\n\n```\n$ cd <path/to/here>\n$ tn up | "
  },
  {
    "path": "examples/basic_srv6/linux/binding_sid/spec.yaml",
    "chars": 9601,
    "preview": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/Makefile",
    "chars": 262,
    "preview": "\nall:\n\tclang -O2 -Wall -target bpf -c filter.c\n\tdocker cp filter.o R2:/filter.o\n\tdocker exec R2 \\\n\t\tip -6 route add fc00"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/bpf_helpers.h",
    "chars": 6904,
    "preview": "#ifndef __BPF_HELPERS_H\n#define __BPF_HELPERS_H\n\n/* helper macro to place programs, maps, license in\n * different sectio"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/filter.c",
    "chars": 868,
    "preview": "#include <stdint.h>\n#include <linux/bpf.h>\n#include <linux/if_ether.h>\n#include <linux/if_packet.h>\n#include <linux/ip.h"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/spec.yaml",
    "chars": 3852,
    "preview": "\npostinit:\n  - cmds:\n      - cmd: make\n      - cmd: docker cp filter.o R2:/filter.o\n\nnodes:\n  - name: R1\n    image: slan"
  },
  {
    "path": "examples/basic_srv6/linux/hands_on/README.md",
    "chars": 31,
    "preview": "\n# SRv6 Hands-on\n\n![](img.png)\n"
  },
  {
    "path": "examples/basic_srv6/linux/hands_on/spec.yaml",
    "chars": 5736,
    "preview": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev"
  },
  {
    "path": "examples/basic_srv6/linux/l2vpn/README.md",
    "chars": 427,
    "preview": "\n# SRv6 Tiny L2VPN Demonstration\n- Hiroki Shirokura <slankdev@coe.ad.jp>\n- 2018.12.30\n\n![img](./topo.jpeg)\n\n```\n$ cd tin"
  },
  {
    "path": "examples/basic_srv6/linux/l2vpn/spec.yaml",
    "chars": 4014,
    "preview": "\n# postinit:\n#   - cmds:\n#     - cmd: make -C /home/vagrant/git/srdump install_container2\n\nnodes:\n  - name: R1\n    image"
  },
  {
    "path": "examples/basic_srv6/linux/sfc/README.md",
    "chars": 998,
    "preview": "\n# SFC using SRv6\n\n![](./topo.jpeg)\n\n```\ntn upconf | sudo sh\n```\n\nmake test traffic\n```\ndocker exec -it R4 ping -I 2001:"
  },
  {
    "path": "examples/basic_srv6/linux/sfc/spec.yaml",
    "chars": 10099,
    "preview": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - nam"
  }
]

// ... and 126 more files (download for full content)

About this extraction

This page contains the full source code of the tinynetwork/tinet GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 326 files (931.5 KB), approximately 353.0k tokens, and a symbol index with 179 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!