[
  {
    "path": ".github/CODEOWNERS",
    "content": "* @ak1ra24 @slankdev\n"
  },
  {
    "path": ".github/auto_assign.yml",
    "content": "# Set to true to add reviewers to pull requests\naddReviewers: true\n\n# Set to true to add assignees to pull requests\naddAssignees: false\n\n# A list of reviewers to be added to pull requests (GitHub user name)\nreviewers:\n  - slankdev\n  - ak1ra24\n\n# A number of reviewers added to the pull request\n# Set 0 to add all the reviewers (default: 0)\nnumberOfReviewers: 1\n\n# A list of assignees, overrides reviewers if set\n# assignees:\n#   - assigneeA\n\n# A number of assignees to add to the pull request\n# Set to 0 to add all of the assignees.\n# Uses numberOfReviewers if unset.\n# numberOfAssignees: 2\n\n# A list of keywords to be skipped the process that add reviewers if pull requests include it\nskipKeywords:\n  - wip\n"
  },
  {
    "path": ".github/workflows/pr-auto-assign.yaml",
    "content": "name: 'Auto Assign'\non: pull_request\n\njobs:\n  add-reviews:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: kentaro-m/auto-assign-action@v1.1.0\n        with:\n          repo-token: \"${{ secrets.GITHUB_TOKEN }}\"\n          configuration-path: \".github/auto_assign.yml\"\n"
  },
  {
    "path": ".github/workflows/release-master.yaml",
    "content": "name: release-master\non:\n  push:\n    branches:\n      - master\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Set up Go 1.13\n      uses: actions/setup-go@v2\n      with:\n        go-version: 1.13\n      id: go\n\n    - name: Check out code into the Go module directory\n      uses: actions/checkout@v2\n\n    - name: Build\n      env:\n        GO111MODULE: on\n        GOPATH: /home/runner/work/\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      run: |\n        go get -u github.com/tcnksm/ghr\n        go get -u github.com/Songmu/ghch/cmd/ghch\n        export TAGNAME=latest\n        go build -ldflags=\"-s -w -X main.Version=$TAGNAME\"\n        mkdir -p dist/latest\n        tar -zcvf dist/latest/tinet_latest_linux64_amd64.tar.gz tinet\n        $GOPATH/bin/ghr -n=$TAGNAME -b=\"$($GOPATH/bin/ghch -F markdown --latest)\" -replace $TAGNAME ./dist/$TAGNAME\n"
  },
  {
    "path": ".github/workflows/release-tag.yaml",
    "content": "name: release tag\non:\n  push:\n    tags:\n      - \"v[0-9]+.[0-9]+.[0-9]+\"\npermissions:\n  contents: write\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - name: Set up Go\n        uses: actions/setup-go@v4\n        with:\n          go-version: stable\n      - name: Run GoReleaser\n        uses: goreleaser/goreleaser-action@v5\n        with:\n          distribution: goreleaser\n          version: v1.23.0\n          args: release --clean\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/test.yaml",
    "content": "name: test\n\non: \n  push:\n    branches:\n    - \"**\"\n  pull_request: {}\n\njobs:\n  lint:\n    name: lint\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        go-version: [1.12.x, 1.13.x, 1.14.x, 1.15.x, 1.16.x, 1.17.x]\n    steps:\n      - uses: actions/setup-go@v3\n        with:\n          go-version: ${{ matrix.go-version }}\n      - name: checkout\n        uses: actions/checkout@v3\n      - name: golangci-lint\n        uses: golangci/golangci-lint-action@v3\n        with:\n            version: v1.45.2\n\n  test:\n    name: go test\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        go-version: [1.12.x, 1.13.x, 1.14.x, 1.15.x, 1.16.x, 1.17.x]\n    steps:\n      - name: Set up Go\n        uses: actions/setup-go@v3\n        with:\n          version: ${{ matrix.go-version }}\n      - name: checkout\n        uses: actions/checkout@v3\n      - name: Run go tests\n        env:\n          GO111MODULE: on\n        run: |\n          go test ./... -v\n"
  },
  {
    "path": ".gitignore",
    "content": "# 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*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\n*.swp\n*~\n"
  },
  {
    "path": ".goreleaser.yml",
    "content": "version: 1\nbefore:\n  hooks:\n    - go mod tidy\nbuilds:\n  - env:\n      - CGO_ENABLED=0\n    ldflags:\n      - -s -w\n      - -X main.Version={{.Version}}\n    goos:\n      - linux\n    goarch:\n      - amd64\n      - arm64\narchives:\n  - format: binary\n    name_template: \"{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}\"\nchangelog:\n  sort: asc\n  use: github-native\n"
  },
  {
    "path": "Dockerfiles/centos7/Dockerfile",
    "content": "FROM centos:centos7\n\nRUN yum -y install git autoconf automake libtool make \\\n  readline-devel texinfo net-snmp-devel groff pkgconfig \\\n  json-c-devel pam-devel bison flex pytest c-ares-devel \\\n  python-devel systemd-devel python-sphinx libcap-devel \\\n\tsudo iproute traceroute iputils bash-completion tcpdump \\\n\twireshark gdb wget vim libunwind libunwind-devel \\\n\tiptables-services\n"
  },
  {
    "path": "Dockerfiles/centos7/build.sh",
    "content": "#!/bin/sh -xe\nIMG=tinet/centos:centos7\ndocker build -t $IMG .\n"
  },
  {
    "path": "Dockerfiles/cloudvpn/Dockerfile",
    "content": "FROM tinet/centos:centos7\n\nRUN yum -y install https://rpm.frrouting.org/repo/frr-stable-repo-1-0.el7.noarch.rpm \\\n && yum -y install frr-7.3.1-01.el7.x86_64 frr-pythontools \\\n && yum -y install https://download.libreswan.org/binaries/rhel/7/x86_64/libreswan-3.32-1.el7.x86_64.rpm\n"
  },
  {
    "path": "Dockerfiles/cloudvpn/build.sh",
    "content": "#!/bin/sh -xe\nIMG=tinet/cloudvpn\ndocker build -t $IMG .\n"
  },
  {
    "path": "Dockerfiles/ebpf/Dockerfile",
    "content": "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 update\nRUN DEBIAN_FRONTEND=noninteractive apt-get install -y \\\n\tvim curl git gcc make flex bison clang-12 libbsd-dev libbfd-dev libcap-dev \\\n  libelf-dev gcc-multilib pkg-config linux-tools-`uname -r`\n\nRUN ln -s /usr/bin/clang-12 /usr/bin/clang\n\nWORKDIR /opt\n\nADD https://github.com/libbpf/libbpf/archive/refs/tags/v${LIBBPF_VERSION}.tar.gz .\nRUN tar xvf v${LIBBPF_VERSION}.tar.gz\nRUN cd libbpf-${LIBBPF_VERSION}/src && make install BUILD_STATIC_ONLY=1 && make install_pkgconfig\nRUN rm -rf libbpf-${LIBBPF_VERSION} v${LIBBPF_VERSION}.tar.gz\n\nADD https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/snapshot/iproute2-${IPROUTE2_VERSION}.tar.gz .\nRUN tar xvf iproute2-${IPROUTE2_VERSION}.tar.gz\nRUN cd iproute2-${IPROUTE2_VERSION} && ./configure --libbpf_force=on --libbpf_dir=/ && make install\nRUN rm -rf iproute2-${IPROUTE2_VERSION} iproute2-${IPROUTE2_VERSION}.tar.gz\n\nADD filter.c .\nADD build_and_attach.sh .\nADD detach.sh .\n"
  },
  {
    "path": "Dockerfiles/ebpf/Makefile",
    "content": "IMG=tinynetwork/ebpf:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker run --rm -it $(IMG) bash\n"
  },
  {
    "path": "Dockerfiles/ebpf/README.md",
    "content": "# Usage\n\n```\ndocker build -t demo:latest .\ndocker run -it --rm --privileged demo:latest bash\n./build_and_attach.sh\nbpftool map dump name pkt_counter_egr\nbpftool map dump name pkt_counter_ing\nbpftool map event_pipe name pkt_counter_eve\n# make some traffic on eth0\n```\n"
  },
  {
    "path": "Dockerfiles/ebpf/build_and_attach.sh",
    "content": "#!/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\ntc filter add dev eth0 ingress bpf obj filter.o section tc-ingress\ntc filter add dev eth0 egress bpf obj filter.o section tc-egress\n"
  },
  {
    "path": "Dockerfiles/ebpf/detach.sh",
    "content": "#!/bin/bash -xe\ntc qdisc del dev eth0 clsact\n"
  },
  {
    "path": "Dockerfiles/ebpf/filter.c",
    "content": "#include <linux/bpf.h>\n#include <linux/pkt_cls.h>\n#include <bpf/bpf_helpers.h>\n\nstruct {\n  __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);\n  __uint(max_entries, 1);\n  __type(key, int);\n  __type(value, int);\n} pkt_counter_ingress SEC(\".maps\");\n\nstruct {\n  __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);\n  __uint(max_entries, 1);\n  __type(key, int);\n  __type(value, int);\n} pkt_counter_egress SEC(\".maps\");\n\nstruct {\n  __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);\n  __uint(key_size, sizeof(int));\n  __uint(value_size, sizeof(int));\n} pkt_counter_events SEC(\".maps\");\n\nstatic __inline int\ncount_packets(struct __sk_buff *skb, void *map)\n{\n  int key = 0;\n  int *val = bpf_map_lookup_elem(map, &key);\n  if (val == NULL) {\n    return TC_ACT_SHOT;\n  }\n  *val = *val + 1;\n\n  int msg = 0xefbeadde;\n  bpf_perf_event_output(skb, &pkt_counter_events, BPF_F_CURRENT_CPU, &msg, sizeof(msg));\n\n  return TC_ACT_OK;\n}\n\nSEC(\"tc-ingress\") int\ncount_packets_ingress(struct __sk_buff *skb)\n{\n  return count_packets(skb, &pkt_counter_ingress);\n}\n\nSEC(\"tc-egress\") int\ncount_packets_egress(struct __sk_buff *skb)\n{\n  return count_packets(skb, &pkt_counter_egress);\n}\n\nchar __license[] SEC(\"license\") = \"GPL\";\n"
  },
  {
    "path": "Dockerfiles/frr/Dockerfile",
    "content": "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",
    "content": "IMG=tinynetwork/frr:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker run --rm -it --privileged $(IMG) bash\n"
  },
  {
    "path": "Dockerfiles/frr/daemons",
    "content": "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\npbrd=no\nbfdd=no\n"
  },
  {
    "path": "Dockerfiles/nginx/Dockerfile",
    "content": "FROM nginx\nRUN apt -y update -y && apt -y install iproute2\nRUN apt update -y && apt install -y tcpdump netcat iperf3 watch file xxd psutils vim\nENTRYPOINT bash\n"
  },
  {
    "path": "Dockerfiles/nginx/Makefile",
    "content": "IMG=tinynetwork/nginx:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker run --rm -it $(IMG) bash\n"
  },
  {
    "path": "Dockerfiles/pmacctd/Dockerfile",
    "content": "FROM peterevans/vegeta as vegeta\nFROM pmacct/pmacctd:v1.7.6\nRUN apt update -y && apt install -y tcpdump netcat iperf3 watch file xxd psutils vim\nRUN apt install -y nfdump jq\nRUN apt install -y curl\nCOPY --from=vegeta /bin/vegeta /bin/vegeta\nENTRYPOINT bash\n"
  },
  {
    "path": "Dockerfiles/pmacctd/Makefile",
    "content": "IMG=tinynetwork/pmacctd:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\nrun:\n\tdocker run --rm -it $(IMG) bash\n"
  },
  {
    "path": "Dockerfiles/trex/Dockerfile",
    "content": "FROM quay.io/centos/centos:stream8\nARG TREX_VERSION=3.04\nENV TREX_VERSION ${TREX_VERSION}\n\nRUN dnf install -y --nodocs \\\n    git wget procps python3 vim python3-pip pciutils gettext \\\n    https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \\\n && dnf clean all \\\n && dnf install -y --nodocs \\\n    hostname iproute net-tools ethtool nmap iputils perf numactl \\\n    sysstat htop rdma-core-devel libibverbs libibverbs-devel net-tools \\\n && dnf clean all\n\nWORKDIR /opt/\nRUN wget --no-check-certificate https://trex-tgn.cisco.com/trex/release/v${TREX_VERSION}.tar.gz && \\\n   tar -xzf v${TREX_VERSION}.tar.gz && \\\n   mv v${TREX_VERSION} trex && \\\n   rm v${TREX_VERSION}.tar.gz\nWORKDIR /opt/trex\n"
  },
  {
    "path": "Dockerfiles/trex/Makefile",
    "content": "IMG=tinynetwork/trex:develop\nbuild:\n\tdocker build -t $(IMG) .\npush:\n\tdocker push $(IMG)\nall: build push\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [2020] [ak1ra24]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Makefile",
    "content": "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-deps\ndevel-deps:\n\tgo get -v \\\n\tgithub.com/x-motemen/gobump/cmd/gobump \\\n\tgithub.com/Songmu/ghch/cmd/ghch \\\n\tgithub.com/Songmu/goxz/cmd/goxz \\\n\tgithub.com/tcnksm/ghr \\\n\tgithub.com/golangci/golangci-lint/cmd/golangci-lint\n\n.PHONY: test\ntest:\n\tgo test -v ./...\n\n.PHONY: lint\nlint: devel-deps\n\tgolangci-lint run\n\n.PHONY: build\nbuild: deps\n\tgo build -o tn\n\n.PHONY: install\ninstall: deps\n\tgo install \n\n.PHONY: release\nrelease: devel-deps\n\techo ghr -n=v$(VERSION) -b=\"$($GOPATH/bin/ghch -F markdown --latest)\" -draft v$(VERSION) ./dist/v$(VERSION)\n\n.PHONY: crossbuild\ncrossbuild: devel-deps\n\tgoxz -pv=$(VERSION) -os=linux -arch=amd64 -d=./dist/v$(VERSION)\n"
  },
  {
    "path": "README.md",
    "content": "# tinet\n\n![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)\n\nAn instant virtual network on your laptop with\nlight-weight virtualization. Here we introduce the\nContainer Network Simulation tools. Users can generate,\nfrom the YAML configuration file, the script to build\nthe L2 container network. Quickstart guide is provided\nin QUICKSTART.md. It is tested on Ubuntu 16.04 LTS and\nlater.\n\n## Requirements\n- Docker\n- OpenvSwitch (optional)\n- graphviz (optional)\n\n## Quick Install\n\nThere is only linux_amd64 pre-built binary\n```\ncurl -Lo /usr/bin/tinet https://github.com/tinynetwork/tinet/releases/download/v0.0.3/tinet.linux_amd64\nchmod +x /usr/bin/tinet\ntinet --version\n```\n\nfor ubuntu user\n```\nsudo apt update\nsudo apt install -y linux-image-extra-virtual\nsudo reboot\n```\n\nupgrading the kernel\n```\n$ sudo apt list \"linux-image-5.15.*-generic\"\nlinux-image-5.15.0-33-generic/focal-updates,focal-security 5.15.0-33.34~20.04.1 amd64\n$ 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\n$ sudo reboot\n```\n```\n$ sudo grep 'menuentry ' $(sudo find /boot -name \"grub.cfg\") | cut -f 2 -d \"'\" | nl -v 0\n     0  Ubuntu\n     1  Ubuntu, with Linux 5.15.0-33-generic\n     2  Ubuntu, with Linux 5.15.0-33-generic (recovery mode)\n     3  Ubuntu, with Linux 5.4.0-113-generic\n     4  Ubuntu, with Linux 5.4.0-113-generic (recovery mode)\n$ sudo grub-set-default 3\n$ sudo reboot\n```\n\n## Build\n```\ngit clone https://github.com/tinynetwork/tinet tinet && cd $_\ndocker run --rm -i -t -v $PWD:/v -w /v golang:1.12 go build\nmv tinet /usr/local/bin\n```\n\n## Usage\n\n```\ntinet up -c spec.yaml | sudo sh -x\ntinet conf -c spec.yaml | sudo sh -x\ntinet test -c spec.yaml | sudo sh -x\ntinet down -c spec.yaml | sudo sh -x\ndocker run -it --rm --privileged --net=container:R1 nicolaka/netshoot bash\n```\n\n## Command Options\n\n```\n# tinet\nNAME:\n   tinet - tinet: Tiny Network\n\nUSAGE:\n   tinet [global options] command [command options] [arguments...]\n\nVERSION:\n   0.0.1 (rev:)\n\nAUTHOR:\n   ak1ra24 <marug4580@gmail.com>\n\nCOMMANDS:\n   check    check config\n   conf     configure Node from tinet config file\n   down     Down Node from tinet config file\n   exec     Execute Command on Node from tinet config file.\n   img      visualize network topology by graphviz from tinet config file\n   init     Generate tinet config template file\n   ps       docker and netns process\n   pull     Pull Node docker image from tinet config file\n   reconf   Stop, remove, create, start and config\n   reup     Stop, remove, create, start\n   test     Execute test commands from tinet config file.\n   up       create Node from tinet config file\n   upconf   Create, start and config\n   help, h  Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --help, -h     show help (default: false)\n   --version, -v  print the version (default: false)\n```\n\n## Contribute\n\nSimply fork and create a pull-request. We'll try to respond in a timely fashion.\n\n## Links\n\n- [Command Line Usage Example](docs/command-line-usage-example.md)\n- [YAML Format](docs/specification_yml.md)\n"
  },
  {
    "path": "cheatsheet.md",
    "content": "# 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::1\n# ip route add 10.0.0.0/24 encap seg6 mode l2encap segs a::,b::,c::,d:: via 2001:db8::1\n# ip route add 10.0.0.0/24 encap seg6 mode inline segs a::,b::,c::,d:: via 2001:db8::1\n\n# ip -6 route add fc00::1/128 encap seg6local \\\n    action End                    via 2001:db8::1\n    action End.X   nh6 fc00::1:1  via 2001:db8::1\n    action End.T   table 100      via 2001:db8::1\n    action End.DX2 oif lxcbr0     via 2001:db8::1\n    action End.DX4 nh4 10.0.3.254 via 2001:db8::1\n    action End.DT4 vrftable 100   via 2001:db8::1\n    action End.DX6 nh6 fc00::1:1  via 2001:db8::1\n    action End.DT6 table 100      via 2001:db8::1\n```\n\n## VPP Networking\n```\nvpp> sr policy add bsid cafe::10 next fc00:2::10 fib-table 0\nvpp> sr steer l3 192.168.1.0/24 via bsid cafe::10 fib-table 10\nvpp> sr steer l2 host-net2 via bsid cafe::10\n\nvpp> set sr encaps source addr fc00:1::\nvpp> sr localsid address fc00:1::   behavior end\nvpp> sr localsid address fc00:1::10 behavior end.dt4 10\nvpp> sr localsid address fc00:1::10 behavior end.dx2 host-net2\n```\n"
  },
  {
    "path": "command_func.go",
    "content": "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/tinynetwork/tinet/internal/pkg/shell\"\n\t\"github.com/tinynetwork/tinet/internal/pkg/utils\"\n\t\"github.com/urfave/cli/v2\"\n)\n\ntype linkstatus struct {\n\tleftNodeName  string\n\tleftInfName   string\n\tleftIsSet     bool\n\tleftNodeType  string\n\trightNodeName string\n\trightInfName  string\n\trightIsSet    bool\n\trightNodeType string\n}\n\nfunc LoadCfg(c *cli.Context) (tnconfig shell.Tn, verbose bool, err error) {\n\tcfgFile := c.String(\"config\")\n\tverbose = c.Bool(\"verbose\")\n\tif cfgFile != \"\" {\n\t\tviper.SetConfigFile(cfgFile)\n\t\tviper.SetConfigType(\"yaml\")\n\n\t\tif err = viper.ReadInConfig(); err != nil {\n\t\t\treturn tnconfig, verbose, err\n\t\t}\n\n\t\tif err = viper.Unmarshal(&tnconfig); err != nil {\n\t\t\treturn tnconfig, verbose, err\n\t\t}\n\t} else {\n\t\terr = fmt.Errorf(\"not set config file.\")\n\t\treturn tnconfig, verbose, err\n\t}\n\n\treturn tnconfig, verbose, nil\n\n}\n\nfunc CmdBuild(c *cli.Context) error {\n\n\ttnconfig, _, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tnodes := tnconfig.Nodes\n\n\tfor _, node := range nodes {\n\t\tbuildCmd := node.BuildCmd()\n\t\tfmt.Fprint(os.Stdout, buildCmd)\n\t}\n\n\treturn nil\n}\n\nfunc CmdCheck(c *cli.Context) error {\n\n\ttnconfig, _, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnodes := tnconfig.Nodes\n\tbridges := tnconfig.Switches\n\tconfmap := map[string]string{}\n\n\tfor _, node := range nodes {\n\t\tfor _, inf := range node.Interfaces {\n\t\t\tif inf.Type == \"direct\" {\n\t\t\t\thost := node.Name + \":\" + inf.Name\n\t\t\t\tpeer := strings.Split(inf.Args, \"#\")\n\t\t\t\ttarget := peer[0] + \":\" + peer[1]\n\t\t\t\tconfmap[host] = target\n\t\t\t} else if inf.Type == \"bridge\" {\n\t\t\t\thost := node.Name + \":\" + inf.Name\n\t\t\t\ttarget := inf.Args + \":\" + node.Name\n\t\t\t\tconfmap[host] = target\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, bridge := range bridges {\n\t\tfor _, inf := range bridge.Interfaces {\n\t\t\thost := bridge.Name + \":\" + inf.Args\n\t\t\ttarget := inf.Args + \":\" + inf.Name\n\t\t\tconfmap[host] = target\n\t\t}\n\t}\n\n\tvar matchNum int\n\tfalseConfigMap := map[string]string{}\n\n\tfor key, value := range confmap {\n\t\tif confmap[key] == value && confmap[value] == key {\n\t\t\tmatchNum++\n\t\t} else {\n\t\t\tfalseConfigMap[key] = value\n\t\t}\n\t}\n\n\tif len(confmap) == matchNum {\n\t\treturn nil\n\t} else {\n\t\tvar errMsg string\n\t\tfor key, value := range falseConfigMap {\n\t\t\terrMsg += fmt.Sprintf(\"%s<->%s\\n\", key, value)\n\t\t}\n\t\treturn fmt.Errorf(errMsg)\n\t}\n}\n\nfunc CmdUp(c *cli.Context) error {\n\n\ttnconfig, verbose, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif len(tnconfig.PreCmd) != 0 {\n\t\tfor _, preCmds := range tnconfig.PreCmd {\n\t\t\tpreExecCmds := shell.ExecCmd(preCmds.Cmds)\n\t\t\tutils.PrintCmds(os.Stdout, preExecCmds, verbose)\n\t\t}\n\t}\n\tif len(tnconfig.PreInit) != 0 {\n\t\tfor _, preInitCmds := range tnconfig.PreInit {\n\t\t\tpreExecInitCmds := shell.ExecCmd(preInitCmds.Cmds)\n\t\t\tutils.PrintCmds(os.Stdout, preExecInitCmds, verbose)\n\t\t}\n\t}\n\tfor _, node := range tnconfig.Nodes {\n\t\tcreateNodeCmds := node.CreateNode()\n\t\tutils.PrintCmds(os.Stdout, createNodeCmds, verbose)\n\n\t\tif node.Type != \"netns\" {\n\t\t\tmountDockerNetnsCmds := node.Mount_docker_netns()\n\t\t\tutils.PrintCmds(os.Stdout, mountDockerNetnsCmds, verbose)\n\t\t}\n\t}\n\n\tif len(tnconfig.Switches) != 0 {\n\t\tfor _, bridge := range tnconfig.Switches {\n\t\t\tcreateSwitchCmds := bridge.CreateSwitch()\n\t\t\tutils.PrintCmds(os.Stdout, createSwitchCmds, verbose)\n\t\t}\n\t}\n\n\tvar links []linkstatus\n\n\tfor _, node := range tnconfig.Nodes {\n\t\tfor _, inf := range node.Interfaces {\n\t\t\tif inf.Type == \"direct\" {\n\t\t\t\trNodeArgs := strings.Split(inf.Args, \"#\")\n\t\t\t\trNodeName := rNodeArgs[0]\n\t\t\t\trInfName := rNodeArgs[1]\n\t\t\t\tpeerFound := false\n\t\t\t\tfor _, link := range links {\n\t\t\t\t\tif !link.rightIsSet {\n\t\t\t\t\t\tnodecheck := link.leftNodeName == rNodeName\n\t\t\t\t\t\tinfcheck := link.leftInfName == rInfName\n\t\t\t\t\t\tif nodecheck && infcheck {\n\t\t\t\t\t\t\tlink.rightNodeName = node.Name\n\t\t\t\t\t\t\tlink.rightInfName = inf.Name\n\t\t\t\t\t\t\tlink.rightNodeType = node.Type\n\t\t\t\t\t\t\tlink.rightIsSet = true\n\t\t\t\t\t\t\tpeerFound = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !peerFound {\n\t\t\t\t\tlink := linkstatus{leftNodeName: node.Name, leftInfName: inf.Name, rightNodeName: rNodeName, rightInfName: rInfName}\n\t\t\t\t\tlink.leftNodeType = node.Type\n\t\t\t\t\tlink.leftIsSet = true\n\t\t\t\t\tlinks = append(links, link)\n\t\t\t\t\tn2nLinkCmds := inf.N2nLink(node.Name)\n\t\t\t\t\tutils.PrintCmds(os.Stdout, n2nLinkCmds, verbose)\n\t\t\t\t}\n\t\t\t\tif len(inf.Addr) != 0 {\n\t\t\t\t\taddrSetCmd := inf.AddrSet(node.Name)\n\t\t\t\t\tutils.PrintCmd(os.Stdout, addrSetCmd, verbose)\n\t\t\t\t}\n\t\t\t} else if inf.Type == \"bridge\" {\n\t\t\t\ts2nLinkCmds := inf.S2nLink(node.Name)\n\t\t\t\tutils.PrintCmds(os.Stdout, s2nLinkCmds, verbose)\n\t\t\t} else if inf.Type == \"veth\" {\n\t\t\t\tv2cLinkCmds := inf.V2cLink(node.Name)\n\t\t\t\tutils.PrintCmds(os.Stdout, v2cLinkCmds, verbose)\n\t\t\t} else if inf.Type == \"phys\" {\n\t\t\t\tp2cLinkCmds := inf.P2cLink(node.Name)\n\t\t\t\tutils.PrintCmds(os.Stdout, p2cLinkCmds, verbose)\n\t\t\t} else {\n\t\t\t\terr := fmt.Errorf(\"not supported interface type: %s\", inf.Type)\n\t\t\t\tlog.Fatal(err)\n\t\t\t}\n\t\t}\n\t}\n\n\t// check\n\terr = CmdCheck(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, node := range tnconfig.Nodes {\n\t\tif node.Type == \"docker\" || node.Type == \"\" {\n\t\t\tdelNsCmd := node.DelNsCmd()\n\t\t\tutils.PrintCmd(os.Stdout, delNsCmd, verbose)\n\t\t\tmountTmplCmd, err := node.MountTmpl()\n\t\t\tutils.PrintCmds(os.Stdout, mountTmplCmd, verbose)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(tnconfig.PostInit) != 0 {\n\t\tfor _, postInitCmds := range tnconfig.PostInit {\n\t\t\tpostExecInitCmds := shell.ExecCmd(postInitCmds.Cmds)\n\t\t\tutils.PrintCmds(os.Stdout, postExecInitCmds, verbose)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc CmdConf(c *cli.Context) error {\n\ttnconfig, verbose, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnodeinfo := map[string]string{}\n\tfor _, node := range tnconfig.Nodes {\n\t\tnodeinfo[node.Name] = node.Type\n\t}\n\n\tif len(tnconfig.PreConf) != 0 {\n\t\tfor _, preConf := range tnconfig.PreConf {\n\t\t\tpreConfCmds := shell.ExecCmd(preConf.Cmds)\n\t\t\tutils.PrintCmds(os.Stdout, preConfCmds, verbose)\n\t\t}\n\t}\n\n\tfor _, nodeConfig := range tnconfig.NodeConfigs {\n\t\texecConfCmds := nodeConfig.ExecConf(nodeinfo[nodeConfig.Name])\n\t\tfor _, execConfCmd := range execConfCmds {\n\t\t\tutils.PrintCmd(os.Stdout, execConfCmd, verbose)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc CmdUpConf(c *cli.Context) error {\n\t// create and start\n\tif err := CmdUp(c); err != nil {\n\t\treturn err\n\t}\n\n\t// config\n\tif err := CmdConf(c); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc CmdDown(c *cli.Context) error {\n\n\ttnconfig, verbose, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, node := range tnconfig.Nodes {\n\t\tdeleteNode := node.DeleteNode()\n\t\tutils.PrintCmds(os.Stdout, deleteNode, verbose)\n\t}\n\tfor _, br := range tnconfig.Switches {\n\t\tdelBrCmd := br.DeleteSwitch()\n\t\tutils.PrintCmd(os.Stdout, delBrCmd, verbose)\n\t}\n\n\tif len(tnconfig.PostFini) != 0 {\n\t\tfor _, postFiniCmds := range tnconfig.PostFini {\n\t\t\tpostExecFiniCmds := shell.ExecCmd(postFiniCmds.Cmds)\n\t\t\tutils.PrintCmds(os.Stdout, postExecFiniCmds, verbose)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc CmdExec(c *cli.Context) error {\n\n\ttnconfig, verbose, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\texecCmdArgs := c.Args().Slice()\n\texecCommand := tnconfig.Exec(execCmdArgs[0], execCmdArgs[1:])\n\tutils.PrintCmd(os.Stdout, execCommand, verbose)\n\n\treturn nil\n\n}\n\nfunc CmdImg(c *cli.Context) error {\n\tformat := c.String(\"format\")\n\ttnconfig, _, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tg := dot.NewGraph(dot.Directed)\n\tfor _, tnnode := range tnconfig.Nodes {\n\t\tnodeName := tnnode.Name\n\t\tfromNode := g.Node(nodeName)\n\t\tfromNode.Label(nodeName)\n\t\tifaceInfos := tnnode.Interfaces\n\t\tfor _, ifaceInfo := range ifaceInfos {\n\t\t\tvar argsName string\n\t\t\tif ifaceInfo.Type == \"direct\" {\n\t\t\t\targsName = strings.Split(ifaceInfo.Args, \"#\")[0]\n\t\t\t\ttoNode := g.Node(argsName)\n\t\t\t\tfindEdges := g.FindEdges(toNode, fromNode)\n\t\t\t\tif len(findEdges) == 0 {\n\t\t\t\t\tnewEdge := g.Edge(fromNode, toNode)\n\t\t\t\t\tnewEdge.Attr(\"arrowhead\", \"none\")\n\t\t\t\t\tnewEdge.Attr(\"labelfloat\", \"true\")\n\t\t\t\t\ttaillabel := \"\"\n\t\t\t\t\tif ifaceInfo.Label != \"\" {\n\t\t\t\t\t\ttaillabel = fmt.Sprintf(\"%s(%s)\", ifaceInfo.Name, ifaceInfo.Label)\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttaillabel = ifaceInfo.Name\n\t\t\t\t\t}\n\t\t\t\t\tnewEdge.Attr(\"headlabel\", strings.Split(ifaceInfo.Args, \"#\")[1])\n\t\t\t\t\tnewEdge.Attr(\"taillabel\", taillabel)\n\t\t\t\t\tnewEdge.Attr(\"fontsize\", \"8\")\n\t\t\t\t} else {\n\t\t\t\t\tedge := findEdges[0]\n\t\t\t\t\tif ifaceInfo.Label != \"\" {\n\t\t\t\t\t\theadlabel := fmt.Sprintf(\"%s(%s)\", edge.GetAttr(\"headlabel\"), ifaceInfo.Label)\n\t\t\t\t\t\tedge.Attr(\"headlabel\", headlabel)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ifaceInfo.Type == \"bridge\" {\n\t\t\t\targsName = ifaceInfo.Args\n\t\t\t\ttoNode := g.Node(argsName)\n\t\t\t\tfindEdges := g.FindEdges(toNode, fromNode)\n\t\t\t\tif len(findEdges) == 0 {\n\t\t\t\t\tnewEdge := g.Edge(fromNode, toNode)\n\t\t\t\t\tnewEdge.Attr(\"arrowhead\", \"none\")\n\t\t\t\t\tnewEdge.Attr(\"labelfloat\", \"true\")\n\t\t\t\t\tnewEdge.Attr(\"headlabel\", argsName)\n\t\t\t\t\ttaillabel := \"\"\n\t\t\t\t\tif ifaceInfo.Label != \"\" {\n\t\t\t\t\t\ttaillabel = fmt.Sprintf(\"%s(%s)\", ifaceInfo.Name, ifaceInfo.Label)\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttaillabel = ifaceInfo.Name\n\t\t\t\t\t}\n\t\t\t\t\tnewEdge.Attr(\"taillabel\", taillabel)\n\t\t\t\t\tnewEdge.Attr(\"fontsize\", \"8\")\n\t\t\t\t} else {\n\t\t\t\t\tedge := findEdges[0]\n\t\t\t\t\tif ifaceInfo.Label != \"\" {\n\t\t\t\t\t\theadlabel := fmt.Sprintf(\"%s(%s)\", edge.GetAttr(\"headlabel\"), ifaceInfo.Label)\n\t\t\t\t\t\tedge.Attr(\"headlabel\", headlabel)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif format == \"mermaid\" {\n\t\tfmt.Println(dot.MermaidGraph(g, dot.MermaidTopToBottom))\n\t} else {\n\t\tfmt.Fprintln(os.Stdout, g.String())\n\t}\n\n\treturn nil\n}\n\nfunc CmdInit(c *cli.Context) error {\n\ttnConf, err := shell.GenerateFile()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Fprintln(os.Stdout, tnConf)\n\n\treturn nil\n\n}\n\nfunc CmdPs(c *cli.Context) error {\n\n\tall := c.Bool(\"all\")\n\tfmt.Println(\"echo '---------------------------------------------------------------------------------'\")\n\tfmt.Println(\"echo '                            Docker Status                                        '\")\n\tfmt.Println(\"echo '---------------------------------------------------------------------------------'\")\n\tdockerPsCmd := shell.DockerPs(all)\n\tfmt.Println(dockerPsCmd)\n\tfmt.Println(\"echo '---------------------------------------------------------------------------------'\")\n\tfmt.Println(\"echo '                            IP NETNS LIST                                        '\")\n\tfmt.Println(\"echo '---------------------------------------------------------------------------------'\")\n\tnetnsPsCmd := shell.NetnsPs()\n\tfmt.Println(netnsPsCmd)\n\n\treturn nil\n}\n\nfunc CmdPull(c *cli.Context) error {\n\ttnconfig, verbose, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tpullCmds := shell.Pull(tnconfig.Nodes)\n\n\tutils.PrintCmds(os.Stdout, pullCmds, verbose)\n\n\treturn nil\n}\n\nfunc CmdReConf(c *cli.Context) error {\n\t// stop, remove\n\tif err := CmdDown(c); err != nil {\n\t\treturn err\n\t}\n\n\t// create and start\n\tif err := CmdUp(c); err != nil {\n\t\treturn err\n\t}\n\n\t// config\n\tif err := CmdConf(c); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc CmdReUp(c *cli.Context) error {\n\t// stop, remove\n\tif err := CmdDown(c); err != nil {\n\t\treturn err\n\t}\n\n\t// create and start\n\tif err := CmdUp(c); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc CmdTest(c *cli.Context) error {\n\ttnconfig, _, err := LoadCfg(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttestName := c.Args().Get(0)\n\n\tvar tnTestCmds []string\n\n\tif testName == \"all\" || testName == \"\" {\n\t\tfor _, test := range tnconfig.Test {\n\t\t\ttnTestCmds = test.TnTestCmdExec()\n\t\t}\n\t} else {\n\t\tfor _, test := range tnconfig.Test {\n\t\t\tif testName == test.Name {\n\t\t\t\ttnTestCmds = test.TnTestCmdExec()\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(tnTestCmds) == 0 {\n\t\treturn fmt.Errorf(\"not found test name\\n\")\n\t}\n\n\tfmt.Fprintln(os.Stdout, strings.Join(tnTestCmds, \"\\n\"))\n\n\treturn nil\n}\n"
  },
  {
    "path": "commands.go",
    "content": "package main\n\nimport \"github.com/urfave/cli/v2\"\n\nvar commands = []*cli.Command{\n\tcommandBuild,\n\tcommandCheck,\n\tcommandConf,\n\tcommandDown,\n\tcommandExec,\n\tcommandImg,\n\tcommandInit,\n\tcommandPs,\n\tcommandPull,\n\tcommandReConf,\n\tcommandReUp,\n\tcommandTest,\n\tcommandUp,\n\tcommandUpConf,\n}\n\nvar commandBuild = &cli.Command{\n\tName:   \"build\",\n\tUsage:  \"Build docker Image from tinet config file\",\n\tAction: CmdBuild,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandUp = &cli.Command{\n\tName:   \"up\",\n\tUsage:  \"create Node from tinet config file\",\n\tAction: CmdUp,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandConf = &cli.Command{\n\tName:   \"conf\",\n\tUsage:  \"configure Node from tinet config file\",\n\tAction: CmdConf,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandUpConf = &cli.Command{\n\tName:   \"upconf\",\n\tUsage:  \"Create, start and config\",\n\tAction: CmdUpConf,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandDown = &cli.Command{\n\tName:   \"down\",\n\tUsage:  \"Down Node from tinet config file\",\n\tAction: CmdDown,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandExec = &cli.Command{\n\tName:   \"exec\",\n\tUsage:  \"Execute Command on Node from tinet config file.\",\n\tAction: CmdExec,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandImg = &cli.Command{\n\tName:   \"img\",\n\tUsage:  \"visualize network topology by graphviz from tinet config file\",\n\tAction: CmdImg,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:    \"format\",\n\t\t\tAliases: []string{\"f\"},\n\t\t\tUsage:   \"Image output format\",\n\t\t\tValue:   \"graphviz\",\n\t\t},\n\t},\n}\n\nvar commandInit = &cli.Command{\n\tName:   \"init\",\n\tUsage:  \"Generate tinet config template file\",\n\tAction: CmdInit,\n}\n\nvar commandPs = &cli.Command{\n\tName:   \"ps\",\n\tUsage:  \"docker and netns process\",\n\tAction: CmdPs,\n\tFlags: []cli.Flag{\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"all\",\n\t\t\tAliases: []string{\"a\"},\n\t\t\tUsage:   \"all docker and netns\",\n\t\t},\n\t},\n}\n\nvar commandPull = &cli.Command{\n\tName:   \"pull\",\n\tUsage:  \"Pull Node docker image from tinet config file\",\n\tAction: CmdPull,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t},\n}\n\nvar commandReConf = &cli.Command{\n\tName:   \"reconf\",\n\tUsage:  \"Stop, remove, create, start and config\",\n\tAction: CmdReConf,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandReUp = &cli.Command{\n\tName:   \"reup\",\n\tUsage:  \"Stop, remove, create, start\",\n\tAction: CmdReUp,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    \"verbose\",\n\t\t\tAliases: []string{\"v\"},\n\t\t\tUsage:   \"Verbose\",\n\t\t},\n\t},\n}\n\nvar commandTest = &cli.Command{\n\tName:   \"test\",\n\tUsage:  \"Execute test commands from tinet config file.\",\n\tAction: CmdTest,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t},\n}\n\nvar commandCheck = &cli.Command{\n\tName:   \"check\",\n\tUsage:  \"check config\",\n\tAction: CmdCheck,\n\tFlags: []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:    \"config\",\n\t\t\tAliases: []string{\"c\"},\n\t\t\tUsage:   \"Specify the Config file.\",\n\t\t\tValue:   \"spec.yaml\",\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "configs/spec_template.yaml",
    "content": "precmd:\n- cmds:\n  - cmd: \"\"\npreinit:\n- cmds:\n  - cmd: \"\"\npreconf:\n- cmds:\n  - cmd: \"\"\npostinit:\n- cmds:\n  - cmd: \"\"\npostfini:\n- cmds:\n  - cmd: \"\"\nnodes:\n- name: \"\"\n  type: \"\"\n  net_base: \"\"\n  image: \"\"\n  interfaces:\n  - name: \"\"\n    type: \"\"\n    args: \"\"\n    addr: \"\"\n    label: \"\"\n  sysctls: []\nswitches:\n- name: \"\"\n  interfaces:\n  - name: \"\"\n    type: \"\"\n    args: \"\"\n    addr: \"\"\nnode_configs:\n- name: \"\"\n  cmds:\n  - cmd: \"\"\ntest:\n- name: \"\"\n  cmds:\n  - cmd: \"\"\n"
  },
  {
    "path": "docs/command-line-usage-example.md",
    "content": "# 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\ntn check -c spec.yaml\n```\n\n## tn conf\n```\ntn conf -c spec.yaml\n\n## docker and netns exec config\ntn conf -c spec.yaml | sudo sh -x\n```\n\n## tn down\n```\ntn down -c spec.yaml\n\n## Remove docker container and netns\ntn conf -c spec.yaml | sudo sh -x\n```\n\n## tn exec\nThat hasn't been implemented yet.\n\n## tn help\n```\ntn help\ntn -h\n```\n\n## tn img\n```\n## Output dot\ntn img -c spec.yaml\n\n## Generate img file\ntn img -c spec.yaml | dot -Tpng > spec.png\n```\n\n## tn init\n```\n## Output tinet config template\ntn init\n\n## Generate Tinet config file\ntn init > spec.yaml\n```\n\n## tn print\n```\ntn print -c spec.yaml\n```\n\n## tn ps\n```\n## Output docker and netns info cmd\ntn ps -c spec.yaml\n\n## Output docker and netns info\ntn ps -c spec.yaml | sudo sh -x\n```\n\n## tn pull\n```\ntn pull -c spec.yaml\n\n## Execute docker pull\ntn pull -c spec.yaml | sudo sh -x\n```\n\n## tn reconf\n```\ntn reconf -c spec.yaml\n\n## down, up, conf\ntn reconf -c spec.yaml | sudo sh -x\n```\n\n## tn reup\n```\ntn reup -c spec.yaml\n\n## down, up\ntn reup -c spec.yaml | sudo sh -x\n```\n\n## tn up\n```\ntn up -c spec.yaml\n\n## up\ntn up -c spec.yaml | sudo sh -x\n```\n\n## tn upconf\n```\ntn upconf -c spec.yaml\n\n## up, conf\ntn upconf -c spec.yaml | sudo sh -x\n```\n\n## tn version\n```\ntn version\n```\n"
  },
  {
    "path": "docs/specification_yml.md",
    "content": "# 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: node type (default: docker)\n\t- docker: node is docker container\n\t- netns: node is just network namespace\n- image: specify docker-image\n- sysctls: set sysctls\n- mounts: mounts file/directory on the container\n- dns: set DNS resolver\n- dns_search: set DNS search domain\n\n\n```\nnodes:\n  - name: Node0\n    image: ubuntu:18.04\n  - name: Node1\n    type: netns\n\t- name: Node2\n\t  build: .\n```\n\n### Interface Definition\n\n- type\n\t- direct: p2p connect to other container\n\t- bridge: bridge connection\n\t- phys  : host's network interface\n- addr: specify mac address\n\n```\nnodes:\n  - name: Node0\n    image: ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R0#net1 }\n      - { name: net0, type: bridge, args: B0 }\n      - { name: eth0, type: phys }\n      - { name: net0, type: direct, args: R1#net1, addr: 11:11:11:11:11:11 }\n```\n\n### Bridge Definition\n\nIf you use the bridge interface type, you need to\ndefine the Bridge-Instance. It'll be created as a\nlinux bridge instance.\n\n- name: interface name\n- type: interface type, you must choose following.\n\t- docker: net-if of docker container\n\t- netns: net-if of network namespace\n\t- phys: host's network interface\n\n```\nbridges:\n  - name: Bridge0\n    interfaces:\n      - { name: net0, type: docker, args: R0 }\n      - { name: net0, type: netns, args: NS0 }\n      - { name: eth0, type: phys }\n```\n\n## Config Definition\n- name: node name\n- cmds: shell command\n\n```\nnode_configs:\n  - name: Router1\n    cmds:\n      - cmd: ip addr add 10.255.0.10/32 dev lo\n      - cmd: ip addr add 10.0.0.10/24 dev net0\n\t\t\t- copy: ./config.conf /usr/local/config.conf\n  - name: Router0\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.255.0.1/32 dev lo\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 10.1.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router bgp 100'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' neighbor 10.0.0.10 remote-as 100'\n          -c ' neighbor 10.0.0.20 remote-as 100'\n          -c ' neighbor 10.0.0.30 remote-as 100'\n```\n\n## Test Definition\n\n- name: test name, you can specify when you run `tn conf -n <name>`\n- cmds: same format of config definition\n\n```\ntest:\n  - name: p2p\n\t  cmds:\n    - cmd: docker exec S0 ping -c2 10.1.0.1\n    - cmd: docker exec S1 ping -c2 192.168.0.1\n    - cmd: docker exec S2 ping -c2 192.168.0.1\n    - cmd: docker exec S3 ping -c2 192.168.0.1\n  - name: remote\n\t  cmds:\n    - cmd: docker exec S0 ping -c2 10.1.0.1\n    - cmd: docker exec S1 ping -c2 192.168.0.1\n    - cmd: docker exec S2 ping -c2 192.168.0.1\n    - cmd: docker exec S3 ping -c2 192.168.0.1\n```\n\n## System Requirement Definition\n\n```\nrequire:\n\t- kernel_min: 4.11.0\n\t- kernel_max: 4.15.0\n\t- kmod: [ mpls_router, mpls_iptunnel, mpls_gso ]\n  - kconfig: [ CONFIG_NET_L3_MASTER_DEV ]\n```\n"
  },
  {
    "path": "examples/bandwidth_tc/spec.yaml",
    "content": "nodes:\n\n  - name: C1\n    image: ip6tables:test\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: C4\n    image: ip6tables:test\n    interfaces:\n      - { name: net0, type: direct, args: R1#net3 }    \n  - name: C2\n    image: ip6tables:test\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: C3\n    image: ip6tables:test\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }    \n  - name: R1\n    image: ip6tables:test\n    interfaces:\n      - { name: net0, type: direct, args: C1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C3#net0 }\n      - { name: net3, type: direct, args: C4#net0 }  \n  \n\nnode_configs:\n\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route replace default via 10.0.0.1\n  - name: C4\n    cmds:\n      - cmd: ip addr add 10.0.0.12/24 dev net0\n      - cmd: ip route replace default via 10.0.0.1  \n  - name: C2\n    cmds:\n      - cmd: ip addr add 10.1.0.2/24 dev net0\n      - cmd: ip route replace default via 10.1.0.1\n  - name: C3\n    cmds:\n      - cmd: ip addr add 10.2.0.2/24 dev net0\n      - cmd: ip route replace default via 10.2.0.1  \n  - name: R1\n    cmds:\n      - cmd: ip link add br0 type bridge\n      - cmd: ip link set br0 up  \n      - cmd: ip addr add 10.0.0.1/24 dev br0\n      - cmd: ip addr add 10.1.0.1/24 dev net1\n      - cmd: ip addr add 10.2.0.1/24 dev net2\n      - cmd: ip link set net0 master br0\n      - cmd: ip link set net3 master br0\n      - cmd: tc qdisc add dev net0 root tbf limit 1Mb buffer 200Kb rate 1Mbps\n      - cmd: tc qdisc add dev net2 root tbf limit 1Mb buffer 200Kb rate 1Mbps\n      - cmd: ethtool -K net0 tso off gso off\n      - cmd: ethtool -K net2 tso off gso off\n      - cmd: tc qdisc replace dev net0 root netem delay 10ms\n      - cmd: tc qdisc replace dev net1 root netem delay 10ms\n      - cmd: tc qdisc replace dev net2 root netem delay 10ms\n      - cmd: tc qdisc replace dev net3 root netem delay 10ms  \n      - cmd: sysctl -w net.ipv4.ip_forward=1\n"
  },
  {
    "path": "examples/basic_bfd/spec.yaml",
    "content": "# http://www.asciiflow.com\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R4#net1 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R3#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.1/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.1/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.5/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' network 10.0.0.0/30 area 0'\n          -c ' network 10.0.0.4/30 area 0'\n          -c 'exit'\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.2/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.2/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.9/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' network 10.0.0.0/30 area 0'\n          -c ' network 10.0.0.8/30 area 0'\n          -c 'exit'\n  - name: R3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.3/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.6/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.13/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' network 10.0.0.4/30 area 0'\n          -c ' network 10.0.0.12/30 area 0'\n  - name: R4\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.4/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.10/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.14/30'\n          -c ' ip ospf bfd'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' network 10.0.0.8/30 area 0'\n          -c ' network 10.0.0.12/30 area 0'\n\ntest:\n  - cmds:\n    ## P2P Link test\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.0.0.6\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.10\n    - cmd: docker exec R3 ping -c2 10.0.0.5\n    - cmd: docker exec R3 ping -c2 10.0.0.14\n    - cmd: docker exec R4 ping -c2 10.0.0.9\n    - cmd: docker exec R4 ping -c2 10.0.0.13\n\n"
  },
  {
    "path": "examples/basic_bgp/README.md",
    "content": "\n# BGP Playground\n\n\n"
  },
  {
    "path": "examples/basic_bgp/bgp_clos_evpn_vxlan/spec.yaml",
    "content": "# ref: https://www.apresiatac.jp/blog/201903121016/\n\nnodes:\n  - name: Spine1\n    image: akiranet24/frr\n    interfaces:\n      - { name: swp49, type: direct, args: Leaf1#swp49 }\n      - { name: swp50, type: direct, args: Leaf2#swp49 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.lo.rp_filter=0\n      - sysctl: net.ipv6.conf.all.disable_ipv6=0\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.seg6_enabled=1\n      - sysctl: net.ipv6.conf.default.seg6_enabled=1\n      - sysctl: net.ipv4.fib_multipath_hash_policy=1\n  - name: Spine2\n    image: akiranet24/frr\n    interfaces:\n      - { name: swp49, type: direct, args: Leaf1#swp50 }\n      - { name: swp50, type: direct, args: Leaf2#swp50 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.lo.rp_filter=0\n      - sysctl: net.ipv6.conf.all.disable_ipv6=0\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.seg6_enabled=1\n      - sysctl: net.ipv6.conf.default.seg6_enabled=1\n      - sysctl: net.ipv4.fib_multipath_hash_policy=1\n  - name: Leaf1\n    image: akiranet24/frr\n    interfaces:\n      - { name: swp49, type: direct, args: Spine1#swp49 }\n      - { name: swp50, type: direct, args: Spine2#swp49 }\n      - { name: swp1, type: direct, args: Vm1#net1 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.lo.rp_filter=0\n      - sysctl: net.ipv6.conf.all.disable_ipv6=0\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.seg6_enabled=1\n      - sysctl: net.ipv6.conf.default.seg6_enabled=1\n      - sysctl: net.ipv4.fib_multipath_hash_policy=1\n  - name: Leaf2\n    image: akiranet24/frr\n    interfaces:\n      - { name: swp49, type: direct, args: Spine1#swp50 }\n      - { name: swp50, type: direct, args: Spine2#swp50 }\n      - { name: swp1, type: direct, args: Vm2#net1 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.lo.rp_filter=0\n      - sysctl: net.ipv6.conf.all.disable_ipv6=0\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.seg6_enabled=1\n      - sysctl: net.ipv6.conf.default.seg6_enabled=1\n      - sysctl: net.ipv4.fib_multipath_hash_policy=1\n\n  - name: Vm1\n    image: akiranet24/frr\n    interfaces: [ { name: net1, type: direct, args: Leaf1#swp1 } ]\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.lo.rp_filter=0\n      - sysctl: net.ipv6.conf.all.disable_ipv6=0\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.seg6_enabled=1\n      - sysctl: net.ipv6.conf.default.seg6_enabled=1\n      - sysctl: net.ipv4.fib_multipath_hash_policy=1\n  - name: Vm2\n    image: akiranet24/frr\n    interfaces: [ { name: net1, type: direct, args: Leaf2#swp1 } ]\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.lo.rp_filter=0\n      - sysctl: net.ipv6.conf.all.disable_ipv6=0\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.forwarding=1\n      - sysctl: net.ipv6.conf.all.seg6_enabled=1\n      - sysctl: net.ipv6.conf.default.seg6_enabled=1\n      - sysctl: net.ipv4.fib_multipath_hash_policy=1\n\nnode_configs:\n  - name: Spine1\n    cmds:\n      - cmd: sed -i s/'#frr_profile=\"datacenter\"'/'frr_profile=\"datacenter\"'/ /etc/frr/daemons\n      - cmd: /etc/init.d/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.0.0.1/32\"\n          -c \"int swp49\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int swp50\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65020\"\n          -c \" bgp router-id 10.0.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC bfd\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor swp49 interface peer-group FABRIC\"\n          -c \" neighbor swp50 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.0.0.1/32\"\n          -c \" exit-address-family\"\n          -c \" address-family l2vpn evpn\"\n          -c \"  neighbor FABRIC activate\"\n          -c \" exit-address-family\"\n  - name: Spine2\n    cmds:\n      - cmd: sed -i s/'#frr_profile=\"datacenter\"'/'frr_profile=\"datacenter\"'/ /etc/frr/daemons\n      - cmd: /etc/init.d/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.0.0.2/32\"\n          -c \"int swp49\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int swp50\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65020\"\n          -c \" bgp router-id 10.0.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC bfd\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor swp49 interface peer-group FABRIC\"\n          -c \" neighbor swp50 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.0.0.2/32\"\n          -c \" exit-address-family\"\n          -c \" address-family l2vpn evpn\"\n          -c \"  neighbor FABRIC activate\"\n          -c \" exit-address-family\"\n  - name: Leaf1\n    cmds:\n      - cmd: sed -i s/'#frr_profile=\"datacenter\"'/'frr_profile=\"datacenter\"'/ /etc/frr/daemons\n      - cmd: /etc/init.d/frr start\n      - cmd: ip link add br0 type bridge vlan_filtering 1\n      - cmd: ip link add link swp1 name swp1.100 type vlan id 100\n      - cmd: ip link add vni-10100 type vxlan id 10100 local 10.0.0.11 remote 10.0.0.12 dstport 4789 nolearning\n      - cmd: ip link set vni-10100 master br0\n      - cmd: ip link set swp1.100 master br0\n      - cmd: ip link set br0 up\n      - cmd: ip link set vni-10100 up\n      - cmd: ip link set swp1.100 up\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.0.0.11/32\"\n          -c \"int swp49\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int swp50\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65011\"\n          -c \" bgp router-id 10.0.0.11\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC bfd\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor swp49 interface peer-group FABRIC\"\n          -c \" neighbor swp50 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.0.0.11/32\"\n          -c \" exit-address-family\"\n          -c \" address-family l2vpn evpn\"\n          -c \"  neighbor FABRIC activate\"\n          -c \"  advertise-all-vni\"\n          -c \" exit-address-family\"\n  - name: Leaf2\n    cmds:\n      - cmd: sed -i s/'#frr_profile=\"datacenter\"'/'frr_profile=\"datacenter\"'/ /etc/frr/daemons\n      - cmd: /etc/init.d/frr start\n      - cmd: ip link add br0 type bridge vlan_filtering 1\n      - cmd: ip link add link swp1 name swp1.100 type vlan id 100\n      - cmd: ip link add vni-10100 type vxlan id 10100 local 10.0.0.12 remote 10.0.0.11 dstport 4789 nolearning\n      - cmd: ip link set vni-10100 master br0\n      - cmd: ip link set swp1.100 master br0\n      - cmd: ip link set br0 up\n      - cmd: ip link set vni-10100 up\n      - cmd: ip link set swp1.100 up\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.0.0.12/32\"\n          -c \"int swp49\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int swp50\" -c \"ipv6 nd ra-interval 10\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65012\"\n          -c \" bgp router-id 10.0.0.12\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC bfd\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor swp49 interface peer-group FABRIC\"\n          -c \" neighbor swp50 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.0.0.12/32\"\n          -c \" exit-address-family\"\n          -c \" address-family l2vpn evpn\"\n          -c \"  neighbor FABRIC activate\"\n          -c \"  advertise-all-vni\"\n          -c \" exit-address-family\"\n  - name: Vm1\n    cmds:\n      - cmd: /etc/init.d/frr start\n      - cmd: ip link add link net1 name net1.100 type vlan id 100\n      - cmd: ip addr add 172.16.100.10/24 dev net1.100\n      - cmd: ip link set net1.100 up\n  - name: Vm2\n    cmds:\n      - cmd: /etc/init.d/frr start\n      - cmd: ip link add link net1 name net1.100 type vlan id 100\n      - cmd: ip addr add 172.16.100.20/24 dev net1.100\n      - cmd: ip link set net1.100 up\n\ntest:\n  - cmds:\n      - cmd: docker exec Vm1 ping -c2 172.16.100.20\n"
  },
  {
    "path": "examples/basic_bgp/graceful_restart/simple_ipv4_unicast/README.md",
    "content": "# 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 # another shell\n$ tinet conf -c spec.yaml | sudo sh \n$ docker exec R1 pkill -9 bgpd\n```\n\n"
  },
  {
    "path": "examples/basic_bgp/graceful_restart/simple_ipv4_unicast/spec.yaml",
    "content": "nodes:\n- name: C1\n  image: alpine:latest\n  interfaces:\n  - { name: net1, type: direct, args: R1#net1 }\n- name: R1\n  image: frrouting/frr:v8.1.0\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1\n- name: R2\n  image: frrouting/frr:v8.1.0\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'interface net0'\n      -c ' ip address 10.255.0.1/16'\n      -c '!'\n      -c 'interface net1'\n      -c ' ip address 192.168.10.1/16'\n      -c '!'\n      -c 'ip prefix-list PL1 permit 192.168.0.0/16'\n      -c '!'\n      -c 'route-map RM1 permit 10'\n      -c ' match ip address prefix-list PL1'\n      -c '!'\n      -c 'router bgp 65001'\n      -c ' no bgp ebgp-requires-policy'\n      -c ' bgp router-id 10.255.0.1'\n      -c ' bgp graceful-restart'\n      -c ' bgp graceful-restart preserve-fw-state'\n      -c ' bgp graceful-restart restart-time 1800'\n      -c ' bgp graceful-restart stalepath-time 1800'\n      -c ' neighbor 10.255.0.2 remote-as 65002'\n      -c ' neighbor 10.255.0.2 route-map RM1 out'\n      -c ' address-family ipv4 unicast'\n      -c '  redistribute connected' \n      -c ' exit-address-family'\n  - cmd: vtysh -c 'write mem'\n- name: R2\n  cmds:\n  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'interface net0'\n      -c ' ip address 10.255.0.2/16'\n      -c '!'\n      -c 'ip prefix-list PL1 permit 192.168.0.0/16'\n      -c '!'\n      -c 'route-map RM1 permit 10'\n      -c ' match ip address prefix-list PL1'\n      -c '!'\n      -c 'router bgp 65002'\n      -c ' no bgp ebgp-requires-policy'\n      -c ' bgp router-id 10.255.0.2'\n      -c ' bgp graceful-restart'\n      -c ' bgp graceful-restart preserve-fw-state'\n      -c ' bgp graceful-restart restart-time 1800'\n      -c ' bgp graceful-restart stalepath-time 1800'\n      -c ' neighbor 10.255.0.1 remote-as 65001'\n      -c ' neighbor 10.255.0.1 route-map RM1 in'\n  - cmd: vtysh -c 'write mem'\n- name: C1\n  cmds:\n  - cmd: ip addr add 192.168.10.254/16 dev net1\n  - cmd: route add default gw 192.168.10.1\ntest:\n- cmds:\n  - cmd: docker exec R1 ping -c2 192.168.10.254\n  - cmd: docker exec R2 ping -c2 192.168.10.254\n"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn/README.md",
    "content": "\n# HV route advertisement study for BGP-DCN\n\n- [GOOD reference about routing-info manupulation by @ukinau](https://engineering.linecorp.com/ja/blog/openstack-summit-vancouver-2018-recap-2-2/)\n- [GOOD reference about proxy arp by @ukinau](https://qiita.com/ukinau/items/cb25588fb0c276a009dc)\n\n![](topo.png)\n\n```\ndocker exec TOR vtysh -c 'show bgp ipv4 unicast'\nBGP table version is 4, local router ID is 10.255.0.99, vrf id 0\nStatus codes:  s suppressed, d damped, h history, * valid, > best, = multipath,\n               i internal, r RIB-failure, S Stale, R Removed\nNexthop codes: @NNN nexthop's vrf id, < announce-nh-self\nOrigin codes:  i - IGP, e - EGP, ? - incomplete\n\n   Network          Next Hop            Metric LocPrf Weight Path\n*> 1.1.1.1/32       0.0.0.0                  0         32768 ?\n*> 10.0.0.11/32     dn1                      0             0 65001 ?\n*> 10.0.0.12/32     dn1                      0             0 65001 ?\n*> 10.0.0.13/32     dn1                      0             0 65001 ?\n\nDisplayed  4 routes and 4 total paths\n```\n\n"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn/spec.yaml",
    "content": "\nnodes:\n  - name: TOR\n    image: slankdev/frr\n    interfaces:\n      - { name: dn1, type: direct, args: HV1#up1 }\n  - name: HV1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: TOR#dn1 }\n      - { name: dn1, type: direct, args: VM1#net0 }\n      - { name: dn2, type: direct, args: VM2#net0 }\n      - { name: dn3, type: direct, args: VM3#net0 }\n  - name: VM1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: HV1#dn1 }\n  - name: VM2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: HV1#dn2 }\n  - name: VM3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: HV1#dn3 }\n\nnode_configs:\n  - name: TOR\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: ip addr add 1.1.1.1/32 dev lo\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface dn1'\n          -c ' ipv6 nd ra-interval 3'\n          -c ' no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65099'\n          -c ' bgp router-id 10.255.0.99'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor dn1 interface peer-group PEER'\n          -c '!'\n          -c ' address-family ipv4 unicast'\n          -c '  neighbor dn1 activate'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n\n  - name: HV1\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: ip addr add 10.0.0.1/24 dev dn1\n      - cmd: ip addr add 10.0.0.1/24 dev dn2\n      - cmd: ip addr add 10.0.0.1/24 dev dn3\n      - cmd: ip route add 10.0.0.11 dev dn1\n      - cmd: ip route add 10.0.0.12 dev dn2\n      - cmd: ip route add 10.0.0.13 dev dn3\n      - cmd: sysctl -w net.ipv4.conf.dn1.proxy_arp=1\n      - cmd: sysctl -w net.ipv4.conf.dn2.proxy_arp=1\n      - cmd: sysctl -w net.ipv4.conf.dn3.proxy_arp=1\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface up1'\n          -c ' ipv6 nd ra-interval 3'\n          -c ' no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65001'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor up1 interface peer-group PEER'\n          -c ' !'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute kernel route-map TO_TOR'\n          -c '  neighbor up1 route-map TO_TOR out'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'route-map TO_TOR permit 1'\n          -c 'match ip address prefix-len 32'\n          -c 'exit'\n\n  - name: VM1\n    cmds:\n      - cmd: ip addr add 10.0.0.11/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n  - name: VM2\n    cmds:\n      - cmd: ip addr add 10.0.0.12/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n  - name: VM3\n    cmds:\n      - cmd: ip addr add 10.0.0.13/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n\n"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn_isol/Makefile",
    "content": "\nsh:\n\tdocker exec TOR vtysh -c 'show bgp ipv4 vpn'\n"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn_isol/README.md",
    "content": "\n# HV route advertisement study for BGP-DCN\n\n- [GOOD reference about routing-info manupulation by @ukinau](https://engineering.linecorp.com/ja/blog/openstack-summit-vancouver-2018-recap-2-2/)\n- [GOOD reference about proxy arp by @ukinau](https://qiita.com/ukinau/items/cb25588fb0c276a009dc)\n\n![](topo.png)\n\n```\ndocker exec TOR vtysh -c 'show bgp ipv4 unicast'\nBGP table version is 4, local router ID is 10.255.0.99, vrf id 0\nStatus codes:  s suppressed, d damped, h history, * valid, > best, = multipath,\n               i internal, r RIB-failure, S Stale, R Removed\nNexthop codes: @NNN nexthop's vrf id, < announce-nh-self\nOrigin codes:  i - IGP, e - EGP, ? - incomplete\n\n   Network          Next Hop            Metric LocPrf Weight Path\n*> 1.1.1.1/32       0.0.0.0                  0         32768 ?\n*> 10.0.0.11/32     dn1                      0             0 65001 ?\n*> 10.0.0.12/32     dn1                      0             0 65001 ?\n*> 10.0.0.13/32     dn1                      0             0 65001 ?\n\nDisplayed  4 routes and 4 total paths\n```\n\n"
  },
  {
    "path": "examples/basic_bgp/hv_bgp_dcn_isol/spec.yaml",
    "content": "\nnodes:\n  - name: TOR\n    # image: slankdev/frr-dev:latest\n    image: slankdev/frr-dev:draft-ietf-bess-srv6-services\n    interfaces:\n      - { name: dn1, type: direct, args: HV1#up1 }\n  - name: HV1\n    # image: slankdev/frr-dev:latest\n    image: slankdev/frr-dev:draft-ietf-bess-srv6-services\n    interfaces:\n      - { name: up1, type: direct, args: TOR#dn1 }\n      - { name: dn1, type: direct, args: VM1#net0 }\n      - { name: dn2, type: direct, args: VM2#net0 }\n      - { name: dn3, type: direct, args: VM3#net0 }\n  - name: VM1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: HV1#dn1 }\n  - name: VM2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: HV1#dn2 }\n  - name: VM3\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: HV1#dn3 }\n\nnode_configs:\n  - name: TOR\n    cmds:\n      - cmd: sh -c \"echo > /etc/frr/frr.conf\"\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: ip addr add 1.1.1.1/32 dev lo\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface dn1'\n          -c ' ipv6 nd ra-interval 3'\n          -c ' no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65099'\n          -c ' bgp router-id 10.255.0.99'\n          -c ' no bgp default ipv4-unicast'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor dn1 interface peer-group PEER'\n          -c '!'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor PEER activate'\n          -c ' exit-address-family'\n\n  - name: HV1\n    cmds:\n      - cmd: sh -c \"echo > /etc/frr/frr.conf\"\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link add vrf1 type vrf table 10\n      - cmd: ip link set vrf1 up\n      - cmd: ip link set dn1 vrf vrf1\n      - cmd: ip link set dn2 vrf vrf1\n      - cmd: ip link set dn3 vrf vrf1\n      - cmd: ip addr add 10.0.0.1/24 dev dn1 noprefixroute\n      - cmd: ip addr add 10.0.0.1/24 dev dn2 noprefixroute\n      - cmd: ip addr add 10.0.0.1/24 dev dn3 noprefixroute\n      - cmd: ip route add 10.0.0.11 dev dn1 vrf vrf1\n      - cmd: ip route add 10.0.0.12 dev dn2 vrf vrf1\n      - cmd: ip route add 10.0.0.13 dev dn3 vrf vrf1\n      - cmd: sysctl -w net.ipv4.conf.dn1.proxy_arp=1\n      - cmd: sysctl -w net.ipv4.conf.dn2.proxy_arp=1\n      - cmd: sysctl -w net.ipv4.conf.dn3.proxy_arp=1\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface up1'\n          -c ' ipv6 nd ra-interval 3'\n          -c ' no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65001'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' no bgp default ipv4-unicast'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor up1 interface peer-group PEER'\n          -c ' !'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor PEER activate'\n          -c '  segment-routing-ipv6'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'router bgp 65001 vrf vrf1'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' !'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute kernel'\n          -c '  sid vpn export locator default'\n          -c '  rd vpn export 65001:1'\n          -c '  rt vpn both 100:1'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'segment-routing-ipv6'\n          -c ' encapsulation source-address 2001:1::'\n          -c ' locator prefix 2001:1::/64'\n          -c ' exit'\n          -c '!'\n          -c 'route-map TO_TOR permit 1'\n          -c ' match ip address prefix-len 32'\n          -c ' exit'\n\n  - name: VM1\n    cmds:\n      - cmd: ip addr add 10.0.0.11/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n  - name: VM2\n    cmds:\n      - cmd: ip addr add 10.0.0.12/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n  - name: VM3\n    cmds:\n      - cmd: ip addr add 10.0.0.13/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n\n"
  },
  {
    "path": "examples/basic_bgp/local_pref/README.md",
    "content": "![topology](topo.png \"bgp\")"
  },
  {
    "path": "examples/basic_bgp/local_pref/spec.yaml",
    "content": "nodes:\n- name: R1\n  image: frrouting/frr:latest\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: R3#net0 }\n  - { name: net2, type: direct, args: R4#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1\n- name: R2\n  image: frrouting/frr:latest\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1\n- name: R3\n  image: frrouting/frr:latest\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R5#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1  \n- name: R4\n  image: frrouting/frr:latest\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n  - { name: net1, type: direct, args: R5#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1  \n- name: R5\n  image: frrouting/frr:latest\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1    \nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 10.1.0.1/24 dev net1\n      - cmd: ip addr add 10.2.0.1/24 dev net2\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65001\"\n          -c \"no bgp ebgp-requires-policy\"\n          -c ' bgp router-id 1.1.1.1'\n          -c \"neighbor 10.0.0.2 remote-as 65002\"\n          -c \"neighbor 10.1.0.2 remote-as 65003\"\n          -c \"neighbor 10.2.0.2 remote-as 65004\"\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  neighbor 10.2.0.2 route-map LOCAL_PREF200 in'\n          -c ' exit-address-family'\n          -c 'access-list 1 permit 10.11.0.0/24'\n          -c 'route-map LOCAL_PREF200 permit 10'\n          -c ' match ip address 1'\n          -c ' set local-preference 200'\n          -c ' exit'\n          -c 'route-map LOCAL_PREF200 permit 20'\n          -c '!'\n  - name: R2\n    cmds:\n      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65002\"\n          -c \"no bgp ebgp-requires-policy\"\n          -c ' bgp router-id 1.1.1.2'\n          -c \"neighbor 10.0.0.1 remote-as 65001\"\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'\n  - name: R3\n    cmds:\n      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: ip addr add 10.1.0.2/24 dev net0\n      - cmd: ip addr add 10.11.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65003\"\n          -c \"no bgp ebgp-requires-policy\"\n          -c ' bgp router-id 1.1.1.3'\n          -c \"neighbor 10.1.0.1 remote-as 65001\"\n          -c \"neighbor 10.11.0.2 remote-as 65005\"\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'    \n  - name: R4\n    cmds:\n      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: ip addr add 10.2.0.2/24 dev net0\n      - cmd: ip addr add 10.12.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65004\"\n          -c \"no bgp ebgp-requires-policy\"\n          -c ' bgp router-id 1.1.1.4'\n          -c \"neighbor 10.2.0.1 remote-as 65001\"\n          -c \"neighbor 10.12.0.2 remote-as 65005\"\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'       \n  - name: R5\n    cmds:\n      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: ip addr add 10.11.0.2/24 dev net0\n      - cmd: ip addr add 10.12.0.2/24 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65005\"\n          -c \"no bgp ebgp-requires-policy\"\n          -c ' bgp router-id 1.1.1.5'\n          -c \"neighbor 10.11.0.1 remote-as 65003\"\n          -c \"neighbor 10.12.0.1 remote-as 65004\"\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'                       "
  },
  {
    "path": "examples/basic_bgp/mpbgp_ipv4_labeled_unicast/README.md",
    "content": "\n# MP-BGP labeled unicast example\n\n```\n     bgp unnumbered\nipv4-labeld-unicast enabled\n\n [R0]-----------------[R1]\n AS1                   AS2\n```\n\n"
  },
  {
    "path": "examples/basic_bgp/mpbgp_ipv4_labeled_unicast/spec.yaml",
    "content": "\nprecmd:\n  - cmds:\n    - cmd: export IMAGE=slankdev/frr:centos-7-stable-7.0\n\nnodes:\n  - name: R0\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: R1\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R0#net0 }\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: sh -c 'enable_seg6_router.py | sh'\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 1\"\n          -c \" bgp router-id 1.1.1.1\"\n          -c \" no bgp default ipv4-unicast\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \"  redistribute kernel\"\n          -c \" exit-address-family\"\n          -c \" !\"\n          -c \" address-family ipv4 labeled-unicast\"\n          -c \"  neighbor FABRIC activate\"\n          -c \" exit-address-family\"\n          -c \"!\"\n\n  - name: R1\n    cmds:\n      - cmd: sh -c 'enable_seg6_router.py | sh'\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 2\"\n          -c \" bgp router-id 2.2.2.2\"\n          -c \" no bgp default ipv4-unicast\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \"  redistribute kernel\"\n          -c \" exit-address-family\"\n          -c \" !\"\n          -c \" address-family ipv4 labeled-unicast\"\n          -c \"  neighbor FABRIC activate\"\n          -c \" exit-address-family\"\n          -c \"!\"\n\n"
  },
  {
    "path": "examples/basic_bgp/path_attr/README.md",
    "content": "\n# BGP route-map playground (import-prefix-filter)\n\n![](topo.png)\n\n```\ndocker exec R3 vtysh -c 'show bgp ipv4 unicast'\nBGP table version is 1, local router ID is 10.255.0.3, vrf id 0\nStatus codes:  s suppressed, d damped, h history, * valid, > best, = multipath,\n               i internal, r RIB-failure, S Stale, R Removed\nNexthop codes: @NNN nexthop's vrf id, < announce-nh-self\nOrigin codes:  i - IGP, e - EGP, ? - incomplete\n\n   Network          Next Hop            Metric LocPrf Weight Path\n*> 10.0.0.2/32      net0                                   0 65001 65002 i\n\nDisplayed  1 routes and 1 total paths\n```\n```\ndocker exec R4 vtysh -c 'show bgp ipv4 unicast'\nBGP table version is 3, local router ID is 10.255.0.4, vrf id 0\nStatus codes:  s suppressed, d damped, h history, * valid, > best, = multipath,\n               i internal, r RIB-failure, S Stale, R Removed\nNexthop codes: @NNN nexthop's vrf id, < announce-nh-self\nOrigin codes:  i - IGP, e - EGP, ? - incomplete\n\n   Network          Next Hop            Metric LocPrf Weight Path\n*> 10.0.0.1/32      net0                                   0 65001 65002 i\n*> 10.0.0.2/32      net0                                   0 65001 65002 i\n*> 10.0.0.3/32      net0                                   0 65001 65002 i\n\nDisplayed  3 routes and 3 total paths\n```\n\n"
  },
  {
    "path": "examples/basic_bgp/path_attr/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: direct, args: R4#net0 }\n\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'\n          -c 'interface net1' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'\n          -c 'interface net2' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65001'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor net0 interface peer-group PEER'\n          -c ' neighbor net1 interface peer-group PEER'\n          -c ' neighbor net2 interface peer-group PEER'\n          -c '!'\n          -c ' address-family ipv4 unicast'\n          -c '  neighbor net0 activate'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'\n          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'\n          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'\n\n  - name: R2\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65002'\n          -c ' bgp router-id 10.255.0.2'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor net0 interface peer-group PEER'\n          -c ' !'\n          -c ' address-family ipv4 unicast'\n          -c '  network 10.0.0.1/32 route-map COM1'\n          -c '  network 10.0.0.2/32 route-map COM2'\n          -c '  network 10.0.0.3/32 route-map COM3'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'\n          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'\n          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'\n          -c '!'\n          -c 'route-map COM1 permit 1' -c 'set community 65002:1' -c 'exit'\n          -c 'route-map COM2 permit 1' -c 'set community 65002:2' -c 'exit'\n          -c 'route-map COM3 permit 1' -c 'set community 65002:3' -c 'exit'\n\n  - name: R3\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65003'\n          -c ' bgp router-id 10.255.0.3'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor net0 interface peer-group PEER'\n          -c ' !'\n          -c ' address-family ipv4 unicast'\n          -c '  neighbor net0 route-map MAP1 in'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'route-map MAP1 permit 1'\n          -c ' match ip address prefix-list PREF2'\n          -c ' !match community 65002:2'\n          -c ' exit'\n          -c '!'\n          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'\n          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'\n          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'\n\n  - name: R4\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface net0' -c 'ipv6 nd ra-interval 3' -c 'no ipv6 nd suppress-ra'\n          -c '!'\n          -c 'router bgp 65004'\n          -c ' bgp router-id 10.255.0.4'\n          -c ' bgp bestpath as-path multipath-relax'\n          -c ' neighbor PEER peer-group'\n          -c ' neighbor PEER remote-as external'\n          -c ' neighbor net0 interface peer-group PEER'\n          -c '!'\n          -c 'ip prefix-list PREF1 seq 5 permit 10.0.0.1/32'\n          -c 'ip prefix-list PREF2 seq 5 permit 10.0.0.2/32'\n          -c 'ip prefix-list PREF3 seq 5 permit 10.0.0.3/32'\n\n"
  },
  {
    "path": "examples/basic_bgp/route_reflector/spec.yaml",
    "content": "\n# DESCRIPTION:\n#    Basic iBGP RR test using and FRR\n#    create reachability with loopback with OSPF\n#\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#    cns spec.yaml test | sudo sh\n# FINI:\n#    cns spec.yaml fini | sudo sh\n# TOPO:\n#        10.0.0.0/24                             .1(net0)\n#     B0----+-----------------+-----------------+------RR0(255.1.0.1)\n#           |                 |                 |\n#           |.10(net0)        |.11(net0)        |.12(net0)\n#          R0(255.10.0.1)    R1(255.11.0.1)    R2(255.12.0.1)\n#           |.1(net1)         |.1(net1)         |.1(net1)\n#           |                 |                 |\n#           |192.168.10.0/24  |192.168.11.0/24  |192.168.12.0/24\n#           |                 |                 |\n#           |.2(net0)         |.2(net0)         |.2(net0)\n#          C0                C1                C2\n#\n\nnodes:\n  - name: RR0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n\n  - name: R0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n      - { name: net1, type: direct, args: C0#net0 }\n  - name: C0\n    image: slankdev/ubuntu:16.04\n    interfaces:\n      - { name: net0, type: direct, args: R0#net1 }\n\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n      - { name: net1, type: direct, args: C1#net0 }\n  - name: C1\n    image: slankdev/ubuntu:16.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n      - { name: net1, type: direct, args: C2#net0 }\n  - name: C2\n    image: slankdev/ubuntu:16.04\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nswitches:\n  - name: B0\n    interfaces:\n      - { name: net0, type: container, args: RR0 }\n      - { name: net0, type: container, args: R0 }\n      - { name: net0, type: container, args: R1 }\n      - { name: net0, type: container, args: R2 }\n\nnode_configs:\n  - name: RR0\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\" -c \"ip address 10.255.0.1/32\" -c \"exit\"\n          -c \"interface net0\" -c \"ip address 10.0.0.1/24\" -c \"exit\"\n          -c \"router ospf\"\n          -c \"  network 10.255.0.1/32 area 0\"\n          -c \"  network 10.0.0.0/24 area 0\"\n          -c \"exit\"\n          -c \"router bgp 100\"\n          -c \"  bgp router-id 10.255.0.1\"\n          -c \"  neighbor 10.255.0.10 remote-as 100\"\n          -c \"  neighbor 10.255.0.10 update-source lo\"\n          -c \"  neighbor 10.255.0.11 remote-as 100\"\n          -c \"  neighbor 10.255.0.11 update-source lo\"\n          -c \"  neighbor 10.255.0.12 remote-as 100\"\n          -c \"  neighbor 10.255.0.12 update-source lo\"\n          -c \"  address-family ipv4 unicast\"\n          -c \"     neighbor 10.255.0.10 route-reflector-client\"\n          -c \"     neighbor 10.255.0.11 route-reflector-client\"\n          -c \"     neighbor 10.255.0.12 route-reflector-client\"\n          -c \"  exit-address-family\"\n          -c \"exit\"\n\n  - name: R0\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\" -c \"ip address 10.255.0.10/32\" -c \"exit\"\n          -c \"interface net0\" -c \"ip address 10.0.0.10/24\" -c \"exit\"\n          -c \"interface net1\" -c \"ip address 192.168.10.1/24\" -c \"exit\"\n          -c \"router ospf\"\n          -c \"  network 10.255.0.10/32 area 0\"\n          -c \"  network 10.0.0.0/24 area 0\"\n          -c \"exit\"\n          -c \"router bgp 100\"\n          -c \"  bgp router-id 10.255.0.10\"\n          -c \"  neighbor 10.255.0.1 remote-as 100\"\n          -c \"  neighbor 10.255.0.1 update-source lo\"\n          -c \"  network 192.168.10.0/24\"\n          -c \"exit\"\n\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\" -c \"ip address 10.255.0.11/32\" -c \"exit\"\n          -c \"interface net0\" -c \"ip address 10.0.0.11/24\" -c \"exit\"\n          -c \"interface net1\" -c \"ip address 192.168.11.1/24\" -c \"exit\"\n          -c \"router ospf\"\n          -c \"  network 10.255.0.11/32 area 0\"\n          -c \"  network 10.0.0.0/24 area 0\"\n          -c \"exit\"\n          -c \"router bgp 100\"\n          -c \"  bgp router-id 10.255.0.11\"\n          -c \"  neighbor 10.255.0.1 remote-as 100\"\n          -c \"  neighbor 10.255.0.1 update-source lo\"\n          -c \"  network 192.168.11.0/24\"\n          -c \"exit\"\n\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\" -c \"ip address 10.255.0.12/32\" -c \"exit\"\n          -c \"interface net0\" -c \"ip address 10.0.0.12/24\" -c \"exit\"\n          -c \"interface net1\" -c \"ip address 192.168.12.1/24\" -c \"exit\"\n          -c \"router ospf\"\n          -c \"  network 10.255.0.12/32 area 0\"\n          -c \"  network 10.0.0.0/24 area 0\"\n          -c \"exit\"\n          -c \"router bgp 100\"\n          -c \"  bgp router-id 10.255.0.12\"\n          -c \"  neighbor 10.255.0.1 remote-as 100\"\n          -c \"  neighbor 10.255.0.1 update-source lo\"\n          -c \"  network 192.168.12.0/24\"\n          -c \"exit\"\n\n  - name: C0\n    cmds:\n      - cmd: ip addr add 192.168.10.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.10.1\n  - name: C1\n    cmds:\n      - cmd: ip addr add 192.168.11.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.11.1\n  - name: C2\n    cmds:\n      - cmd: ip addr add 192.168.12.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.12.1\n\ntest:\n  - cmds:\n    - cmd: docker exec RR0 ping -c2 10.255.0.1\n    - cmd: docker exec RR0 ping -c2 10.255.0.10\n    - cmd: docker exec RR0 ping -c2 10.255.0.11\n    - cmd: docker exec RR0 ping -c2 10.255.0.12\n    - cmd: docker exec C0 ping -c2 192.168.10.1\n    - cmd: docker exec C0 ping -c2 192.168.11.2\n    - cmd: docker exec C0 ping -c2 192.168.12.2\n    - cmd: docker exec C1 ping -c2 192.168.11.1\n    - cmd: docker exec C1 ping -c2 192.168.10.2\n    - cmd: docker exec C1 ping -c2 192.168.12.2\n    - cmd: docker exec C2 ping -c2 192.168.12.1\n    - cmd: docker exec C2 ping -c2 192.168.10.2\n    - cmd: docker exec C2 ping -c2 192.168.11.2\n\n"
  },
  {
    "path": "examples/basic_bgp/route_server/spec.yaml",
    "content": "# DESCRIPTION: eBGP RS test\n# TOPO:\n#        10.0.0.0/24                             .1(net0)\n#     B0----+-----------------+-----------------+------RS1(10.255.0.1)\n#           |                 |                 |\n#           |.10(net0)        |.11(net0)        |.12(net0)\n#          R1                R2                R3\n#           |.1(net1)         |.1(net1)         |.1(net1)\n#           |                 |                 |\n#           |192.168.1.0/24  |192.168.2.0/24  |192.168.3.0/24\n#           |                 |                 |\n#           |.2(net0)         |.2(net0)         |.2(net0)\n#          C1                C2                C3\n\nnodes:\n- name: RS1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\n- name: R1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: C1#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n- name: C1\n  image: slankdev/ubuntu:16.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\n- name: R2\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: C2#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n- name: C2\n  image: slankdev/ubuntu:16.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\n- name: R3\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: C3#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n- name: C3\n  image: slankdev/ubuntu:16.04\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\nswitches:\n- name: B0\n  interfaces:\n  - { name: net0, type: container, args: RS1 }\n  - { name: net0, type: container, args: R1 }\n  - { name: net0, type: container, args: R2 }\n  - { name: net0, type: container, args: R3 }\n\nnode_configs:\n- name: RS1\n  cmds:\n  - cmd: ip addr add 10.255.0.1/24 dev net0\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 1\"\n      -c \" bgp router-id 10.255.0.1\"\n      -c \" neighbor 10.255.0.11 remote-as 11\"\n      -c \" neighbor 10.255.0.12 remote-as 12\"\n      -c \" neighbor 10.255.0.13 remote-as 13\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  neighbor 10.255.0.11 route-server-client\"\n      -c \"  neighbor 10.255.0.12 route-server-client\"\n      -c \"  neighbor 10.255.0.13 route-server-client\"\n      -c \"  !neighbor 10.255.0.11 next-hop-self\"\n      -c \"  !neighbor 10.255.0.12 next-hop-self\"\n      -c \"  !neighbor 10.255.0.13 next-hop-self\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  neighbor 10.255.0.11 activate\"\n      -c \"  neighbor 10.255.0.12 activate\"\n      -c \"  neighbor 10.255.0.13 activate\"\n      -c \"  neighbor 10.255.0.11 route-server-client\"\n      -c \"  neighbor 10.255.0.12 route-server-client\"\n      -c \"  neighbor 10.255.0.13 route-server-client\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.255.0.11/24 dev net0\n  - cmd: ip addr add 192.168.11.1/24 dev net1\n  - cmd: ip -6 addr add 2001:11::1/64 dev net1\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 11\"\n      -c \" bgp router-id 10.255.0.11\"\n      -c \" neighbor 10.255.0.1 remote-as 1\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor 10.255.0.1 activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor 10.255.0.1 activate\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.255.0.12/24 dev net0\n  - cmd: ip addr add 192.168.12.1/24 dev net1\n  - cmd: ip -6 addr add 2001:12::1/64 dev net1\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 12\"\n      -c \" bgp router-id 10.255.0.12\"\n      -c \" neighbor 10.255.0.1 remote-as 1\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor 10.255.0.1 activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor 10.255.0.1 activate\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.255.0.13/24 dev net0\n  - cmd: ip addr add 192.168.13.1/24 dev net1\n  - cmd: ip -6 addr add 2001:13::1/64 dev net1\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 13\"\n      -c \" bgp router-id 10.255.0.13\"\n      -c \" neighbor 10.255.0.1 remote-as 1\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor 10.255.0.1 activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor 10.255.0.1 activate\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 192.168.11.2/24 dev net0\n  - cmd: ip route replace default via 192.168.11.1\n\n- name: C2\n  cmds:\n  - cmd: ip addr add 192.168.12.2/24 dev net0\n  - cmd: ip route replace default via 192.168.12.1\n\n- name: C3\n  cmds:\n  - cmd: ip addr add 192.168.13.2/24 dev net0\n  - cmd: ip route replace default via 192.168.13.1\n"
  },
  {
    "path": "examples/basic_bgp/route_server_multihop/spec.yaml",
    "content": "nodes:\n- name: RS1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: S1#net0 }\n\n- name: S1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: RS1#net0 }\n  - { name: net1, type: direct, args: R1#net0 }\n  - { name: net2, type: direct, args: R2#net0 }\n  - { name: net3, type: direct, args: R3#net0 }\n\n- name: R1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: S1#net1 }\n  - { name: net1, type: direct, args: C1#net0 }\n\n- name: R2\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: S1#net2 }\n  - { name: net1, type: direct, args: C2#net0 }\n- name: R3\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: S1#net3 }\n  - { name: net1, type: direct, args: C3#net0 }\n\n- name: C1\n  image: slankdev/ubuntu:16.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: slankdev/ubuntu:16.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n- name: C3\n  image: slankdev/ubuntu:16.04\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n\nnode_configs:\n- name: RS1\n  cmds:\n  - cmd: ip addr add 10.255.1.1/24 dev net0\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 1\"\n      -c \" bgp router-id 1.1.1.1\"\n      -c \" neighbor 10.255.1.2 remote-as 100\"\n      -c \" neighbor 10.255.11.1 remote-as 11\"\n      -c \" neighbor 10.255.11.1 ebgp-multihop 64\"\n      -c \" neighbor 10.255.12.1 remote-as 12\"\n      -c \" neighbor 10.255.12.1 ebgp-multihop 64\"\n      -c \" neighbor 10.255.13.1 remote-as 13\"\n      -c \" neighbor 10.255.13.1 ebgp-multihop 64\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: S1\n  cmds:\n  - cmd: ip addr add 10.255.1.2/24 dev net0\n  - cmd: ip addr add 10.255.11.2/24 dev net1\n  - cmd: ip addr add 10.255.12.2/24 dev net2\n  - cmd: ip addr add 10.255.13.2/24 dev net3\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 100\"\n      -c \" bgp router-id 100.100.100.100\"\n      -c \" neighbor 10.255.1.1 remote-as 1\"\n      -c \" neighbor 10.255.11.1 remote-as 11\"\n      -c \" neighbor 10.255.12.1 remote-as 12\"\n      -c \" neighbor 10.255.13.1 remote-as 13\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.255.11.1/24 dev net0\n  - cmd: ip addr add 192.168.11.1/24 dev net1\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 11\"\n      -c \" bgp router-id 11.11.11.11\"\n      -c \" neighbor 10.255.11.2 remote-as 100\"\n      -c \" neighbor 10.255.1.1 remote-as 1\"\n      -c \" neighbor 10.255.1.1 ebgp-multihop 64\"\n      -c \" neighbor 10.255.1.1 timer connect 1\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  neighbor 10.255.11.2 prefix-list core-out out\"\n      -c \"  neighbor 10.255.11.2 prefix-list core-in in\"\n      -c \"  neighbor 10.255.1.1 prefix-list rs-out out\"\n      -c \"  neighbor 10.255.1.1 prefix-list rs-in in\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n      -c \"ip prefix-list core-out permit 10.255.0.0/16 le 32\"\n      -c \"ip prefix-list core-in permit 10.255.0.0/16 le 32\"\n      -c \"ip prefix-list rs-out permit 192.168.0.0/16 le 32\"\n      -c \"ip prefix-list rs-in permit 192.168.0.0/16 le 32\"\n\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.255.12.1/24 dev net0\n  - cmd: ip addr add 192.168.12.1/24 dev net1\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 12\"\n      -c \" bgp router-id 12.12.12.12\"\n      -c \" neighbor 10.255.12.2 remote-as 100\"\n      -c \" neighbor 10.255.1.1 remote-as 1\"\n      -c \" neighbor 10.255.1.1 ebgp-multihop 64\"\n      -c \" neighbor 10.255.1.1 timer connect 1\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  neighbor 10.255.12.2 prefix-list core-out out\"\n      -c \"  neighbor 10.255.12.2 prefix-list core-in in\"\n      -c \"  neighbor 10.255.1.1 prefix-list rs-out out\"\n      -c \"  neighbor 10.255.1.1 prefix-list rs-in in\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n      -c \"ip prefix-list core-out permit 10.255.0.0/16 le 32\"\n      -c \"ip prefix-list core-in permit 10.255.0.0/16 le 32\"\n      -c \"ip prefix-list rs-out permit 192.168.0.0/16 le 32\"\n      -c \"ip prefix-list rs-in permit 192.168.0.0/16 le 32\"\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.255.13.1/24 dev net0\n  - cmd: ip addr add 192.168.13.1/24 dev net1\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 13\"\n      -c \" bgp router-id 13.13.13.13\"\n      -c \" neighbor 10.255.13.2 remote-as 100\"\n      -c \" neighbor 10.255.1.1 remote-as 1\"\n      -c \" neighbor 10.255.1.1 ebgp-multihop 64\"\n      -c \" neighbor 10.255.1.1 timer connect 1\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  neighbor 10.255.13.2 prefix-list core-out out\"\n      -c \"  neighbor 10.255.13.2 prefix-list core-in in\"\n      -c \"  neighbor 10.255.1.1 prefix-list rs-out out\"\n      -c \"  neighbor 10.255.1.1 prefix-list rs-in in\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n      -c \"ip prefix-list core-out permit 10.255.0.0/16 le 32\"\n      -c \"ip prefix-list core-in permit 10.255.0.0/16 le 32\"\n      -c \"ip prefix-list rs-out permit 192.168.0.0/16 le 32\"\n      -c \"ip prefix-list rs-in permit 192.168.0.0/16 le 32\"\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 192.168.11.2/24 dev net0\n  - cmd: ip route replace default via 192.168.11.1\n\n- name: C2\n  cmds:\n  - cmd: ip addr add 192.168.12.2/24 dev net0\n  - cmd: ip route replace default via 192.168.12.1\n\n- name: C3\n  cmds:\n  - cmd: ip addr add 192.168.13.2/24 dev net0\n  - cmd: ip route replace default via 192.168.13.1\n"
  },
  {
    "path": "examples/basic_bgp/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65001\"\n          -c \"bgp router-id 10.255.0.1\"\n          -c \"neighbor 10.0.0.2 remote-as 65002\"\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65002\"\n          -c \"bgp router-id 10.255.0.2\"\n          -c \"neighbor 10.0.0.1 remote-as 65001\"\n\n"
  },
  {
    "path": "examples/basic_bgp/unnumbered/spec.yaml",
    "content": "nodes:\n- name: R1\n  image: frrouting/frr:v8.1.0\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1\n- name: R2\n  image: frrouting/frr:v8.1.0\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv4.ip_forward=1\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'interface net0'\n      -c ' ipv6 nd ra-interval 3'\n      -c ' no ipv6 nd suppress-ra'\n      -c '!'\n      -c 'router bgp 65001'\n      -c ' bgp router-id 10.255.0.1'\n      -c ' bgp bestpath as-path multipath-relax'\n      -c ' no bgp ebgp-requires-policy'\n      -c ' neighbor PEER peer-group'\n      -c ' neighbor PEER remote-as external'\n      -c ' neighbor net0 interface peer-group PEER'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  redistribute connected'\n      -c ' exit-address-family'\n\n- name: R2\n  cmds:\n  - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'interface net0'\n      -c ' ipv6 nd ra-interval 3'\n      -c ' no ipv6 nd suppress-ra'\n      -c '!'\n      -c 'router bgp 65002'\n      -c ' bgp router-id 10.255.0.2'\n      -c ' bgp bestpath as-path multipath-relax'\n      -c ' no bgp ebgp-requires-policy'\n      -c ' neighbor PEER peer-group'\n      -c ' neighbor PEER remote-as external'\n      -c ' neighbor net0 interface peer-group PEER'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  redistribute connected'\n      -c ' exit-address-family'\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_mpls/README.md",
    "content": "\n# MP-BGP VPNv4 per-VRF w/ MPLS\n\n![](./topo.png)\n\nreferences: configure example of vpnv4 as small set.\nhttps://gist.github.com/hkwi/5c116f05667a3abf43c7456fae32a529\n\nsetup\n```\n$ tn upconf | sudo sh\n```\n\ncheck vpn routes on R1\n```\n$ docker exec R1 vtysh -c 'show bgp ipv4 vpn'\nBGP table version is 1, local router ID is 10.255.0.1, vrf id 0\nStatus codes:  s suppressed, d damped, h history, * valid, > best, = multipath,\n               i internal, r RIB-failure, S Stale, R Removed\nNexthop codes: @NNN nexthop's vrf id, < announce-nh-self\nOrigin codes:  i - IGP, e - EGP, ? - incomplete\n\n   Network          Next Hop            Metric LocPrf Weight Path\nRoute Distinguisher: 65001:1\n*> 20.1.0.0/24      0.0.0.0@6<         0         32768 ?\n    UN=0.0.0.0 EC{100:1} label=80 type=bgp, subtype=5\nRoute Distinguisher: 65001:2\n*> 20.3.0.0/24      0.0.0.0@7<         0         32768 ?\n    UN=0.0.0.0 EC{100:2} label=81 type=bgp, subtype=5\nRoute Distinguisher: 65001:3\n*> 20.5.0.0/24      0.0.0.0@8<         0         32768 ?\n    UN=0.0.0.0 EC{100:1} label=82 type=bgp, subtype=5\nRoute Distinguisher: 65002:1\n*> 20.2.0.0/24      10.0.0.2         0             0 65002 ?\n    UN=10.0.0.2 EC{100:1} label=80 type=bgp, subtype=0\nRoute Distinguisher: 65002:2\n*> 20.4.0.0/24      10.0.0.2         0             0 65002 ?\n    UN=10.0.0.2 EC{100:2} label=81 type=bgp, subtype=0\nRoute Distinguisher: 65002:3\n*> 20.6.0.0/24      10.0.0.2         0             0 65002 ?\n    UN=10.0.0.2 EC{100:2} label=82 type=bgp, subtype=0\n\nDisplayed  6 routes and 6 total paths\n```\n\ncheck vrf's route on VRF1 on R1 (VPNv4 rt100:1)\n```\ndocker exec R1 vtysh -c 'show ip route vrf vrf1'\nCodes: K - kernel route, C - connected, S - static, R - RIP,\n       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,\n       T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,\n       F - PBR,\n       > - selected route, * - FIB route\n\n\nVRF vrf1:\nC>* 20.1.0.0/24 is directly connected, net1, 00:01:37\nB>* 20.2.0.0/24 [200/0] via 10.0.0.2, net0(vrf Default-IP-Routing-Table), label 80, 00:01:30\nB>* 20.5.0.0/24 [200/0] is directly connected, net3(vrf vrf3), 00:01:37\n```\n\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_mpls/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C3#net0 }\n      - { name: net3, type: direct, args: C5#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n      - { name: net3, type: direct, args: C6#net0 }\n  - name: C1\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C3\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C4\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n  - name: C5\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R1#net3 } ]\n  - name: C6\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R2#net3 } ]\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sh -c 'echo 100000 > /proc/sys/net/mpls/platform_labels'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net0/input'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net1/input'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net2/input'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net3/input'\n      - cmd: ip link add vrf1 type vrf table 10\n      - cmd: ip link set vrf1 up\n      - cmd: ip link add vrf2 type vrf table 20\n      - cmd: ip link set vrf2 up\n      - cmd: ip link add vrf3 type vrf table 30\n      - cmd: ip link set vrf3 up\n      - cmd: ip link set net1 vrf vrf1\n      - cmd: ip link set net2 vrf vrf2\n      - cmd: ip link set net3 vrf vrf3\n      - cmd: tcpdump -ni net0 -w /tmp/R1.in.pcap &\n\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf te'\n          -c 'int net0'\n          -c ' ip address 10.0.0.1/24'\n          -c '!'\n          -c 'int net1 vrf vrf1'\n          -c ' ip address 20.1.0.1/24'\n          -c '!'\n          -c 'int net2 vrf vrf2'\n          -c ' ip address 20.3.0.1/24'\n          -c '!'\n          -c 'int net3 vrf vrf3'\n          -c ' ip address 20.5.0.1/24'\n          -c '!'\n          -c 'router bgp 65001'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' neighbor 10.0.0.2 remote-as 65002'\n          -c ' !'\n          -c ' address-family ipv4 unicast'\n          -c '  neighbor 10.0.0.2 activate'\n          -c '  redistribute connected'\n          -c '  redistribute static'\n          -c ' exit-address-family'\n          -c ' !'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.0.0.2 activate'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'router bgp 65001 vrf vrf1'\n          -c ' address-family ipv4'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c '  rd vpn export 65001:1'\n          -c '  rt vpn both 100:1'\n          -c '  label vpn export auto'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'router bgp 65001 vrf vrf2'\n          -c ' address-family ipv4'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c '  rd vpn export 65001:2'\n          -c '  rt vpn both 100:2'\n          -c '  label vpn export auto'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'router bgp 65001 vrf vrf3'\n          -c ' address-family ipv4'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c '  rd vpn export 65001:3'\n          -c '  rt vpn both 100:1'\n          -c '  label vpn export auto'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'\n\n  - name: R2\n    cmds:\n      - cmd: sh -c 'echo 100000 > /proc/sys/net/mpls/platform_labels'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net0/input'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net1/input'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net2/input'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net3/input'\n      - cmd: ip link add vrf1 type vrf table 10\n      - cmd: ip link set vrf1 up\n      - cmd: ip link add vrf2 type vrf table 20\n      - cmd: ip link set vrf2 up\n      - cmd: ip link add vrf3 type vrf table 30\n      - cmd: ip link set vrf3 up\n      - cmd: ip link set net1 vrf vrf1\n      - cmd: ip link set net2 vrf vrf2\n      - cmd: ip link set net3 vrf vrf3\n      - cmd: tcpdump -ni net0 -w /tmp/R2.in.pcap &\n\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf te'\n          -c 'int net0'\n          -c ' ip address 10.0.0.2/24'\n          -c '!'\n          -c 'int net1 vrf vrf1'\n          -c ' ip address 20.2.0.1/24'\n          -c '!'\n          -c 'int net2 vrf vrf2'\n          -c ' ip address 20.4.0.1/24'\n          -c '!'\n          -c 'int net3 vrf vrf3'\n          -c ' ip address 20.6.0.1/24'\n          -c '!'\n          -c 'router bgp 65002'\n          -c ' bgp router-id 10.255.0.2'\n          -c ' neighbor 10.0.0.1 remote-as 65001'\n          -c ' !'\n          -c ' address-family ipv4'\n          -c '  neighbor 10.0.0.1 activate'\n          -c '  redistribute connected'\n          -c '  redistribute static'\n          -c ' exit-address-family'\n          -c ' !'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.0.0.1 activate'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'router bgp 65002 vrf vrf1'\n          -c ' address-family ipv4'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c '  rd vpn export 65002:1'\n          -c '  rt vpn both 100:1'\n          -c '  label vpn export auto'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'router bgp 65002 vrf vrf2'\n          -c ' address-family ipv4'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c '  rd vpn export 65002:2'\n          -c '  rt vpn both 100:2'\n          -c '  label vpn export auto'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'\n          -c 'router bgp 65002 vrf vrf3'\n          -c ' address-family ipv4'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c '  rd vpn export 65002:3'\n          -c '  rt vpn both 100:2'\n          -c '  label vpn export auto'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c '!'\n\n  - name: C1\n    cmds:\n      - cmd: ip addr replace 20.1.0.2/24 dev net0\n      - cmd: ip route replace default via 20.1.0.1\n  - name: C2\n    cmds:\n      - cmd: ip addr replace 20.2.0.2/24 dev net0\n      - cmd: ip route replace default via 20.2.0.1\n  - name: C3\n    cmds:\n      - cmd: ip addr replace 20.3.0.2/24 dev net0\n      - cmd: ip route replace default via 20.3.0.1\n  - name: C4\n    cmds:\n      - cmd: ip addr replace 20.4.0.2/24 dev net0\n      - cmd: ip route replace default via 20.4.0.1\n  - name: C5\n    cmds:\n      - cmd: ip addr replace 20.5.0.2/24 dev net0\n      - cmd: ip route replace default via 20.5.0.1\n  - name: C6\n    cmds:\n      - cmd: ip addr replace 20.6.0.2/24 dev net0\n      - cmd: ip route replace default via 20.6.0.1\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: echo slankdev slankdev\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srmpls/README.md",
    "content": "# 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",
    "content": "preinit:\n  - cmds:\n    - cmd: modprobe mpls_router\n    - cmd: modprobe mpls_gso\n    - cmd: modprobe mpls_iptunnel\n\nnodes:\n  - name: R1\n    image: frrouting/frr:v7.5.1\n    docker_run_extra_args: --entrypoint bash\n    interfaces:\n    - { name: net0, type: direct, args: R2#net0 }\n    - { name: net1, type: direct, args: R4#net0 }\n    - { name: net2, type: direct, args: HostA1#net0 }\n    - { name: net3, type: direct, args: HostB1#net0 }\n  - name: R2\n    image: frrouting/frr:v7.5.1\n    docker_run_extra_args: --entrypoint bash\n    interfaces:\n    - { name: net0, type: direct, args: R1#net0 }\n    - { name: net1, type: direct, args: R3#net0 }\n    - { name: net2, type: direct, args: R4#net1 }\n  - name: R3\n    image: frrouting/frr:v7.5.1\n    docker_run_extra_args: --entrypoint bash\n    interfaces:\n    - { name: net0, type: direct, args: R2#net1 }\n    - { name: net1, type: direct, args: R4#net2 }\n    - { name: net2, type: direct, args: HostA2#net0 }\n    - { name: net3, type: direct, args: HostB2#net0 }\n  - name: R4\n    image: frrouting/frr:v7.5.1\n    docker_run_extra_args: --entrypoint bash\n    interfaces:\n    - { name: net0, type: direct, args: R1#net1 }\n    - { name: net1, type: direct, args: R2#net2 }\n    - { name: net2, type: direct, args: R3#net1 }\n  - name: HostA1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: R1#net2 }\n  - name: HostA2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: R3#net2 }\n  - name: HostB1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: R1#net3 }\n  - name: HostB2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: R3#net3 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons\n      - cmd: sed -i -e 's/ospfd=no/ospfd=yes/g' /etc/frr/daemons\n      - cmd: sed -i -e 's/pimd=no/pimd=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n\n      - cmd: ip link add CUST-A type vrf table 10\n      - cmd: ip link add CUST-B type vrf table 20\n      - cmd: ip link set CUST-A up\n      - cmd: ip link set CUST-B up\n      - cmd: ip link set net2 master CUST-A\n      - cmd: ip link set net3 master CUST-B\n\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.1/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.1/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.9/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 192.168.0.1/24'\n          -c 'exit'\n          -c 'interface net3'\n          -c ' ip address 192.168.0.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.1'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.1'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.1/32 index 1001'\n          -c 'exit'\n          -c 'router bgp 65000'\n          -c ' neighbor 10.255.0.3 remote-as 65000'\n          -c ' neighbor 10.255.0.3 update-source 10.255.0.1'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.255.0.3 activate'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-A'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:10'\n          -c '  rt vpn both 65000:10'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-B'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:20'\n          -c '  rt vpn both 65000:20'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.conf.net2.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.2/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.2/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.5/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 10.0.0.13/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.2'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.2'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.2/32 index 1002'\n          -c 'exit'\n  - name: R3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n\n      - cmd: ip link add CUST-A type vrf table 10\n      - cmd: ip link add CUST-B type vrf table 20\n      - cmd: ip link set CUST-A up\n      - cmd: ip link set CUST-B up\n      - cmd: ip link set net2 master CUST-A\n      - cmd: ip link set net3 master CUST-B\n\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.3/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.6/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.17/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 192.168.1.1/24'\n          -c 'exit'\n          -c 'interface net3'\n          -c ' ip address 192.168.1.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.3'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.3'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.3/32 index 1003'\n          -c 'exit'\n          -c 'router bgp 65000'\n          -c ' neighbor 10.255.0.1 remote-as 65000'\n          -c ' neighbor 10.255.0.1 update-source 10.255.0.3'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.255.0.1 activate'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-A'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:10'\n          -c '  rt vpn both 65000:10'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-B'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:20'\n          -c '  rt vpn both 65000:20'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n  - name: R4\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.conf.net2.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.4/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.10/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.14/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 10.0.0.18/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.4'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.4'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.4/32 index 1004'\n          -c 'exit'\n  - name: HostA1\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route add default via 192.168.0.1\n  - name: HostA2\n    cmds:\n      - cmd: ip addr add 192.168.1.2/24 dev net0\n      - cmd: ip route add default via 192.168.1.1\n  - name: HostB1\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route add default via 192.168.0.1\n  - name: HostB2\n    cmds:\n      - cmd: ip addr add 192.168.1.2/24 dev net0\n      - cmd: ip route add default via 192.168.1.1\n\ntest:\n  - cmds:\n    ## SR-MPLS Operation\n    - cmd: docker exec R1 ip route add 10.255.0.3/32 encap mpls 17004/17003 via 10.0.0.2\n    - cmd: docker exec R3 ip route add 10.255.0.1/32 encap mpls 17002/17001 via 10.0.0.18\n    ## SR-MPLS Test\n    - cmd: docker exec HostA1 ping -c2 192.168.1.2\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srmpls_interas_option-b/README.md",
    "content": "# 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",
    "content": "preinit:\n  - cmds:\n    - cmd: modprobe mpls_router\n    - cmd: modprobe mpls_gso\n    - cmd: modprobe mpls_iptunnel\n\nnodes:\n  ## AS65000\n  - name: ASBR1\n    image: frrouting/frr:v7.5.1\n    interfaces:\n    - { name: net0, type: direct, args: ASBR2#net0 }\n    - { name: net1, type: direct, args: P1#net0 }\n  - name: P1\n    image: frrouting/frr:v7.5.1\n    interfaces:\n    - { name: net0, type: direct, args: ASBR1#net1 }\n    - { name: net1, type: direct, args: PE1#net0 }\n  - name: PE1\n    image: frrouting/frr:v7.5.1\n    interfaces:\n    - { name: net0, type: direct, args: P1#net1 }\n    - { name: net1, type: direct, args: HostA1#net0 }\n    - { name: net2, type: direct, args: HostB1#net0 }\n  - name: HostA1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: PE1#net1 }\n  - name: HostB1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: PE1#net2 }\n  ## AS65001\n  - name: ASBR2\n    image: frrouting/frr:v7.5.1\n    interfaces:\n    - { name: net0, type: direct, args: ASBR1#net0 }\n    - { name: net1, type: direct, args: P2#net0 }\n  - name: P2\n    image: frrouting/frr:v7.5.1\n    interfaces:\n    - { name: net0, type: direct, args: ASBR2#net1 }\n    - { name: net1, type: direct, args: PE2#net0 }\n  - name: PE2\n    image: frrouting/frr:v7.5.1\n    interfaces:\n    - { name: net0, type: direct, args: P2#net1 }\n    - { name: net1, type: direct, args: HostA2#net0 }\n    - { name: net2, type: direct, args: HostB2#net0 }\n  - name: HostA2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: PE2#net1 }\n  - name: HostB2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n    - { name: net0, type: direct, args: PE2#net2 }\n\nnode_configs:\n  - name: ASBR1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n\n      - cmd: ip link add CUST-A type vrf table 10\n      - cmd: ip link add CUST-B type vrf table 20\n      - cmd: ip link set CUST-A up\n      - cmd: ip link set CUST-B up\n\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.1/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 172.16.0.1/30'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.1/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.1'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.1'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.1/32 index 1001'\n          -c 'exit'\n          -c 'router bgp 65000'\n          -c ' neighbor 10.255.0.3 remote-as 65000'\n          -c ' neighbor 10.255.0.3 update-source 10.255.0.1'\n          -c ' neighbor 172.16.0.2 remote-as 65001'\n          -c ' neighbor 172.16.0.2 update-source 172.16.0.1'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.255.0.3 activate'\n          -c '  neighbor 10.255.0.3 next-hop-self'\n          -c '  neighbor 172.16.0.2 activate'\n          -c '  neighbor 172.16.0.2 route-map AS65001-IN in'\n          -c '  neighbor 172.16.0.2 route-map AS65001-OUT out'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-A'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:10'\n          -c '  rt vpn both 65000:10'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-B'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:20'\n          -c '  rt vpn both 65000:20'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'bgp extcommunity-list 1 seq 1 permit rt 65000:10'\n          -c 'bgp extcommunity-list 2 seq 1 permit rt 65000:20'\n          -c 'route-map AS65001-IN permit 1'\n          -c 'route-map AS65001-OUT permit 1'\n          -c ' match extcommunity 1'\n          -c ' set extcommunity rt 65001:10'\n          -c 'route-map AS65001-OUT permit 2'\n          -c ' match extcommunity 2'\n          -c ' set extcommunity rt 65001:20'\n\n  - name: P1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.2/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.2/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.5/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.2'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.2'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.2/32 index 1002'\n          -c 'exit'\n\n  - name: PE1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n\n      - cmd: ip link add CUST-A type vrf table 10\n      - cmd: ip link add CUST-B type vrf table 20\n      - cmd: ip link set CUST-A up\n      - cmd: ip link set CUST-B up\n      - cmd: ip link set net1 master CUST-A\n      - cmd: ip link set net2 master CUST-B\n\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.3/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.6/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 192.168.0.1/24'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 192.168.0.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.3'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.3'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.3/32 index 1003'\n          -c 'exit'\n          -c 'router bgp 65000'\n          -c ' neighbor 10.255.0.1 remote-as 65000'\n          -c ' neighbor 10.255.0.1 update-source 10.255.0.3'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.255.0.1 activate'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-A'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:10'\n          -c '  rt vpn both 65000:10'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65000 vrf CUST-B'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65000:20'\n          -c '  rt vpn both 65000:20'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n\n  - name: ASBR2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n\n      - cmd: ip link add CUST-A type vrf table 10\n      - cmd: ip link add CUST-B type vrf table 20\n      - cmd: ip link set CUST-A up\n      - cmd: ip link set CUST-B up\n\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.1/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 172.16.0.2/30'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.1.1/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.1'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.1'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.1/32 index 1001'\n          -c 'exit'\n          -c 'router bgp 65001'\n          -c ' neighbor 10.255.0.3 remote-as 65001'\n          -c ' neighbor 10.255.0.3 update-source 10.255.0.1'\n          -c ' neighbor 172.16.0.1 remote-as 65000'\n          -c ' neighbor 172.16.0.1 update-source 172.16.0.2'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.255.0.3 activate'\n          -c '  neighbor 10.255.0.3 next-hop-self'\n          -c '  neighbor 172.16.0.1 activate'\n          -c '  neighbor 172.16.0.1 route-map AS65000-IN in'\n          -c '  neighbor 172.16.0.1 route-map AS65000-OUT out'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65001 vrf CUST-A'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65001:10'\n          -c '  rt vpn both 65001:10'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65001 vrf CUST-B'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65001:20'\n          -c '  rt vpn both 65001:20'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'bgp extcommunity-list 1 seq 1 permit rt 65001:10'\n          -c 'bgp extcommunity-list 2 seq 1 permit rt 65001:20'\n          -c 'route-map AS65000-IN permit 1'\n          -c 'route-map AS65000-OUT permit 1'\n          -c ' match extcommunity 1'\n          -c ' set extcommunity rt 65000:10'\n          -c 'route-map AS65000-OUT permit 2'\n          -c ' match extcommunity 2'\n          -c ' set extcommunity rt 65000:20'\n\n  - name: P2\n    cmds:\n      - cmd: /usr/lib/fro/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.2/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.1.2/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.1.5/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.2'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.2'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.2/32 index 1002'\n          -c 'exit'\n\n  - name: PE2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sed -i -e 's/=no/=yes/g' /etc/frr/daemons\n      - cmd: /usr/lib/frr/frrinit.sh restart\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: systcl -w net.ipv4.conf.all.rp_filter=0\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n\n      - cmd: ip link add CUST-A type vrf table 10\n      - cmd: ip link add CUST-B type vrf table 20\n      - cmd: ip link set CUST-A up\n      - cmd: ip link set CUST-B up\n      - cmd: ip link set net1 master CUST-A\n      - cmd: ip link set net2 master CUST-B\n\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.3/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.1.6/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 192.168.1.1/24'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 192.168.1.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.3'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.3'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.3/32 index 1003'\n          -c 'exit'\n          -c 'router bgp 65001'\n          -c ' neighbor 10.255.0.1 remote-as 65001'\n          -c ' neighbor 10.255.0.1 update-source 10.255.0.3'\n          -c ' address-family ipv4 vpn'\n          -c '  neighbor 10.255.0.1 activate'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65001 vrf CUST-A'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65001:10'\n          -c '  rt vpn both 65001:10'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n          -c 'router bgp 65001 vrf CUST-B'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c '  label vpn export auto'\n          -c '  rd vpn export 65001:20'\n          -c '  rt vpn both 65001:20'\n          -c '  export vpn'\n          -c '  import vpn'\n          -c ' exit-address-family'\n          -c 'exit'\n\n  - name: HostA1\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route add default via 192.168.0.1\n  - name: HostA2\n    cmds:\n      - cmd: ip addr add 192.168.1.2/24 dev net0\n      - cmd: ip route add default via 192.168.1.1\n  - name: HostB1\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route add default via 192.168.0.1\n  - name: HostB2\n    cmds:\n      - cmd: ip addr add 192.168.1.2/24 dev net0\n      - cmd: ip route add default via 192.168.1.1\n\ntest:\n  - cmds:\n    ## SR-MPLS Test\n    - cmd: docker exec HostA1 ping -c2 192.168.1.2\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/Makefile",
    "content": "\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\ninstall:\n\tdocker exec R1 rm -rf /usr/lib/frr\n\tdocker cp /usr/lib/frr R1:/usr/lib/frr\n\tdocker cp /usr/bin/vtysh R1:/usr/bin/vtysh\n\t\\\n\tdocker exec R2 rm -rf /usr/lib/frr\n\tdocker cp /usr/lib/frr R2:/usr/lib/frr\n\tdocker cp /usr/bin/vtysh R2:/usr/bin/vtysh\n\nconfig_srv6_only:\n\tdocker cp frr.conf.srv6.R1 R1:/etc/frr/frr.conf\n\tdocker cp frr.conf.srv6.R2 R2:/etc/frr/frr.conf\n\nstop:\n\tdocker exec R1 /usr/lib/frr/frrinit.sh stop\n\tdocker exec R2 /usr/lib/frr/frrinit.sh stop\n\nstart:\n\tdocker exec R1 /usr/lib/frr/frrinit.sh start\n\tdocker exec R2 /usr/lib/frr/frrinit.sh start\n\nrestart:\n\tdocker exec R1 /usr/lib/frr/frrinit.sh restart\n\tdocker exec R2 /usr/lib/frr/frrinit.sh restart\n\ncapture:\n\tdocker exec R1 pkill tcpdump | true\n\tdocker exec R2 pkill tcpdump | true\n\tdocker exec -d R1 tcpdump -ni net0 -w /tmp/r1.pcap\n\tdocker exec -d R2 tcpdump -ni net0 -w /tmp/r2.pcap\n\nnocapture:\n\tdocker exec R1 pkill tcpdump | true\n\tdocker exec R2 pkill tcpdump | true\n\tdocker cp R1:/tmp/r1.pcap /vagrant/r1.pcap\n\tdocker cp R2:/tmp/r2.pcap /vagrant/r2.pcap\n\nrere:\n\tmake -C . build\n\tmake -C . install\n\tmake -C . reload\n\ntaillog_R1:\n\twhile :; do \\\n\t\tdocker exec -it R1 touch /tmp/frr.log; \\\n\t\tdocker exec -it R1 chown frr.frr /tmp/frr.log; \\\n\t\tdocker exec -it R1 tail -f /tmp/frr.log -n0; \\\n\t\tsleep 1 ; done\ntaillog_R2:\n\twhile :; do \\\n\t\tdocker exec -it R2 touch /tmp/frr.log; \\\n\t\tdocker exec -it R2 chown frr.frr /tmp/frr.log; \\\n\t\tdocker exec -it R2 tail -f /tmp/frr.log -n0; \\\n\t\tsleep 1 ; done\n\ntn_reconf:\n\ttn reconf | sudo sh\n\tmake -C . install\n\tmake -C . config_srv6_only\n\nsh_route_vrfs:\n\t@echo -e '\\n[[R1-glb]]'\n\t@docker exec R1 ip route list\n\t@docker exec R1 ip -6 route list\n\t@echo -e '\\n[[R1-vrf1]]'\n\t@docker exec R1 ip route list vrf vrf1\n\t@echo -e '\\n[[R1-vrf2]]'\n\t@docker exec R1 ip route list vrf vrf2\n\t@echo -e '\\n[[R1-vrf3]]'\n\t@docker exec R1 ip route list vrf vrf3\n\t@echo -e '\\n[[R2-glb]]'\n\t@docker exec R2 ip route list\n\t@docker exec R2 ip -6 route list\n\t@echo -e '\\n[[R2-vrf1]]'\n\t@docker exec R2 ip route list vrf vrf1\n\t@echo -e '\\n[[R2-vrf2]]'\n\t@docker exec R2 ip route list vrf vrf2\n\t@echo -e '\\n[[R2-vrf3]]'\n\t@docker exec R2 ip route list vrf vrf3\n\t@echo\n\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/README.md",
    "content": "\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.254.99.10 dev vrf1 scope link\n169.254.99.20 dev vrf2 scope link\n169.254.99.30 dev vrf3 scope link\n1:1::  encap seg6local action End.DX4 nh4 169.254.99.10 dev net0 metric 1024 pref medium\n1:2::  encap seg6local action End.DX4 nh4 169.254.99.20 dev net0 metric 1024 pref medium\n1:3::  encap seg6local action End.DX4 nh4 169.254.99.30 dev net0 metric 1024 pref medium\n2:1:: via 2001::2 dev net0 metric 1024 pref medium\n2:2:: via 2001::2 dev net0 metric 1024 pref medium\n2:3:: via 2001::2 dev net0 metric 1024 pref medium\n2001::/64 dev net0 proto kernel metric 256 pref medium\nfe80::/64 dev net0 proto kernel metric 256 pref medium\n\n[[R1-vrf1]]\n30.1.0.0/24 dev net1 proto kernel scope link src 30.1.0.1\n30.2.0.0/24  encap seg6 mode encap segs 1 [ 2:1:: ] dev net0 scope link\n\n[[R1-vrf2]]\n30.3.0.0/24 dev net2 proto kernel scope link src 30.3.0.1\n30.4.0.0/24  encap seg6 mode encap segs 1 [ 2:2:: ] dev net0 scope link\n\n[[R1-vrf3]]\n30.5.0.0/24 dev net3 proto kernel scope link src 30.5.0.1\n30.6.0.0/24  encap seg6 mode encap segs 1 [ 2:3:: ] dev net0 scope link\n\n[[R2-glb]]\n169.254.99.10 dev vrf1 scope link\n169.254.99.20 dev vrf2 scope link\n169.254.99.30 dev vrf3 scope link\n1:1:: via 2001::1 dev net0 metric 1024 pref medium\n1:2:: via 2001::1 dev net0 metric 1024 pref medium\n1:3:: via 2001::1 dev net0 metric 1024 pref medium\n2:1::  encap seg6local action End.DX4 nh4 169.254.99.10 dev net0 metric 1024 pref medium\n2:2::  encap seg6local action End.DX4 nh4 169.254.99.20 dev net0 metric 1024 pref medium\n2:3::  encap seg6local action End.DX4 nh4 169.254.99.30 dev net0 metric 1024 pref medium\n2001::/64 dev net0 proto kernel metric 256 pref medium\nfe80::/64 dev net0 proto kernel metric 256 pref medium\n\n[[R2-vrf1]]\n30.1.0.0/24  encap seg6 mode encap segs 1 [ 1:1:: ] dev net0 scope link\n30.2.0.0/24 dev net1 proto kernel scope link src 30.2.0.1\n\n[[R2-vrf2]]\n30.3.0.0/24  encap seg6 mode encap segs 1 [ 1:2:: ] dev net0 scope link\n30.4.0.0/24 dev net2 proto kernel scope link src 30.4.0.1\n\n[[R2-vrf3]]\n30.5.0.0/24  encap seg6 mode encap segs 1 [ 1:3:: ] dev net0 scope link\n30.6.0.0/24 dev net3 proto kernel scope link src 30.6.0.1\n```\n\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/frr.conf.srv6.R1",
    "content": "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 vpn rmap-event\ndebug bgp vpn adv-prefix-sid\n!\nint net0\n ipv6 address 2001::1/64\n!\nint net1 vrf vrf1\n ip address 30.1.0.1/24\n!\nint net2 vrf vrf2\n ip address 30.3.0.1/24\n!\nint net3 vrf vrf3\n ip address 30.5.0.1/24\n!\nrouter bgp 65001\n bgp router-id 10.255.0.1\n neighbor 2001::2 remote-as 65002\n !\n address-family ipv4 unicast\n  redistribute connected\n  redistribute static\n exit-address-family\n !\n address-family ipv4 srv6-vpn\n  neighbor 2001::2 activate\n exit-address-family\n!\nrouter bgp 65001 vrf vrf1\n bgp router-id 10.255.0.1\n !\n address-family ipv4 unicast\n  redistribute connected\n  sid srv6-vpn export 1:1::\n  rd srv6-vpn export 65001:1\n  rt srv6-vpn both 100:1\n  export srv6-vpn\n  import srv6-vpn\n exit-address-family\n!\nrouter bgp 65001 vrf vrf2\n bgp router-id 10.255.0.1\n !\n address-family ipv4 unicast\n  redistribute connected\n  sid srv6-vpn export 1:2::\n  rd srv6-vpn export 65001:2\n  rt srv6-vpn both 100:2\n  export srv6-vpn\n  import srv6-vpn\n exit-address-family\n!\nrouter bgp 65001 vrf vrf3\n bgp router-id 10.255.0.1\n !\n address-family ipv4 unicast\n  redistribute connected\n  sid srv6-vpn export 1:3::\n  rd srv6-vpn export 65001:3\n  rt srv6-vpn both 100:3\n  export srv6-vpn\n  import srv6-vpn\n exit-address-family\n!\nline vty\n!\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/frr.conf.srv6.R2",
    "content": "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 vpn rmap-event\ndebug bgp vpn adv-prefix-sid\n!\nint net0\n ipv6 address 2001::2/64\n!\nint net1 vrf vrf1\n ip address 30.2.0.1/24\n!\nint net2 vrf vrf2\n ip address 30.4.0.1/24\n!\nint net3 vrf vrf3\n ip address 30.6.0.1/24\n!\nrouter bgp 65002\n bgp router-id 10.255.0.2\n neighbor 2001::1 remote-as 65001\n !\n address-family ipv4 unicast\n  redistribute connected\n  redistribute static\n exit-address-family\n !\n address-family ipv4 srv6-vpn\n  neighbor 2001::1 activate\n exit-address-family\n!\nrouter bgp 65002 vrf vrf1\n bgp router-id 10.255.0.2\n !\n address-family ipv4 unicast\n  redistribute connected\n  sid srv6-vpn export 2:1::\n  rd srv6-vpn export 65002:1\n  rt srv6-vpn both 100:1\n  export srv6-vpn\n  import srv6-vpn\n exit-address-family\n!\nrouter bgp 65002 vrf vrf2\n bgp router-id 10.255.0.2\n !\n address-family ipv4 unicast\n  redistribute connected\n  sid srv6-vpn export 2:2::\n  rd srv6-vpn export 65002:2\n  rt srv6-vpn both 100:2\n  export srv6-vpn\n  import srv6-vpn\n exit-address-family\n!\nrouter bgp 65002 vrf vrf3\n bgp router-id 10.255.0.2\n !\n address-family ipv4 unicast\n  redistribute connected\n  sid srv6-vpn export 2:3::\n  rd srv6-vpn export 65002:3\n  rt srv6-vpn both 100:3\n  export srv6-vpn\n  import srv6-vpn\n exit-address-family\n!\nline vty\n!\n"
  },
  {
    "path": "examples/basic_bgp/vpnv4_srv6/spec.yaml",
    "content": "\nnodes:\n\n  - name: R1\n    image: slankdev/frr-7.3:slankdev-support-mpbgp-vpnv4-srv6-cplane\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C3#net0 }\n      - { name: net3, type: direct, args: C5#net0 }\n\n  - name: R2\n    image: slankdev/frr-7.3:slankdev-support-mpbgp-vpnv4-srv6-cplane\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n      - { name: net3, type: direct, args: C6#net0 }\n\n  - name: C1\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C3\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C4\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n  - name: C5\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R1#net3 } ]\n  - name: C6\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: R2#net3 } ]\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: touch /etc/frr/frr.conf\n\n      - cmd: ip link add vrf1 type vrf table 10\n      - cmd: ip link set vrf1 up\n      - cmd: ip link set net1 vrf vrf1\n      - cmd: ip route add 169.254.99.10 dev vrf1\n\n      - cmd: ip link add vrf2 type vrf table 20\n      - cmd: ip link set vrf2 up\n      - cmd: ip link set net2 vrf vrf2\n      - cmd: ip route add 169.254.99.20 dev vrf2\n\n      - cmd: ip link add vrf3 type vrf table 30\n      - cmd: ip link set vrf3 up\n      - cmd: ip link set net3 vrf vrf3\n      - cmd: ip route add 169.254.99.30 dev vrf3\n\n  - name: R2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: touch /etc/frr/frr.conf\n\n      - cmd: ip link add vrf1 type vrf table 10\n      - cmd: ip link set vrf1 up\n      - cmd: ip link set net1 vrf vrf1\n      - cmd: ip route add 169.254.99.10 dev vrf1\n\n      - cmd: ip link add vrf2 type vrf table 20\n      - cmd: ip link set vrf2 up\n      - cmd: ip link set net2 vrf vrf2\n      - cmd: ip route add 169.254.99.20 dev vrf2\n\n      - cmd: ip link add vrf3 type vrf table 30\n      - cmd: ip link set vrf3 up\n      - cmd: ip link set net3 vrf vrf3\n      - cmd: ip route add 169.254.99.30 dev vrf3\n\n  - name: C1\n    cmds:\n      - cmd: ip addr replace 30.1.0.2/24 dev net0\n      - cmd: ip route replace default via 30.1.0.1\n  - name: C2\n    cmds:\n      - cmd: ip addr replace 30.2.0.2/24 dev net0\n      - cmd: ip route replace default via 30.2.0.1\n  - name: C3\n    cmds:\n      - cmd: ip addr replace 30.3.0.2/24 dev net0\n      - cmd: ip route replace default via 30.3.0.1\n  - name: C4\n    cmds:\n      - cmd: ip addr replace 30.4.0.2/24 dev net0\n      - cmd: ip route replace default via 30.4.0.1\n  - name: C5\n    cmds:\n      - cmd: ip addr replace 30.5.0.2/24 dev net0\n      - cmd: ip route replace default via 30.5.0.1\n  - name: C6\n    cmds:\n      - cmd: ip addr replace 30.6.0.2/24 dev net0\n      - cmd: ip route replace default via 30.6.0.1\n\n"
  },
  {
    "path": "examples/basic_bgp/vpnv6_srv6_rs/spec.yaml",
    "content": "nodes:\n- name: RS1\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: S1#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\n- name: S1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: RS1#net0 }\n  - { name: net1, type: direct, args: R1#net0 }\n  - { name: net2, type: direct, args: R2#net0 }\n  - { name: net3, type: direct, args: R3#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\n- name: R1\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: S1#net1 }\n  - { name: net1, type: direct, args: C1#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n- name: R2\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: S1#net2 }\n  - { name: net1, type: direct, args: C2#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n- name: R3\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: S1#net3 }\n  - { name: net1, type: direct, args: C3#net0 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\n- name: C1\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n- name: C2\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n- name: C3\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n\nnode_configs:\n- name: RS1\n  cmds:\n  - cmd: ip addr add 10.255.0.1/32 dev lo\n  - cmd: ip addr add 2001:db8:e:1::0/128 dev lo\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 1\"\n      -c \" bgp router-id 1.1.1.1\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" !\"\n      -c \" neighbor PEER peer-group\"\n      -c \" neighbor PEER remote-as external\"\n      -c \" neighbor net0 interface peer-group PEER\"\n      -c \" !\"\n      -c \" neighbor PE peer-group\"\n      -c \" neighbor PE remote-as external\"\n      -c \" neighbor PE ebgp-multihop 255\"\n      -c \" bgp listen range 2001:db8:e::/48 peer-group PE\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  neighbor PEER activate\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 vpn\"\n      -c \"  neighbor PE activate\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: S1\n  cmds:\n  - cmd: ip addr add 10.255.0.100/32 dev lo\n  - cmd: /usr/lib/frr/frr start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"router bgp 100\"\n      -c \" bgp router-id 100.100.100.100\"\n      -c \" !\"\n      -c \" neighbor PEER peer-group\"\n      -c \" neighbor PEER remote-as external\"\n      -c \" neighbor net0 interface peer-group PEER\"\n      -c \" neighbor net1 interface peer-group PEER\"\n      -c \" neighbor net2 interface peer-group PEER\"\n      -c \" neighbor net3 interface peer-group PEER\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  neighbor PEER activate\"\n      -c \"  network 0::/0\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.255.0.11/32 dev lo\n  - cmd: ip addr add 2001:db8:e:11::0/128 dev lo\n  - cmd: ip link add vrf1 type vrf table 1001\n  - cmd: ip link set vrf1 up\n  - cmd: ip link set net1 master vrf1\n  - cmd: ip -6 addr add 2001:11::1/64 dev net1\n  - cmd: ip sr tunsrc set 2001:db8:f:1::0\n  - cmd: ip -6 rule add to 2001:db8::/32 pref 1 table main\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"segment-routing\"\n      -c \" srv6\"\n      -c \"  locators\"\n      -c \"   locator default\"\n      -c \"     prefix 2001:db8:f:1::/64\"\n      -c \"   !\"\n      -c \"  !\"\n      -c \" !\"\n      -c \"!\"\n      -c \"ipv6 route 2001:db8:f:1::/64 Null0\"\n      -c \"!\"\n      -c \"router bgp 11\"\n      -c \" bgp router-id 11.11.11.11\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" !\"\n      -c \" neighbor PEER peer-group\"\n      -c \" neighbor PEER remote-as external\"\n      -c \" neighbor net0 interface peer-group PEER\"\n      -c \" !\"\n      -c \" neighbor PE peer-group\"\n      -c \" neighbor PE remote-as external\"\n      -c \" neighbor PE ebgp-multihop 255\"\n      -c \" neighbor 2001:db8:e:1:: peer-group PE\"\n      -c \" !\"\n      -c \" segment-routing srv6\"\n      -c \"  locator default\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  network 2001:db8:f:1::/64\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 vpn\"\n      -c \"  neighbor PE activate\"\n      -c \" exit-address-family\"\n      -c \"!\"\n      -c \"router bgp 11 vrf vrf1\"\n      -c \" bgp router-id 11.11.11.11\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" neighbor 2001:11::2 remote-as external\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  neighbor 2001:11::2 activate\"\n      -c \"  sid vpn export auto\"\n      -c \"  rd vpn export 11:1001\"\n      -c \"  rt vpn export 1:1001\"\n      -c \"  rt vpn import 1:1001\"\n      -c \"  import vpn\"\n      -c \"  export vpn\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.255.0.12/32 dev lo\n  - cmd: ip addr add 2001:db8:e:12::0/128 dev lo\n  - cmd: ip link add vrf1 type vrf table 1001\n  - cmd: ip link set vrf1 up\n  - cmd: ip link set net1 master vrf1\n  - cmd: ip -6 addr add 2001:12::1/64 dev net1\n  - cmd: ip sr tunsrc set 2001:db8:f:2::0\n  - cmd: ip -6 rule add to 2001:db8::/32 pref 1 table main\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"segment-routing\"\n      -c \" srv6\"\n      -c \"  locators\"\n      -c \"   locator default\"\n      -c \"     prefix 2001:db8:f:2::/64\"\n      -c \"   !\"\n      -c \"  !\"\n      -c \" !\"\n      -c \"!\"\n      -c \"ipv6 route 2001:db8:f:2::/64 Null0\"\n      -c \"!\"\n      -c \"router bgp 12\"\n      -c \" bgp router-id 12.12.12.12\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" !\"\n      -c \" neighbor PEER peer-group\"\n      -c \" neighbor PEER remote-as external\"\n      -c \" neighbor net0 interface peer-group PEER\"\n      -c \" !\"\n      -c \" neighbor PE peer-group\"\n      -c \" neighbor PE remote-as external\"\n      -c \" neighbor PE ebgp-multihop 255\"\n      -c \" neighbor 2001:db8:e:1:: peer-group PE\"\n      -c \" !\"\n      -c \" segment-routing srv6\"\n      -c \"  locator default\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  network 2001:db8:f:2::/64\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 vpn\"\n      -c \"  neighbor PE activate\"\n      -c \" exit-address-family\"\n      -c \"!\"\n      -c \"router bgp 12 vrf vrf1\"\n      -c \" bgp router-id 12.12.12.12\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" neighbor 2001:12::2 remote-as external\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  neighbor 2001:12::2 activate\"\n      -c \"  sid vpn export auto\"\n      -c \"  rd vpn export 12:1001\"\n      -c \"  rt vpn export 1:1001\"\n      -c \"  rt vpn import 1:1001\"\n      -c \"  import vpn\"\n      -c \"  export vpn\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.255.0.13/32 dev lo\n  - cmd: ip addr add 2001:db8:e:13::0/128 dev lo\n  - cmd: ip link add vrf1 type vrf table 1001\n  - cmd: ip link set vrf1 up\n  - cmd: ip link set net1 master vrf1\n  - cmd: ip -6 addr add 2001:13::1/64 dev net1\n  - cmd: ip sr tunsrc set 2001:db8:f:3::0\n  - cmd: ip -6 rule add to 2001:db8::/32 pref 1 table main\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"segment-routing\"\n      -c \" srv6\"\n      -c \"  locators\"\n      -c \"   locator default\"\n      -c \"     prefix 2001:db8:f:3::/64\"\n      -c \"   !\"\n      -c \"  !\"\n      -c \" !\"\n      -c \"!\"\n      -c \"ipv6 route 2001:db8:f:3::/64 Null0\"\n      -c \"!\"\n      -c \"router bgp 13\"\n      -c \" bgp router-id 13.13.13.13\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" !\"\n      -c \" neighbor PEER peer-group\"\n      -c \" neighbor PEER remote-as external\"\n      -c \" neighbor net0 interface peer-group PEER\"\n      -c \" !\"\n      -c \" neighbor PE peer-group\"\n      -c \" neighbor PE remote-as external\"\n      -c \" neighbor PE ebgp-multihop 255\"\n      -c \" neighbor 2001:db8:e:1:: peer-group PE\"\n      -c \" !\"\n      -c \" segment-routing srv6\"\n      -c \"  locator default\"\n      -c \" !\"\n      -c \" address-family ipv4 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  redistribute connected\"\n      -c \"  network 2001:db8:f:3::/64\"\n      -c \"  neighbor PEER activate\"\n      -c \" exit-address-family\"\n      -c \" !\"\n      -c \" address-family ipv6 vpn\"\n      -c \"  neighbor PE activate\"\n      -c \" exit-address-family\"\n      -c \"!\"\n      -c \"router bgp 13 vrf vrf1\"\n      -c \" bgp router-id 13.13.13.13\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  sid vpn export auto\"\n      -c \"  rd vpn export 13:1001\"\n      -c \"  rt vpn export 1:1001\"\n      -c \"  rt vpn import 1:1001\"\n      -c \"  import vpn\"\n      -c \"  export vpn\"\n      -c \"  redistribute connected\"\n      -c \" exit-address-family\"\n      -c \"!\"\n\n- name: C1\n  cmds:\n  - cmd: ip -6 addr add 2001:11::2/64 dev net0\n  - cmd: ip -6 route replace default via 2001:11::1\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"ipv6 route 0::/0 Null0\"\n      -c \"!\"\n      -c \"router bgp 101\"\n      -c \" bgp router-id 101.101.101.101\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" neighbor 2001:11::1 remote-as external\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  neighbor 2001:11::1 activate\"\n      -c \"  network 0::/0\"\n      -c \" exit-address-family\"\n- name: C2\n  cmds:\n  - cmd: ip -6 addr add 2001:12::2/64 dev net0\n  - cmd: ip -6 route replace default via 2001:12::1\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c \"conf t\"\n      -c \"ipv6 route 0::/0 Null0\"\n      -c \"!\"\n      -c \"router bgp 102\"\n      -c \" bgp router-id 102.102.102.102\"\n      -c \" no bgp ebgp-requires-policy\"\n      -c \" neighbor 2001:12::1 remote-as external\"\n      -c \" !\"\n      -c \" address-family ipv6 unicast\"\n      -c \"  neighbor 2001:12::1 activate\"\n      -c \"  network 0::/0\"\n      -c \" exit-address-family\"\n- name: C3\n  cmds:\n  - cmd: ip -6 addr add 2001:13::2/64 dev net0\n  - cmd: ip -6 route replace default via 2001:13::1\n  - cmd: /usr/lib/frr/frrinit.sh start\n"
  },
  {
    "path": "examples/basic_bgp/vrf2vrf_rouet_leak/Makefile",
    "content": "\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 blu\n\t@echo\n\tdocker exec R1 ip route list vrf grn\n"
  },
  {
    "path": "examples/basic_bgp/vrf2vrf_rouet_leak/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr-dev:latest\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/frr-dev:latest\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link add grn type vrf table 30\n      - cmd: ip link set red up\n      - cmd: ip link set blu up\n      - cmd: ip link set grn up\n      - cmd: ip link set net0 vrf red\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int net0' -c 'ip addr 10.0.0.1/24' -c 'exit'\n          -c 'router bgp 1 vrf red'\n          -c ' bgp router-id 1.1.1.1'\n          -c ' address-family ipv4 unicast'\n          -c '  redistribute connected'\n          -c ' exit-address-family'\n          -c 'router bgp 2 vrf blu'\n          -c ' bgp router-id 2.2.2.2'\n          -c ' address-family ipv4 unicast'\n          -c '  import vrf red'\n          -c ' exit-address-family'\n          -c 'router bgp 3 vrf grn'\n          -c ' bgp router-id 3.3.3.3'\n          -c ' address-family ipv4 unicast'\n          -c '  import vrf blu'\n          -c ' exit-address-family'\n\n"
  },
  {
    "path": "examples/basic_bond/spec.yaml",
    "content": "\nprecmd:\n  - cmds:\n      - cmd: export IMAGE=slankdev/frr\n      - cmd: export IMAGE=slankdev/gobgp\n      - cmd: export IMAGE=slankdev/ubuntu:18.04\n\nnodes:\n  - name: R1\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R2#net1 }\n  - name: R2\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R1#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip link add bond0 type bond miimon 100 mode active-backup\n      - cmd: ip link set bond0 up\n      - cmd: ip link set net0 down\n      - cmd: ip link set net1 down\n      - cmd: ip link set net0 master bond0\n      - cmd: ip link set net1 master bond0\n      - cmd: ip addr add 10.0.0.1/24 dev bond0\n  - name: R2\n    cmds:\n      - cmd: ip link add bond0 type bond miimon 100 mode active-backup\n      - cmd: ip link set bond0 up\n      - cmd: ip link set net0 down\n      - cmd: ip link set net1 down\n      - cmd: ip link set net0 master bond0\n      - cmd: ip link set net1 master bond0\n      - cmd: ip addr add 10.0.0.2/24 dev bond0\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: echo slankdev slankdev\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_bufferbloat/README.md",
    "content": "# Bufferbloat demonstration\n\nSimple demonstration of the [bufferbloat](https://www.bufferbloat.net/projects/) problem.\n\n![](./topo.png)\n"
  },
  {
    "path": "examples/basic_bufferbloat/spec.yaml",
    "content": "nodes:\n- name: R1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n  - { name: net2, type: direct, args: C2#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C3#net0 }\n  - { name: net2, type: direct, args: C4#net0 }\n- name: C1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: C3\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n- name: C4\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net1\n  - cmd: ip addr add 10.0.1.1/24 dev net2\n  - cmd: ip addr add 10.0.2.1/24 dev net0\n  - cmd: ip route add default via 10.0.2.2\n  - cmd: tc qdisc add dev net0 root netem rate 500mbit\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.0.2.2/24 dev net0\n  - cmd: ip addr add 10.0.3.1/24 dev net1\n  - cmd: ip addr add 10.0.4.1/24 dev net2\n  - cmd: ip route add default via 10.0.2.1\n  - cmd: tc qdisc add dev net0 root netem rate 500mbit\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.0.1.2/24 dev net0\n  - cmd: ip route add default via 10.0.1.1\n- name: C3\n  cmds:\n  - cmd: ip addr add 10.0.3.2/24 dev net0\n  - cmd: ip route add default via 10.0.3.1\n- name: C4\n  cmds:\n  - cmd: ip addr add 10.0.4.2/24 dev net0\n  - cmd: ip route add default via 10.0.4.1\ntest:\n  - cmds:\n    - cmd: echo \"==========================================\"\n    - cmd: echo \"iperf from C1 to C3\"\n    - cmd: echo \"==========================================\"\n    - cmd: docker exec C3 iperf -s -i 1 &\n    - cmd: sleep 3\n    - cmd: docker exec C1 iperf -c 10.0.3.2 2>&1 > /dev/null\n    - cmd: docker exec C3 pkill iperf\n    - cmd: echo \"==========================================\"\n    - cmd: echo \"ping from C2 to C4\"\n    - cmd: echo \"==========================================\"\n    - cmd: docker exec C2 ping -c 10 10.0.4.2\n    - cmd: echo \"==========================================\"\n    - cmd: echo \"ping from C2 to C4 while iperf-ing from C1 to C3\"\n    - cmd: echo \"==========================================\"\n    - cmd: docker exec C3 iperf -s 2>&1 > /dev/null &\n    - cmd: sleep 3\n    - cmd: docker exec C1 iperf -c 10.0.3.2 -t 60 2>&1 > /dev/null &\n    - cmd: sleep 3\n    - cmd: docker exec C2 ping -c 10 10.0.4.2\n    - cmd: docker exec C1 pkill iperf\n    - cmd: sleep 3\n    - cmd: docker exec C3 pkill iperf\n"
  },
  {
    "path": "examples/basic_clos/README.md",
    "content": "\n# CLOS Topology\n\nPractice of designing DCN. Following are principle of Design.\n- using modernaized technology (such as BGP-unnumbered.)\n\nVersion\n- 0.0.0: basic CLOS-network ([yaml](./spec.v0.0.0.yaml))\n- 0.0.1: using BGP-unnumbered ([yaml](./spec.v0.0.1.yaml))\n- 0.0.2: using ECMP anycast ([yaml](./spec.v0.0.2.yaml))\n- 0.0.3: add VM and ToR nodes ([yaml](./spec.v0.0.3.yaml))\n- 0.0.4: support multi-tenancy ([yaml](./spec.v0.0.4.yaml)) (**currentry version**)\n- 0.0.5: support SRv6 network slicing ([yaml](./spec.v0.0.5.yaml))\n\n**version v0.0.3**\n![](./topo.v0.0.3.png)\n\n**version v0.0.2**\n![](./topo.v0.0.2.png)\n\n**version v0.0.1**\n![](./topo.v0.0.1.png)\n\n**version v0.0.0**\n![](./topo.v0.0.0.png)\n\nreferences\n- LINE-SRv6-DCN ENOG55 http://enog.jp/wp-content/uploads/2018/12/05_20190222_ENOG55_LINE.pdf\n- Large Scale DC Network Design https://www.slideshare.net/MasayukiKobayashi/dc-66865243\n- Good TiNET examples by MIYA-kun https://github.com/mi2428/netben\n- LINE DCN Overview by Kobayashi-san 2018.10 https://www.slideshare.net/linecorp/ss-116867631\n- 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\n- OpenStack Summit Vancouver 2018 Recap LINE-verda https://engineering.linecorp.com/ja/blog/openstack-summit-vancouver-2018-recap-2-2\n\noperation performance\n```\nv0.0.3 sh -c 'tn up | sudo sh'\nreal    0m29.151s\nuser    0m6.945s\nsys     0m4.472s\n\nv0.0.3 sh -c 'tn conf | sudo sh' frr-all\nreal    1m25.104s\nuser    0m6.110s\nsys     0m4.263s\n\nv0.0.3 sh -c 'tn conf | sudo sh' frr-zebra,bgpd\nreal    1m13.867s\nuser    0m6.239s\nsys     0m4.143s\n```\n"
  },
  {
    "path": "examples/basic_clos/spec.v0.0.0.yaml",
    "content": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0 }\n      - { name: net1, type: direct, args: Spine1#up1 }\n      - { name: net2, type: direct, args: Spine2#up1 }\n  - name: Spine1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#net1 }\n      - { name: dn1, type: direct, args: Leaf1#up1 }\n      - { name: dn2, type: direct, args: Leaf2#up1 }\n      - { name: dn3, type: direct, args: Leaf3#up1 }\n      - { name: dn4, type: direct, args: Leaf4#up1 }\n  - name: Spine2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#net2 }\n      - { name: dn1, type: direct, args: Leaf1#up2 }\n      - { name: dn2, type: direct, args: Leaf2#up2 }\n      - { name: dn3, type: direct, args: Leaf3#up2 }\n      - { name: dn4, type: direct, args: Leaf4#up2 }\n  - name: Leaf1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn1 }\n      - { name: up2, type: direct, args: Spine2#dn1 }\n      - { name: dn1, type: direct, args: Serv1#net0 }\n      - { name: dn2, type: direct, args: Serv2#net0 }\n  - name: Leaf2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn2 }\n      - { name: up2, type: direct, args: Spine2#dn2 }\n      - { name: dn1, type: direct, args: Serv3#net0 }\n      - { name: dn2, type: direct, args: Serv4#net0 }\n  - name: Leaf3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn3 }\n      - { name: up2, type: direct, args: Spine2#dn3 }\n      - { name: dn1, type: direct, args: Serv5#net0 }\n      - { name: dn2, type: direct, args: Serv6#net0 }\n  - name: Leaf4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn4 }\n      - { name: up2, type: direct, args: Spine2#dn4 }\n      - { name: dn1, type: direct, args: Serv7#net0 }\n      - { name: dn2, type: direct, args: Serv8#net0 }\n  - name: Serv1\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf1#dn1 } ]\n  - name: Serv2\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf1#dn2 } ]\n  - name: Serv3\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf2#dn1 } ]\n  - name: Serv4\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf2#dn2 } ]\n  - name: Serv5\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf3#dn1 } ]\n  - name: Serv6\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf3#dn2 } ]\n  - name: Serv7\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf4#dn1 } ]\n  - name: Serv8\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf4#dn2 } ]\n\nnode_configs:\n  - name: Ext1\n    cmds:\n      - cmd: echo slankdev slankdev\n  - name: Spine1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.1/32\"\n          -c \"int dn1\" -c \"ip addr 10.0.0.1/30\"\n          -c \"int dn2\" -c \"ip addr 10.0.0.5/30\"\n          -c \"int dn3\" -c \"ip addr 10.0.0.9/30\"\n          -c \"int dn4\" -c \"ip addr 10.0.0.13/30\"\n          -c \"router bgp 65001\"\n          -c \" bgp router-id 10.255.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 10.0.0.2 remote-as 65011\"\n          -c \" neighbor 10.0.0.6 remote-as 65012\"\n          -c \" neighbor 10.0.0.10 remote-as 65013\"\n          -c \" neighbor 10.0.0.14 remote-as 65014\"\n  - name: Spine2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.2/32\"\n          -c \"int dn1\" -c \"ip addr 10.0.0.17/30\"\n          -c \"int dn2\" -c \"ip addr 10.0.0.21/30\"\n          -c \"int dn3\" -c \"ip addr 10.0.0.25/30\"\n          -c \"int dn4\" -c \"ip addr 10.0.0.29/30\"\n          -c \"router bgp 65002\"\n          -c \" bgp router-id 10.255.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 10.0.0.18 remote-as 65011\"\n          -c \" neighbor 10.0.0.22 remote-as 65012\"\n          -c \" neighbor 10.0.0.26 remote-as 65013\"\n          -c \" neighbor 10.0.0.30 remote-as 65014\"\n  - name: Leaf1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.11/32\"\n          -c \"int up1\" -c \"ip addr 10.0.0.2/30\"\n          -c \"int up2\" -c \"ip addr 10.0.0.18/30\"\n          -c \"int dn1\" -c \"ip addr 20.0.0.1/30\"\n          -c \"int dn2\" -c \"ip addr 20.0.0.5/30\"\n          -c \"router bgp 65011\"\n          -c \" bgp router-id 10.255.0.11\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 10.0.0.1 remote-as 65001\"\n          -c \" neighbor 10.0.0.17 remote-as 65002\"\n          -c \" neighbor 20.0.0.2 remote-as 65021\"\n          -c \" neighbor 20.0.0.6 remote-as 65022\"\n  - name: Leaf2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.12/32\"\n          -c \"int up1\" -c \"ip addr 10.0.0.6/30\"\n          -c \"int up2\" -c \"ip addr 10.0.0.22/30\"\n          -c \"int dn1\" -c \"ip addr 20.0.0.9/30\"\n          -c \"int dn2\" -c \"ip addr 20.0.0.13/30\"\n          -c \"router bgp 65012\"\n          -c \" bgp router-id 10.255.0.12\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 10.0.0.5 remote-as 65001\"\n          -c \" neighbor 10.0.0.21 remote-as 65002\"\n          -c \" neighbor 20.0.0.10 remote-as 65023\"\n          -c \" neighbor 20.0.0.14 remote-as 65024\"\n  - name: Leaf3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.13/32\"\n          -c \"int up1\" -c \"ip addr 10.0.0.10/30\"\n          -c \"int up2\" -c \"ip addr 10.0.0.26/30\"\n          -c \"int dn1\" -c \"ip addr 20.0.0.17/30\"\n          -c \"int dn2\" -c \"ip addr 20.0.0.21/30\"\n          -c \"router bgp 65013\"\n          -c \" bgp router-id 10.255.0.13\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 10.0.0.9 remote-as 65001\"\n          -c \" neighbor 10.0.0.25 remote-as 65002\"\n          -c \" neighbor 20.0.0.18 remote-as 65025\"\n          -c \" neighbor 20.0.0.22 remote-as 65026\"\n  - name: Leaf4\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.14/32\"\n          -c \"int up1\" -c \"ip addr 10.0.0.14/30\"\n          -c \"int up2\" -c \"ip addr 10.0.0.30/30\"\n          -c \"int dn1\" -c \"ip addr 20.0.0.25/30\"\n          -c \"int dn2\" -c \"ip addr 20.0.0.29/30\"\n          -c \"router bgp 65014\"\n          -c \" bgp router-id 10.255.0.14\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 10.0.0.13 remote-as 65001\"\n          -c \" neighbor 10.0.0.29 remote-as 65002\"\n          -c \" neighbor 20.0.0.26 remote-as 65027\"\n          -c \" neighbor 20.0.0.30 remote-as 65028\"\n  - name: Serv1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.21/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.2/30\"\n          -c \"router bgp 65021\"\n          -c \" bgp router-id 10.255.0.21\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.1 remote-as external\"\n          -c \" network 20.0.0.2/30\"\n  - name: Serv2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.22/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.6/30\"\n          -c \"router bgp 65022\"\n          -c \" bgp router-id 10.255.0.22\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.5 remote-as external\"\n          -c \" network 20.0.0.6/30\"\n  - name: Serv3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.23/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.10/30\"\n          -c \"router bgp 65023\"\n          -c \" bgp router-id 10.255.0.23\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.9 remote-as external\"\n          -c \" network 20.0.0.10/30\"\n  - name: Serv4\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.24/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.14/30\"\n          -c \"router bgp 65024\"\n          -c \" bgp router-id 10.255.0.24\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.13 remote-as external\"\n          -c \" network 20.0.0.14/30\"\n  - name: Serv5\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.25/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.18/30\"\n          -c \"router bgp 65025\"\n          -c \" bgp router-id 10.255.0.25\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.17 remote-as external\"\n          -c \" network 20.0.0.18/30\"\n  - name: Serv6\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.26/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.22/30\"\n          -c \"router bgp 65026\"\n          -c \" bgp router-id 10.255.0.26\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.21 remote-as external\"\n          -c \" network 20.0.0.22/30\"\n  - name: Serv7\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.27/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.26/30\"\n          -c \"router bgp 65027\"\n          -c \" bgp router-id 10.255.0.27\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.25 remote-as external\"\n          -c \" network 20.0.0.26/30\"\n  - name: Serv8\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.28/32\"\n          -c \"int net0\" -c \"ip addr 20.0.0.30/30\"\n          -c \"router bgp 65028\"\n          -c \" bgp router-id 10.255.0.28\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor 20.0.0.29 remote-as external\"\n          -c \" network 20.0.0.30/30\"\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec Ext1 echo slank\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_clos/spec.v0.0.1.yaml",
    "content": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0 }\n      - { name: net1, type: direct, args: Spine1#up1 }\n      - { name: net2, type: direct, args: Spine2#up1 }\n  - name: Spine1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#net1 }\n      - { name: dn1, type: direct, args: Leaf1#up1 }\n      - { name: dn2, type: direct, args: Leaf2#up1 }\n      - { name: dn3, type: direct, args: Leaf3#up1 }\n      - { name: dn4, type: direct, args: Leaf4#up1 }\n  - name: Spine2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#net2 }\n      - { name: dn1, type: direct, args: Leaf1#up2 }\n      - { name: dn2, type: direct, args: Leaf2#up2 }\n      - { name: dn3, type: direct, args: Leaf3#up2 }\n      - { name: dn4, type: direct, args: Leaf4#up2 }\n  - name: Leaf1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn1 }\n      - { name: up2, type: direct, args: Spine2#dn1 }\n      - { name: dn1, type: direct, args: Serv1#net0 }\n      - { name: dn2, type: direct, args: Serv2#net0 }\n  - name: Leaf2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn2 }\n      - { name: up2, type: direct, args: Spine2#dn2 }\n      - { name: dn1, type: direct, args: Serv3#net0 }\n      - { name: dn2, type: direct, args: Serv4#net0 }\n  - name: Leaf3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn3 }\n      - { name: up2, type: direct, args: Spine2#dn3 }\n      - { name: dn1, type: direct, args: Serv5#net0 }\n      - { name: dn2, type: direct, args: Serv6#net0 }\n  - name: Leaf4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn4 }\n      - { name: up2, type: direct, args: Spine2#dn4 }\n      - { name: dn1, type: direct, args: Serv7#net0 }\n      - { name: dn2, type: direct, args: Serv8#net0 }\n  - name: Serv1\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf1#dn1 } ]\n  - name: Serv2\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf1#dn2 } ]\n  - name: Serv3\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf2#dn1 } ]\n  - name: Serv4\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf2#dn2 } ]\n  - name: Serv5\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf3#dn1 } ]\n  - name: Serv6\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf3#dn2 } ]\n  - name: Serv7\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf4#dn1 } ]\n  - name: Serv8\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf4#dn2 } ]\n\nnode_configs:\n  - name: Ext1\n    cmds:\n      - cmd: echo slankdev slankdev\n  - name: Spine1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.1/32\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65001\"\n          -c \" bgp router-id 10.255.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Spine2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.2/32\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65002\"\n          -c \" bgp router-id 10.255.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.11/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65011\"\n          -c \" bgp router-id 10.255.0.11\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.12/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65012\"\n          -c \" bgp router-id 10.255.0.12\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.13/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65013\"\n          -c \" bgp router-id 10.255.0.13\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.14/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65014\"\n          -c \" bgp router-id 10.255.0.14\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.21/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65021\"\n          -c \" bgp router-id 10.255.0.21\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.22/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65022\"\n          -c \" bgp router-id 10.255.0.22\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.23/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65023\"\n          -c \" bgp router-id 10.255.0.23\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 3.3.3.3/32\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.24/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65024\"\n          -c \" bgp router-id 10.255.0.24\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 4.4.4.4/32\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv5\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.25/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65025\"\n          -c \" bgp router-id 10.255.0.25\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 5.5.5.5/32\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv6\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.26/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65026\"\n          -c \" bgp router-id 10.255.0.26\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 6.6.6.6/32\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv7\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.27/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65027\"\n          -c \" bgp router-id 10.255.0.27\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 7.7.7.7/32\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv8\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.28/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65028\"\n          -c \" bgp router-id 10.255.0.28\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 8.8.8.8/32\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec Ext1 echo slank\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_clos/spec.v0.0.2.yaml",
    "content": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0 }\n      - { name: dn1, type: direct, args: Spine1#up1 }\n      - { name: dn2, type: direct, args: Spine2#up1 }\n  - name: Spine1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#dn1 }\n      - { name: dn1, type: direct, args: Leaf1#up1 }\n      - { name: dn2, type: direct, args: Leaf2#up1 }\n      - { name: dn3, type: direct, args: Leaf3#up1 }\n      - { name: dn4, type: direct, args: Leaf4#up1 }\n  - name: Spine2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#dn2 }\n      - { name: dn1, type: direct, args: Leaf1#up2 }\n      - { name: dn2, type: direct, args: Leaf2#up2 }\n      - { name: dn3, type: direct, args: Leaf3#up2 }\n      - { name: dn4, type: direct, args: Leaf4#up2 }\n  - name: Leaf1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn1 }\n      - { name: up2, type: direct, args: Spine2#dn1 }\n      - { name: dn1, type: direct, args: Serv1a#net0 }\n      - { name: dn2, type: direct, args: Serv2a#net0 }\n  - name: Leaf2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn2 }\n      - { name: up2, type: direct, args: Spine2#dn2 }\n      - { name: dn1, type: direct, args: Serv3a#net0 }\n      - { name: dn2, type: direct, args: Serv4a#net0 }\n  - name: Leaf3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn3 }\n      - { name: up2, type: direct, args: Spine2#dn3 }\n      - { name: dn1, type: direct, args: Serv1b#net0 }\n      - { name: dn2, type: direct, args: Serv2b#net0 }\n  - name: Leaf4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn4 }\n      - { name: up2, type: direct, args: Spine2#dn4 }\n      - { name: dn1, type: direct, args: Serv3b#net0 }\n      - { name: dn2, type: direct, args: Serv4b#net0 }\n  - name: Serv1a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf1#dn1 } ]\n  - name: Serv2a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf1#dn2 } ]\n  - name: Serv3a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf2#dn1 } ]\n  - name: Serv4a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf2#dn2 } ]\n  - name: Serv1b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf3#dn1 } ]\n  - name: Serv2b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf3#dn2 } ]\n  - name: Serv3b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf4#dn1 } ]\n  - name: Serv4b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Leaf4#dn2 } ]\n\nnode_configs:\n  - name: Ext1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.254/32\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65999\"\n          -c \" bgp router-id 10.255.0.254\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Spine1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.1/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65001\"\n          -c \" bgp router-id 10.255.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Spine2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.2/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65002\"\n          -c \" bgp router-id 10.255.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.11/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65011\"\n          -c \" bgp router-id 10.255.0.11\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.12/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65012\"\n          -c \" bgp router-id 10.255.0.12\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf3\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.13/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65013\"\n          -c \" bgp router-id 10.255.0.13\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Leaf4\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.14/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65014\"\n          -c \" bgp router-id 10.255.0.14\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv1a\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.21/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65021\"\n          -c \" bgp router-id 10.255.0.21\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv2a\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.22/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65022\"\n          -c \" bgp router-id 10.255.0.22\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv3a\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.23/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65023\"\n          -c \" bgp router-id 10.255.0.23\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv4a\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.24/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65024\"\n          -c \" bgp router-id 10.255.0.24\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv1b\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.21/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65021\"\n          -c \" bgp router-id 10.255.0.21\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv2b\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.22/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65022\"\n          -c \" bgp router-id 10.255.0.22\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv3b\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.23/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65023\"\n          -c \" bgp router-id 10.255.0.23\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n  - name: Serv4b\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.24/32\"\n          -c \"int net0\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65024\"\n          -c \" bgp router-id 10.255.0.24\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec Ext1 echo slank\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_clos/spec.v0.0.3.yaml",
    "content": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0 }\n      - { name: dn1, type: direct, args: Spine1#up1 }\n      - { name: dn2, type: direct, args: Spine2#up1 }\n  - name: Spine1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#dn1 }\n      - { name: dn1, type: direct, args: Leaf1#up1 }\n      - { name: dn2, type: direct, args: Leaf2#up1 }\n      - { name: dn3, type: direct, args: Leaf3#up1 }\n      - { name: dn4, type: direct, args: Leaf4#up1 }\n  - name: Spine2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#dn2 }\n      - { name: dn1, type: direct, args: Leaf1#up2 }\n      - { name: dn2, type: direct, args: Leaf2#up2 }\n      - { name: dn3, type: direct, args: Leaf3#up2 }\n      - { name: dn4, type: direct, args: Leaf4#up2 }\n  - name: Leaf1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn1 }\n      - { name: up2, type: direct, args: Spine2#dn1 }\n      - { name: dn1, type: direct, args: Tor1#up1 }\n      - { name: dn2, type: direct, args: Tor2#up1 }\n      - { name: dn3, type: direct, args: Tor3#up1 }\n      - { name: dn4, type: direct, args: Tor4#up1 }\n      - { name: dn5, type: direct, args: Tor5#up1 }\n      - { name: dn6, type: direct, args: Tor6#up1 }\n      - { name: dn7, type: direct, args: Tor7#up1 }\n      - { name: dn8, type: direct, args: Tor8#up1 }\n  - name: Leaf2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn2 }\n      - { name: up2, type: direct, args: Spine2#dn2 }\n      - { name: dn1, type: direct, args: Tor1#up2 }\n      - { name: dn2, type: direct, args: Tor2#up2 }\n      - { name: dn3, type: direct, args: Tor3#up2 }\n      - { name: dn4, type: direct, args: Tor4#up2 }\n      - { name: dn5, type: direct, args: Tor5#up2 }\n      - { name: dn6, type: direct, args: Tor6#up2 }\n      - { name: dn7, type: direct, args: Tor7#up2 }\n      - { name: dn8, type: direct, args: Tor8#up2 }\n  - name: Leaf3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn3 }\n      - { name: up2, type: direct, args: Spine2#dn3 }\n      - { name: dn1, type: direct, args: Tor1#up3 }\n      - { name: dn2, type: direct, args: Tor2#up3 }\n      - { name: dn3, type: direct, args: Tor3#up3 }\n      - { name: dn4, type: direct, args: Tor4#up3 }\n      - { name: dn5, type: direct, args: Tor5#up3 }\n      - { name: dn6, type: direct, args: Tor6#up3 }\n      - { name: dn7, type: direct, args: Tor7#up3 }\n      - { name: dn8, type: direct, args: Tor8#up3 }\n  - name: Leaf4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn4 }\n      - { name: up2, type: direct, args: Spine2#dn4 }\n      - { name: dn1, type: direct, args: Tor1#up4 }\n      - { name: dn2, type: direct, args: Tor2#up4 }\n      - { name: dn3, type: direct, args: Tor3#up4 }\n      - { name: dn4, type: direct, args: Tor4#up4 }\n      - { name: dn5, type: direct, args: Tor5#up4 }\n      - { name: dn6, type: direct, args: Tor6#up4 }\n      - { name: dn7, type: direct, args: Tor7#up4 }\n      - { name: dn8, type: direct, args: Tor8#up4 }\n\n  - name: Tor1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn1 }\n      - { name: up2, type: direct, args: Leaf2#dn1 }\n      - { name: up3, type: direct, args: Leaf3#dn1 }\n      - { name: up4, type: direct, args: Leaf4#dn1 }\n      - { name: dn1, type: direct, args: Serv1#up1 }\n      - { name: dn2, type: direct, args: Serv2#up1 }\n      - { name: dn3, type: direct, args: Serv3#up1 }\n      - { name: dn4, type: direct, args: Serv4#up1 }\n  - name: Tor2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn2 }\n      - { name: up2, type: direct, args: Leaf2#dn2 }\n      - { name: up3, type: direct, args: Leaf3#dn2 }\n      - { name: up4, type: direct, args: Leaf4#dn2 }\n      - { name: dn1, type: direct, args: Serv1#up2 }\n      - { name: dn2, type: direct, args: Serv2#up2 }\n      - { name: dn3, type: direct, args: Serv3#up2 }\n      - { name: dn4, type: direct, args: Serv4#up2 }\n  - name: Tor3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn3 }\n      - { name: up2, type: direct, args: Leaf2#dn3 }\n      - { name: up3, type: direct, args: Leaf3#dn3 }\n      - { name: up4, type: direct, args: Leaf4#dn3 }\n      - { name: dn1, type: direct, args: Serv5#up1 }\n      - { name: dn2, type: direct, args: Serv6#up1 }\n      - { name: dn3, type: direct, args: Serv7#up1 }\n      - { name: dn4, type: direct, args: Serv8#up1 }\n  - name: Tor4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn4 }\n      - { name: up2, type: direct, args: Leaf2#dn4 }\n      - { name: up3, type: direct, args: Leaf3#dn4 }\n      - { name: up4, type: direct, args: Leaf4#dn4 }\n      - { name: dn1, type: direct, args: Serv5#up2 }\n      - { name: dn2, type: direct, args: Serv6#up2 }\n      - { name: dn3, type: direct, args: Serv7#up2 }\n      - { name: dn4, type: direct, args: Serv8#up2 }\n  - name: Tor5\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn5 }\n      - { name: up2, type: direct, args: Leaf2#dn5 }\n      - { name: up3, type: direct, args: Leaf3#dn5 }\n      - { name: up4, type: direct, args: Leaf4#dn5 }\n      - { name: dn1, type: direct, args: Serv9#up1 }\n      - { name: dn2, type: direct, args: Serv10#up1 }\n      - { name: dn3, type: direct, args: Serv11#up1 }\n      - { name: dn4, type: direct, args: Serv12#up1 }\n  - name: Tor6\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn6 }\n      - { name: up2, type: direct, args: Leaf2#dn6 }\n      - { name: up3, type: direct, args: Leaf3#dn6 }\n      - { name: up4, type: direct, args: Leaf4#dn6 }\n      - { name: dn1, type: direct, args: Serv9#up2 }\n      - { name: dn2, type: direct, args: Serv10#up2 }\n      - { name: dn3, type: direct, args: Serv11#up2 }\n      - { name: dn4, type: direct, args: Serv12#up2 }\n  - name: Tor7\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn7 }\n      - { name: up2, type: direct, args: Leaf2#dn7 }\n      - { name: up3, type: direct, args: Leaf3#dn7 }\n      - { name: up4, type: direct, args: Leaf4#dn7 }\n      - { name: dn1, type: direct, args: Serv13#up1 }\n      - { name: dn2, type: direct, args: Serv14#up1 }\n      - { name: dn3, type: direct, args: Serv15#up1 }\n      - { name: dn4, type: direct, args: Serv16#up1 }\n  - name: Tor8\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn8 }\n      - { name: up2, type: direct, args: Leaf2#dn8 }\n      - { name: up3, type: direct, args: Leaf3#dn8 }\n      - { name: up4, type: direct, args: Leaf4#dn8 }\n      - { name: dn1, type: direct, args: Serv13#up2 }\n      - { name: dn2, type: direct, args: Serv14#up2 }\n      - { name: dn3, type: direct, args: Serv15#up2 }\n      - { name: dn4, type: direct, args: Serv16#up2 }\n\n  - name: Serv1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn1 }\n      - { name: up2, type: direct, args: Tor2#dn1 }\n      - { name: dn1, type: direct, args: Vm1a#net0 }\n      - { name: dn2, type: direct, args: Vm1b#net0 }\n  - name: Serv2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn2 }\n      - { name: up2, type: direct, args: Tor2#dn2 }\n      - { name: dn1, type: direct, args: Vm2a#net0 }\n      - { name: dn2, type: direct, args: Vm2b#net0 }\n  - name: Serv3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn3 }\n      - { name: up2, type: direct, args: Tor2#dn3 }\n      - { name: dn1, type: direct, args: Vm3a#net0 }\n      - { name: dn2, type: direct, args: Vm3b#net0 }\n  - name: Serv4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn4 }\n      - { name: up2, type: direct, args: Tor2#dn4 }\n      - { name: dn1, type: direct, args: Vm4a#net0 }\n      - { name: dn2, type: direct, args: Vm4b#net0 }\n  - name: Serv5\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn1 }\n      - { name: up2, type: direct, args: Tor4#dn1 }\n      - { name: dn1, type: direct, args: Vm5a#net0 }\n      - { name: dn2, type: direct, args: Vm5b#net0 }\n  - name: Serv6\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn2 }\n      - { name: up2, type: direct, args: Tor4#dn2 }\n      - { name: dn1, type: direct, args: Vm6a#net0 }\n      - { name: dn2, type: direct, args: Vm6b#net0 }\n  - name: Serv7\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn3 }\n      - { name: up2, type: direct, args: Tor4#dn3 }\n      - { name: dn1, type: direct, args: Vm7a#net0 }\n      - { name: dn2, type: direct, args: Vm7b#net0 }\n  - name: Serv8\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn4 }\n      - { name: up2, type: direct, args: Tor4#dn4 }\n      - { name: dn1, type: direct, args: Vm8a#net0 }\n      - { name: dn2, type: direct, args: Vm8b#net0 }\n  - name: Serv9\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn1 }\n      - { name: up2, type: direct, args: Tor6#dn1 }\n      - { name: dn1, type: direct, args: Vm9a#net0 }\n      - { name: dn2, type: direct, args: Vm9b#net0 }\n  - name: Serv10\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn2 }\n      - { name: up2, type: direct, args: Tor6#dn2 }\n      - { name: dn1, type: direct, args: Vm10a#net0 }\n      - { name: dn2, type: direct, args: Vm10b#net0 }\n  - name: Serv11\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn3 }\n      - { name: up2, type: direct, args: Tor6#dn3 }\n      - { name: dn1, type: direct, args: Vm11a#net0 }\n      - { name: dn2, type: direct, args: Vm11b#net0 }\n  - name: Serv12\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn4 }\n      - { name: up2, type: direct, args: Tor6#dn4 }\n      - { name: dn1, type: direct, args: Vm12a#net0 }\n      - { name: dn2, type: direct, args: Vm12b#net0 }\n  - name: Serv13\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn1 }\n      - { name: up2, type: direct, args: Tor8#dn1 }\n      - { name: dn1, type: direct, args: Vm13a#net0 }\n      - { name: dn2, type: direct, args: Vm13b#net0 }\n  - name: Serv14\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn2 }\n      - { name: up2, type: direct, args: Tor8#dn2 }\n      - { name: dn1, type: direct, args: Vm14a#net0 }\n      - { name: dn2, type: direct, args: Vm14b#net0 }\n  - name: Serv15\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn3 }\n      - { name: up2, type: direct, args: Tor8#dn3 }\n      - { name: dn1, type: direct, args: Vm15a#net0 }\n      - { name: dn2, type: direct, args: Vm15b#net0 }\n  - name: Serv16\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn4 }\n      - { name: up2, type: direct, args: Tor8#dn4 }\n      - { name: dn1, type: direct, args: Vm16a#net0 }\n      - { name: dn2, type: direct, args: Vm16b#net0 }\n\n  - name: Vm1a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv1#dn1 } ]\n  - name: Vm2a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv2#dn1 } ]\n  - name: Vm3a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv3#dn1 } ]\n  - name: Vm4a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv4#dn1 } ]\n  - name: Vm5a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv5#dn1 } ]\n  - name: Vm6a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv6#dn1 } ]\n  - name: Vm7a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv7#dn1 } ]\n  - name: Vm8a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv8#dn1 } ]\n  - name: Vm9a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv9#dn1 } ]\n  - name: Vm10a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv10#dn1 } ]\n  - name: Vm11a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv11#dn1 } ]\n  - name: Vm12a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv12#dn1 } ]\n  - name: Vm13a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv13#dn1 } ]\n  - name: Vm14a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv14#dn1 } ]\n  - name: Vm15a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv15#dn1 } ]\n  - name: Vm16a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv16#dn1 } ]\n  - name: Vm1b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv1#dn2 } ]\n  - name: Vm2b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv2#dn2 } ]\n  - name: Vm3b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv3#dn2 } ]\n  - name: Vm4b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv4#dn2 } ]\n  - name: Vm5b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv5#dn2 } ]\n  - name: Vm6b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv6#dn2 } ]\n  - name: Vm7b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv7#dn2 } ]\n  - name: Vm8b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv8#dn2 } ]\n  - name: Vm9b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv9#dn2 } ]\n  - name: Vm10b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv10#dn2 } ]\n  - name: Vm11b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv11#dn2 } ]\n  - name: Vm12b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv12#dn2 } ]\n  - name: Vm13b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv13#dn2 } ]\n  - name: Vm14b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv14#dn2 } ]\n  - name: Vm15b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv15#dn2 } ]\n  - name: Vm16b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv16#dn2 } ]\n\nnode_configs:\n  - name: Ext1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.254/32\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65999\"\n          -c \" bgp router-id 10.255.0.254\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Spine1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.1/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65001\"\n          -c \" bgp router-id 10.255.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Spine2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.2/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65002\"\n          -c \" bgp router-id 10.255.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.11/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65011\"\n          -c \" bgp router-id 10.255.0.11\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.12/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65012\"\n          -c \" bgp router-id 10.255.0.12\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf3\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.13/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65013\"\n          -c \" bgp router-id 10.255.0.13\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf4\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.14/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65014\"\n          -c \" bgp router-id 10.255.0.14\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\n  - name: Tor1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.31/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65031\"\n          -c \" bgp router-id 10.255.0.31\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.32/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65032\"\n          -c \" bgp router-id 10.255.0.32\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor3\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.33/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65033\"\n          -c \" bgp router-id 10.255.0.33\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor4\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.34/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65034\"\n          -c \" bgp router-id 10.255.0.34\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor5\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.35/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65035\"\n          -c \" bgp router-id 10.255.0.35\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor6\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.36/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65036\"\n          -c \" bgp router-id 10.255.0.36\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor7\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.37/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65037\"\n          -c \" bgp router-id 10.255.0.37\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor8\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.38/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65038\"\n          -c \" bgp router-id 10.255.0.38\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\n  - name: Serv1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.201/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65201\"\n          -c \" bgp router-id 10.255.0.201\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.202/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65202\"\n          -c \" bgp router-id 10.255.0.202\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv3\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.203/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65203\"\n          -c \" bgp router-id 10.255.0.203\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv4\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.204/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65204\"\n          -c \" bgp router-id 10.255.0.204\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv5\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.205/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65205\"\n          -c \" bgp router-id 10.255.0.205\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv6\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.206/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65206\"\n          -c \" bgp router-id 10.255.0.206\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv7\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.207/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65207\"\n          -c \" bgp router-id 10.255.0.207\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv8\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.208/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65208\"\n          -c \" bgp router-id 10.255.0.208\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\n  - name: Serv9\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.209/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65209\"\n          -c \" bgp router-id 10.255.0.209\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv10\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.210/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65210\"\n          -c \" bgp router-id 10.255.0.210\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv11\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.211/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65211\"\n          -c \" bgp router-id 10.255.0.211\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv12\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.212/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65212\"\n          -c \" bgp router-id 10.255.0.212\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv13\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.213/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65213\"\n          -c \" bgp router-id 10.255.0.213\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv14\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.214/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65214\"\n          -c \" bgp router-id 10.255.0.214\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv15\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.215/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65215\"\n          -c \" bgp router-id 10.255.0.215\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv16\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.216/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65216\"\n          -c \" bgp router-id 10.255.0.216\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec Ext1 echo slank\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_clos/spec.yaml",
    "content": "\nnodes:\n  - name: Ext1\n    image: slankdev/frr\n    interfaces:\n      # - { name: net0, type: direct, args: Internet#net0 }\n      - { name: dn1, type: direct, args: Spine1#up1 }\n      - { name: dn2, type: direct, args: Spine2#up1 }\n  - name: Spine1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#dn1 }\n      - { name: dn1, type: direct, args: Leaf1#up1 }\n      - { name: dn2, type: direct, args: Leaf2#up1 }\n      - { name: dn3, type: direct, args: Leaf3#up1 }\n      - { name: dn4, type: direct, args: Leaf4#up1 }\n  - name: Spine2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Ext1#dn2 }\n      - { name: dn1, type: direct, args: Leaf1#up2 }\n      - { name: dn2, type: direct, args: Leaf2#up2 }\n      - { name: dn3, type: direct, args: Leaf3#up2 }\n      - { name: dn4, type: direct, args: Leaf4#up2 }\n  - name: Leaf1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn1 }\n      - { name: up2, type: direct, args: Spine2#dn1 }\n      - { name: dn1, type: direct, args: Tor1#up1 }\n      - { name: dn2, type: direct, args: Tor2#up1 }\n      - { name: dn3, type: direct, args: Tor3#up1 }\n      - { name: dn4, type: direct, args: Tor4#up1 }\n      - { name: dn5, type: direct, args: Tor5#up1 }\n      - { name: dn6, type: direct, args: Tor6#up1 }\n      - { name: dn7, type: direct, args: Tor7#up1 }\n      - { name: dn8, type: direct, args: Tor8#up1 }\n  - name: Leaf2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn2 }\n      - { name: up2, type: direct, args: Spine2#dn2 }\n      - { name: dn1, type: direct, args: Tor1#up2 }\n      - { name: dn2, type: direct, args: Tor2#up2 }\n      - { name: dn3, type: direct, args: Tor3#up2 }\n      - { name: dn4, type: direct, args: Tor4#up2 }\n      - { name: dn5, type: direct, args: Tor5#up2 }\n      - { name: dn6, type: direct, args: Tor6#up2 }\n      - { name: dn7, type: direct, args: Tor7#up2 }\n      - { name: dn8, type: direct, args: Tor8#up2 }\n  - name: Leaf3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn3 }\n      - { name: up2, type: direct, args: Spine2#dn3 }\n      - { name: dn1, type: direct, args: Tor1#up3 }\n      - { name: dn2, type: direct, args: Tor2#up3 }\n      - { name: dn3, type: direct, args: Tor3#up3 }\n      - { name: dn4, type: direct, args: Tor4#up3 }\n      - { name: dn5, type: direct, args: Tor5#up3 }\n      - { name: dn6, type: direct, args: Tor6#up3 }\n      - { name: dn7, type: direct, args: Tor7#up3 }\n      - { name: dn8, type: direct, args: Tor8#up3 }\n  - name: Leaf4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Spine1#dn4 }\n      - { name: up2, type: direct, args: Spine2#dn4 }\n      - { name: dn1, type: direct, args: Tor1#up4 }\n      - { name: dn2, type: direct, args: Tor2#up4 }\n      - { name: dn3, type: direct, args: Tor3#up4 }\n      - { name: dn4, type: direct, args: Tor4#up4 }\n      - { name: dn5, type: direct, args: Tor5#up4 }\n      - { name: dn6, type: direct, args: Tor6#up4 }\n      - { name: dn7, type: direct, args: Tor7#up4 }\n      - { name: dn8, type: direct, args: Tor8#up4 }\n\n  - name: Tor1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn1 }\n      - { name: up2, type: direct, args: Leaf2#dn1 }\n      - { name: up3, type: direct, args: Leaf3#dn1 }\n      - { name: up4, type: direct, args: Leaf4#dn1 }\n      - { name: dn1, type: direct, args: Serv1#up1 }\n      - { name: dn2, type: direct, args: Serv2#up1 }\n      - { name: dn3, type: direct, args: Serv3#up1 }\n      - { name: dn4, type: direct, args: Serv4#up1 }\n  - name: Tor2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn2 }\n      - { name: up2, type: direct, args: Leaf2#dn2 }\n      - { name: up3, type: direct, args: Leaf3#dn2 }\n      - { name: up4, type: direct, args: Leaf4#dn2 }\n      - { name: dn1, type: direct, args: Serv1#up2 }\n      - { name: dn2, type: direct, args: Serv2#up2 }\n      - { name: dn3, type: direct, args: Serv3#up2 }\n      - { name: dn4, type: direct, args: Serv4#up2 }\n  - name: Tor3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn3 }\n      - { name: up2, type: direct, args: Leaf2#dn3 }\n      - { name: up3, type: direct, args: Leaf3#dn3 }\n      - { name: up4, type: direct, args: Leaf4#dn3 }\n      - { name: dn1, type: direct, args: Serv5#up1 }\n      - { name: dn2, type: direct, args: Serv6#up1 }\n      - { name: dn3, type: direct, args: Serv7#up1 }\n      - { name: dn4, type: direct, args: Serv8#up1 }\n  - name: Tor4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn4 }\n      - { name: up2, type: direct, args: Leaf2#dn4 }\n      - { name: up3, type: direct, args: Leaf3#dn4 }\n      - { name: up4, type: direct, args: Leaf4#dn4 }\n      - { name: dn1, type: direct, args: Serv5#up2 }\n      - { name: dn2, type: direct, args: Serv6#up2 }\n      - { name: dn3, type: direct, args: Serv7#up2 }\n      - { name: dn4, type: direct, args: Serv8#up2 }\n  - name: Tor5\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn5 }\n      - { name: up2, type: direct, args: Leaf2#dn5 }\n      - { name: up3, type: direct, args: Leaf3#dn5 }\n      - { name: up4, type: direct, args: Leaf4#dn5 }\n      - { name: dn1, type: direct, args: Serv9#up1 }\n      - { name: dn2, type: direct, args: Serv10#up1 }\n      - { name: dn3, type: direct, args: Serv11#up1 }\n      - { name: dn4, type: direct, args: Serv12#up1 }\n  - name: Tor6\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn6 }\n      - { name: up2, type: direct, args: Leaf2#dn6 }\n      - { name: up3, type: direct, args: Leaf3#dn6 }\n      - { name: up4, type: direct, args: Leaf4#dn6 }\n      - { name: dn1, type: direct, args: Serv9#up2 }\n      - { name: dn2, type: direct, args: Serv10#up2 }\n      - { name: dn3, type: direct, args: Serv11#up2 }\n      - { name: dn4, type: direct, args: Serv12#up2 }\n  - name: Tor7\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn7 }\n      - { name: up2, type: direct, args: Leaf2#dn7 }\n      - { name: up3, type: direct, args: Leaf3#dn7 }\n      - { name: up4, type: direct, args: Leaf4#dn7 }\n      - { name: dn1, type: direct, args: Serv13#up1 }\n      - { name: dn2, type: direct, args: Serv14#up1 }\n      - { name: dn3, type: direct, args: Serv15#up1 }\n      - { name: dn4, type: direct, args: Serv16#up1 }\n  - name: Tor8\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Leaf1#dn8 }\n      - { name: up2, type: direct, args: Leaf2#dn8 }\n      - { name: up3, type: direct, args: Leaf3#dn8 }\n      - { name: up4, type: direct, args: Leaf4#dn8 }\n      - { name: dn1, type: direct, args: Serv13#up2 }\n      - { name: dn2, type: direct, args: Serv14#up2 }\n      - { name: dn3, type: direct, args: Serv15#up2 }\n      - { name: dn4, type: direct, args: Serv16#up2 }\n\n  - name: Serv1\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn1 }\n      - { name: up2, type: direct, args: Tor2#dn1 }\n      - { name: dn1, type: direct, args: Vm1a#net0 }\n      - { name: dn2, type: direct, args: Vm1b#net0 }\n  - name: Serv2\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn2 }\n      - { name: up2, type: direct, args: Tor2#dn2 }\n      - { name: dn1, type: direct, args: Vm2a#net0 }\n      - { name: dn2, type: direct, args: Vm2b#net0 }\n  - name: Serv3\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn3 }\n      - { name: up2, type: direct, args: Tor2#dn3 }\n      - { name: dn1, type: direct, args: Vm3a#net0 }\n      - { name: dn2, type: direct, args: Vm3b#net0 }\n  - name: Serv4\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor1#dn4 }\n      - { name: up2, type: direct, args: Tor2#dn4 }\n      - { name: dn1, type: direct, args: Vm4a#net0 }\n      - { name: dn2, type: direct, args: Vm4b#net0 }\n  - name: Serv5\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn1 }\n      - { name: up2, type: direct, args: Tor4#dn1 }\n      - { name: dn1, type: direct, args: Vm5a#net0 }\n      - { name: dn2, type: direct, args: Vm5b#net0 }\n  - name: Serv6\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn2 }\n      - { name: up2, type: direct, args: Tor4#dn2 }\n      - { name: dn1, type: direct, args: Vm6a#net0 }\n      - { name: dn2, type: direct, args: Vm6b#net0 }\n  - name: Serv7\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn3 }\n      - { name: up2, type: direct, args: Tor4#dn3 }\n      - { name: dn1, type: direct, args: Vm7a#net0 }\n      - { name: dn2, type: direct, args: Vm7b#net0 }\n  - name: Serv8\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor3#dn4 }\n      - { name: up2, type: direct, args: Tor4#dn4 }\n      - { name: dn1, type: direct, args: Vm8a#net0 }\n      - { name: dn2, type: direct, args: Vm8b#net0 }\n  - name: Serv9\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn1 }\n      - { name: up2, type: direct, args: Tor6#dn1 }\n      - { name: dn1, type: direct, args: Vm9a#net0 }\n      - { name: dn2, type: direct, args: Vm9b#net0 }\n  - name: Serv10\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn2 }\n      - { name: up2, type: direct, args: Tor6#dn2 }\n      - { name: dn1, type: direct, args: Vm10a#net0 }\n      - { name: dn2, type: direct, args: Vm10b#net0 }\n  - name: Serv11\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn3 }\n      - { name: up2, type: direct, args: Tor6#dn3 }\n      - { name: dn1, type: direct, args: Vm11a#net0 }\n      - { name: dn2, type: direct, args: Vm11b#net0 }\n  - name: Serv12\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor5#dn4 }\n      - { name: up2, type: direct, args: Tor6#dn4 }\n      - { name: dn1, type: direct, args: Vm12a#net0 }\n      - { name: dn2, type: direct, args: Vm12b#net0 }\n  - name: Serv13\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn1 }\n      - { name: up2, type: direct, args: Tor8#dn1 }\n      - { name: dn1, type: direct, args: Vm13a#net0 }\n      - { name: dn2, type: direct, args: Vm13b#net0 }\n  - name: Serv14\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn2 }\n      - { name: up2, type: direct, args: Tor8#dn2 }\n      - { name: dn1, type: direct, args: Vm14a#net0 }\n      - { name: dn2, type: direct, args: Vm14b#net0 }\n  - name: Serv15\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn3 }\n      - { name: up2, type: direct, args: Tor8#dn3 }\n      - { name: dn1, type: direct, args: Vm15b#net0 }\n      - { name: dn2, type: direct, args: Vm15b#net0 }\n  - name: Serv16\n    image: slankdev/frr\n    interfaces:\n      - { name: up1, type: direct, args: Tor7#dn4 }\n      - { name: up2, type: direct, args: Tor8#dn4 }\n      - { name: dn1, type: direct, args: Vm16b#net0 }\n      - { name: dn2, type: direct, args: Vm16b#net0 }\n\n  - name: Vm1a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv1#dn1 } ]\n  - name: Vm2a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv2#dn1 } ]\n  - name: Vm3a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv3#dn1 } ]\n  - name: Vm4a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv4#dn1 } ]\n  - name: Vm5a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv5#dn1 } ]\n  - name: Vm6a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv6#dn1 } ]\n  - name: Vm7a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv7#dn1 } ]\n  - name: Vm8a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv8#dn1 } ]\n  - name: Vm9a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv9#dn1 } ]\n  - name: Vm10a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv10#dn1 } ]\n  - name: Vm11a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv11#dn1 } ]\n  - name: Vm12a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv12#dn1 } ]\n  - name: Vm13a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv13#dn1 } ]\n  - name: Vm14a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv14#dn1 } ]\n  - name: Vm15a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv15#dn1 } ]\n  - name: Vm16a\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv16#dn1 } ]\n  - name: Vm1b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv1#dn2 } ]\n  - name: Vm2b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv2#dn2 } ]\n  - name: Vm3b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv3#dn2 } ]\n  - name: Vm4b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv4#dn2 } ]\n  - name: Vm5b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv5#dn2 } ]\n  - name: Vm6b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv6#dn2 } ]\n  - name: Vm7b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv7#dn2 } ]\n  - name: Vm8b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv8#dn2 } ]\n  - name: Vm9b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv9#dn2 } ]\n  - name: Vm10b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv10#dn2 } ]\n  - name: Vm11b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv11#dn2 } ]\n  - name: Vm12b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv12#dn2 } ]\n  - name: Vm13b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv13#dn2 } ]\n  - name: Vm14b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv14#dn2 } ]\n  - name: Vm15b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv15#dn2 } ]\n  - name: Vm16b\n    image: slankdev/frr\n    interfaces: [ { name: net0, type: direct, args: Serv16#dn2 } ]\n\nnode_configs:\n  - name: Ext1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.254/32\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65999\"\n          -c \" bgp router-id 10.255.0.254\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Spine1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.1/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65001\"\n          -c \" bgp router-id 10.255.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Spine2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.2/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65002\"\n          -c \" bgp router-id 10.255.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.11/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65011\"\n          -c \" bgp router-id 10.255.0.11\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.12/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65012\"\n          -c \" bgp router-id 10.255.0.12\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf3\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.13/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65013\"\n          -c \" bgp router-id 10.255.0.13\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Leaf4\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.14/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn5\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn6\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn7\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn8\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65014\"\n          -c \" bgp router-id 10.255.0.14\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" neighbor dn5 interface peer-group FABRIC\"\n          -c \" neighbor dn6 interface peer-group FABRIC\"\n          -c \" neighbor dn7 interface peer-group FABRIC\"\n          -c \" neighbor dn8 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\n  - name: Tor1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.31/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65031\"\n          -c \" bgp router-id 10.255.0.31\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.32/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65032\"\n          -c \" bgp router-id 10.255.0.32\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor3\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.33/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65033\"\n          -c \" bgp router-id 10.255.0.33\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor4\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.34/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65034\"\n          -c \" bgp router-id 10.255.0.34\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor5\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.35/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65035\"\n          -c \" bgp router-id 10.255.0.35\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor6\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.36/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65036\"\n          -c \" bgp router-id 10.255.0.36\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor7\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.37/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65037\"\n          -c \" bgp router-id 10.255.0.37\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Tor8\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.38/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn3\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int dn4\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65038\"\n          -c \" bgp router-id 10.255.0.38\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" neighbor up3 interface peer-group FABRIC\"\n          -c \" neighbor up4 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" neighbor dn2 interface peer-group FABRIC\"\n          -c \" neighbor dn3 interface peer-group FABRIC\"\n          -c \" neighbor dn4 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\n  - name: Serv1\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.201/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65201\"\n          -c \" bgp router-id 10.255.0.201\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv2\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.202/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65202\"\n          -c \" bgp router-id 10.255.0.202\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv3\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.203/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65203\"\n          -c \" bgp router-id 10.255.0.203\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv4\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.204/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65204\"\n          -c \" bgp router-id 10.255.0.204\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv5\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.205/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65205\"\n          -c \" bgp router-id 10.255.0.205\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv6\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.206/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65206\"\n          -c \" bgp router-id 10.255.0.206\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv7\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.207/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65207\"\n          -c \" bgp router-id 10.255.0.207\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv8\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.208/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65208\"\n          -c \" bgp router-id 10.255.0.208\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\n  - name: Serv9\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.209/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65209\"\n          -c \" bgp router-id 10.255.0.209\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv10\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.210/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65210\"\n          -c \" bgp router-id 10.255.0.210\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv11\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.211/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65211\"\n          -c \" bgp router-id 10.255.0.211\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv12\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.212/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65212\"\n          -c \" bgp router-id 10.255.0.212\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv13\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.213/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65213\"\n          -c \" bgp router-id 10.255.0.213\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv14\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.214/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65214\"\n          -c \" bgp router-id 10.255.0.214\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv15\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.215/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65215\"\n          -c \" bgp router-id 10.255.0.215\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n  - name: Serv16\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.216/32\"\n          -c \"int up1\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"int up2\" -c \"ipv6 nd ra-interval 1\" -c \"no ipv6 nd suppress-ra\"\n          -c \"router bgp 65216\"\n          -c \" bgp router-id 10.255.0.216\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor up2 interface peer-group FABRIC\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected route-map redis_lo\"\n          -c \" exit-address-family\"\n          -c \"route-map redis_lo permit 10\"\n          -c \" match interface lo\"\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec Ext1 echo slank\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_conntrack/connection_sync/Makefile",
    "content": "\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 $(NAME) tail -f /tmp/frr.log; \\\n\t\tsleep 1 ; done\n\n"
  },
  {
    "path": "examples/basic_conntrack/connection_sync/README.md",
    "content": "\n# Connection Sync with conntrackd and keepalived\n\n```\ntn upconf | sudo sh\n```\n\n<!-- docker exec -it S1 tcpdump -ni net0 -Qin '(tcp[tcpflags] & tcp-syn)' != 0 -->\n<!-- docker exec C1 curl --interface 10.0.0.2 20.0.0.2 -->\n<!-- docker exec C1 curl --interface 10.0.0.3 20.0.0.2 -->\n<!-- docker exec C1 curl --interface 10.0.0.4 20.0.0.2 -->\n<!-- docker exec S1 conntrack -L -->\n"
  },
  {
    "path": "examples/basic_conntrack/connection_sync/spec.yaml",
    "content": "\nnodes:\n\n  - name: C1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: S1#net0, }\n  - name: C2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: S2#net0, }\n\n  - name: S1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: C1#net0, }\n      - { name: net1, type: direct, args: N1#net0, }\n      - { name: net2, type: direct, args: N2#net0, }\n  - name: S2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: C2#net0, }\n      - { name: net1, type: direct, args: N1#net1, }\n      - { name: net2, type: direct, args: N2#net1, }\n\n  - name: N1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: S1#net1, }\n      - { name: net1, type: direct, args: S2#net1, }\n      - { name: fab0, type: direct, args: N2#fab0, }\n  - name: N2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: S1#net2, }\n      - { name: net1, type: direct, args: S2#net2, }\n      - { name: fab0, type: direct, args: N1#fab0, }\n\nnode_configs:\n\n  - name: C1\n    cmds:\n      - cmd: ip addr add 8.8.8.8/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 1\"\n          -c \" bgp router-id 10.255.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n          -c \"!\"\n          -c \"do write\"\n      - cmd: sh -c \"echo It works > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n  - name: C2\n    cmds:\n      - cmd: ip addr add 10.0.0.1/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 2\"\n          -c \" bgp router-id 10.255.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n          -c \"!\"\n          -c \"do write\"\n\n  - name: S1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 3\"\n          -c \" bgp router-id 10.255.0.3\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" neighbor net1 interface peer-group FABRIC\"\n          -c \" neighbor net2 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n          -c \"!\"\n          -c \"do write\"\n\n  - name: S2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 4\"\n          -c \" bgp router-id 10.255.0.4\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" neighbor net1 interface peer-group FABRIC\"\n          -c \" neighbor net2 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \" exit-address-family\"\n          -c \"!\"\n          -c \"do write\"\n\n  - name: N1\n    cmds:\n      - cmd: ip addr add 99.0.0.1/24 dev fab0\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 5\"\n          -c \" bgp router-id 10.255.0.5\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" neighbor net0 interface remote-as external\"\n          -c \" neighbor net1 interface remote-as external\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 0.0.0.0/0\"\n          -c \"  redistribute connected\"\n          -c \"  neighbor net0 route-map MAP1 out\"\n          -c \"  neighbor net1 route-map MAP2 out\"\n          -c \" exit-address-family\"\n          -c \"!\"\n          -c \"route-map MAP1 permit 1\"\n          -c \" match ip address prefix-list PLIST1\"\n          -c \"!\"\n          -c \"route-map MAP2 permit 1\"\n          -c \" match ip address prefix-list PLIST2\"\n          -c \"!\"\n          -c \"ip prefix-list PLIST1 seq 5 permit 20.0.0.0/8 ge 24\"\n          -c \"ip prefix-list PLIST2 seq 5 permit 0.0.0.0/0\"\n          -c \"!\"\n          -c \"do write\"\n\n      - cmd: ip addr add 20.0.0.1/32 dev lo\n      - cmd: ip addr add 20.0.0.2/32 dev lo\n      - cmd: iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT -p tcp --to-source 20.0.0.1:10000-20008\n\n  - name: N2\n    cmds:\n      - cmd: ip addr add 99.0.0.2/24 dev fab0\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip addr add 20.0.0.1/32 dev lo\n      - cmd: ip addr add 20.0.0.2/32 dev lo\n      - cmd: iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT -p tcp --to-source 20.0.0.1:10000-20008\n\n"
  },
  {
    "path": "examples/basic_coredns/blacklist/Corefile.NS1",
    "content": ".: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 http://10.0.0.100:2379\n  }\n}\n\nemacs.org {\n}\nsublimetext.com {\n}\n"
  },
  {
    "path": "examples/basic_coredns/blacklist/README.md",
    "content": "\n# CoreDNS example (very simple blacklist)\n\n![](topo.png)\n\n- Blacklisted\n\t-\temacs.org\n\t- sublimetext.com\n\n```\ndocker exec R1 nslookup slank.dev\ndocker exec R1 nslookup test1.ichihara.org\ndocker exec R1 nslookup test2.ichihara.org\n\ndocker exec R1 nslookup www.vim.org\ndocker exec R1 nslookup emacs.org\ndocker exec R1 nslookup sublimetext.com\n```\n"
  },
  {
    "path": "examples/basic_coredns/blacklist/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n      - cmd: docker cp Corefile.NS1 NS1:/Corefile\n      # - cmd: docker cp Corefile.NS2 NS2:/Corefile\n      # - cmd: docker cp Corefile.NS3 NS3:/Corefile\n\nnodes:\n  - name: S1\n    image: slankdev/coredns:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: NS1#net0 }\n      - { name: net2, type: direct, args: NS2#net0 }\n      - { name: net3, type: direct, args: NS3#net0 }\n      - { name: net4, type: direct, args: KVS#net0 }\n\n  - name: R1\n    image: slankdev/coredns:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: S1#net0 }\n\n  - name: KVS\n    image: slankdev/etcd:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: S1#net4 }\n\n  - name: NS1\n    image: slankdev/coredns:centos-7\n    net_base: bridge\n    interfaces:\n      - { name: net0, type: direct, args: S1#net1 }\n  - name: NS2\n    image: slankdev/coredns:centos-7\n    net_base: bridge\n    interfaces:\n      - { name: net0, type: direct, args: S1#net2 }\n  - name: NS3\n    image: slankdev/coredns:centos-7\n    net_base: bridge\n    interfaces:\n      - { name: net0, type: direct, args: S1#net3 }\n\nnode_configs:\n\n  - name: S1\n    cmds:\n      - cmd: ip link add br0 type bridge\n      - cmd: ip link set br0 up\n      - cmd: ip link set net0 master br0\n      - cmd: ip link set net1 master br0\n      - cmd: ip link set net2 master br0\n      - cmd: ip link set net3 master br0\n      - cmd: ip link set net4 master br0\n\n  - name: KVS\n    cmds:\n      - cmd: ip addr add 10.0.0.100/24 dev net0\n      - cmd: >-\n          nohup etcd --listen-peer-urls=\"http://10.0.0.100:2380\"\n          --listen-client-urls=\"http://10.0.0.100:2379\"\n          --advertise-client-urls=\"http://10.0.0.100:2379\" &\n      - cmd: sleep 3\n      - cmd: etcdctl --endpoints=\"http://10.0.0.100:2379\" put /dns-server01/org/ichihara/test1/server01 '{\"host\":\"99.1.0.1\",\"port\":80}'\n      - cmd: etcdctl --endpoints=\"http://10.0.0.100:2379\" put /dns-server01/org/ichihara/test1/server02 '{\"host\":\"99.1.0.2\",\"port\":80}'\n      - cmd: etcdctl --endpoints=\"http://10.0.0.100:2379\" put /dns-server01/org/ichihara/test2/server01 '{\"host\":\"99.2.0.2\",\"port\":80}'\n\n  - name: NS1\n    cmds:\n      - cmd: ip addr add 10.0.0.254/24 dev net0\n      - cmd: nohup coredns -conf /Corefile &\n\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: sh -c 'echo nameserver 10.0.0.254 > /etc/resolv.conf'\n\n"
  },
  {
    "path": "examples/basic_ebgp/spec.yaml",
    "content": "\n# DESCRIPTION: BGP network using FRR\n#\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#    cns spec.yaml test | sudo sh\n#\n# FINI:\n#    cns spec.yaml fini | sudo sh\n#\n# TOPO:\n#\n#                          vlan1:10.0.0.0/24\n#                     .1(net0)          .2(net0)\n#                R0(AS100)------------------R1(AS200)\n#            (net1).1|                          |.1(net1)\n#                    |                          |\n#  vlan1:10.1.0.0/24 |                          | vlan1:10.2.0.0/24\n#                    |                          |\n#            (net0).2|                          |.2(net0)\n#                R2(AS300)                  R3(AS400)\n#            (net1).1|                          |.1(net1)\n#                    |                          |\n#  vlan1:10.3.0.0/24 |                          | vlan1:10.4.0.0/24\n#                    |                          |\n#            (net0).2|                          |.2(net0)\n#                    C0                         C1\n#\n\nnodes:\n  - name: R0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R2#net0 }\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R0#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R0#net1 }\n      - { name: net1, type: direct, args: C0#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: C1#net0 }\n\n  - name: C0\n    image: slankdev/ubuntu:16.04\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: C1\n    image: slankdev/ubuntu:16.04\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 10.1.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 100\"\n          -c \"bgp router-id 1.1.1.1\"\n          -c \"neighbor 10.0.0.2 remote-as 200\"\n          -c \"neighbor 10.1.0.2 remote-as 300\"\n          -c \"network 10.1.0.0/24\"\n          -c \"network 10.1.2.0/24\"\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip addr add 10.2.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 200\"\n          -c \"bgp router-id 2.2.2.2\"\n          -c \"neighbor 10.0.0.1 remote-as 100\"\n          -c \"neighbor 10.2.0.2 remote-as 400\"\n          -c \"network 10.2.0.0/24\"\n          -c \"network 10.2.4.0/24\"\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.1.0.2/24 dev net0\n      - cmd: ip addr add 10.3.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 300\"\n          -c \"bgp router-id 3.3.3.3\"\n          -c \"neighbor 10.1.0.1 remote-as 100\"\n          -c \"network 10.3.0.0/24\"\n  - name: R3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.2.0.2/24 dev net0\n      - cmd: ip addr add 10.4.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 400\"\n          -c \"bgp router-id 4.4.4.4\"\n          -c \"neighbor 10.2.0.1 remote-as 200\"\n          -c \"network 10.4.0.0/24\"\n\n  - name: C0\n    cmds:\n      - cmd: ip addr add 10.3.0.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 10.3.0.1\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.4.0.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 10.4.0.1\n\ntest:\n  - cmds:\n      - cmd: docker exec C0 ping -c2 10.4.0.2\n\n"
  },
  {
    "path": "examples/basic_ecmp/README.md",
    "content": "\n![](topo.jpeg)\n"
  },
  {
    "path": "examples/basic_ecmp/scale.diff",
    "content": "diff --git a/examples/basic_ecmp/spec.yaml b/examples/basic_ecmp/spec.yaml\nindex c2c0bd2..79ab538 100644\n--- a/examples/basic_ecmp/spec.yaml\n+++ b/examples/basic_ecmp/spec.yaml\n@@ -38,6 +38,16 @@ nodes:\n     interfaces:\n       - { name: net0, type: direct, args: R3#net1 }\n \n+  - name: R4\n+    image: slankdev/frr\n+    interfaces:\n+      - { name: net0, type: bridge, args: B0 }\n+      - { name: net1, type: direct, args: S4#net0 }\n+  - name: S4\n+    image: tmp\n+    interfaces:\n+      - { name: net0, type: direct, args: R4#net1 }\n+\n switches:\n   - name: B0\n     interfaces:\n@@ -45,6 +55,7 @@ switches:\n       - { name: net0, type: container, args: R1 }\n       - { name: net0, type: container, args: R2 }\n       - { name: net0, type: container, args: R3 }\n+      - { name: net0, type: container, args: R4 }\n \n node_configs:\n   - name: S0\n@@ -123,6 +134,26 @@ node_configs:\n       - cmd: sh -c \"echo S3 > index.html\"\n       - cmd: nohup python3 -m http.server 80 &\n \n+  - name: R4\n+    cmds:\n+      - cmd: /usr/lib/frr/frr start\n+      - cmd: ip addr add 10.255.0.40/32 dev lo\n+      - cmd: ip addr add 10.0.0.40/24 dev net0\n+      - cmd: ip addr add 192.168.0.1/24 dev net1\n+      - cmd: ip route replace default via 10.0.0.1\n+      - cmd: >-\n+          vtysh -c 'conf t'\n+          -c 'router bgp 100'\n+          -c ' bgp router-id 10.255.0.40'\n+          -c ' neighbor 10.0.0.1 remote-as 100'\n+          -c ' network 192.168.0.2/32'\n+  - name: S4\n+    cmds:\n+      - cmd: ip addr add 192.168.0.2/24 dev net0\n+      - cmd: ip route replace default via 192.168.0.1\n+      - cmd: sh -c \"echo S4 > index.html\"\n+      - cmd: nohup python3 -m http.server 80 &\n+\n test:\n   - cmds:\n     # local link\n"
  },
  {
    "path": "examples/basic_ecmp/spec.yaml",
    "content": "# http://www.asciiflow.com\n\nnodes:\n  - name: S0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R0#net1 }\n  - name: R0\n    image: slankdev/frr\n    interfaces:\n      - { name: net1, type: direct, args: S0#net0 }\n      - { name: net0, type: bridge, args: B0 }\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n      - { name: net1, type: direct, args: S1#net0 }\n  - name: S1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n      - { name: net1, type: direct, args: S2#net0 }\n  - name: S2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n      - { name: net1, type: direct, args: S3#net0 }\n  - name: S3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n\nswitches:\n  - name: B0\n    interfaces:\n      - { name: net0, type: container, args: R0 }\n      - { name: net0, type: container, args: R1 }\n      - { name: net0, type: container, args: R2 }\n      - { name: net0, type: container, args: R3 }\n\nnode_configs:\n  - name: S0\n    cmds:\n      - cmd: ip addr add 10.1.0.2/24 dev net0\n      - cmd: ip route replace default via 10.1.0.1\n  - name: R0\n    cmds:\n      - cmd: sysctl -w 'net.ipv4.fib_multipath_hash_policy=1'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.255.0.1/32 dev lo\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 10.1.0.1/24 dev net1\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router bgp 100'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' neighbor 10.0.0.10 remote-as 100'\n          -c ' neighbor 10.0.0.20 remote-as 100'\n          -c ' neighbor 10.0.0.30 remote-as 100'\n      - cmd: vtysh -c \"do write mem\"\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.255.0.10/32 dev lo\n      - cmd: ip addr add 10.0.0.10/24 dev net0\n      - cmd: ip addr add 192.168.0.1/24 dev net1\n      - cmd: ip route replace default via 10.0.0.1\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router bgp 100'\n          -c ' bgp router-id 10.255.0.10'\n          -c ' neighbor 10.0.0.1 remote-as 100'\n          -c ' network 192.168.0.2/32'\n  - name: S1\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route replace default via 192.168.0.1\n      - cmd: sh -c \"echo S1 > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.255.0.20/32 dev lo\n      - cmd: ip addr add 10.0.0.20/24 dev net0\n      - cmd: ip addr add 192.168.0.1/24 dev net1\n      - cmd: ip route replace default via 10.0.0.1\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router bgp 100'\n          -c ' bgp router-id 10.255.0.20'\n          -c ' neighbor 10.0.0.1 remote-as 100'\n          -c ' network 192.168.0.2/32'\n  - name: S2\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route replace default via 192.168.0.1\n      - cmd: sh -c \"echo S2 > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n  - name: R3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.255.0.30/32 dev lo\n      - cmd: ip addr add 10.0.0.30/24 dev net0\n      - cmd: ip addr add 192.168.0.1/24 dev net1\n      - cmd: ip route replace default via 10.0.0.1\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router bgp 100'\n          -c ' bgp router-id 10.255.0.30'\n          -c ' neighbor 10.0.0.1 remote-as 100'\n          -c ' network 192.168.0.2/32'\n  - name: S3\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route replace default via 192.168.0.1\n      - cmd: sh -c \"echo S3 > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n\ntest:\n  - cmds:\n    # local link\n    - cmd: docker exec S0 ping -c2 10.1.0.1\n    - cmd: docker exec S1 ping -c2 192.168.0.1\n    - cmd: docker exec S2 ping -c2 192.168.0.1\n    - cmd: docker exec S3 ping -c2 192.168.0.1\n    - cmd: docker exec R0 ping -c2 10.1.0.2\n    - cmd: docker exec R0 ping -c2 10.0.0.10\n    - cmd: docker exec R0 ping -c2 10.0.0.20\n    - cmd: docker exec R0 ping -c2 10.0.0.30\n    - cmd: docker exec R1 ping -c2 192.168.0.2\n    - cmd: docker exec R1 ping -c2 10.0.0.1\n    - cmd: docker exec R1 ping -c2 10.0.0.10\n    - cmd: docker exec R1 ping -c2 10.0.0.20\n    - cmd: docker exec R1 ping -c2 10.0.0.30\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.10\n    - cmd: docker exec R2 ping -c2 10.0.0.20\n    - cmd: docker exec R2 ping -c2 10.0.0.30\n    - cmd: docker exec R3 ping -c2 10.0.0.1\n    - cmd: docker exec R3 ping -c2 10.0.0.10\n    - cmd: docker exec R3 ping -c2 10.0.0.20\n    - cmd: docker exec R3 ping -c2 10.0.0.30\n    # remote link\n    - cmd: docker exec S0 ping -c2 192.168.0.2\n\n"
  },
  {
    "path": "examples/basic_evpn/README.md",
    "content": "\n# EVPN\n\n![](./topo.png)\n\n"
  },
  {
    "path": "examples/basic_evpn/spec.yaml",
    "content": "\nnodes:\n  - name: RR\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C3#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C5#net0 }\n      - { name: net2, type: direct, args: C6#net0 }\n\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C3\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C4\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n  - name: C5\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R3#net1 } ]\n  - name: C6\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R3#net2 } ]\n\nswitches:\n  - name: BB_SW\n    interfaces:\n      - { name: net0, type: container, args: R1 }\n      - { name: net0, type: container, args: R2 }\n      - { name: net0, type: container, args: R3 }\n      - { name: net0, type: container, args: RR }\n\nnode_configs:\n  - name: RR\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:ff:00:00\n      - cmd: /usr/lib/frr/frr start\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\"\n          -c \" ip address 10.255.0.254/32\"\n          -c \" exit\"\n          -c \"int net0\"\n          -c \" ip address 10.0.0.254/24\"\n          -c \" exit\"\n          -c \"ip route 10.255.0.1/32 10.0.0.1\"\n          -c \"ip route 10.255.0.2/32 10.0.0.2\"\n          -c \"ip route 10.255.0.3/32 10.0.0.3\"\n          -c \"router bgp 65001\"\n          -c \"  bgp router-id 10.255.0.254\"\n          -c \"  neighbor 10.255.0.1 remote-as internal\"\n          -c \"  neighbor 10.255.0.1 update-source lo\"\n          -c \"  neighbor 10.255.0.2 remote-as internal\"\n          -c \"  neighbor 10.255.0.2 update-source lo\"\n          -c \"  neighbor 10.255.0.3 remote-as internal\"\n          -c \"  neighbor 10.255.0.3 update-source lo\"\n          -c \"  address-family ipv4 unicast\"\n          -c \"   neighbor 10.255.0.1 activate\"\n          -c \"   neighbor 10.255.0.1 route-reflector-client\"\n          -c \"   neighbor 10.255.0.2 activate\"\n          -c \"   neighbor 10.255.0.2 route-reflector-client\"\n          -c \"   neighbor 10.255.0.3 activate\"\n          -c \"   neighbor 10.255.0.3 route-reflector-client\"\n          -c \"   exit-address-family\"\n          -c \"  address-family l2vpn evpn\"\n          -c \"   neighbor 10.255.0.1 activate\"\n          -c \"   neighbor 10.255.0.1 route-reflector-client\"\n          -c \"   neighbor 10.255.0.2 activate\"\n          -c \"   neighbor 10.255.0.2 route-reflector-client\"\n          -c \"   neighbor 10.255.0.3 activate\"\n          -c \"   neighbor 10.255.0.3 route-reflector-client\"\n          -c \"   advertise-all-vni\"\n          -c \"   exit-address-family\"\n\n  - name: R1\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:01:00\n      - cmd: ip link set net1 address 52:54:00:aa:01:01\n      - cmd: ip link set net2 address 52:54:00:aa:01:02\n      - cmd: /usr/lib/frr/frr start\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 10.100.0.1/16 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 local 10.255.0.1\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 10.200.0.1/16 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 local 10.255.0.1\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\"\n          -c \" ip address 10.255.0.1/32\"\n          -c \" exit\"\n          -c \"int net0\"\n          -c \" ip address 10.0.0.1/24\"\n          -c \" exit\"\n          -c \"ip route 10.255.0.254/32 10.0.0.254\"\n          -c \"ip route 10.255.0.2/32 10.0.0.2\"\n          -c \"ip route 10.255.0.3/32 10.0.0.3\"\n          -c \"router bgp 65001\"\n          -c \"  bgp router-id 10.255.0.1\"\n          -c \"  neighbor 10.255.0.254 remote-as internal\"\n          -c \"  neighbor 10.255.0.254 update-source lo\"\n          -c \"  address-family l2vpn evpn\"\n          -c \"   neighbor 10.255.0.254 activate\"\n          -c \"   advertise-all-vni\"\n          -c \"   exit-address-family\"\n\n  - name: R2\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:02:00\n      - cmd: ip link set net1 address 52:54:00:aa:02:01\n      - cmd: ip link set net2 address 52:54:00:aa:02:02\n      - cmd: /usr/lib/frr/frr start\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 10.100.0.2/16 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 local 10.255.0.2\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 10.200.0.2/16 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 local 10.255.0.2\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\"\n          -c \" ip address 10.255.0.2/32\"\n          -c \" exit\"\n          -c \"int net0\"\n          -c \" ip address 10.0.0.2/24\"\n          -c \" exit\"\n          -c \"ip route 10.255.0.254/32 10.0.0.254\"\n          -c \"ip route 10.255.0.1/32 10.0.0.1\"\n          -c \"ip route 10.255.0.3/32 10.0.0.3\"\n          -c \"router bgp 65001\"\n          -c \"  bgp router-id 10.255.0.2\"\n          -c \"  neighbor 10.255.0.254 remote-as internal\"\n          -c \"  neighbor 10.255.0.254 update-source lo\"\n          -c \"  address-family l2vpn evpn\"\n          -c \"   neighbor 10.255.0.254 activate\"\n          -c \"   advertise-all-vni\"\n          -c \"  exit-address-family\"\n\n  - name: R3\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:03:00\n      - cmd: ip link set net1 address 52:54:00:aa:03:01\n      - cmd: ip link set net2 address 52:54:00:aa:03:02\n      - cmd: /usr/lib/frr/frr start\n\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\"\n          -c \" ip address 10.255.0.3/32\"\n          -c \" exit\"\n          -c \"int net0\"\n          -c \" ip address 10.0.0.3/24\"\n          -c \" exit\"\n          -c \"ip route 10.255.0.254/32 10.0.0.254\"\n          -c \"ip route 10.255.0.1/32 10.0.0.1\"\n          -c \"ip route 10.255.0.2/32 10.0.0.2\"\n          -c \"router bgp 65001\"\n          -c \"  bgp router-id 10.255.0.3\"\n          -c \"  neighbor 10.255.0.254 remote-as internal\"\n          -c \"  neighbor 10.255.0.254 update-source lo\"\n          -c \"  address-family l2vpn evpn\"\n          -c \"   neighbor 10.255.0.254 activate\"\n          -c \"   advertise-all-vni\"\n          -c \"  exit-address-family\"\n\n  - name: C1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:01:00\n      - cmd: ip addr add 10.100.1.1/16 dev net0\n  - name: C2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:02:00\n      - cmd: ip addr add 10.200.1.2/16 dev net0\n  - name: C3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:03:00\n      - cmd: ip addr add 10.100.2.3/16 dev net0\n  - name: C4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:04:00\n      - cmd: ip addr add 10.200.2.4/16 dev net0\n\n# test:\n#   - cmds:\n#     - cmd: docker exec R0 ping -c2 10.0.0.2\n#     - cmd: docker exec R0 ping -c2 2.2.2.2\n#     - cmd: docker exec R1 ping -c2 1.1.1.1\n#     - cmd: docker exec C0 ping -c2 192.168.0.20\n#     - cmd: docker exec C1 ping -c2 192.168.0.2\n\n"
  },
  {
    "path": "examples/basic_exabgp/Makefile",
    "content": "\nexabgp:\n\texabgp ./exabgp.conf\n\nPCAP_PATH=/vagrant\ngetcapture:\n\ttcpdump -ni net0 -w $(PCAP_PATH)/in.pcap &\n\texabgp ./exabgp.conf &\n\tsleep 2\n\tkillall tcpdump\n\tkillall python3\n\nshow:\n\tdocker exec R1 vtysh -c 'sh bgp ipv4 uni'\n\n"
  },
  {
    "path": "examples/basic_exabgp/README.md",
    "content": "\n# ExaBGP test\n\n```\ntn upconf | sudo sh\ndocker_mount_netns R2 ns0\nip netns exec ns0 bash\nmake       //execute exabgp\nmake getcapture //execute exabgp and pcap.\n```\n\n\n"
  },
  {
    "path": "examples/basic_exabgp/daemons.R1",
    "content": "# This file tells the frr package which daemons to start.\n#\n# Sample configurations for these daemons can be found in\n# /usr/share/doc/frr/examples/.\n#\n# ATTENTION:\n#\n# When activating a daemon for the first time, a config file, even if it is\n# empty, has to be present *and* be owned by the user and group \"frr\", else\n# the daemon will not be started by /etc/init.d/frr. The permissions should\n# be u=rw,g=r,o=.\n# When using \"vtysh\" such a config file is also needed. It should be owned by\n# group \"frrvty\" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.\n#\n# The watchfrr and zebra daemons are always started.\n#\nbgpd=yes\nospfd=no\nospf6d=no\nripd=no\nripngd=no\nisisd=no\npimd=no\nldpd=no\nnhrpd=no\neigrpd=no\nbabeld=no\nsharpd=no\npbrd=no\nbfdd=no\nfabricd=no\nvrrpd=no\n\n#\n# If this option is set the /etc/init.d/frr script automatically loads\n# the config via \"vtysh -b\" when the servers are started.\n# Check /etc/pam.d/frr if you intend to use \"vtysh\"!\n#\nvtysh_enable=yes\nzebra_options=\"  -A 127.0.0.1 -s 90000000\"\nbgpd_options=\"   -A 127.0.0.1\"\nospfd_options=\"  -A 127.0.0.1\"\nospf6d_options=\" -A ::1\"\nripd_options=\"   -A 127.0.0.1\"\nripngd_options=\" -A ::1\"\nisisd_options=\"  -A 127.0.0.1\"\npimd_options=\"   -A 127.0.0.1\"\nldpd_options=\"   -A 127.0.0.1\"\nnhrpd_options=\"  -A 127.0.0.1\"\neigrpd_options=\" -A 127.0.0.1\"\nbabeld_options=\" -A 127.0.0.1\"\nsharpd_options=\" -A 127.0.0.1\"\npbrd_options=\"   -A 127.0.0.1\"\nstaticd_options=\"-A 127.0.0.1\"\nbfdd_options=\"   -A 127.0.0.1\"\nfabricd_options=\"-A 127.0.0.1\"\nvrrpd_options=\"  -A 127.0.0.1\"\n\n# configuration profile\n#\n#frr_profile=\"traditional\"\n#frr_profile=\"datacenter\"\n\n#\n# This is the maximum number of FD's that will be available.\n# Upon startup this is read by the control files and ulimit\n# is called.  Uncomment and use a reasonable value for your\n# setup if you are expecting a large number of peers in\n# say BGP.\n#MAX_FDS=1024\n\n# The list of daemons to watch is automatically generated by the init script.\n##watchfrr_options=\"\"\n\n# for debugging purposes, you can specify a \"wrap\" command to start instead\n# of starting the daemon directly, e.g. to use valgrind on ospfd:\n#   ospfd_wrap=\"/usr/bin/valgrind\"\n# or you can use \"all_wrap\" for all daemons, e.g. to use perf record:\n#   all_wrap=\"/usr/bin/perf record --call-graph -\"\n# the normal daemon command is added to this at the end.\n"
  },
  {
    "path": "examples/basic_exabgp/exabgp.conf",
    "content": "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 true;\n\t#}\n\n\tfamily {\n\t\tipv4 unicast;\n\t\tipv4 mpls-vpn;\n\t}\n\n\tnexthop {\n\t\t#ipv4 unicast ipv6;\n\t\t#ipv4 mpls-vpn ipv6;\n\t}\n\n\tstatic {\n\t\t#route 1.1.1.1/32 next-hop 2.2.2.2;\n\t\t#route 1.1.1.3/32 next-hop 2.2.2.2 bgp-prefix-sid [ 888 ];\n\t\t#route 1.1.1.6/32 next-hop 3.3.3.3 bgp-prefix-sid-srv6 ( ipv6 A:: );\n\t\t#route 2.2.2.2/32 rd 1:1 nexthop 2.2.2.2 extended-community [0x ]\n\t\t#route 1.1.1.10/32 next-hop cafe::1;\n\t\t#route 10.0.0.0/24 rd 65000:1 next-hop 200.10.0.101 extended-community [ 0x0002fde800000001 ] label 3 bgp-prefix-sid-srv6 ( vpn A:: );\n\t\t#route 10.0.0.0/24 rd 65000:1 next-hop 200.10.0.101 extended-community [ 0x0002fde800000001 ] label 3 bgp-prefix-sid-srv6 ( l3vpn A:: );\n\t\troute 10.0.0.0/24 rd 1:1 next-hop cafe::1 extended-community [ 0x0002fde800000001 ] label 3 bgp-prefix-sid-srv6 ( l3vpn 2001:1::10 );\n\t}\n}\n"
  },
  {
    "path": "examples/basic_exabgp/exabgp.conf.R2",
    "content": "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        #graceful-restart;\n\n        static {\n                route 8.8.8.8/32 next-hop 10.0.0.2;\n        }\n}\n"
  },
  {
    "path": "examples/basic_exabgp/frr.conf.R1",
    "content": "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 neighbor 10.0.0.2 remote-as 2\n neighbor 10.0.0.2 capability extended-nexthop\n !\n address-family ipv4 unicast\n  redistribute kernel\n exit-address-family\n !\n address-family ipv4 vpn\n  neighbor 10.0.0.2 activate\n exit-address-family\n!\nline vty\n!\n"
  },
  {
    "path": "examples/basic_exabgp/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: docker cp daemons.R1 R1:/etc/frr/daemons\n    - cmd: docker cp frr.conf.R1 R1:/etc/frr/frr.conf\n    - cmd: docker cp exabgp.conf.R2 R2:/root/exabgp.conf\n\nnodes:\n  - name: R1\n    # image: slankdev/centos-frr-dev:7\n    image: slankdev/frr:centos-7-latest\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/exabgp\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: /usr/lib/frr/frrinit.sh start\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n\n"
  },
  {
    "path": "examples/basic_fq_codel/README.md",
    "content": "# FQ-Codel demonstration\n\nSimple demonstration of the [FQ-Codel](https://www.bufferbloat.net/projects/codel/wiki/) that solves bufferbloat problem.\n\nYou can try the [bufferbloat demonstration](https://github.com/tinynetwork/tinet/tree/master/examples/basic_bufferbloat) first and compare what happened after fq_codel is enabled.\n\n![](./topo.png)\n"
  },
  {
    "path": "examples/basic_fq_codel/spec.yaml",
    "content": "nodes:\n- name: R1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n  - { name: net2, type: direct, args: C2#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C3#net0 }\n  - { name: net2, type: direct, args: C4#net0 }\n- name: C1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: C3\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n- name: C4\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net1\n  - cmd: ip addr add 10.0.1.1/24 dev net2\n  - cmd: ip addr add 10.0.2.1/24 dev net0\n  - cmd: ip route add default via 10.0.2.2\n  - cmd: \"tc qdisc add dev net0 root handle 1: htb default 1\"\n  - cmd: \"tc class add dev net0 parent 1: classid 1:1 htb rate 500mbit quantum 1514\"\n  - cmd: \"tc qdisc add dev net0 parent 1:1 fq_codel\"\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.0.2.2/24 dev net0\n  - cmd: ip addr add 10.0.3.1/24 dev net1\n  - cmd: ip addr add 10.0.4.1/24 dev net2\n  - cmd: ip route add default via 10.0.2.1\n  - cmd: \"tc qdisc add dev net0 root handle 1: htb default 1\"\n  - cmd: \"tc class add dev net0 parent 1: classid 1:1  htb rate 500mbit quantum 1514\"\n  - cmd: \"tc qdisc add dev net0 parent 1:1 fq_codel\"\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.0.1.2/24 dev net0\n  - cmd: ip route add default via 10.0.1.1\n- name: C3\n  cmds:\n  - cmd: ip addr add 10.0.3.2/24 dev net0\n  - cmd: ip route add default via 10.0.3.1\n- name: C4\n  cmds:\n  - cmd: ip addr add 10.0.4.2/24 dev net0\n  - cmd: ip route add default via 10.0.4.1\ntest:\n  - cmds:\n    - cmd: echo \"==========================================\"\n    - cmd: echo \"iperf from C1 to C3\"\n    - cmd: echo \"==========================================\"\n    - cmd: docker exec C3 iperf -s -i 1 &\n    - cmd: sleep 3\n    - cmd: docker exec C1 iperf -c 10.0.3.2 2>&1 > /dev/null\n    - cmd: docker exec C3 pkill iperf\n    - cmd: echo \"==========================================\"\n    - cmd: echo \"ping from C2 to C4\"\n    - cmd: echo \"==========================================\"\n    - cmd: docker exec C2 ping -c 10 10.0.4.2\n    - cmd: echo \"==========================================\"\n    - cmd: echo \"ping from C2 to C4 while iperf-ing from C1 to C3\"\n    - cmd: echo \"==========================================\"\n    - cmd: docker exec C3 iperf -s 2>&1 > /dev/null &\n    - cmd: sleep 3\n    - cmd: docker exec C1 iperf -c 10.0.3.2 -t 60 2>&1 > /dev/null &\n    - cmd: sleep 3\n    - cmd: docker exec C2 ping -c 10 10.0.4.2\n    - cmd: docker exec C1 pkill iperf\n    - cmd: sleep 3\n    - cmd: docker exec C3 pkill iperf\n"
  },
  {
    "path": "examples/basic_gcp_hv/spec.yaml",
    "content": "---\nnodes:\n- name: HV1\n  image: slankdev/frr\n  interfaces:\n  - { name: tap1, type: direct, args: VM1#net0 }\n  - { name: tap2, type: direct, args: VM2#net0 }\n- name: VM1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: HV1#tap1 }\n- name: VM2\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: HV1#tap2 }\n\nnode_configs:\n\n- name: HV1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/32 dev tap1\n  - cmd: ip addr add 10.0.0.1/32 dev tap2\n  - cmd: ip route add 10.0.0.11/32 dev tap1\n  - cmd: ip route add 10.0.0.12/32 dev tap2\n\n- name: VM1\n  cmds:\n  - cmd: ip addr add 10.0.0.11/32 dev net0\n  - cmd: ip route add 10.0.0.1 dev net0 proto static scope link src 10.0.0.11 metric 100\n  - cmd: ip route add default via 10.0.0.1 dev net0 proto static src 10.0.0.11 metric 100\n\n- name: VM2\n  cmds:\n  - cmd: ip addr add 10.0.0.12/32 dev net0\n  - cmd: ip route add 10.0.0.1 dev net0 proto static scope link src 10.0.0.12 metric 100\n  - cmd: ip route add default via 10.0.0.1 dev net0 proto static src 10.0.0.12 metric 100\n"
  },
  {
    "path": "examples/basic_geneve/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n- name: R2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C2#net0 }\n- name: C1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip link add name geneve0 type geneve id 10 remote 10.0.0.2\n  - cmd: ip link set geneve0 up\n  - cmd: ip link add br0 type bridge\n  - cmd: ip link set br0 up\n  - cmd: ip link set geneve0 master br0\n  - cmd: ip link set net1 master br0\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip link add name geneve0 type geneve id 10 remote 10.0.0.1\n  - cmd: ip link set geneve0 up\n  - cmd: ip link add br0 type bridge\n  - cmd: ip link set br0 up\n  - cmd: ip link set geneve0 master br0\n  - cmd: ip link set net1 master br0\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.99.0.1/24 dev net0\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.99.0.2/24 dev net0\n"
  },
  {
    "path": "examples/basic_gre/README.md",
    "content": "\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_ADDR> ttl <TTL>\nip link set <IF_NAME> mtu <MTU> up\nip addr add <LOCAL_IPV6_ADDR>/<PREFIXLEN> dev <IF_NAME>\n```\n"
  },
  {
    "path": "examples/basic_gre/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R5#net0 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R6#net0 }\n  - name: R5\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n  - name: R6\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R4#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.255.0.1/32 dev lo\n      - cmd: ip addr add 10.0.0.1/30 dev net0\n      - cmd: ip addr add 10.0.0.5/30 dev net1\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.1'\n          -c ' network 10.255.0.1/32 area 0'\n          -c ' network 10.0.0.0/30 area 0'\n          -c ' network 10.0.0.4/30 area 0'\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.255.0.2/32 dev lo\n      - cmd: ip addr add 10.0.0.2/30 dev net0\n      - cmd: ip addr add 10.0.0.9/30 dev net1\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.2'\n          -c ' network 10.255.0.2/32 area 0'\n          -c ' network 10.0.0.0/30 area 0'\n          -c ' network 10.0.0.8/30 area 0'\n  - name: R3\n    cmds:\n      - cmd: ip addr add 10.255.0.3/32 dev lo\n      - cmd: ip addr add 10.0.0.6/30 dev net0\n      - cmd: ip addr add 10.0.0.13/30 dev net1\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'ip route 10.0.0.8/30 10.0.0.5' ## This is IMPORTANT..?\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.3'\n          -c ' network 10.255.0.3/32 area 0'\n          -c ' network 10.0.0.4/30 area 0'\n          -c ' network 10.0.0.12/30 area 0'\n          -c ' network 20.0.0.0/30 area 0'\n      - cmd: ip tunnel add gre1 mode gre remote 10.255.0.4 local 10.255.0.3 ttl 10\n      - cmd: ip link set gre1 up\n      - cmd: ip addr add 20.0.0.1/30 dev gre1\n  - name: R4\n    cmds:\n      - cmd: ip addr add 10.255.0.4/32 dev lo\n      - cmd: ip addr add 10.0.0.10/30 dev net0\n      - cmd: ip addr add 10.0.0.17/30 dev net1\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'ip route 10.0.0.4/30 10.0.0.9' ## This is IMPORTANT..?\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.4'\n          -c ' network 10.255.0.4/32 area 0'\n          -c ' network 10.0.0.8/30 area 0'\n          -c ' network 10.0.0.16/30 area 0'\n          -c ' network 20.0.0.0/30 area 0'\n      - cmd: ip tunnel add gre1 mode gre remote 10.255.0.3 local 10.255.0.4 ttl 10\n      - cmd: ip link set gre1 up\n      - cmd: ip addr add 20.0.0.2/30 dev gre1\n  - name: R5\n    cmds:\n      - cmd: ip addr add 10.255.0.5/32 dev lo\n      - cmd: ip addr add 10.0.0.14/30 dev net0\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.5'\n          -c ' network 10.255.0.5/32 area 0'\n          -c ' network 10.0.0.12/30 area 0'\n  - name: R6\n    cmds:\n      - cmd: ip addr add 10.255.0.6/32 dev lo\n      - cmd: ip addr add 10.0.0.18/30 dev net0\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.6'\n          -c ' network 10.255.0.6/32 area 0'\n          -c ' network 10.0.0.16/30 area 0'\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec R1 ping -c2 10.0.0.1\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.0.0.5\n    - cmd: docker exec R1 ping -c2 10.0.0.6\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.2\n    - cmd: docker exec R2 ping -c2 10.0.0.9\n    - cmd: docker exec R2 ping -c2 10.0.0.10\n    - cmd: docker exec R3 ping -c2 10.0.0.5\n    - cmd: docker exec R3 ping -c2 10.0.0.6\n    - cmd: docker exec R3 ping -c2 10.0.0.13\n    - cmd: docker exec R3 ping -c2 10.0.0.14\n    - cmd: docker exec R4 ping -c2 10.0.0.9\n    - cmd: docker exec R4 ping -c2 10.0.0.10\n    - cmd: docker exec R4 ping -c2 10.0.0.17\n    - cmd: docker exec R4 ping -c2 10.0.0.18\n    - cmd: docker exec R5 ping -c2 10.0.0.13\n    - cmd: docker exec R5 ping -c2 10.0.0.14\n    - cmd: docker exec R6 ping -c2 10.0.0.17\n    - cmd: docker exec R6 ping -c2 10.0.0.18\n  - name: lo\n    cmds:\n    - cmd: docker exec R1 ping -c2 10.255.0.1\n    - cmd: docker exec R1 ping -c2 10.255.0.2\n    - cmd: docker exec R1 ping -c2 10.255.0.3\n    - cmd: docker exec R1 ping -c2 10.255.0.4\n    - cmd: docker exec R1 ping -c2 10.255.0.5\n    - cmd: docker exec R1 ping -c2 10.255.0.6\n    - cmd: docker exec R2 ping -c2 10.255.0.1\n    - cmd: docker exec R2 ping -c2 10.255.0.2\n    - cmd: docker exec R2 ping -c2 10.255.0.3\n    - cmd: docker exec R2 ping -c2 10.255.0.4\n    - cmd: docker exec R2 ping -c2 10.255.0.5\n    - cmd: docker exec R2 ping -c2 10.255.0.6\n    - cmd: docker exec R3 ping -c2 10.255.0.1\n    - cmd: docker exec R3 ping -c2 10.255.0.2\n    - cmd: docker exec R3 ping -c2 10.255.0.3\n    - cmd: docker exec R3 ping -c2 10.255.0.4\n    - cmd: docker exec R3 ping -c2 10.255.0.5\n    - cmd: docker exec R3 ping -c2 10.255.0.6\n    - cmd: docker exec R4 ping -c2 10.255.0.1\n    - cmd: docker exec R4 ping -c2 10.255.0.2\n    - cmd: docker exec R4 ping -c2 10.255.0.3\n    - cmd: docker exec R4 ping -c2 10.255.0.4\n    - cmd: docker exec R4 ping -c2 10.255.0.5\n    - cmd: docker exec R4 ping -c2 10.255.0.6\n    - cmd: docker exec R5 ping -c2 10.255.0.1\n    - cmd: docker exec R5 ping -c2 10.255.0.2\n    - cmd: docker exec R5 ping -c2 10.255.0.3\n    - cmd: docker exec R5 ping -c2 10.255.0.4\n    - cmd: docker exec R5 ping -c2 10.255.0.5\n    - cmd: docker exec R5 ping -c2 10.255.0.6\n    - cmd: docker exec R6 ping -c2 10.255.0.1\n    - cmd: docker exec R6 ping -c2 10.255.0.2\n    - cmd: docker exec R6 ping -c2 10.255.0.3\n    - cmd: docker exec R6 ping -c2 10.255.0.4\n    - cmd: docker exec R6 ping -c2 10.255.0.5\n    - cmd: docker exec R6 ping -c2 10.255.0.6\n\n\n"
  },
  {
    "path": "examples/basic_haproxy/README.md",
    "content": "# HAProxy demonstration\n\n![](./topo.png)\n\n**How to test**<br>\nP1 is configured HAProxy container as-a TCP proxy.\nYou can check the behabiour of proxy when you run\nthe curl command to access 10.0.0.1(P1's address) on C1.\n```\n$ cd /path/to/here\n$ tn upconf | sudo sh\n...\n$ docker exec C1 curl -s 10.0.0.1\nS1\n$ docker exec C1 curl -s 10.0.0.1\nS2\n$ docker exec C1 curl -s 10.0.0.1\nS3\n$ docker exec C1 curl -s 10.0.0.1\nS4\n$ docker exec C1 curl -s 10.0.0.1\nS1\n$ docker exec C1 curl -s 10.0.0.1\nS2\n```\n"
  },
  {
    "path": "examples/basic_haproxy/spec.yaml",
    "content": "\nnodes:\n  - name: C1\n    image: slankdev/sandbox\n    interfaces:\n      - { name: net0, type: direct, args: P1#net0 }\n  - name: P1\n    image: slankdev/sandbox\n    interfaces:\n      - { name: net0, type: direct, args: C1#net0 }\n      - { name: net1, type: bridge, args: SW }\n  - name: S1\n    image: slankdev/sandbox\n    interfaces: [ { name: net0, type: bridge, args: SW } ]\n  - name: S2\n    image: slankdev/sandbox\n    interfaces: [ { name: net0, type: bridge, args: SW } ]\n  - name: S3\n    image: slankdev/sandbox\n    interfaces: [ { name: net0, type: bridge, args: SW } ]\n  - name: S4\n    image: slankdev/sandbox\n    interfaces: [ { name: net0, type: bridge, args: SW } ]\n\nswitches:\n  - name: SW\n    interfaces:\n      - { name: net1, type: docker, args: P1 }\n      - { name: net0, type: docker, args: S1 }\n      - { name: net0, type: docker, args: S2 }\n      - { name: net0, type: docker, args: S3 }\n      - { name: net0, type: docker, args: S4 }\n\nnode_configs:\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n  - name: P1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 10.1.0.254/24 dev net1\n      - cmd: bash -c \"echo 'global                       ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  daemon                     ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '                             ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo 'defaults                     ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  log global                 ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  mode tcp                   ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '                             ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo 'frontend main                ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  bind *:80                  ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  default_backend static     ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '                             ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo 'backend static               ' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  server S1 10.1.0.1:80 check' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  server S2 10.1.0.2:80 check' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  server S3 10.1.0.3:80 check' >> /root/haproxy.conf\"\n      - cmd: bash -c \"echo '  server S4 10.1.0.4:80 check' >> /root/haproxy.conf\"\n      - cmd: haproxy -f /root/haproxy.conf\n\n  - name: S1\n    cmds:\n      - cmd: ip addr add 10.1.0.1/24 dev net0\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n  - name: S2\n    cmds:\n      - cmd: ip addr add 10.1.0.2/24 dev net0\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n  - name: S3\n    cmds:\n      - cmd: ip addr add 10.1.0.3/24 dev net0\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n  - name: S4\n    cmds:\n      - cmd: ip addr add 10.1.0.4/24 dev net0\n      - cmd: sh -c \"cat /etc/hostname > index.html\"\n      - cmd: nohup python3 -m http.server 80 &\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec C1 ping -c2 10.0.0.1\n    - cmd: docker exec C1 ping -c2 10.0.0.2\n    - cmd: docker exec P1 ping -c2 10.0.0.1\n    - cmd: docker exec P1 ping -c2 10.0.0.2\n    - cmd: docker exec P1 ping -c2 10.1.0.1\n    - cmd: docker exec P1 ping -c2 10.1.0.2\n    - cmd: docker exec P1 ping -c2 10.1.0.3\n    - cmd: docker exec P1 ping -c2 10.1.0.4\n\n"
  },
  {
    "path": "examples/basic_ipip/anycast_tunnel/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: docker cp /root/dotfiles/bin/linkstat.py CLOS:/usr/bin/linkstat.py\n    - cmd: docker cp /root/dotfiles/bin/http_server.py CS:/usr/bin/http_server.py\n    - cmd: docker cp /root/dotfiles/bin/echo_server.py CS:/usr/bin/echo_server.py\n\nnodes:\n  - name: CLOS\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net1, type: direct, args: N1#net0 }\n      - { name: net2, type: direct, args: N2#net0 }\n      - { name: net3, type: direct, args: N2#net0 }\n      - { name: up1, type: direct, args: CS#net0 }\n      - { name: dn1, type: direct, args: HV1#net0 }\n\n  - name: N1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: CLOS#net1 }\n  - name: N2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: CLOS#net2 }\n  - name: N3\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: CLOS#net3 }\n\n  - name: HV1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: CLOS#dn1 }\n  - name: CS\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: CLOS#up1 }\n\nnode_configs:\n  - name: CLOS\n    cmds:\n      - cmd: ip addr add 10.255.0.10/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: sysctl -w net.ipv4.fib_multipath_hash_policy=1\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 10\"\n          -c \" bgp router-id 10.255.0.10\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net1 interface peer-group FABRIC\"\n          -c \" neighbor net2 interface peer-group FABRIC\"\n          -c \" neighbor net3 interface peer-group FABRIC\"\n          -c \" neighbor up1 interface peer-group FABRIC\"\n          -c \" neighbor dn1 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.255.0.10/32\"\n          -c \" exit-address-family\"\n\n  - name: N1\n    cmds:\n      - cmd: ip addr add 10.255.0.1/32 dev lo\n      - cmd: ip addr add 10.255.0.254/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 1\"\n          -c \" bgp router-id 10.255.0.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.255.0.1/32\"\n          -c \"  network 10.255.0.254/32\"\n          -c \" exit-address-family\"\n      - cmd: ip tunnel add tun-nat2 mode ipip local 10.255.0.1 remote 10.255.0.2 dev net0\n      - cmd: ip addr add 10.254.0.1/32 peer 10.254.0.2/32 dev tun-nat2\n      - cmd: ip link set tun-nat2 up\n      - cmd: ip tunnel add tun-nat3 mode ipip local 10.255.0.1 remote 10.255.0.3 dev net0\n      - cmd: ip addr add 10.254.0.1/32 peer 10.254.0.3/32 dev tun-nat3\n      - cmd: ip link set tun-nat3 up\n\n      - cmd: ip link set tunl0 up\n      - cmd: iptables -t nat -A POSTROUTING -s 10.255.0.20/32 -j SNAT -p tcp --to-source 10.255.0.254:10000-10063\n\n  - name: N2\n    cmds:\n      - cmd: ip addr add 10.255.0.2/32 dev lo\n      - cmd: ip addr add 10.255.0.254/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 2\"\n          -c \" bgp router-id 10.255.0.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.255.0.2/32\"\n          -c \"  !network 10.255.0.254/32\"\n          -c \" exit-address-family\"\n      - cmd: ip tunnel add tun-nat1 mode ipip local 10.255.0.2 remote 10.255.0.1 dev net0\n      - cmd: ip addr add 10.254.0.2/32 peer 10.254.0.1/32 dev tun-nat1\n      - cmd: ip link set tun-nat1 up\n      - cmd: ip tunnel add tun-nat3 mode ipip local 10.255.0.2 remote 10.255.0.3 dev net0\n      - cmd: ip addr add 10.254.0.2/32 peer 10.254.0.3/32 dev tun-nat3\n      - cmd: ip link set tun-nat3 up\n\n      - cmd: ip link set tunl0 up\n\n  - name: N3\n    cmds:\n      - cmd: ip addr add 10.255.0.3/32 dev lo\n      - cmd: ip addr add 10.255.0.254/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 3\"\n          -c \" bgp router-id 10.255.0.3\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.255.0.3/32\"\n          -c \"  !network 10.255.0.254/32\"\n          -c \" exit-address-family\"\n      - cmd: ip tunnel add tun-nat1 mode ipip local 10.255.0.3 remote 10.255.0.1 dev net0\n      - cmd: ip addr add 10.254.0.3/32 peer 10.254.0.1/32 dev tun-nat1\n      - cmd: ip link set tun-nat1 up\n      - cmd: ip tunnel add tun-nat2 mode ipip local 10.255.0.3 remote 10.255.0.2 dev net0\n      - cmd: ip addr add 10.254.0.3/32 peer 10.254.0.2/32 dev tun-nat2\n      - cmd: ip link set tun-nat2 up\n\n      - cmd: ip link set tunl0 up\n\n  - name: HV1\n    cmds:\n      - cmd: ip addr add 10.255.0.20/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 20\"\n          -c \" bgp router-id 10.255.0.20\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.255.0.20/32\"\n          -c \" exit-address-family\"\n\n      - cmd: ip tunnel add tun-nat1 mode ipip remote 10.255.0.254 dev net0\n      - cmd: ip link set tun-nat1 up\n      - cmd: ip route add default dev tun-nat1\n\n  - name: CS\n    cmds:\n      - cmd: ip addr add 10.255.0.30/32 dev lo\n      - cmd: ip addr add 8.8.8.8/32 dev lo\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 30\"\n          -c \" bgp router-id 10.255.0.30\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  network 10.255.0.30/32\"\n          -c \"  network 0.0.0.0/0\"\n          -c \" exit-address-family\"\n\n      - cmd: nohup /usr/bin/http_server.py &\n      - cmd: nohup /usr/bin/echo_server.py &\n"
  },
  {
    "path": "examples/basic_ipip/simple/README.md",
    "content": "\n# IPIP tunnel\n\n![](topo.png)\n\n"
  },
  {
    "path": "examples/basic_ipip/simple/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n- name: R2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R3#net0 }\n- name: R3\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip route add default via 10.0.0.2\n  - cmd: ip tunnel add tun0 mode ipip remote 10.1.0.2 local 10.0.0.1 dev net0\n  - cmd: ip addr add 1.1.1.1 peer 1.1.1.2 dev tun0\n  - cmd: ip link set tun0 up\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n  - cmd: ip tunnel add tun0 mode ipip remote 10.0.0.1 local 10.1.0.2 dev net0\n  - cmd: ip addr add 1.1.1.2 peer 1.1.1.1 dev tun0\n  - cmd: ip link set tun0 up\n"
  },
  {
    "path": "examples/basic_ipsec/bgp/README.md",
    "content": "## References\n\nhttps://gist.github.com/Manouchehri/de3adfb02c5b55f3edc2da9e8ee59fae\n"
  },
  {
    "path": "examples/basic_ipsec/bgp/spec.yaml",
    "content": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.conf\n      conn vpn1\n        authby=secret\n        left=10.91.0.2\n        right=10.92.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.conf\n      conn vpn1\n        authby=secret\n        left=10.92.0.2\n        right=10.91.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/vpn1.r1.secrets R1:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r2.secrets R2:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r1.conf R1:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/vpn1.r2.conf R2:/etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.secrets\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.secrets\n\nnodes:\n- name: R0\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n- name: R1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R0#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n- name: R2\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R0#net1 }\n  - { name: net1, type: direct, args: C2#net0 }\n- name: C1\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R0\n  cmds:\n  - cmd: ip addr add 10.91.0.1/24 dev net0\n  - cmd: ip addr add 10.92.0.1/24 dev net1\n\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.91.0.2/24 dev net0\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n  - cmd: ip route add 10.92.0.0/24 via 10.91.0.1\n\n  - cmd: ip link add vti0 type vti key 100 remote 10.92.0.2 local 10.91.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.1/30 remote 169.254.0.2/30 dev vti0\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65001'\n      -c ' bgp router-id 169.254.0.1'\n      -c ' neighbor 169.254.0.2 remote-as 65002'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.1.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.92.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: ip route add 10.91.0.0/24 via 10.92.0.1\n\n  - cmd: ip link add vti0 type vti key 100 remote 10.91.0.2 local 10.92.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.2/30 remote 169.254.0.1/30 dev vti0\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65002'\n      -c ' bgp router-id 169.254.0.2'\n      -c ' neighbor 169.254.0.1 remote-as 65001'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.2.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n"
  },
  {
    "path": "examples/basic_ipsec/bgp_ha/spec.yaml",
    "content": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn2.r3.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn2.r2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.conf\n      conn vpn1\n        authby=secret\n        left=10.91.0.2\n        right=10.92.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn2.r3.conf\n      conn vpn1\n        authby=secret\n        left=10.93.0.2\n        right=10.92.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.conf\n      conn vpn1\n        authby=secret\n        left=10.92.0.2\n        right=10.91.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn2.r2.conf\n      conn vpn2\n        authby=secret\n        left=10.92.0.2\n        right=10.93.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/vpn1.r1.secrets R1:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r2.secrets R2:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r1.conf R1:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/vpn1.r2.conf R2:/etc/ipsec.d/vpn1.conf\n\n  - cmd: docker cp /tmp/vpn2.r3.secrets R3:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/vpn2.r2.secrets R2:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/vpn2.r3.conf R3:/etc/ipsec.d/vpn2.conf\n  - cmd: docker cp /tmp/vpn2.r2.conf R2:/etc/ipsec.d/vpn2.conf\n\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.secrets\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.secrets\n\n  - cmd: docker exec R3 chmod 600 /etc/ipsec.d/vpn2.conf\n  - cmd: docker exec R3 chmod 600 /etc/ipsec.d/vpn2.secrets\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn2.conf\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn2.secrets\n\nnodes:\n- name: R0\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R3#net0 }\n- name: R1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R0#net0 }\n  - { name: net1, type: direct, args: N1#net0 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: R2\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R0#net1 }\n  - { name: net1, type: direct, args: C2#net0 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: R3\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R0#net2 }\n  - { name: net1, type: direct, args: N1#net1 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: N1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R3#net1 }\n  - { name: net2, type: direct, args: C1#net0 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: C1\n  image: slankdev/tmp\n  interfaces:\n  - { name: net0, type: direct, args: N1#net2 }\n- name: C2\n  image: slankdev/tmp\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R0\n  cmds:\n  - cmd: ip addr add 10.91.0.1/24 dev net0\n  - cmd: ip addr add 10.92.0.1/24 dev net1\n  - cmd: ip addr add 10.93.0.1/24 dev net2\n\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.91.0.2/24 dev net0\n  - cmd: ip addr add 10.1.0.101/24 dev net1\n  - cmd: ip route add 10.92.0.0/24 via 10.91.0.1\n\n  - cmd: ip link add vti0 type vti key 100 remote 10.92.0.2 local 10.91.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.1/30 remote 169.254.0.2/30 dev vti0\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65001'\n      -c ' bgp router-id 169.254.0.1'\n      -c ' neighbor 169.254.0.2 remote-as 65002'\n      -c ' neighbor 10.1.0.10   remote-as 65000'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.1.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.93.0.2/24 dev net0\n  - cmd: ip addr add 10.1.0.103/24 dev net1\n  - cmd: ip route add 10.92.0.0/24 via 10.93.0.1\n\n  - cmd: ip link add vti0 type vti key 100 remote 10.92.0.2 local 10.93.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.1.1/30 remote 169.254.1.2/30 dev vti0\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65001'\n      -c ' bgp router-id 169.254.1.1'\n      -c ' neighbor 169.254.1.2 remote-as 65002'\n      -c ' neighbor 10.1.0.11   remote-as 65000'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.1.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.92.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: ip route add 10.91.0.0/24 via 10.92.0.1\n  - cmd: ip route add 10.93.0.0/24 via 10.92.0.1\n\n  - cmd: ip link add vti0 type vti key 100 remote 10.91.0.2 local 10.92.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.2/30 remote 169.254.0.1/30 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 10.93.0.2 local 10.92.0.2\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.1.2/30 remote 169.254.1.1/30 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65002'\n      -c ' bgp router-id 169.254.0.2'\n      -c ' neighbor 169.254.0.1 remote-as 65001'\n      -c ' neighbor 169.254.1.1 remote-as 65001'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.2.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: N1\n  cmds:\n  - cmd: ip addr add 10.1.0.10/24 dev net0\n  - cmd: ip addr add 10.1.0.11/24 dev net1\n  - cmd: ip addr add 10.1.0.1/24 dev net2\n  - cmd: ip route add 10.1.0.101/32 dev net0\n  - cmd: ip route add 10.1.0.103/32 dev net1\n  - cmd: ip route add 10.1.0.2/32 dev net2\n\n  - cmd: sysctl -w net.ipv4.conf.net0.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net1.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net2.proxy_arp=1\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65000'\n      -c ' bgp router-id 1.1.1.1'\n      -c ' neighbor 10.1.0.101 remote-as 65001'\n      -c ' neighbor 10.1.0.101 disable-connected-check'\n      -c ' neighbor 10.1.0.103 remote-as 65001'\n      -c ' neighbor 10.1.0.103 disable-connected-check'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n"
  },
  {
    "path": "examples/basic_ipsec/mesh/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N1#net0 }\n- name: R2\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N1#net1 }\n- name: R3\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N2#net0 }\n- name: R4\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N2#net1 }\n- name: N1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: C1#net0 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: N2\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: C2#net0 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: C1\n  image: slankdev/tmp\n  interfaces:\n  - { name: net0, type: direct, args: N1#net2 }\n- name: C2\n  image: slankdev/tmp\n  interfaces:\n  - { name: net0, type: direct, args: N2#net2 }\n\nswitches:\n- name: B0\n  interfaces:\n  - { name: net0, type: container, args: R1 }\n  - { name: net0, type: container, args: R2 }\n  - { name: net0, type: container, args: R3 }\n  - { name: net0, type: container, args: R4 }\n\nnode_configs:\n\n- name: R1\n  cmds:\n  - cmd: ip addr add 20.0.0.1/24 dev net0\n  - cmd: ip addr add 10.1.0.100/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.3 local 20.0.0.1\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.1/32 remote 169.254.0.3/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.4 local 20.0.0.1\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.1/32 remote 169.254.0.4/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 20.0.0.2/24 dev net0\n  - cmd: ip addr add 10.1.0.101/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.3 local 20.0.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.2/32 remote 169.254.0.3/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.4 local 20.0.0.2\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.2/32 remote 169.254.0.4/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 20.0.0.3/24 dev net0\n  - cmd: ip addr add 10.2.0.100/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.1 local 20.0.0.3\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.3/32 remote 169.254.0.1/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.2 local 20.0.0.3\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.3/32 remote 169.254.0.2/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 20.0.0.4/24 dev net0\n  - cmd: ip addr add 10.2.0.101/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.1 local 20.0.0.4\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.4/32 remote 169.254.0.1/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.2 local 20.0.0.4\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.4/32 remote 169.254.0.2/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: N1\n  cmds:\n  - cmd: ip addr add 10.1.0.1/24 dev net0\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n  - cmd: ip addr add 10.1.0.1/24 dev net2\n  - cmd: ip route add 10.1.0.100/32 dev net0\n  - cmd: ip route add 10.1.0.101/32 dev net1\n  - cmd: ip route add 10.1.0.10/32 dev net2\n  - cmd: sysctl -w net.ipv4.conf.net0.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net1.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net2.proxy_arp=1\n\n- name: N1\n  cmds:\n  - cmd: ip addr add 10.2.0.1/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: ip addr add 10.2.0.1/24 dev net2\n  - cmd: ip route add 10.2.0.100/32 dev net0\n  - cmd: ip route add 10.2.0.101/32 dev net1\n  - cmd: ip route add 10.2.0.10/32 dev net2\n  - cmd: sysctl -w net.ipv4.conf.net0.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net1.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net2.proxy_arp=1\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.10/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.10/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.1\n        right=20.0.0.3\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.1\n        right=20.0.0.4\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/r1_vpn1.secrets R1:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r1_vpn2.secrets R1:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r1_vpn1.conf    R1:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r1_vpn2.conf    R1:/etc/ipsec.d/vpn2.conf\n\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.2\n        right=20.0.0.3\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.2\n        right=20.0.0.4\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/r2_vpn1.secrets R2:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r2_vpn2.secrets R2:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r2_vpn1.conf    R2:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r2_vpn2.conf    R2:/etc/ipsec.d/vpn2.conf\n\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.3\n        right=20.0.0.1\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.3\n        right=20.0.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/r3_vpn1.secrets R3:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r3_vpn2.secrets R3:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r3_vpn1.conf    R3:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r3_vpn2.conf    R3:/etc/ipsec.d/vpn2.conf\n\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.4\n        right=20.0.0.1\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.4\n        right=20.0.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/r4_vpn1.secrets R4:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r4_vpn2.secrets R4:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r4_vpn1.conf    R4:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r4_vpn2.conf    R4:/etc/ipsec.d/vpn2.conf\n"
  },
  {
    "path": "examples/basic_ipsec/mesh_bgp/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N1#net0 }\n- name: R2\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N1#net1 }\n- name: R3\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N2#net0 }\n- name: R4\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: bridge, args: B0 }\n  - { name: net1, type: direct, args: N2#net1 }\n- name: N1\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: C1#net0 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: N2\n  image: tinet/cloudvpn\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: C2#net0 }\n  sysctls:\n  - { sysctl: net.ipv4.fib_multipath_hash_policy=1 }\n- name: C1\n  image: slankdev/tmp\n  interfaces:\n  - { name: net0, type: direct, args: N1#net2 }\n- name: C2\n  image: slankdev/tmp\n  interfaces:\n  - { name: net0, type: direct, args: N2#net2 }\n\nswitches:\n- name: B0\n  interfaces:\n  - { name: net0, type: container, args: R1 }\n  - { name: net0, type: container, args: R2 }\n  - { name: net0, type: container, args: R3 }\n  - { name: net0, type: container, args: R4 }\n\nnode_configs:\n\n- name: R1\n  cmds:\n  - cmd: ip addr add 20.0.0.1/24 dev net0\n  - cmd: ip addr add 10.1.0.100/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.3 local 20.0.0.1\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.1/32 remote 169.254.0.3/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.4 local 20.0.0.1\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.1/32 remote 169.254.0.4/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65001'\n      -c ' bgp router-id 169.254.0.1'\n      -c ' neighbor 169.254.0.3 remote-as 65002'\n      -c ' neighbor 169.254.0.4 remote-as 65002'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.1.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 20.0.0.2/24 dev net0\n  - cmd: ip addr add 10.1.0.101/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.3 local 20.0.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.2/32 remote 169.254.0.3/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.4 local 20.0.0.2\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.2/32 remote 169.254.0.4/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65001'\n      -c ' bgp router-id 169.254.0.2'\n      -c ' neighbor 169.254.0.3 remote-as 65002'\n      -c ' neighbor 169.254.0.4 remote-as 65002'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.1.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 20.0.0.3/24 dev net0\n  - cmd: ip addr add 10.2.0.100/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.1 local 20.0.0.3\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.3/32 remote 169.254.0.1/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.2 local 20.0.0.3\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.3/32 remote 169.254.0.2/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65002'\n      -c ' bgp router-id 169.254.0.3'\n      -c ' neighbor 169.254.0.1 remote-as 65001'\n      -c ' neighbor 169.254.0.2 remote-as 65001'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.2.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 20.0.0.4/24 dev net0\n  - cmd: ip addr add 10.2.0.101/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 20.0.0.1 local 20.0.0.4\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip addr add 169.254.0.4/32 remote 169.254.0.1/32 dev vti0\n\n  - cmd: ip link add vti1 type vti key 101 remote 20.0.0.2 local 20.0.0.4\n  - cmd: ip link set vti1 up\n  - cmd: sysctl -w net.ipv4.conf.vti1.disable_policy=1\n  - cmd: ip addr add 169.254.0.4/32 remote 169.254.0.2/32 dev vti1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n  - cmd: sed -i -e \"s/bgpd=no/bgpd=yes/g\" /etc/frr/daemons\n  - cmd: /usr/lib/frr/frrinit.sh start\n  - cmd: >-\n      vtysh -c 'conf t'\n      -c 'router bgp 65002'\n      -c ' bgp router-id 169.254.0.4'\n      -c ' neighbor 169.254.0.1 remote-as 65001'\n      -c ' neighbor 169.254.0.2 remote-as 65001'\n      -c ' !'\n      -c ' address-family ipv4 unicast'\n      -c '  network 10.2.0.0/24'\n      -c ' exit-address-family'\n      -c '!'\n\n- name: N1\n  cmds:\n  - cmd: ip addr add 10.1.0.1/24 dev net0\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n  - cmd: ip addr add 10.1.0.1/24 dev net2\n  - cmd: ip route add 10.1.0.100/32 dev net0\n  - cmd: ip route add 10.1.0.101/32 dev net1\n  - cmd: ip route add 10.1.0.10/32 dev net2\n  - cmd: sysctl -w net.ipv4.conf.net0.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net1.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net2.proxy_arp=1\n  - cmd: >-\n      ip route add default\n      nexthop via 10.1.0.100 dev net0\n      nexthop via 10.1.0.101 dev net1\n\n- name: N2\n  cmds:\n  - cmd: ip addr add 10.2.0.1/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: ip addr add 10.2.0.1/24 dev net2\n  - cmd: ip route add 10.2.0.100/32 dev net0\n  - cmd: ip route add 10.2.0.101/32 dev net1\n  - cmd: ip route add 10.2.0.10/32 dev net2\n  - cmd: sysctl -w net.ipv4.conf.net0.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net1.proxy_arp=1\n  - cmd: sysctl -w net.ipv4.conf.net2.proxy_arp=1\n  - cmd: >-\n      ip route add default\n      nexthop via 10.2.0.100 dev net0\n      nexthop via 10.2.0.101 dev net1\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.10/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.10/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.1\n        right=20.0.0.3\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r1_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.1\n        right=20.0.0.4\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: docker cp /tmp/r1_vpn1.secrets R1:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r1_vpn2.secrets R1:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r1_vpn1.conf    R1:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r1_vpn2.conf    R1:/etc/ipsec.d/vpn2.conf\n\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.2\n        right=20.0.0.3\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r2_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.2\n        right=20.0.0.4\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: docker cp /tmp/r2_vpn1.secrets R2:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r2_vpn2.secrets R2:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r2_vpn1.conf    R2:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r2_vpn2.conf    R2:/etc/ipsec.d/vpn2.conf\n\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.3\n        right=20.0.0.1\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r3_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.3\n        right=20.0.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: docker cp /tmp/r3_vpn1.secrets R3:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r3_vpn2.secrets R3:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r3_vpn1.conf    R3:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r3_vpn2.conf    R3:/etc/ipsec.d/vpn2.conf\n\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn1.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn2.secrets\n      : PSK \"sekainoichihara\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn1.conf\n      conn vpn1\n        authby=secret\n        left=20.0.0.4\n        right=20.0.0.1\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/r4_vpn2.conf\n      conn vpn2\n        authby=secret\n        left=20.0.0.4\n        right=20.0.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=101/0xffffffff\n        vti-interface=vti1\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n        ike=aes_cbc128-sha2_256;dh19\n        phase2alg=aes_gcm128;dh19\n        remote_peer_type=cisco\n      EOF\n  - cmd: docker cp /tmp/r4_vpn1.secrets R4:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/r4_vpn2.secrets R4:/etc/ipsec.d/vpn2.secrets\n  - cmd: docker cp /tmp/r4_vpn1.conf    R4:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/r4_vpn2.conf    R4:/etc/ipsec.d/vpn2.conf\n"
  },
  {
    "path": "examples/basic_ipsec/simple/README.md",
    "content": "\n## IPsec Example\n\n- libreswan\n\n```bash\n> docker exec R1 ipsec status | grep \"Total IPsec connections\" -A5\n000 Total IPsec connections: loaded 1, active 1\n000\n000 State Information: DDoS cookies not required, Accepting new IKE connections\n000 IKE SAs: total(2), half-open(0), open(0), authenticated(2), anonymous(0)\n000 IPsec SAs: total(2), authenticated(2), anonymous(0)\n000\n```\n"
  },
  {
    "path": "examples/basic_ipsec/simple/spec.yaml",
    "content": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"vpn1\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.secrets\n      : PSK \"vpn1\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.conf\n      conn vpn1\n        left=10.0.0.1\n        leftsubnet=10.1.0.0/24\n        right=10.0.0.2\n        rightsubnet=10.2.0.0/24\n        auto=start\n        authby=secret\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.conf\n      conn vpn1\n        left=10.0.0.2\n        leftsubnet=10.2.0.0/24\n        right=10.0.0.1\n        rightsubnet=10.1.0.0/24\n        auto=start\n        authby=secret\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/vpn1.r1.secrets R1:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r2.secrets R2:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r1.conf R1:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/vpn1.r2.conf R2:/etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.secrets\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.secrets\n\nnodes:\n- name: R1\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n- name: R2\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C2#net0 }\n- name: C1\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n  - cmd: ip route add 10.2.0.0/24 via 10.0.0.2\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: ip route add 10.1.0.0/24 via 10.0.0.1\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n"
  },
  {
    "path": "examples/basic_ipsec/static_esp_tunnel_simple/README.md",
    "content": "# Simple statically-configured ESP tunnel mode example just works\n\nEstablish SA bidirectionally between R0 and R1. Apply xfrm allow policy for the traffic between C0 and C1.\n\n![topo](topo.png)\n\n## Demo\n\nTry `tinet test`. Below is an example output. You can see the ICMP packets are correctly encapsulated with ESP header.\n\n```\n===================================================\nStarting packet capture on R0 (net1) and R1 (net1)\n===================================================\ntcpdump: listening on net1, link-type EN10MB (Ethernet), snapshot length 262144 bytes\ntcpdump: listening on net1, link-type EN10MB (Ethernet), snapshot length 262144 bytes\n===================================================\nping from C0 to C1\n===================================================\nPING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.\n64 bytes from 10.0.1.2: icmp_seq=1 ttl=62 time=0.081 ms\n\n--- 10.0.1.2 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 0.081/0.081/0.081/0.000 ms\n===================================================\nStopping packet capture on R0 (net1) and R1 (net1)\n===================================================\n5 packets captured\n5 packets received by filter\n0 packets dropped by kernel\n5 packets captured\n5 packets received by filter\n0 packets dropped by kernel\n===================================================\nPacket capture on R0 (net1)\n===================================================\n16:23:28.663259 ARP, Request who-has 192.168.0.2 tell 192.168.0.1, length 28\n16:23:28.663267 ARP, Reply 192.168.0.2 is-at c6:b7:02:a9:e9:6f, length 28\n16:23:28.663267 IP 192.168.0.1 > 192.168.0.2: ESP(spi=0x00000001,seq=0x1), length 120\n16:23:28.663294 IP 192.168.0.2 > 192.168.0.1: ESP(spi=0x00000001,seq=0x1), length 120\n16:23:28.663294 IP 10.0.1.2 > 10.0.0.2: ICMP echo reply, id 62643, seq 1, length 64\nreading from file /tmp/record.pcap, link-type EN10MB (Ethernet), snapshot length 262144\n===================================================\nPacket capture on R1 (net1)\n===================================================\n16:23:28.663261 ARP, Request who-has 192.168.0.2 tell 192.168.0.1, length 28\n16:23:28.663267 ARP, Reply 192.168.0.2 is-at c6:b7:02:a9:e9:6f, length 28\n16:23:28.663268 IP 192.168.0.1 > 192.168.0.2: ESP(spi=0x00000001,seq=0x1), length 120\n16:23:28.663268 IP 10.0.0.2 > 10.0.1.2: ICMP echo request, id 62643, seq 1, length 64\n16:23:28.663294 IP 192.168.0.2 > 192.168.0.1: ESP(spi=0x00000001,seq=0x1), length 120\nreading from file /tmp/record.pcap, link-type EN10MB (Ethernet), snapshot length 262144\n```\n"
  },
  {
    "path": "examples/basic_ipsec/static_esp_tunnel_simple/spec.yaml",
    "content": "nodes:\n- name: C0\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - name: net0\n    type: direct\n    args: R0#net0\n- name: R0\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - name: net0\n    type: direct\n    args: C0#net0\n  - name: net1\n    type: direct\n    args: R1#net1\n- name: R1\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - name: net0\n    type: direct\n    args: C1#net0\n  - name: net1\n    type: direct\n    args: R0#net1\n- name: C1\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - name: net0\n    type: direct\n    args: R1#net0\nnode_configs:\n- name: C0\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: R0\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip addr add 192.168.0.1/24 dev net1\n  - cmd: ip route add 10.0.1.0/24 via 192.168.0.2\n  - cmd: ip xfrm state add src 192.168.0.2 dst 192.168.0.1 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel\n  - cmd: ip xfrm state add src 192.168.0.1 dst 192.168.0.2 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.0.2/32 dst 10.0.1.2/32 dir out tmpl src 192.168.0.1 dst 192.168.0.2 proto esp spi 1 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.1.2/32 dst 10.0.0.2/32 dir in tmpl src 192.168.0.2 dst 192.168.0.1 proto esp spi 1 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.1.2/32 dst 10.0.0.2/32 dir fwd tmpl src 192.168.0.2 dst 192.168.0.1 proto esp spi 1 mode tunnel\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.1.1/24 dev net0\n  - cmd: ip addr add 192.168.0.2/24 dev net1\n  - cmd: ip route add 10.0.0.0/24 via 192.168.0.1\n  - cmd: ip xfrm state add src 192.168.0.1 dst 192.168.0.2 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel\n  - cmd: ip xfrm state add src 192.168.0.2 dst 192.168.0.1 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.1.2/32 dst 10.0.0.2/32 dir out tmpl src 192.168.0.2 dst 192.168.0.1 proto esp spi 1 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.0.2/32 dst 10.0.1.2/32 dir in tmpl src 192.168.0.1 dst 192.168.0.2 proto esp spi 1 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.0.2/32 dst 10.0.1.2/32 dir fwd tmpl src 192.168.0.1 dst 192.168.0.2 proto esp spi 1 mode tunnel\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.0.1.2/24 dev net0\n  - cmd: ip route add default via 10.0.1.1\ntest:\n  - cmds:\n    - cmd: echo \"===================================================\"\n    - cmd: echo \"Starting packet capture on R0 (net1) and R1 (net1)\"\n    - cmd: echo \"===================================================\"\n    - cmd: docker exec R0 tcpdump -nni net1 -w /tmp/record.pcap 2>&1 > /dev/null &\n    - cmd: docker exec R1 tcpdump -nni net1 -w /tmp/record.pcap 2>&1 > /dev/null &\n    - cmd: sleep 3\n    - cmd: echo \"===================================================\"\n    - cmd: echo \"ping from C0 to C1\"\n    - cmd: echo \"===================================================\"\n    - cmd: docker exec C0 ping -c 1 10.0.1.2\n    - cmd: sleep 3\n    - cmd: echo \"===================================================\"\n    - cmd: echo \"Stopping packet capture on R0 (net1) and R1 (net1)\"\n    - cmd: echo \"===================================================\"\n    - cmd: docker exec R0 pkill tcpdump\n    - cmd: docker exec R1 pkill tcpdump\n    - cmd: echo \"===================================================\"\n    - cmd: echo \"Packet capture on R0 (net1)\"\n    - cmd: echo \"===================================================\"\n    - cmd: docker exec R0 tcpdump -nnr /tmp/record.pcap\n    - cmd: echo \"===================================================\"\n    - cmd: echo \"Packet capture on R1 (net1)\"\n    - cmd: echo \"===================================================\"\n    - cmd: docker exec R1 tcpdump -nnr /tmp/record.pcap\n"
  },
  {
    "path": "examples/basic_ipsec/with_vti/README.md",
    "content": "\n## IPsec Example\n\n- libreswan\n\n```bash\n> docker exec R1 ipsec status | grep \"Total IPsec connections\" -A5\n000 Total IPsec connections: loaded 1, active 1\n000\n000 State Information: DDoS cookies not required, Accepting new IKE connections\n000 IKE SAs: total(2), half-open(0), open(0), authenticated(2), anonymous(0)\n000 IPsec SAs: total(2), authenticated(2), anonymous(0)\n000\n```\n"
  },
  {
    "path": "examples/basic_ipsec/with_vti/spec.yaml",
    "content": "---\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.secrets\n      : PSK \"vpn1\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.secrets\n      : PSK \"vpn1\"\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r1.conf\n      conn vpn1\n        authby=secret\n        left=10.0.0.1\n        right=10.0.0.2\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vpn1.r2.conf\n      conn vpn1\n        left=10.0.0.2\n        right=10.0.0.1\n        leftsubnet=0.0.0.0/0\n        rightsubnet=0.0.0.0/0\n        auto=start\n        authby=secret\n        mark=100/0xffffffff\n        vti-interface=vti0\n        vti-routing=no\n        dpddelay=10\n        dpdtimeout=5\n        dpdaction=restart\n      EOF\n  - cmd: docker cp /tmp/vpn1.r1.secrets R1:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r2.secrets R2:/etc/ipsec.d/vpn1.secrets\n  - cmd: docker cp /tmp/vpn1.r1.conf R1:/etc/ipsec.d/vpn1.conf\n  - cmd: docker cp /tmp/vpn1.r2.conf R2:/etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R1 chmod 600 /etc/ipsec.d/vpn1.secrets\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.conf\n  - cmd: docker exec R2 chmod 600 /etc/ipsec.d/vpn1.secrets\n\nnodes:\n- name: R1\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n- name: R2\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C2#net0 }\n- name: C1\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: tinet/centos:centos7\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 10.0.0.2 local 10.0.0.1\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip route add 10.2.0.0/24 dev vti0\n  - cmd: ip addr add 169.254.0.1/30 remote 169.254.0.2/30 dev vti0\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n\n  - cmd: ip link add vti0 type vti key 100 remote 10.0.0.1 local 10.0.0.2\n  - cmd: ip link set vti0 up\n  - cmd: sysctl -w net.ipv4.conf.vti0.disable_policy=1\n  - cmd: ip route add 10.1.0.0/24 dev vti0\n  - cmd: ip addr add 169.254.0.2/30 remote 169.254.0.1/30 dev vti0\n\n  - cmd: /usr/libexec/ipsec/addconn --config /etc/ipsec.conf --checkconfig\n  - cmd: /usr/libexec/ipsec/_stackmanager start\n  - cmd: /usr/sbin/ipsec --checknss\n  - cmd: /usr/sbin/ipsec --checknflog\n  - cmd: /usr/libexec/ipsec/pluto --leak-detective --config /etc/ipsec.conf\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n"
  },
  {
    "path": "examples/basic_ipsec/xfrm_interface/README.md",
    "content": "# Simple statically-configured ESP tunnel with XFRM Interface\n\nEstablish SA bidirectionally between R0 and R1. Apply xfrm allow policy for the traffic between C0 and C1 using [XFRM Interface](https://wiki.strongswan.org/projects/strongswan/wiki/RouteBasedVPN#XFRM-Interfaces-on-Linux).\n"
  },
  {
    "path": "examples/basic_ipsec/xfrm_interface/spec.yaml",
    "content": "---\nnodes:\n- name: C0\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net0, type: direct, args: R0#net0 }\n- name: R0\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net0, type: direct, args: C0#net0 }\n  - { name: net1, type: direct, args: R1#net1 }\n- name: R1\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net1, type: direct, args: R0#net1 }\n  - { name: net0, type: direct, args: C1#net0 }\n- name: C1\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n\nnode_configs:\n- name: C0\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: R0\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip addr add 192.168.0.1/24 dev net1\n  - cmd: ip link add type xfrm dev net1 if_id 1\n  # if_id 1 are important in below. We need to match it to the if_id 1 passed in above. So that the policies/states\n  # are not evaluated in the regular xfrm path (which lies in the middle of routing and device) and only evaluated\n  # inside the XFRM device.\n  - cmd: ip xfrm state add src 192.168.0.2 dst 192.168.0.1 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel if_id 1\n  - cmd: ip xfrm state add src 192.168.0.1 dst 192.168.0.2 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel if_id 1\n  - cmd: ip xfrm policy add src 10.0.0.0/24 dst 10.0.1.0/24 dir out if_id 1 tmpl src 192.168.0.1 dst 192.168.0.2 proto esp spi 1 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.1.0/24 dst 10.0.0.0/24 dir fwd if_id 1 tmpl src 192.168.0.2 dst 192.168.0.1 proto esp spi 1 mode tunnel\n  - cmd: ip link set xfrm0 up\n  - cmd: ip route add 10.0.1.0/24 dev xfrm0\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.0.1.1/24 dev net0\n  - cmd: ip addr add 192.168.0.2/24 dev net1\n  - cmd: ip link add type xfrm dev net1 if_id 1\n  - cmd: ip xfrm state add src 192.168.0.1 dst 192.168.0.2 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel if_id 1\n  - cmd: ip xfrm state add src 192.168.0.2 dst 192.168.0.1 proto esp spi 0x1 aead \"rfc4106(gcm(aes))\" 0x0000000000112233445566778899aabbccddeeff 128 mode tunnel if_id 1\n  - cmd: ip xfrm policy add src 10.0.1.0/24 dst 10.0.0.0/24 dir out if_id 1 tmpl src 192.168.0.2 dst 192.168.0.1 proto esp spi 1 mode tunnel\n  - cmd: ip xfrm policy add src 10.0.0.0/24 dst 10.0.1.0/24 dir fwd if_id 1 tmpl src 192.168.0.1 dst 192.168.0.2 proto esp spi 1 mode tunnel\n  - cmd: ip link set xfrm0 up\n  - cmd: ip route add 10.0.0.0/24 dev xfrm0\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.0.1.2/24 dev net0\n  - cmd: ip route add default via 10.0.1.1\n"
  },
  {
    "path": "examples/basic_iptables/napt/README.md",
    "content": "\n# Managed NAPT example\n\n```\ntn upconf | sudo sh\ndocker exec -it S1 tcpdump -ni net0 -Qin '(tcp[tcpflags] & tcp-syn)' != 0\ndocker exec C1 curl --interface 10.0.0.2 20.0.0.2\ndocker exec C1 curl --interface 10.0.0.3 20.0.0.2\ndocker exec C1 curl --interface 10.0.0.4 20.0.0.2\ndocker exec S1 conntrack -L\n```\n"
  },
  {
    "path": "examples/basic_iptables/napt/spec.yaml",
    "content": "\n# DESCRIPTION: NAPT network using FRR\n#\n# TOPO:\n#                    S0\n#            (net0).2|\n#                    |\n#    WAN:20.0.0.0/24 |\n#                    |\n#            (net0).1|\n#                 R1(NAPT)\n#            (net1).1|\n#                    |\n#    LAN:10.0.0.0/24 |\n#                    |\n#            (net0).2|\n#                    C0\n#\n# INIT:\n#   cns spec7.yaml init | sudo sh\n#   ./setup7.sh\n# FINI:\n#   cns spec7.yaml fini | sudo sh\n#\n\nnodes:\n  - name: R1\n    image: slankdev/conntrack\n    interfaces:\n      - { name: net0, type: direct, args: S1#net0, }\n      - { name: net1, type: direct, args: C1#net0, }\n  - name: S1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net0, } ]\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1, } ]\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net1\n      - cmd: ip addr add 20.0.0.1/24 dev net0\n\n      #######################\n      ## NAT CONFIGURATION ##\n      #######################\n      - cmd: ip addr add 20.0.0.100/24 dev net0\n      - cmd: ip addr add 20.0.0.101/24 dev net0\n      - cmd: >-\n            iptables -t nat -A POSTROUTING -s 10.0.0.2/32\n            -j SNAT -p tcp --to-source 20.0.0.100:10000-10008\n      - cmd: >-\n            iptables -t nat -A POSTROUTING -s 10.0.0.3/32\n            -j SNAT -p tcp --to-source 20.0.0.100:20000-20008\n      - cmd: >-\n            iptables -t nat -A POSTROUTING -s 10.0.0.4/32\n            -j SNAT -p tcp --to-source 20.0.0.101:30000-30008\n\n  - name: S1\n    cmds:\n      - cmd: ip addr add 20.0.0.2/24 dev net0\n      - cmd: ip route add default via 20.0.0.1\n      - cmd: nohup python3 -m http.server 80 &\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip addr add 10.0.0.3/24 dev net0\n      - cmd: ip addr add 10.0.0.4/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n\n"
  },
  {
    "path": "examples/basic_iptables/test/README.md",
    "content": "\n# iptables study\n\n```\nroot@R2:/# iptables -L\nChain INPUT (policy ACCEPT)\ntarget     prot opt source               destination\n\nChain FORWARD (policy ACCEPT)\ntarget     prot opt source               destination\nLOG        all  --  10.0.0.2             anywhere             LOG level warning\n\nChain OUTPUT (policy ACCEPT)\ntarget     prot opt source               destination\n```\n\n```\nroot@R2:/# iptables-save                                                                                     │\n# Generated by iptables-save v1.6.1 on Wed May 15 10:12:54 2019                                              │\n*filter                                                                                                      │\n:INPUT ACCEPT [5:420]                                                                                        │\n:FORWARD ACCEPT [6:504]                                                                                      │\n:OUTPUT ACCEPT [5:420]                                                                                       │\n-A FORWARD -s 10.0.0.2/32 -j LOG                                                                             │\nCOMMIT                                                                                                       │\n# Completed on Wed May 15 10:12:54 2019\n```\n\n```\nroot@R2:/# iptables -A FORWARD -s 10.0.0.2 -j LOG\nroot@R2:/# iptables -D FORWARD -s 10.0.0.2 -j LOG\n```\n\nIf you want to check the LOG of iptables on network-namespace,\nfollowing kernel option helps you. this option enables us,\noutput netns's log to host's log.\n```\nsudo sh -c 'echo 0 > /proc/sys/net/netfilter/nf_log_all_netns'\ndmesg\n```\n"
  },
  {
    "path": "examples/basic_iptables/test/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/sandbox\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/sandbox\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R3\n    image: slankdev/sandbox\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 20.0.0.1/24 dev net1\n  - name: R3\n    cmds:\n      - cmd: ip addr add 20.0.0.2/24 dev net0\n      - cmd: ip route add default via 20.0.0.1\n\n"
  },
  {
    "path": "examples/basic_iptables/u32/spec.yaml",
    "content": "nodes:\n- name: C1_1\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net1_1, type: direct, args: C2#net1_1 }\n\n- name: C1_2\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net1_2, type: direct, args: C2#net1_2 }\n\n- name: C2\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net1_1, type: direct, args: C1_1#net1_1 }\n  - { name: net1_2, type: direct, args: C1_2#net1_2 }\n  - { name: net2, type: direct, args: C3#net2 }\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n\n- name: C3\n  image: nicolaka/netshoot:latest\n  interfaces:\n  - { name: net2, type: direct, args: C2#net2 }\n\nnode_configs:\n- name: C1_1\n  cmds:\n  - cmd: ip addr add 10.1.0.1/24 dev net1_1\n  - cmd: ip route add 10.3.0.1 via 10.1.0.2\n  - cmd: ip tunnel add tun0 mode ipip local 10.1.0.1 remote 10.3.0.1 dev net1_1\n  - cmd: ip addr add 1.1.1.1/24 dev tun0\n  - cmd: ip link set tun0 up\n  - cmd: ip route add 1.1.3.1 dev tun0\n\n- name: C1_2\n  cmds:\n  - cmd: ip addr add 10.2.0.1/24 dev net1_2\n  - cmd: ip route add 10.3.0.1 via 10.2.0.2\n  - cmd: ip tunnel add tun0 mode ipip local 10.2.0.1 remote 10.3.0.1 dev net1_2\n  - cmd: ip addr add 1.1.2.1/24 dev tun0\n  - cmd: ip link set tun0 up\n  - cmd: ip route add 1.1.4.1 dev tun0\n\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net1_1\n  - cmd: ip addr add 10.2.0.2/24 dev net1_2\n  - cmd: ip addr add 10.3.0.2/24 dev net2\n  # drop packet which has source IP 1.1.2.1/32 in IPIP inner IP header\n  - cmd: iptables -m u32 --u32 \"6&0xFF=0x4 && 0>>22&0x3C@12=0x1010102\" -A FORWARD -j DROP\n  # drop packet which has source IP 1.1.2.0/24 in IPIP inner IP header\n  - cmd: iptables -m u32 --u32 \"6&0xFF=0x4 && 0>>22&0x3C@12=0x1010200:0x10102ff\" -A FORWARD -j DROP\n\n- name: C3\n  cmds:\n  - cmd: ip addr add 10.3.0.1/24 dev net2\n  - cmd: ip route add 10.1.0.1 via 10.3.0.2\n  - cmd: ip route add 10.2.0.1 via 10.3.0.2\n  - cmd: ip tunnel add tun0 mode ipip local 10.3.0.1 remote 10.1.0.1 dev net2\n  - cmd: ip addr add 1.1.3.1/24 dev tun0\n  - cmd: ip link set tun0 up\n  - cmd: ip route add 1.1.1.1 dev tun0\n  - cmd: ip tunnel add tun1 mode ipip local 10.3.0.1 remote 10.2.0.1 dev net2\n  - cmd: ip addr add 1.1.4.1/24 dev tun1\n  - cmd: ip link set tun1 up\n  - cmd: ip route add 1.1.2.1 dev tun1\n"
  },
  {
    "path": "examples/basic_isis/README.md",
    "content": "\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",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: direct, args: R5#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n      - { name: net2, type: direct, args: R6#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R4#net1 }\n      - { name: net2, type: direct, args: R7#net0 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R3#net1 }\n      - { name: net2, type: direct, args: R8#net0 }\n  - name: R5\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n  - name: R6\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n  - name: R7\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n  - name: R8\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R4#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo'\n          -c ' ip address 10.255.0.1/32'\n          -c ' exit'\n          -c 'int net0'\n          -c ' ip address 10.0.0.1/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net1'\n          -c ' ip address 10.0.0.5/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net2'\n          -c ' ip address 20.1.0.1/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'router isis FOO'\n          -c ' net 47.0023.0000.0000.0001.00'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.1'\n          -c ' exit'\n\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo'\n          -c ' ip address 10.255.0.2/32'\n          -c ' exit'\n          -c 'int net0'\n          -c ' ip address 10.0.0.2/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net1'\n          -c ' ip address 10.0.0.9/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net2'\n          -c ' ip address 20.2.0.1/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'router isis FOO'\n          -c ' net 47.0023.0000.0000.0002.00'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.2'\n          -c ' exit'\n  - name: R3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo'\n          -c ' ip address 10.255.0.3/32'\n          -c ' exit'\n          -c 'int net0'\n          -c ' ip address 10.0.0.6/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net1'\n          -c ' ip address 10.0.0.13/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net2'\n          -c ' ip address 20.3.0.1/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'router isis FOO'\n          -c ' net 47.0023.0000.0000.0003.00'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.3'\n          -c ' exit'\n  - name: R4\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo'\n          -c ' ip address 10.255.0.4/32'\n          -c ' exit'\n          -c 'int net0'\n          -c ' ip address 10.0.0.10/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net1'\n          -c ' ip address 10.0.0.14/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'int net2'\n          -c ' ip address 20.4.0.1/30'\n          -c ' ip router isis FOO'\n          -c ' exit'\n          -c 'router isis FOO'\n          -c ' net 47.0023.0000.0000.0004.00'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.4'\n          -c ' exit'\n\n  - name: R5\n    cmds:\n      - cmd: ip addr add 20.1.0.2/24 dev net0\n      - cmd: ip route replace default via 20.1.0.1\n  - name: R6\n    cmds:\n      - cmd: ip addr add 20.2.0.2/24 dev net0\n      - cmd: ip route replace default via 20.2.0.1\n  - name: R7\n    cmds:\n      - cmd: ip addr add 20.3.0.2/24 dev net0\n      - cmd: ip route replace default via 20.3.0.1\n  - name: R8\n    cmds:\n      - cmd: ip addr add 20.4.0.2/24 dev net0\n      - cmd: ip route replace default via 20.4.0.1\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec R1 ping -c2 10.0.0.1\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.0.0.5\n    - cmd: docker exec R1 ping -c2 10.0.0.6\n\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.2\n    - cmd: docker exec R2 ping -c2 10.0.0.9\n    - cmd: docker exec R2 ping -c2 10.0.0.10\n\n    - cmd: docker exec R3 ping -c2 10.0.0.5\n    - cmd: docker exec R3 ping -c2 10.0.0.6\n    - cmd: docker exec R3 ping -c2 10.0.0.13\n    - cmd: docker exec R3 ping -c2 10.0.0.14\n\n    - cmd: docker exec R4 ping -c2 10.0.0.9\n    - cmd: docker exec R4 ping -c2 10.0.0.10\n    - cmd: docker exec R4 ping -c2 10.0.0.13\n    - cmd: docker exec R4 ping -c2 10.0.0.14\n\n    - cmd: docker exec R5 ping -c2 20.1.0.1\n    - cmd: docker exec R5 ping -c2 20.1.0.2\n    - cmd: docker exec R6 ping -c2 20.2.0.1\n    - cmd: docker exec R6 ping -c2 20.2.0.2\n    - cmd: docker exec R7 ping -c2 20.3.0.1\n    - cmd: docker exec R7 ping -c2 20.3.0.2\n    - cmd: docker exec R8 ping -c2 20.4.0.1\n    - cmd: docker exec R8 ping -c2 20.4.0.2\n\n  - name: remote\n    cmds:\n    - cmd: docker exec R5 ping -c2 20.1.0.2\n    - cmd: docker exec R5 ping -c2 20.2.0.2\n    - cmd: docker exec R5 ping -c2 20.3.0.2\n    - cmd: docker exec R5 ping -c2 20.4.0.2\n\n    - cmd: docker exec R6 ping -c2 20.1.0.2\n    - cmd: docker exec R6 ping -c2 20.2.0.2\n    - cmd: docker exec R6 ping -c2 20.3.0.2\n    - cmd: docker exec R6 ping -c2 20.4.0.2\n\n    - cmd: docker exec R7 ping -c2 20.1.0.2\n    - cmd: docker exec R7 ping -c2 20.2.0.2\n    - cmd: docker exec R7 ping -c2 20.3.0.2\n    - cmd: docker exec R7 ping -c2 20.4.0.2\n\n    - cmd: docker exec R8 ping -c2 20.1.0.2\n    - cmd: docker exec R8 ping -c2 20.2.0.2\n    - cmd: docker exec R8 ping -c2 20.3.0.2\n    - cmd: docker exec R8 ping -c2 20.4.0.2\n\n"
  },
  {
    "path": "examples/basic_l3dsr/dscp/Dockerfile",
    "content": "\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",
    "content": "preinit:\n  - cmds:\n    - cmd: docker build -t xdptmp .\n\nnodes:\n  - name: R1\n    image: xdptmp\n    interfaces:\n      - { name: net1, type: direct, args: CLOS#net1 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.default.rp_filter=0\n\n  - name: C1\n    image: slankdev/mikanectl\n    docker_run_extra_args: --entrypoint bash\n    interfaces:\n      - { name: net0, type: direct, args: CLOS#net0 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.default.rp_filter=0\n\n  - name: C2\n    image: slankdev/mikanectl\n    docker_run_extra_args: --entrypoint bash\n    interfaces:\n      - { name: net2, type: direct, args: CLOS#net2 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.default.rp_filter=0\n\n  - name: CLOS\n    image: nicolaka/netshoot\n    interfaces:\n      - { name: net0, type: direct, args: C1#net0 }\n      - { name: net1, type: direct, args: R1#net1 }\n      - { name: net2, type: direct, args: C2#net2 }\n    sysctls:\n      - sysctl: net.ipv4.ip_forward=1\n      - sysctl: net.ipv4.conf.all.rp_filter=0\n      - sysctl: net.ipv4.conf.default.rp_filter=0\n\npostinit:\n  cmds:\n  - cmd: docker cp xdp.c R1:/root/xdp.c\n  - cmd: docker exec R1 clang -O2 -Wall -target bpf -c /root/xdp.c\n  - cmd: docker exec R1 ip link set net1 xdpgeneric obj xdp.o sec xdp-lb\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 142.0.0.1/32 dev lo\n      - cmd: ip addr add 10.0.1.1/24 dev net1\n      - cmd: ip route add default via 10.0.1.2\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip route add default via 10.0.0.2\n  - name: C2\n    cmds:\n      - cmd: nohup mikanectl ifconfig-http -p 80 &\n      - cmd: ip addr add 10.0.2.1/24 dev net2\n      - cmd: ip route add default via 10.0.2.2\n      - cmd: ip route add local 142.0.0.1/32 dev lo\n      - cmd: tc qdisc add dev net2 clsact\n      - cmd: tc filter add dev net2 ingress u32 match ip dsfield 0xa 0x1e action nat ingress 10.0.2.1 142.0.0.1\n\n  - name: CLOS\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip addr add 10.0.1.2/24 dev net1\n      - cmd: ip addr add 10.0.2.2/24 dev net2\n      - cmd: ip route add 142.0.0.1/32 dev net1\n"
  },
  {
    "path": "examples/basic_l3dsr/dscp/xdp.c",
    "content": "#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#include <bpf/bpf_helpers.h>\n#include <bpf/bpf_endian.h>\n\n#ifndef DSCP\n#define DSCP 10\n#endif\n\nstatic __always_inline __u16 csum_fold_helper(__u64 csum) {\n  int i;\n#pragma unroll\n  for (i = 0; i < 4; i ++) {\n    if (csum >> 16)\n      csum = (csum & 0xffff) + (csum >> 16);\n  }\n  return ~csum;\n}\n\nstatic __always_inline void ipv4_csum(void *data_start, int data_size,  __u64 *csum) {\n  *csum = bpf_csum_diff(0, 0, data_start, data_size, *csum);\n  *csum = csum_fold_helper(*csum);\n}\n\nstatic __always_inline int process_ipv4(struct xdp_md* ctx,\n  __u64 data, __u64 data_end) {\n  __u8 src_mac[ETH_ALEN];\n  struct ethhdr *eth;\n  struct iphdr *iph;\n\n  __u32 dst_addr = 0xa000201;\n  __u64 csum = 0;\n\n  eth = (struct ethhdr*)(data);\n\n  if ((__u64)(eth + 1) > data_end)\n    return XDP_DROP;\n\n  iph = (struct iphdr*)(data + sizeof(struct ethhdr));\n\n  if ((__u64)(iph + 1) > data_end)\n    return XDP_DROP;\n\n  if (iph->daddr == bpf_htonl(0x8e000001)) {\n    iph->tos = DSCP;\n    iph->daddr = bpf_htonl(dst_addr);\n    iph->check = 0;\n    ipv4_csum(iph, sizeof(struct iphdr), &csum);\n    iph->check = csum;\n\n    __builtin_memcpy(src_mac, eth->h_source, ETH_ALEN);\n    __builtin_memcpy(eth->h_source, eth->h_dest, ETH_ALEN);\n    __builtin_memcpy(eth->h_dest, src_mac, ETH_ALEN);\n  \n    return XDP_TX;\n  }\n  return XDP_PASS;\n}\n\nstatic __always_inline int process_eth(struct xdp_md* ctx) {\n  __u64 data = ctx->data;\n  __u64 data_end = ctx->data_end;\n  struct ethhdr *eth;\n\n  eth = (struct ethhdr*)data;\n\n  if ((__u64)(eth + 1) > data_end)\n    return XDP_DROP;\n\n  if (eth->h_proto == bpf_htons(ETH_P_IP)) {\n    return process_ipv4(ctx, data, data_end);\n  }\n  return XDP_PASS;\n}\n\nSEC(\"xdp-lb\")\nint entry(struct xdp_md *ctx) {\n  int ret = process_eth(ctx);\n  return ret;\n}\n\nchar __license[] SEC(\"license\") = \"GPL\";\n"
  },
  {
    "path": "examples/basic_ldp/README.md",
    "content": "\n# LDP Example\n\ncreate basic mpls backbone-network\n![](./topo.png)\n\n```\nhost# modprobe mpls_router\nhost# modprobe mpls_iptunnel\n```\n\nreferences\n- https://github.com/FRRouting/frr/blob/master/doc/developer/ldpd-basic-test-setup.md\n- https://github.com/FRRouting/frr/issues/651\n- http://docs.frrouting.org/en/latest/ldpd.html\n"
  },
  {
    "path": "examples/basic_ldp/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sh -c 'enable_seg6_router.py | sh'\n      - cmd: sh -c 'echo 100000 > /proc/sys/net/mpls/platform_labels'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net0/input'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf te'\n          -c 'int lo'\n          -c ' ip address 10.255.0.1/32'\n          -c '!'\n          -c 'int net0'\n          -c ' ip address 10.0.0.1/24'\n          -c ' ipv6 address 2001::1/64'\n          -c '!'\n          -c 'mpls ldp'\n          -c ' router-id 10.255.0.1'\n          -c ' neighbor 10.255.0.2 password slank'\n          -c ' !'\n          -c ' address-family ipv4'\n          -c '  discovery transport-address 10.255.0.1'\n          -c '  label local advertise explicit-null'\n          -c '  interface net0'\n          -c '!'\n          -c 'ip route 10.255.0.2 10.0.0.2 net0'\n\n  - name: R2\n    cmds:\n      - cmd: sh -c 'enable_seg6_router.py | sh'\n      - cmd: sh -c 'echo 100000 > /proc/sys/net/mpls/platform_labels'\n      - cmd: sh -c 'echo 1 > /proc/sys/net/mpls/conf/net0/input'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf te'\n          -c 'int lo'\n          -c ' ip address 10.255.0.2/32'\n          -c '!'\n          -c 'int net0'\n          -c ' ip address 10.0.0.2/24'\n          -c ' ipv6 address 2001::2/64'\n          -c '!'\n          -c 'mpls ldp'\n          -c ' router-id 10.255.0.2'\n          -c ' neighbor 10.255.0.1 password slank'\n          -c ' !'\n          -c ' address-family ipv4'\n          -c '  discovery transport-address 10.255.0.2'\n          -c '  label local advertise explicit-null'\n          -c '  interface net0'\n          -c '!'\n          -c 'ip route 10.255.0.1 10.0.0.1 net0'\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: echo slankdev slankdev\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_mirror/local/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n- name: R2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R3#net0 }\n  - { name: net2, type: direct, args: M1#net0 }\n- name: R3\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n- name: M1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.1.0.1/24 dev net0\n  - cmd: ip route add default via 10.1.0.2\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n\n  - cmd: ip link add mon0 type dummy\n  - cmd: ip link set mon0 up\n\n  ## [EGRESS MIRROR]\n  ## prio  match  action\n  ## ----  -----  ------\n  ## 100   any    accept\n  - cmd: tc qdisc add dev net0 root handle \"10:\" prio\n  - cmd: >-\n      tc filter add dev net0 parent \"10:\"\n      prio 100\n      protocol all u32 match u32 0 0\n      flowid 10:1 action mirred egress mirror dev mon0\n\n  ## [EGRESS MIRROR]\n  ## prio  match           action\n  ## ----  --------------  ------\n  ## 100   tcp sport 2020  deny\n  ## 101   any             deny\n  - cmd: tc qdisc add dev net0 root handle \"10:\" prio\n  - cmd: >-\n      tc filter add dev net0 parent \"10:\"\n      prio 100\n      protocol all u32 match ip sport 2020 0xffff\n      flowid 10:1 action pass\n  - cmd: >-\n      tc filter add dev net0 parent \"10:\"\n      prio 101\n      protocol all u32 match u32 0 0\n      flowid 10:1 action mirred egress mirror dev mon0\n\n  ## [INGRESS MIRROR]\n  ## prio  match  action\n  ## ----  -----  ------\n  ## 100   any    accept\n  - cmd: tc qdisc add dev net0 ingress\n  - cmd: >-\n      tc filter add dev net0 parent \"ffff:\"\n      prio 100\n      protocol all u32 match u32 0 0\n      flowid ffff:1 action mirred egress mirror dev mon0\n\n  ## [INGRESS MIRROR]\n  ## prio  match           action\n  ## ----  --------------  ------\n  ## 100   tcp dport 2020  deny\n  ## 101   any    accept\n  - cmd: tc qdisc add dev net0 ingress\n  - cmd: >-\n      tc filter add dev net0 parent \"ffff:\"\n      prio 100\n      protocol all u32 match ip dport 2020 0xffff\n      flowid 10:1 action pass\n  - cmd: >-\n      tc filter add dev net0 parent \"ffff:\"\n      prio 101\n      protocol all u32 match u32 0 0\n      flowid ffff:1 action mirred egress mirror dev mon0\n\n  ## ANOTHER TIPS\n  # [MATCH]\n  # match ip protocol 6 0xff\n  # match ip src 10.255.1.1/32\n  # match ip dst 10.255.0.0/24\n  # match ip sport 2020 0xffff\n  # match ip dport 8080 0xffff\n  #\n  # [CHECK]\n  # tc filter list dev net0 parent 10:\n  # tc filter list dev net0 parent ffff:\n  # tc filter del  dev net0 parent 10:\n  # tc filter del  dev net0 parent ffff:\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n"
  },
  {
    "path": "examples/basic_mirror/remote/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n- name: R2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R3#net0 }\n  - { name: net2, type: direct, args: R4#net0 }\n- name: R3\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n- name: R4\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n  - { name: net1, type: direct, args: R5#net0 }\n- name: R5\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R4#net1 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.1.0.1/24 dev net0\n  - cmd: ip route add default via 10.1.0.2\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: ip addr add 10.3.0.1/24 dev net2\n  - cmd: ip route add 10.4.0.0/24 via 10.3.0.2\n\n  # - cmd: ip link add mon0 type dummy\n  # - cmd: ip link set mon0 up\n  # - cmd: \"tc qdisc add dev net0 root handle 10: prio\"\n  # - cmd: \"tc qdisc add dev net0 ingress\"\n  # - cmd: \"tc filter add dev net0 parent 10: prio 10 protocol all u32 match u32 0 0 flowid 10:1 action mirred egress mirror dev mon0\"\n  # - cmd: \"tc filter add dev net0 parent ffff: prio 10 protocol all u32 match u32 0 0 flowid ffff:1 action mirred egress mirror dev mon0\"\n\n  - cmd: ip link add mon0 type gretap remote 10.4.0.2 local 10.3.0.1 ttl 10\n  - cmd: ip link set mon0 up\n\n  - cmd: \"tc qdisc add dev net0 root handle 10: prio\"\n  - cmd: \"tc filter add dev net0 parent 10: prio 10 protocol all u32 match u32 0 0 flowid 10:1 action mirred egress mirror dev mon0\"\n  - cmd: \"tc qdisc add dev net0 ingress\"\n  - cmd: \"tc filter add dev net0 parent ffff: prio 10 protocol all u32 match u32 0 0 flowid ffff:1 action mirred egress mirror dev mon0\"\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 10.3.0.2/24 dev net0\n  - cmd: ip addr add 10.4.0.1/24 dev net1\n\n- name: R5\n  cmds:\n  - cmd: ip addr add 10.4.0.2/24 dev net0\n  - cmd: ip route add default via 10.4.0.1\n  - cmd: ip link add mon0 type gretap remote 10.3.0.1 local 10.4.0.2 ttl 10\n  - cmd: ip link set mon0 up\n"
  },
  {
    "path": "examples/basic_mpls/spec.yaml",
    "content": "# DESCRIPTION: Basic MPLS Traffic Engneering\n# TEST:\n#    docker exec C0 ping 192.168.1.2 -I 192.168.0.2 &\n#    docker exec C0 ping 192.168.1.20 -I 192.168.0.20 &\n#    docker exec R5 sysctl -w net.ipv4.ip_forward=0\n#\n# TOPO:\n#       +------+             10.1.      +------+     10.2.             +------+\n#       |      |             0.0/24   .2|      |.2   0.0/24            |      |\n#       |  C0  |                +--+net0|  R4  |net1+-+                |  C1  |\n#       |      |                |       |      |      |                |      |\n#       +------+                |       +------+      |                +------+\n#         net0                  |                     |                  net0\n#          +.2 .20              |                     |                    +.2 .20\n#          |                    |                     |                    |\n#          |                    |                     |                    |\n# 192.168  |                    |                     |                    |  192.168\n# .0.0/24  +.1                  +.1                 .1+                  .1+  .1.0/24\n#         net1                 net2                 net2                 net1\n#       +------+             +------+             +------+             +------+\n#       |      |.2         .1|      |             |      |.1         .2|      |\n#       |  R0  |net0+---+net1|  R2  |             |  R3  |net1+---+net0|  R1  |\n#       |      |    10.3.    |      |             |      |    10.4.    |      |\n#       +------+    0.0/24   +------+             +------+    0.0/24   +------+\n#                              net0                 net0\n#                               +.1                 .1+\n#                               |                     |\n#                               |                     |\n#                               |                     |\n#                         10.0. |       +------+      |10.0.\n#                         1.0/24|     .2|      |.2    |2.0/24\n#                               +--+net0|  R5  |net1+-+\n#                                       |      |\n#                                       +------+\n\n\npre_init:\n  - cmds:\n    - cmd: modprobe mpls_router\n    - cmd: modprobe mpls_gso\n    - cmd: modprobe mpls_iptunnel\n\nnodes:\n  - name: R0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: C0#net0 }\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n      - { name: net1, type: direct, args: C1#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R5#net0 }\n      - { name: net1, type: direct, args: R0#net0 }\n      - { name: net2, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R5#net1 }\n      - { name: net1, type: direct, args: R1#net0 }\n      - { name: net2, type: direct, args: R4#net1 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n      - { name: net1, type: direct, args: R3#net2 }\n  - name: R5\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: C0\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R0#net1 }\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: sysctl -w net.ipv4.ip_forward=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.lo.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net0.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net1.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.platform_labels=1024 > /dev/null\n      - cmd: ip addr add 10.3.0.2/24 dev net0\n      - cmd: ip addr add 192.168.0.1/24 dev net1\n      - cmd: ip route add 192.168.1.0/24 via 10.3.0.1\n      - cmd: ip route add 192.168.1.20/32 encap mpls 100 via inet 10.3.0.1\n  - name: R1\n    cmds:\n      - cmd: sysctl -w net.ipv4.ip_forward=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.lo.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net0.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net1.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.platform_labels=1024 > /dev/null\n      - cmd: ip addr add 10.4.0.2/24 dev net0\n      - cmd: ip addr add 192.168.1.1/24 dev net1\n      - cmd: ip route add 192.168.0.0/24 via 10.4.0.1\n      - cmd: ip route add 192.168.0.20/32 encap mpls 200 via inet 10.4.0.1\n  - name: R2\n    cmds:\n      - cmd: sysctl -w net.ipv4.ip_forward=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.lo.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net0.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net1.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net2.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.platform_labels=1024 > /dev/null\n      - cmd: ip addr add 10.0.1.1/24 dev net0\n      - cmd: ip addr add 10.3.0.1/24 dev net1\n      - cmd: ip addr add 10.1.0.1/24 dev net2\n      - cmd: ip route add 192.168.0.0/24 via 10.3.0.2\n      - cmd: ip route add 192.168.1.0/24 via 10.0.1.2\n      - cmd: ip -f mpls route add 100 via inet 10.1.0.2\n  - name: R3\n    cmds:\n      - cmd: sysctl -w net.ipv4.ip_forward=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.lo.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net0.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net1.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net2.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.platform_labels=1024 > /dev/null\n      - cmd: ip addr add 10.0.2.1/24 dev net0\n      - cmd: ip addr add 10.4.0.1/24 dev net1\n      - cmd: ip addr add 10.2.0.1/24 dev net2\n      - cmd: ip route add 192.168.0.0/24 via 10.0.2.2\n      - cmd: ip route add 192.168.1.0/24 via 10.4.0.2\n      - cmd: ip -f mpls route add 200 via inet 10.2.0.2\n  - name: R4\n    cmds:\n      - cmd: sysctl -w net.ipv4.ip_forward=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.lo.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net0.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net1.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.platform_labels=1024 > /dev/null\n      - cmd: ip addr add 10.1.0.2/24 dev net0\n      - cmd: ip addr add 10.2.0.2/24 dev net1\n      - cmd: ip route add 192.168.0.0/24 via 10.1.0.1\n      - cmd: ip route add 192.168.1.0/24 via 10.2.0.1\n  - name: R5\n    cmds:\n      - cmd: sysctl -w net.ipv4.ip_forward=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.lo.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net0.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.conf.net1.input=1 > /dev/null\n      - cmd: sysctl -w net.mpls.platform_labels=1024 > /dev/null\n      - cmd: ip addr add 10.0.1.2/24 dev net0\n      - cmd: ip addr add 10.0.2.2/24 dev net1\n      - cmd: ip route add 192.168.0.0/24 via 10.0.1.1\n      - cmd: ip route add 192.168.1.0/24 via 10.0.2.1\n  - name: C0\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip addr add 192.168.0.20/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.0.1\n  - name: C1\n    cmds:\n      - cmd: ip addr add 192.168.1.2/24 dev net0\n      - cmd: ip addr add 192.168.1.20/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.1.1\n\ntest:\n  - cmds:\n    - cmd: docker exec C0 ping 192.168.1.2 -I 192.168.0.2\n    - cmd: docker exec C0 ping 192.168.1.20 -I 192.168.0.20\n    - cmd: docker exec R5 sysctl -w net.ipv4.ip_forward=0\n\n\n"
  },
  {
    "path": "examples/basic_multipath/README.md",
    "content": "# Multipath Configuration\n\ndiagram\n```\n+-----------+\n|    R1     |\n+-----------+\n(net0) (net1)\n  |      |\n(net0) (net0)\n+----+ +----+\n| R2 | | R3 ||\n+----+ +----+\n(net1) (net1)\n  |      |\n(net0) (net1)\n+-----------+\n|    R4     |\n+-----------+\n```\n\nother multipath config snippets\n```\nip route add 1.1.1.1/32 \\\n    nexthop via 10.0.0.1 weight 1 \\\n    nexthop via 10.0.0.2 weight 2\n\nip route add :: table 10 \\\n  nexthop weight 10 encap seg6 mode encap segs A::,B:: via fe80::1 dev eth0 \\\n  nexthop weight 20 encap seg6 mode encap segs C::,D:: via fe80::2 dev eth0\n\nip route add :: vrf vrf0 \\\n  nexthop weight 10 encap seg6 mode encap segs A::,B:: via fe80::1 dev eth0 \\\n  nexthop weight 20 encap seg6 mode encap segs C::,D:: via fe80::2 dev eth0\n```\n"
  },
  {
    "path": "examples/basic_multipath/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2 }\n  - { name: net1, type: direct, args: R3 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: R2\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1 }\n  - { name: net1, type: direct, args: R4 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: R3\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1 }\n  - { name: net1, type: direct, args: R4 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: R4\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2 }\n  - { name: net1, type: direct, args: R3 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.1.0.1/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.2/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.1.0.3/24 dev net0\n  - cmd: ip addr add 10.2.0.3/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n- name: R4\n  cmds:\n  - cmd: ip addr add 10.1.0.4/24 dev net0\n  - cmd: ip addr add 10.2.0.4/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.10/24 dev net0\n  - cmd: >-\n      ip route replace default\n      nexthop via 10.1.0.1\n      nexthop via 10.1.0.2\n      nexthop via 10.1.0.3\n      nexthop via 10.1.0.4\n  - cmd: nginx\n  - cmd: iperf3 -s -D\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.10/24 dev net0\n  - cmd: >-\n      ip route replace default\n      nexthop via 10.2.0.1\n      nexthop via 10.2.0.2\n      nexthop via 10.2.0.3\n      nexthop via 10.2.0.4\n- name: C3\n  cmds:\n  - cmd: ip addr add 10.2.0.11/24 dev net0\n  - cmd: >-\n      ip route replace default\n      nexthop via 10.2.0.1\n      nexthop via 10.2.0.2\n      nexthop via 10.2.0.3\n      nexthop via 10.2.0.4\n\ntest:\n- name: test\n  cmds:\n  - cmd: docker exec R1 ping \n  - cmd: docker exec R2 pmacct -e -p /tmp/collect.pipe\n"
  },
  {
    "path": "examples/basic_namespace/README.md",
    "content": "\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 upconf | sudo sh\ndocker ps\nCONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES\n6d5f9e4d6c51        slankdev/ubuntu:18.04   \"/bin/bash\"         2 seconds ago       Up 1 second                             green_R2\n92210c5eea85        slankdev/ubuntu:18.04   \"/bin/bash\"         3 seconds ago       Up 2 seconds                            green_R1\n48a50568c9c1        slankdev/ubuntu:18.04   \"/bin/bash\"         7 seconds ago       Up 6 seconds                            blue_R2\n86c2c4c9fc52        slankdev/ubuntu:18.04   \"/bin/bash\"         7 seconds ago       Up 7 seconds                            blue_R1\n```\n\n"
  },
  {
    "path": "examples/basic_namespace/spec.blue.yaml",
    "content": "\nmeta:\n  namespace: blue_\n\nnodes:\n  - name: R1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n\n"
  },
  {
    "path": "examples/basic_namespace/spec.green.yaml",
    "content": "\nmeta:\n  namespace: green_\n\nnodes:\n  - name: R1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n\n"
  },
  {
    "path": "examples/basic_napt/spec.yaml",
    "content": "\n# DESCRIPTION: NAPT network using FRR\n#\n# TOPO:\n#                    S0\n#            (net0).2|\n#                    |\n#    WAN:20.0.0.0/24 |\n#                    |\n#            (net0).1|\n#                 R1(NAPT)\n#            (net1).1|\n#                    |\n#    LAN:10.0.0.0/24 |\n#                    |\n#            (net0).2|\n#                    C0\n#\n# INIT:\n#   cns spec7.yaml init | sudo sh\n#   ./setup7.sh\n# FINI:\n#   cns spec7.yaml fini | sudo sh\n#\n\nnodes:\n  - name: R0\n    image: slankdev/frr\n    interfaces:\n      - name: net0\n        type: direct\n        args: S0#net0\n      - name: net1\n        type: direct\n        args: C0#net0\n  - name: S0\n    image: slankdev/ubuntu:16.04\n    interfaces:\n      - name: net0\n        type: direct\n        args: R0#net0\n  - name: C0\n    image: slankdev/ubuntu:16.04\n    interfaces:\n      - name: net0\n        type: direct\n        args: R0#net1\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: >-\n            vtysh -c \"conf t\"\n            -c \"interface net0\"\n            -c \"ip address 20.0.0.1/24\"\n            -c \"exit\"\n            -c \"interface net1\"\n            -c \"ip address 10.0.0.1/24\"\n            -c \"exit\"\n      - cmd: >-\n            iptables -t nat -A POSTROUTING\n            -s 10.0.0.0/24 -j MASQUERADE\n\n  - name: S0\n    cmds:\n      - cmd: ip addr add 20.0.0.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 20.0.0.1\n\n  - name: C0\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 10.0.0.1\n\ntest:\n  - cmds:\n    - cmd: docker exec C0 ping -c2 20.0.0.2\n    - cmd: docker exec -d S0 iperf -s\n    - cmd: docker exec C0 iperf -c 20.0.0.2\n"
  },
  {
    "path": "examples/basic_netflow/README.md",
    "content": "# NetFlow/IPFIX using pmacctd\n\n## pmacct\nref: https://github.com/linsomniac/pmacct/blob/master/EXAMPLES\n\n```\npmacctd -P print -r 1 -i net0 -c src_host,dst_host\npmacctd -P memory -i net0 -c src_host,dst_host\npmacctd -P memory -c src_host,dst_host\npmacctd -P memory -c src_host,dst_host -D\npmacctd -P memory -c src_host,dst_host,proto,src_port,dst_port\npmacctd -f /conf.txt\n\npmacct -s -p /tmp/collect.pipe\npmacct -s -p /tmp/collect.pipe -O json\n```\n\n```\nplugins:            memory\naggregate:          src_host,dst_host,proto,src_port,dst_port\nplugin_buffer_size: 35200\nplugin_pipe_size:   409600000\n```\n\n## nfcapd/nfdump\n```\nnfcapd -w -l /tmp -p 2100\n```\n"
  },
  {
    "path": "examples/basic_netflow/multipath/Makefile",
    "content": "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.packets, .stats64.tx.packets] | @tsv' -r\"\n\t@echo -n \"R2:net0  \"\n\t@docker exec -it R1 sh -c \"ip -j -s link show dev net0 | jq '.[0] | [.stats64.rx.packets, .stats64.tx.packets] | @tsv' -r\"\n\t@echo -n \"R3:net0  \"\n\t@docker exec -it R3 sh -c \"ip -j -s link show dev net0 | jq '.[0] | [.stats64.rx.packets, .stats64.tx.packets] | @tsv' -r\"\n\t@echo -n \"R4:net0  \"\n\t@docker exec -it R4 sh -c \"ip -j -s link show dev net0 | jq '.[0] | [.stats64.rx.packets, .stats64.tx.packets] | @tsv' -r\"\nflowstats:\n\tdocker exec C3 pmacct -s -p /tmp/collect.pipe\nreset:\n\tdocker exec C3 pmacct -e -p /tmp/collect.pipe\n\tdocker exec R1 pmacct -e -p /tmp/collect.pipe\n\tdocker exec R2 pmacct -e -p /tmp/collect.pipe\n\tdocker exec R3 pmacct -e -p /tmp/collect.pipe\n\tdocker exec R4 pmacct -e -p /tmp/collect.pipe\ntest-iperf:\n\t#docker exec -it C2 iperf3 -c 10.1.0.10 -P5 -t 5\n\tdocker exec -it C2 iperf3 -c 10.1.0.10 -n 5G\ntest-vegeta:\n\tdocker exec -it C2 sh -c \"cat /vegeta.conf | vegeta attack -keepalive=false -duration=5s | tee results.bin | vegeta report\"\n\t#docker exec -it C2 sh -c \"cat /vegeta.conf | vegeta attack -duration=5s | tee results.bin | vegeta report\"\n"
  },
  {
    "path": "examples/basic_netflow/multipath/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: bridge, args: B1 }\n  - { name: net1, type: bridge, args: B2 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: R2\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: bridge, args: B1 }\n  - { name: net1, type: bridge, args: B2 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: R3\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: bridge, args: B1 }\n  - { name: net1, type: bridge, args: B2 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: R4\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: bridge, args: B1 }\n  - { name: net1, type: bridge, args: B2 }\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n\n- name: C1\n  image: tinynetwork/nginx:develop\n  interfaces: [{ name: net0, type: bridge, args: B1 }]\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: C2\n  image: tinynetwork/pmacctd:develop\n  interfaces: [{ name: net0, type: bridge, args: B2 }]\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n- name: C3\n  image: tinynetwork/pmacctd:develop\n  interfaces: [{ name: net0, type: bridge, args: B2 }]\n  sysctls: [{ sysctl: net.ipv4.fib_multipath_hash_policy=1 }]\n\nswitches:\n- name: B1\n  interfaces:\n  - { name: net0, type: container, args: R1 }\n  - { name: net0, type: container, args: R2 }\n  - { name: net0, type: container, args: R3 }\n  - { name: net0, type: container, args: R4 }\n  - { name: net0, type: container, args: C1 }\n- name: B2\n  interfaces:\n  - { name: net1, type: container, args: R1 }\n  - { name: net1, type: container, args: R2 }\n  - { name: net1, type: container, args: R3 }\n  - { name: net1, type: container, args: R4 }\n  - { name: net0, type: container, args: C2 }\n  - { name: net0, type: container, args: C3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.1.0.1/24 dev net0\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip addr add 10.2.0.2/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.1.0.3/24 dev net0\n  - cmd: ip addr add 10.2.0.3/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n- name: R4\n  cmds:\n  - cmd: ip addr add 10.1.0.4/24 dev net0\n  - cmd: ip addr add 10.2.0.4/24 dev net1\n  - cmd: pmacctd -f /pmacctd.conf\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.10/24 dev net0\n  - cmd: >-\n      ip route replace default\n      nexthop via 10.1.0.1\n      nexthop via 10.1.0.2\n      nexthop via 10.1.0.3\n      nexthop via 10.1.0.4\n  - cmd: nginx\n  - cmd: iperf3 -s -D\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.10/24 dev net0\n  - cmd: >-\n      ip route replace default\n      nexthop via 10.2.0.1\n      nexthop via 10.2.0.2\n      nexthop via 10.2.0.3\n      nexthop via 10.2.0.4\n- name: C3\n  cmds:\n  - cmd: ip addr add 10.2.0.11/24 dev net0\n  - cmd: >-\n      ip route replace default\n      nexthop via 10.2.0.1\n      nexthop via 10.2.0.2\n      nexthop via 10.2.0.3\n      nexthop via 10.2.0.4\n  #- cmd: nfacctd -f /nfacctd.conf\n  - cmd: nfcapd -l /tmp -p 2100 -t 10 -D\npostinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/pmacctd.conf\n      daemonize:          true\n      aggregate:          src_host,dst_host,proto,src_port,dst_port\n      logfile:            /var/log/pmacctd.log\n      interface:          net0\n      plugin_buffer_size: 3520000\n      plugin_pipe_size:   409600000\n\n      !plugins:            memory\n\n      plugins:            nfprobe\n      nfprobe_receiver:   10.2.0.11:2100\n      nfprobe_version:    9\n      nfprobe_timeouts:   maxlife=1\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/nfacctd.conf\n      daemonize:          true\n      aggregate:          src_host,dst_host,proto,src_port,dst_port\n      nfacctd_port:       2100\n      plugins:            memory\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/vegeta.conf\n      GET http://10.1.0.10\n      EOF\n  - cmd: docker cp /tmp/pmacctd.conf R1:/pmacctd.conf\n  - cmd: docker cp /tmp/pmacctd.conf R2:/pmacctd.conf\n  - cmd: docker cp /tmp/pmacctd.conf R3:/pmacctd.conf\n  - cmd: docker cp /tmp/pmacctd.conf R4:/pmacctd.conf\n  - cmd: docker cp /tmp/nfacctd.conf C3:/nfacctd.conf\n  - cmd: docker cp /tmp/vegeta.conf  C2:/vegeta.conf\n\ntest:\n- name: clear\n  cmds:\n  - cmd: docker exec R1 pmacct -e -p /tmp/collect.pipe\n  - cmd: docker exec R2 pmacct -e -p /tmp/collect.pipe\n"
  },
  {
    "path": "examples/basic_netflow/simple/spec.yaml",
    "content": "---\nnodes:\n- name: R1\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: R3#net0 }\n  - { name: net2, type: direct, args: R4#net0 }\n- name: R2\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n- name: R3\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: R4\n  image: tinynetwork/pmacctd:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.2.0.1/24 dev net0\n  - cmd: ip addr add 10.3.0.1/24 dev net1\n  - cmd: ip addr add 10.4.0.1/24 dev net2\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.3.0.2/24 dev net0\n  - cmd: ip route add default via 10.3.0.1\n- name: R4\n  cmds:\n  - cmd: ip addr add 10.4.0.2/24 dev net0\n  - cmd: ip route add default via 10.4.0.1\n"
  },
  {
    "path": "examples/basic_netns/spec.yaml",
    "content": "\nnodes:\n  - name: H0\n    type: netns\n    interfaces:\n      - { name: net0, type: direct, args: C0#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n  - name: C0\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: H0#net0 }\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: H0#net1 }\n\nnode_configs:\n  - name: H0\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 10.1.0.1/24 dev net1\n  - name: C0\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route replace default via 10.0.0.1\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.1.0.2/24 dev net0\n      - cmd: ip route replace default via 10.1.0.1\n\ntest:\n  - cmds:\n    - cmd: echo slankdev\n\n"
  },
  {
    "path": "examples/basic_nftables/masquerade/README.md",
    "content": "\n# nftables study (MASQ)\n\ncheck nft is enabled (m is OK)\n```\n# cat /boot/config-`uname -r` | grep CONFIG_NF_TABLES\nCONFIG_NF_TABLES=m\nCONFIG_NF_TABLES_INET=m\nCONFIG_NF_TABLES_NETDEV=m\nCONFIG_NF_TABLES_IPV4=m\nCONFIG_NF_TABLES_ARP=m\nCONFIG_NF_TABLES_IPV6=m\nCONFIG_NF_TABLES_BRIDGE=m\n```\n\n- Good reference\n\t-\thttps://knowledge.sakura.ad.jp/22636/\n\t- https://www.slideshare.net/s1061123/nftables-the-next-generation-firewall-in-linux\n"
  },
  {
    "path": "examples/basic_nftables/masquerade/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n      - cmd: docker cp ../../../tools/http_server.py R3:/usr/bin\n      - cmd: docker cp ../../../tools/echo_server.py R3:/usr/bin\n\nnodes:\n  - name: R1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R3\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 20.0.0.1/24 dev net1\n      - cmd: nft create table ip nat\n      - cmd: nft create chain ip nat prerouting { type nat hook prerouting priority 0 \\;}\n      - cmd: nft create chain ip nat postrouting { type nat hook postrouting priority 0 \\;}\n      - cmd: nft add rule nat postrouting ip saddr 10.0.0.0/24 oif net1 masquerade\n\n  - name: R3\n    cmds:\n      - cmd: ip addr add 20.0.0.2/24 dev net0\n      - cmd: nohup http_server.py &\n\n"
  },
  {
    "path": "examples/basic_nftables/snat/README.md",
    "content": "\n# nftables study (SNAT)\n\ncheck nft is enabled (m is OK)\n```\n# cat /boot/config-`uname -r` | grep CONFIG_NF_TABLES\nCONFIG_NF_TABLES=m\nCONFIG_NF_TABLES_INET=m\nCONFIG_NF_TABLES_NETDEV=m\nCONFIG_NF_TABLES_IPV4=m\nCONFIG_NF_TABLES_ARP=m\nCONFIG_NF_TABLES_IPV6=m\nCONFIG_NF_TABLES_BRIDGE=m\n```\n\n- Good reference\n\t-\thttps://knowledge.sakura.ad.jp/22636/\n\t- https://www.slideshare.net/s1061123/nftables-the-next-generation-firewall-in-linux\n"
  },
  {
    "path": "examples/basic_nftables/snat/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n      - cmd: docker cp ../../../tools/http_server.py R3:/usr/bin\n      - cmd: docker cp ../../../tools/echo_server.py R3:/usr/bin\n\nnodes:\n  - name: R1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R3\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 20.0.0.1/24 dev net1\n      - cmd: nft create table ip nat\n      - cmd: nft create chain ip nat prerouting { type nat hook prerouting priority 0 \\;}\n      - cmd: nft create chain ip nat postrouting { type nat hook postrouting priority 0 \\;}\n      - cmd: nft add rule nat postrouting ip protocol tcp snat to 20.0.0.1:100-200\n\n  - name: R3\n    cmds:\n      - cmd: ip addr add 20.0.0.2/24 dev net0\n      - cmd: nohup http_server.py &\n\n"
  },
  {
    "path": "examples/basic_ospfv2_bird/README.md",
    "content": "\n# Multiple OSPFv3 Instance using Bird\n\n![](./topo.png)\n\n```\n```\n"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R1_bird.conf",
    "content": "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 instance_A {\n\trouter id 10.255.0.1;\n\texport all;\n\timport all;\n\tarea 0.0.0.0 {\n\t\tinterface \"net0\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net1\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net2\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t};\n}\n"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R2_bird.conf",
    "content": "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 instance_A {\n\trouter id 10.255.0.2;\n\texport all;\n\timport all;\n\tarea 0.0.0.0 {\n\t\tinterface \"net0\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net1\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t};\n}\n\n"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R3_bird.conf",
    "content": "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 instance_A {\n\trouter id 10.255.0.3;\n\texport all;\n\timport all;\n\tarea 0.0.0.0 {\n\t\tinterface \"net0\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net1\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net2\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t};\n}\n\n"
  },
  {
    "path": "examples/basic_ospfv2_bird/bird/R4_bird.conf",
    "content": "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 instance_A {\n\trouter id 10.255.0.4;\n\texport all;\n\timport all;\n\tarea 0.0.0.0 {\n\t\tinterface \"net0\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net1\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net2\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t};\n}\n\n"
  },
  {
    "path": "examples/basic_ospfv2_bird/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: docker cp bird/R1_bird.conf R1:/etc/bird/bird.conf\n    - cmd: docker cp bird/R2_bird.conf R2:/etc/bird/bird.conf\n    - cmd: docker cp bird/R3_bird.conf R3:/etc/bird/bird.conf\n    - cmd: docker cp bird/R4_bird.conf R4:/etc/bird/bird.conf\n\nnodes:\n  - name: R1\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: direct, args: S1#net0 }\n  - name: R2\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n  - name: R3\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R4#net1 }\n      - { name: net2, type: direct, args: S3#net0 }\n  - name: R4\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R3#net1 }\n      - { name: net2, type: direct, args: S4#net0 }\n  - name: S1\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n  - name: S3\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n  - name: S4\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R4#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/30 dev net0\n      - cmd: ip addr add 10.0.0.9/30 dev net1\n      - cmd: ip addr add 10.0.0.17/30 dev net2\n      - cmd: ip addr add 10.255.0.1/32 dev lo\n      - cmd: mkdir -p /run/bird\n      - cmd: bird -c /etc/bird/bird.conf\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.2/30 dev net0\n      - cmd: ip addr add 10.0.0.13/30 dev net1\n      - cmd: ip addr add 10.255.0.2/32 dev lo\n      - cmd: mkdir -p /run/bird\n      - cmd: bird -c /etc/bird/bird.conf\n  - name: R3\n    cmds:\n      - cmd: ip addr add 10.0.0.10/30 dev net0\n      - cmd: ip addr add 10.0.0.5/30 dev net1\n      - cmd: ip addr add 10.0.0.21/30 dev net2\n      - cmd: ip addr add 10.255.0.3/32 dev lo\n      - cmd: mkdir -p /run/bird\n      - cmd: bird -c /etc/bird/bird.conf\n  - name: R4\n    cmds:\n      - cmd: ip addr add 10.0.0.14/30 dev net0\n      - cmd: ip addr add 10.0.0.6/30 dev net1\n      - cmd: ip addr add 10.0.0.25/30 dev net2\n      - cmd: ip addr add 10.255.0.4/32 dev lo\n      - cmd: mkdir -p /run/bird\n      - cmd: bird -c /etc/bird/bird.conf\n  - name: S1\n    cmds:\n      - cmd: ip addr add 10.0.0.18/30 dev net0\n      - cmd: ip route replace default via 10.0.0.17\n  - name: S3\n    cmds:\n      - cmd: ip addr add 10.0.0.22/30 dev net0\n      - cmd: ip route replace default via 10.0.0.21\n  - name: S4\n    cmds:\n      - cmd: ip addr add 10.0.0.26/30 dev net0\n      - cmd: ip route replace default via 10.0.0.25\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec R1 ping -c2 10.0.0.1\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.0.0.9\n    - cmd: docker exec R1 ping -c2 10.0.0.10\n    - cmd: docker exec R1 ping -c2 10.0.0.17\n    - cmd: docker exec R1 ping -c2 10.0.0.18\n\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.2\n    - cmd: docker exec R2 ping -c2 10.0.0.13\n    - cmd: docker exec R2 ping -c2 10.0.0.14\n\n    - cmd: docker exec R3 ping -c2 10.0.0.9\n    - cmd: docker exec R3 ping -c2 10.0.0.10\n    - cmd: docker exec R3 ping -c2 10.0.0.5\n    - cmd: docker exec R3 ping -c2 10.0.0.6\n    - cmd: docker exec R3 ping -c2 10.0.0.21\n    - cmd: docker exec R3 ping -c2 10.0.0.22\n\n    - cmd: docker exec R4 ping -c2 10.0.0.13\n    - cmd: docker exec R4 ping -c2 10.0.0.14\n    - cmd: docker exec R4 ping -c2 10.0.0.5\n    - cmd: docker exec R4 ping -c2 10.0.0.6\n    - cmd: docker exec R4 ping -c2 10.0.0.25\n    - cmd: docker exec R4 ping -c2 10.0.0.26\n\n"
  },
  {
    "path": "examples/basic_ospfv2_frr/README.md",
    "content": "\n# OSPFv2 using FRR\n\n![](./topo.png)\n\n\n"
  },
  {
    "path": "examples/basic_ospfv2_frr/spec.yaml",
    "content": "\n# DESCRIPTION: OSPF network using FRR\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#    cns spec.yaml test | sudo sh\n# FINI:\n#    cns spec.yaml fini | sudo sh\n# TOPO:\n#\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: direct, args: S1#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R4#net1 }\n      - { name: net2, type: direct, args: S3#net0 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R3#net1 }\n      - { name: net2, type: direct, args: S4#net0 }\n  - name: S1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n  - name: S3\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n  - name: S4\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R4#net2 }\n\nnode_configs:\n  - name: S1\n    cmds:\n      - cmd: ip addr add 10.0.0.18/30 dev net0\n      - cmd: ip route replace default via 10.0.0.17\n  - name: S3\n    cmds:\n      - cmd: ip addr add 10.0.0.22/30 dev net0\n      - cmd: ip route replace default via 10.0.0.21\n  - name: S4\n    cmds:\n      - cmd: ip addr add 10.0.0.26/30 dev net0\n      - cmd: ip route replace default via 10.0.0.25\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.1/30 dev net0\n      - cmd: ip addr add 10.0.0.9/30 dev net1\n      - cmd: ip addr add 10.0.0.17/30 dev net2\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf\"\n          -c \" network 10.0.0.0/30 area 0\"\n          -c \" network 10.0.0.8/30 area 0\"\n          -c \" network 10.0.0.16/30 area 0\"\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.2/30 dev net0\n      - cmd: ip addr add 10.0.0.13/30 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf\"\n          -c \" network 10.0.0.0/30 area 0\"\n          -c \" network 10.0.0.12/30 area 0\"\n  - name: R3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.10/30 dev net0\n      - cmd: ip addr add 10.0.0.5/30 dev net1\n      - cmd: ip addr add 10.0.0.21/30 dev net2\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf\"\n          -c \" network 10.0.0.8/30 area 0\"\n          -c \" network 10.0.0.4/30 area 0\"\n          -c \" network 10.0.0.20/30 area 0\"\n  - name: R4\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add 10.0.0.14/30 dev net0\n      - cmd: ip addr add 10.0.0.6/30 dev net1\n      - cmd: ip addr add 10.0.0.25/30 dev net2\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf\"\n          -c \" network 10.0.0.12/30 area 0\"\n          -c \" network 10.0.0.4/30 area 0\"\n          -c \" network 10.0.0.24/30 area 0\"\n\ntest:\n  - cmds:\n    # P2P Link test\n    - cmd: docker exec S1 ping -c2 10.0.0.17\n    - cmd: docker exec S3 ping -c2 10.0.0.21\n    - cmd: docker exec S4 ping -c2 10.0.0.25\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.0.0.10\n    - cmd: docker exec R1 ping -c2 10.0.0.18\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.14\n    - cmd: docker exec R3 ping -c2 10.0.0.9\n    - cmd: docker exec R3 ping -c2 10.0.0.6\n    - cmd: docker exec R3 ping -c2 10.0.0.21\n    - cmd: docker exec R4 ping -c2 10.0.0.13\n    - cmd: docker exec R4 ping -c2 10.0.0.5\n    - cmd: docker exec R4 ping -c2 10.0.0.26\n\n"
  },
  {
    "path": "examples/basic_ospfv3_bird_multiple_instance/R3_bird6.conf",
    "content": "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;\nprotocol kernel ker1 {\n\tlearn;\n\texport all;\n\timport all;\n\ttable red;\n\tkernel table 10;\n}\n\ntable blu;\nprotocol kernel ker2 {\n\tlearn;\n\texport all;\n\timport all;\n\ttable blu;\n\tkernel table 20;\n}\n\nprotocol direct dir1 {\n\ttable red;\n\tinterface \"net0\";\n\tinterface \"net2\";\n}\n\nprotocol direct dir2 {\n\ttable blu;\n\tinterface \"net1\";\n\tinterface \"net3\";\n}\n\nprotocol ospf ored {\n\tvrf \"red\";\n\ttable red;\n\trouter id 10.255.0.30;\n\texport all;\n\timport all;\n\tarea 0.0.0.0 {\n\t\tinterface \"net0\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net2\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t};\n}\n\nprotocol ospf oblu {\n\tvrf \"blu\";\n\ttable blu;\n\trouter id 10.255.0.31;\n\texport all;\n\timport all;\n\tarea 0.0.0.0 {\n\t\tinterface \"net1\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t\tinterface \"net3\" {\n\t\t\thello 10;\n\t\t\twait 40;\n\t\t\ttype ptp;\n\t\t};\n\t};\n}\n\n"
  },
  {
    "path": "examples/basic_ospfv3_bird_multiple_instance/README.md",
    "content": "\n# OSPFv3 Multiple Instance(VRF) using Bird\n\n![](./topo.png)\n\n- the tmp image should include **bird-1.6.6**\n- also kernel's version can be perform l3mdev\n"
  },
  {
    "path": "examples/basic_ospfv3_bird_multiple_instance/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: docker exec R3 mkdir -p /etc/bird\n    - cmd: docker cp R3_bird6.conf R3:/etc/bird/bird6.conf\n\nnodes:\n  - name: R1\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R3#net0 }\n  - name: R2\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n  - name: R3\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R2#net0 }\n      - { name: net2, type: direct, args: R4#net0 }\n      - { name: net3, type: direct, args: R4#net1 }\n  - name: R4\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n      - { name: net1, type: direct, args: R3#net3 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int net0'\n          -c ' ipv6 address 2001:111::2/64'\n          -c ' ipv6 ospf6 network point-to-point'\n          -c ' exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.1'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' exit'\n\n  - name: R2\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int net0'\n          -c ' ipv6 address 2001:222::2/64'\n          -c ' ipv6 ospf6 network point-to-point'\n          -c ' exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.2'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' exit'\n\n  - name: R3\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link set dev red up\n      - cmd: ip link set dev blu up\n      - cmd: ip link set net0 vrf red\n      - cmd: ip link set net2 vrf red\n      - cmd: ip link set net1 vrf blu\n      - cmd: ip link set net3 vrf blu\n      - cmd: ip -6 addr add 2001:111::1/64 dev net0\n      - cmd: ip -6 addr add 2001:222::1/64 dev net1\n      - cmd: ip -6 addr add 2001:f10::1/64 dev net2\n      - cmd: ip -6 addr add 2001:f11::1/64 dev net3\n      - cmd: mkdir -p /run/bird\n      - cmd: bird6 -c /etc/bird/bird6.conf\n\n  - name: R4\n    cmds:\n      - cmd: sh -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int net0'\n          -c ' ipv6 address 2001:f10::2/64'\n          -c ' ipv6 ospf6 network point-to-point'\n          -c ' exit'\n          -c 'int net1'\n          -c ' ipv6 address 2001:f11::2/64'\n          -c ' ipv6 ospf6 network point-to-point'\n          -c ' exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.4'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c ' exit'\n\ntest:\n  - name: p2p\n    cmds:\n    # - cmd: docker exec R1 ping -c2 10.0.0.1\n    # - cmd: docker exec R1 ping -c2 10.0.0.2\n    # - cmd: docker exec R2 ping -c2 10.0.0.1\n    # - cmd: docker exec R2 ping -c2 10.0.0.2\n\n"
  },
  {
    "path": "examples/basic_ospfv3_frr/README.md",
    "content": "\n# OSPFv3 using FRR\n\n![](./topo.png)\n\n\n"
  },
  {
    "path": "examples/basic_ospfv3_frr/spec.yaml",
    "content": "\n# DESCRIPTION: OSPF network using FRR\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#    cns spec.yaml test | sudo sh\n# FINI:\n#    cns spec.yaml fini | sudo sh\n# TOPO:\n#\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: direct, args: S1#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R4#net1 }\n      - { name: net2, type: direct, args: S3#net0 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R3#net1 }\n      - { name: net2, type: direct, args: S4#net0 }\n  - name: S1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n  - name: S3\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n  - name: S4\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R4#net2 }\n\nnode_configs:\n  - name: S1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip -6 addr add 2001:11::2/64 dev net0\n      - cmd: ip -6 route replace default via 2001:11::1\n  - name: S3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip -6 addr add 2001:33::2/64 dev net0\n      - cmd: ip -6 route replace default via 2001:33::1\n  - name: S4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip -6 addr add 2001:44::2/64 dev net0\n      - cmd: ip -6 route replace default via 2001:44::1\n  - name: R1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip -6 addr add 2001:12::1/64 dev net0\n      - cmd: ip -6 addr add 2001:13::1/64 dev net1\n      - cmd: ip -6 addr add 2001:11::1/64 dev net2\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.1'\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n          -c \" interface net2 area 0.0.0.0\"\n  - name: R2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      - cmd: ip -6 addr add 2001:24::1/64 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.2'\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n  - name: R3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip -6 addr add 2001:13::2/64 dev net0\n      - cmd: ip -6 addr add 2001:34::1/64 dev net1\n      - cmd: ip -6 addr add 2001:33::1/64 dev net2\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.3'\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n          -c \" interface net2 area 0.0.0.0\"\n  - name: R4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip -6 addr add 2001:24::2/64 dev net0\n      - cmd: ip -6 addr add 2001:34::2/64 dev net1\n      - cmd: ip -6 addr add 2001:44::1/64 dev net2\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.4'\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n          -c \" interface net2 area 0.0.0.0\"\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec S1 ping -c2 2001:11::1\n    - cmd: docker exec S3 ping -c2 2001:33::1\n    - cmd: docker exec S4 ping -c2 2001:44::1\n\n    - cmd: docker exec R1 ping -c2 2001:12::1\n    - cmd: docker exec R1 ping -c2 2001:12::2\n    - cmd: docker exec R1 ping -c2 2001:13::1\n    - cmd: docker exec R1 ping -c2 2001:13::2\n    - cmd: docker exec R1 ping -c2 2001:11::1\n    - cmd: docker exec R1 ping -c2 2001:11::2\n\n    - cmd: docker exec R2 ping -c2 2001:12::1\n    - cmd: docker exec R2 ping -c2 2001:12::2\n    - cmd: docker exec R2 ping -c2 2001:24::1\n    - cmd: docker exec R2 ping -c2 2001:24::2\n\n    - cmd: docker exec R3 ping -c2 2001:13::1\n    - cmd: docker exec R3 ping -c2 2001:13::2\n    - cmd: docker exec R3 ping -c2 2001:34::1\n    - cmd: docker exec R3 ping -c2 2001:34::2\n    - cmd: docker exec R3 ping -c2 2001:33::1\n    - cmd: docker exec R3 ping -c2 2001:33::2\n\n    - cmd: docker exec R4 ping -c2 2001:24::1\n    - cmd: docker exec R4 ping -c2 2001:24::2\n    - cmd: docker exec R4 ping -c2 2001:34::1\n    - cmd: docker exec R4 ping -c2 2001:34::2\n    - cmd: docker exec R4 ping -c2 2001:44::1\n    - cmd: docker exec R4 ping -c2 2001:44::2\n\n"
  },
  {
    "path": "examples/basic_pbr/spec.yaml",
    "content": "postinit:\n- cmds:\n  - cmd: |\n      cat <<EOF > /tmp/Corefile\n      .:53 {\n        forward . 8.8.8.8\n        log\n        errors\n        cache\n      }\n      EOF\n  - cmd: docker cp /tmp/Corefile S1:/Corefile\n\nnodes:\n- name: S1\n  image: slankdev/coredns:centos-7\n  net_base: bridge\n  interfaces:\n  - { name: net0, type: direct, args: HV1#net0 }\n  - { name: net1, type: direct, args: HV1#net1 }\n- name: HV1\n  image: slankdev/coredns:centos-7\n  interfaces:\n  - { name: net0, type: direct, args: S1#net0 }\n  - { name: net1, type: direct, args: S1#net1 }\n\nnode_configs:\n- name: S1\n  cmds:\n  - cmd: ip addr add 10.0.0.10/24 dev net0\n  - cmd: ip addr add 10.0.0.11/24 dev net1\n  - cmd: ip rule add prio 100 from 10.0.0.11 table 300\n  - cmd: ip route add default via 10.0.0.1 dev net1 table 300\n  - cmd: nohup coredns -conf /Corefile &\n\n- name: HV1\n  cmds:\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip addr add 10.0.0.1/24 dev net1\n  - cmd: ip route add 10.0.0.10/32 dev net0\n  - cmd: ip route add 10.0.0.11/32 dev net1\n"
  },
  {
    "path": "examples/basic_peer/spec.yaml",
    "content": "\nprecmd:\n  - cmds:\n    - cmd: export IMAGE=slankdev/frr:centos-7-stable-7.0\n\nnodes:\n  - name: R0\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: R1\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R0#net0 }\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: sh -c 'enable_seg6_router.py | sh'\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 1\"\n          -c \" bgp router-id 1.1.1.1\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \"  redistribute kernel\"\n          -c \" exit-address-family\"\n\n  - name: R1\n    cmds:\n      - cmd: sh -c 'enable_seg6_router.py | sh'\n      - cmd: /usr/lib/frr/frrinit.sh start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 2\"\n          -c \" bgp router-id 2.2.2.2\"\n          -c \" bgp bestpath as-path multipath-relax\"\n          -c \" bgp bestpath compare-routerid\"\n          -c \" neighbor FABRIC peer-group\"\n          -c \" neighbor FABRIC remote-as external\"\n          -c \" neighbor FABRIC capability extended-nexthop\"\n          -c \" neighbor net0 interface peer-group FABRIC\"\n          -c \" !\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute connected\"\n          -c \"  redistribute kernel\"\n          -c \" exit-address-family\"\n\n"
  },
  {
    "path": "examples/basic_pim/README.md",
    "content": "\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 <time>\niperf -u -c 239.1.1.5 -i 1 -T 10 -t 5\n```\n\n## when add/del mroute\n\nadd\n```\n[ns0]ubuntu-bionic:~/git/netlinkd:) nlsniff -g all\nmonitoring group(RTMGRP) is 0xffffffff ...\nRTM_NEWROUTE f=0x0000 s=0000000000 p=0000000000 :: fmly=128 dl=32 sl=32 tos=0 tab=253 pro=17 scope=0 type=5 f=0x0\n  0x000f RTA_TABLE        :: 253\n  0x0002 RTA_SRC          :: 0.0.0.0\n  0x0001 RTA_DST          :: 239.1.1.5\n  0x0003 RTA_IIF          :: 1\n  0x0009 RTA_MULTIPATH    :: unknown-fmt(rta_len=20,data=08000001...)\n  0x0011 RTA_MFC_STATS    :: unknown-fmt(rta_len=28,data=00000000...)\n  0x0017 RTA_EXPIRES      :: unknown-fmt(rta_len=12,data=00000000...)\n```\n\ndel\n```\n[ns0]ubuntu-bionic:~/git/netlinkd:) nlsniff -g all\nmonitoring group(RTMGRP) is 0xffffffff ...\nRTM_NEWROUTE f=0x0000 s=0000000000 p=0000000000 :: fmly=128 dl=32 sl=32 tos=0 tab=253 pro=17 scope=0 type=5 f=0x0\n  0x000f RTA_TABLE        :: 253\n  0x0002 RTA_SRC          :: 0.0.0.0\n  0x0001 RTA_DST          :: 239.1.1.5\n  0x0003 RTA_IIF          :: 1\n  0x0009 RTA_MULTIPATH    :: unknown-fmt(rta_len=12,data=08000001...)\n  0x0011 RTA_MFC_STATS    :: unknown-fmt(rta_len=28,data=00000000...)\n  0x0017 RTA_EXPIRES      :: unknown-fmt(rta_len=12,data=00000000...)\n\nRTM_DELROUTE f=0x0000 s=0000000000 p=0000000000 :: fmly=128 dl=32 sl=32 tos=0 tab=253 pro=17 scope=0 type=5 f=0x0\n  0x000f RTA_TABLE        :: 253\n  0x0002 RTA_SRC          :: 0.0.0.0\n  0x0001 RTA_DST          :: 239.1.1.5\n  0x0003 RTA_IIF          :: 1\n  0x0009 RTA_MULTIPATH    :: unknown-fmt(rta_len=12,data=08000001...)\n  0x0011 RTA_MFC_STATS    :: unknown-fmt(rta_len=28,data=00000000...)\n  0x0017 RTA_EXPIRES      :: unknown-fmt(rta_len=12,data=00000000...)\n```\n"
  },
  {
    "path": "examples/basic_pim/spec.yaml",
    "content": "# http://www.asciiflow.com\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\"\n          -c \" ip address 10.255.0.1/32\"\n          -c \" ip pim sm\"\n          -c \" ip igmp\"\n          -c \" exit\"\n          -c \"int net0\"\n          -c \" ip address 10.0.0.1/30\"\n          -c \" ip pim sm\"\n          -c \" ip igmp\"\n          -c \" exit\"\n          -c \"int net1\"\n          -c \" ip address 10.0.0.5/30\"\n          -c \" ip pim sm\"\n          -c \" ip igmp\"\n          -c \" exit\"\n          -c \"ip pim rp 10.255.0.2\"\n          -c 'ip route 10.255.0.2/32 10.0.0.2'\n          -c 'ip route 10.255.0.3/32 10.0.0.6'\n  - name: R2\n    cmds:\n      - cmd: ip route del default\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\"\n          -c \" ip address 10.255.0.2/32\"\n          -c \" ip pim sm\"\n          -c \" ip igmp\"\n          -c \" exit\"\n          -c \"int net0\"\n          -c \" ip address 10.0.0.2/30\"\n          -c \" ip pim sm\"\n          -c \" ip igmp\"\n          -c \" exit\"\n          -c \"ip pim rp 10.255.0.2\"\n          -c 'ip route 0.0.0.0/0 10.0.0.1'\n  - name: R3\n    cmds:\n      - cmd: ip route del default\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\"\n          -c \" ip address 10.255.0.3/32\"\n          -c \" ip pim sm\"\n          -c \" ip igmp\"\n          -c \" exit\"\n          -c \"int net0\"\n          -c \" ip address 10.0.0.6/30\"\n          -c \" ip pim sm\"\n          -c \" ip igmp\"\n          -c \" exit\"\n          -c \"ip pim rp 10.255.0.2\"\n          -c 'ip route 0.0.0.0/0 10.0.0.5'\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec R1 ping -c2 10.0.0.1\n      - cmd: docker exec R1 ping -c2 10.0.0.2\n      - cmd: docker exec R1 ping -c2 10.0.0.5\n      - cmd: docker exec R1 ping -c2 10.0.0.6\n      - cmd: docker exec R2 ping -c2 10.0.0.1\n      - cmd: docker exec R2 ping -c2 10.0.0.2\n      - cmd: docker exec R3 ping -c2 10.0.0.5\n      - cmd: docker exec R3 ping -c2 10.0.0.6\n  - name: remote\n    cmds:\n      - cmd: docker exec R1 ping -c2 10.255.0.1\n      - cmd: docker exec R1 ping -c2 10.255.0.2\n      - cmd: docker exec R1 ping -c2 10.255.0.3\n      - cmd: docker exec R2 ping -c2 10.255.0.1\n      - cmd: docker exec R2 ping -c2 10.255.0.2\n      - cmd: docker exec R2 ping -c2 10.255.0.3\n      - cmd: docker exec R3 ping -c2 10.255.0.1\n      - cmd: docker exec R3 ping -c2 10.255.0.2\n      - cmd: docker exec R3 ping -c2 10.255.0.3\n\n"
  },
  {
    "path": "examples/basic_pim2/README.md",
    "content": "\n# PIM Multicast Test\n\n![](topo.jpeg)\n\ndebug commands (vtysh)\n```\nshow ip mroute\nshow ip pim neighbor\nshow ip pim join\nshow ip pim state\nshow ip pim rp-info\nshow ip pim interface\n```\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 <time>\niperf -u -c 239.1.1.5 -i 1 -T 10 -t 5\n```\n\n## ip mroute result\n\n```\ndocker exec -it R1 vtysh -c 'show ip pim rp-info'\ndocker exec -it R2 vtysh -c 'show ip pim rp-info'\ndocker exec -it R3 vtysh -c 'show ip pim rp-info'\n\ndocker exec -it R1 vtysh -c 'show ip pim nei'\ndocker exec -it R2 vtysh -c 'show ip pim nei'\ndocker exec -it R3 vtysh -c 'show ip pim nei'\n```\n```\nip mroute\n```\n"
  },
  {
    "path": "examples/basic_pim2/spec.yaml",
    "content": "# http://www.asciiflow.com\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n      - { name: net2, type: direct, args: R5#net0 }\n\n  # - name: R3\n  #   image: slankdev/ovs\n  #   interfaces:\n  #     - { name: ens7, type: phys }\n  #     - { name: ens8, type: phys }\n  #     - { name: ens9, type: phys }\n  #     - { name: net0, type: direct, args: R1#net1 }\n  #     - { name: net1, type: direct, args: R6#net0 }\n  #     - { name: net2, type: direct, args: R7#net0 }\n\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R6#net0 }\n      - { name: net2, type: direct, args: R7#net0 }\n\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: R5\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n  - name: R6\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n  - name: R7\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.disable_ipv6=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip address 10.255.0.1/32\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n          -c \"int net0\" -c \"ip address 10.0.0.1/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n          -c \"int net1\" -c \"ip address 10.0.0.5/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n          -c \"ip pim rp 10.255.0.1\"\n          -c \"router ospf\"\n          -c \" ospf router-id 10.255.0.1\"\n          -c \" network 10.255.0.1/32 area 0\"\n          -c \" network 10.0.0.0/30 area 0\"\n          -c \" network 10.0.0.4/30 area 0\"\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.disable_ipv6=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"int lo\" -c \"ip addr 10.255.0.2/32\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n          -c \"int net0\" -c \"ip addr 10.0.0.2/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n          -c \"int net1\" -c \"ip addr 10.0.0.9/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n          -c \"int net2\" -c \"ip addr 10.0.0.13/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n          -c \"ip pim rp 10.255.0.1\"\n          -c \"router ospf\"\n          -c \"router ospf\"\n          -c \" ospf router-id 10.255.0.2\"\n          -c \" network 10.255.0.2/32 area 0\"\n          -c \" network 10.0.0.0/30 area 0\"\n          -c \" network 10.0.0.8/30 area 0\"\n          -c \" network 10.0.0.12/30 area 0\"\n  - name: R3\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.disable_ipv6=0'\n      # - cmd: /usr/lib/frr/frr start\n      # - cmd: >-\n      #     vtysh -c \"conf t\"\n      #     -c \"int lo\" -c \"ip addr 10.255.0.3/32\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n      #     -c \"int net0\" -c \"ip addr 10.0.0.6/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n      #     -c \"int net1\" -c \"ip addr 10.0.0.17/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n      #     -c \"int net2\" -c \"ip addr 10.0.0.21/30\" -c \"ip pim sm\" -c \"ip igmp\" -c \"exit\"\n      #     -c \"ip pim rp 10.255.0.1\"\n      #     -c \"router ospf\"\n      #     -c \" ospf router-id 10.255.0.3\"\n      #     -c \" network 10.255.0.3/32 area 0\"\n      #     -c \" network 10.0.0.4/30 area 0\"\n      #     -c \" network 10.0.0.16/30 area 0\"\n      #     -c \" network 10.0.0.20/30 area 0\"\n\n      - cmd: ovs-vsctl add-br ovs0\n      - cmd: ovs-vsctl add-port ovs0 net0 tag=1\n      - cmd: ovs-vsctl add-port ovs0 ens7 tag=1\n      - cmd: ovs-vsctl add-port ovs0 net1 tag=2\n      - cmd: ovs-vsctl add-port ovs0 ens8 tag=2\n      - cmd: ovs-vsctl add-port ovs0 net2 tag=3\n      - cmd: ovs-vsctl add-port ovs0 ens9 tag=3\n  - name: R4\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.forwarding=1'\n      - cmd: ip addr add 10.0.0.10/30 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 10.0.0.9\n  - name: R5\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.forwarding=1'\n      - cmd: ip addr add 10.0.0.14/30 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 10.0.0.13\n  - name: R6\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.forwarding=1'\n      - cmd: ip addr add 10.0.0.18/30 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 10.0.0.17\n  - name: R7\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.forwarding=1'\n      - cmd: ip addr add 10.0.0.22/30 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 10.0.0.21\n\ntest:\n  - name: remote\n    cmds:\n      - cmd: docker exec R1 ping -c2 10.255.0.1\n      - cmd: docker exec R1 ping -c2 10.255.0.2\n      - cmd: docker exec R1 ping -c2 10.255.0.3\n      - cmd: docker exec R2 ping -c2 10.255.0.1\n      - cmd: docker exec R2 ping -c2 10.255.0.2\n      - cmd: docker exec R2 ping -c2 10.255.0.3\n      - cmd: docker exec R3 ping -c2 10.255.0.1\n      - cmd: docker exec R3 ping -c2 10.255.0.2\n      - cmd: docker exec R3 ping -c2 10.255.0.3\n      - cmd: docker exec R4 ping -c2 10.255.0.1\n      - cmd: docker exec R4 ping -c2 10.255.0.2\n      - cmd: docker exec R4 ping -c2 10.255.0.3\n      - cmd: docker exec R5 ping -c2 10.255.0.1\n      - cmd: docker exec R5 ping -c2 10.255.0.2\n      - cmd: docker exec R5 ping -c2 10.255.0.3\n      - cmd: docker exec R6 ping -c2 10.255.0.1\n      - cmd: docker exec R6 ping -c2 10.255.0.2\n      - cmd: docker exec R6 ping -c2 10.255.0.3\n      - cmd: docker exec R7 ping -c2 10.255.0.1\n      - cmd: docker exec R7 ping -c2 10.255.0.2\n      - cmd: docker exec R7 ping -c2 10.255.0.3\n\n"
  },
  {
    "path": "examples/basic_pppoe_WIP/spec.yaml",
    "content": "# http://www.asciiflow.com\n\nnodes:\n  - name: R0\n    image: tmp\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n      - { name: net1, type: direct, args: S0#net0 }\n  - name: S0\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: R0#net1 }\n  - name: S1\n    image: tmp\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n  - name: S2\n    image: tmp\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n\nswitches:\n  - name: B0\n    interfaces:\n      - { name: net0, type: container, args: R0 }\n      - { name: net0, type: container, args: S1 }\n      - { name: net0, type: container, args: S2 }\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: sh -c 'echo  > /etc/ppp/options'\n      - cmd: sh -c 'echo asyncmap 0           >> /etc/ppp/options'\n      - cmd: sh -c 'echo auth                 >> /etc/ppp/options'\n      - cmd: sh -c 'echo crtscts              >> /etc/ppp/options'\n      - cmd: sh -c 'echo lock                 >> /etc/ppp/options'\n      - cmd: sh -c 'echo hide-password        >> /etc/ppp/options'\n      - cmd: sh -c 'echo modem                >> /etc/ppp/options'\n      - cmd: sh -c 'echo +pap                 >> /etc/ppp/options'\n      - cmd: sh -c 'echo proxyarp             >> /etc/ppp/options'\n      - cmd: sh -c 'echo lcp-echo-interval 30 >> /etc/ppp/options'\n      - cmd: sh -c 'echo lcp-echo-failure 4   >> /etc/ppp/options'\n      - cmd: sh -c 'echo noipx                >> /etc/ppp/options'\n      - cmd: sh -c 'echo  > /etc/ppp/pap-secrets'\n      - cmd: sh -c 'echo testuser1 * \"password\" 172.16.0.101 >> /etc/ppp/pap-secrets'\n      - cmd: sh -c 'echo testuser2 * \"password\" 172.16.0.102 >> /etc/ppp/pap-secrets'\n      - cmd: ip link set net0 up\n      - cmd: pppoe-server -I net0 -C slankPPPoEserv -L 172.16.0.254 -O /etc/ppp/options\n\ntest:\n  - cmds:\n    - cmd: docker exec S1 echo slankdev slankdev\n    - cmd: docker exec S2 echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_rift/README.md",
    "content": "\n# RIFT: Routing In Fat Tree\n\nThis is evaluation of rift-python powered by IETF.\n\n- draft-ietf-rift-rift-03 https://tools.ietf.org/html/draft-ietf-rift-rift-03\n- rift-python https://github.com/brunorijsman/rift-python\n- juniper's explanation (ppt) https://www.ripe.net/participate/forms/uploads/fobi_plugins/file/see7/Szarkowicz_RIFT_RIPE_TM_bbd50ec4-6dab-4c14-acea-1e767ef7f9da.pptx\n- Kobayashi-san's good explanation jp, (this is talking about rift-01).\n  https://www.slideshare.net/MasayukiKobayashi/rift-a-new-routing-protocol-for-ip-fabrics\n- Miyasaka-san's good explanation jp about IETF100-report that includes about RIFT.\n  https://www.isoc.jp/wiki.cgi?action=ATTACH&file=s4%2Dmiyasaka%2Epdf&page=IETF100Update\n\n\n![](./topo.png)\n\n```\ntn upconf | sudo sh\ndocker exec -it Spine1 telnet localhost `docker exec Spine1 cat /rift`\nTrying 127.0.0.1...\nConnected to localhost.\nEscape character is '^]'.\nSpine1> show interfaces\n+-----------+------------+-----------+-----------+\n| Interface | Neighbor   | Neighbor  | Neighbor  |\n| Name      | Name       | System ID | State     |\n+-----------+------------+-----------+-----------+\n| net0      | Leaf1:net0 | 1001      | THREE_WAY |\n+-----------+------------+-----------+-----------+\n| net1      | Leaf2:net0 | 1002      | THREE_WAY |\n+-----------+------------+-----------+-----------+\n```\n\nBasically In the RIFT world, Southbound side was received to-Northbound-route\nas a default-route (0.0.0.0/0, 0::/0). We can check that with following cli\n```\ndocker exec Leaf1 ip -4 route list\ndefault proto 99\n        nexthop via 99.1.2.2 dev net0 weight 2\n        nexthop via 99.3.4.4 dev net1 weight 2\n77.1.0.0/24 dev net2 proto kernel scope link src 77.1.0.1\n99.1.2.0/24 dev net0 proto kernel scope link src 99.1.2.1\n99.3.4.0/24 dev net1 proto kernel scope link src 99.3.4.3\n```\n\n"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/meta_topology_2c_2x2.yaml",
    "content": "nr-leaf-nodes-per-pod: 2\nnr-spine-nodes-per-pod: 2\n"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_leaf1.yaml",
    "content": "shards:\n  - id: 0\n    nodes:\n      - name: Leaf1\n        level: 0\n        systemid: 1001\n        interfaces:\n          - name: net0 # leaf1:net0 -> spine1:net0\n          - name: net1 # leaf1:net1 -> spine2:net0\n          - name: net2\n        v4prefixes:\n          - address: 88.0.1.1\n            mask: 32\n            metric: 1\n          - address: 77.1.0.0\n            mask: 24\n            metric: 1\n"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_leaf2.yaml",
    "content": "shards:\n  - id: 0\n    nodes:\n      - name: Leaf2\n        level: 0\n        systemid: 1002\n        interfaces:\n          - name: net0 # leaf2:net0 -> spine1:net1\n          - name: net1 # leaf2:net1 -> spine2:net1\n          - name: net2\n        v4prefixes:\n          - address: 88.0.2.1\n            mask: 32\n            metric: 1\n          - address: 77.2.0.0\n            mask: 24\n            metric: 1\n"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_spine1.yaml",
    "content": "shards:\n  - id: 0\n    nodes:\n      - name: Spine1\n        level: 1\n        systemid: 101\n        interfaces:\n          - name: net0 # spine1:net0 -> leaf1:net0\n          - name: net1 # spine1:net1 -> leaf2:net0\n        v4prefixes:\n          - address: 88.1.1.1\n            mask: 32\n            metric: 1\n"
  },
  {
    "path": "examples/basic_rift/ietf_rift_python/rift_spine2.yaml",
    "content": "shards:\n  - id: 0\n    nodes:\n      - name: Spine2\n        level: 1\n        systemid: 102\n        interfaces:\n          - name: net0 # spine2:net0 -> leaf1:net1\n          - name: net1 # spine2:net1 -> leaf2:net1\n        v4prefixes:\n          - address: 88.1.2.1\n            mask: 32\n            metric: 1\n"
  },
  {
    "path": "examples/basic_rift/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: docker cp ietf_rift_python/rift_spine1.yaml Spine1:/root/config.yaml\n    - cmd: docker cp ietf_rift_python/rift_spine2.yaml Spine2:/root/config.yaml\n    - cmd: docker cp ietf_rift_python/rift_leaf1.yaml Leaf1:/root/config.yaml\n    - cmd: docker cp ietf_rift_python/rift_leaf2.yaml Leaf2:/root/config.yaml\n\nnodes:\n  - name: Spine1\n    image: slankdev/rift:ietf-rift-03\n    interfaces:\n      - { name: net0, type: direct, args: Leaf1#net0 }\n      - { name: net1, type: direct, args: Leaf2#net0 }\n  - name: Spine2\n    image: slankdev/rift:ietf-rift-03\n    interfaces:\n      - { name: net0, type: direct, args: Leaf1#net1 }\n      - { name: net1, type: direct, args: Leaf2#net1 }\n  - name: Leaf1\n    image: slankdev/rift:ietf-rift-03\n    interfaces:\n      - { name: net0, type: direct, args: Spine1#net0 }\n      - { name: net1, type: direct, args: Spine2#net0 }\n      - { name: net2, type: direct, args: Serv1#net0 }\n  - name: Leaf2\n    image: slankdev/rift:ietf-rift-03\n    interfaces:\n      - { name: net0, type: direct, args: Spine1#net1 }\n      - { name: net1, type: direct, args: Spine2#net1 }\n      - { name: net2, type: direct, args: Serv2#net0 }\n  - name: Serv1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: Leaf1#net2 } ]\n  - name: Serv2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: Leaf2#net2 } ]\n\nnode_configs:\n  - name: Spine1\n    cmds:\n      - cmd: ip addr add 88.1.1.1/32 dev lo\n      - cmd: ip addr add 99.1.2.2/24 dev net0\n      - cmd: ip addr add 99.5.6.6/24 dev net1\n      - cmd: >-\n          nohup bash -c \"source rift-python/env/bin/activate;\n          python rift-python/rift --telnet-port-file /rift config.yaml\" &\n  - name: Spine2\n    cmds:\n      - cmd: ip addr add 88.1.2.1/32 dev lo\n      - cmd: ip addr add 99.3.4.4/24 dev net0\n      - cmd: ip addr add 99.7.8.8/24 dev net1\n      - cmd: >-\n          nohup bash -c \"source rift-python/env/bin/activate;\n          python rift-python/rift --telnet-port-file /rift config.yaml\" &\n  - name: Leaf1\n    cmds:\n      - cmd: ip addr add 88.0.1.1/32 dev lo\n      - cmd: ip addr add 99.1.2.1/24 dev net0\n      - cmd: ip addr add 99.3.4.3/24 dev net1\n      - cmd: ip addr add 77.1.0.1/24 dev net2\n      - cmd: >-\n          nohup bash -c \"source rift-python/env/bin/activate;\n          python rift-python/rift --telnet-port-file /rift config.yaml\" &\n  - name: Leaf2\n    cmds:\n      - cmd: ip addr add 88.0.2.1/32 dev lo\n      - cmd: ip addr add 99.5.6.5/24 dev net0\n      - cmd: ip addr add 99.7.8.7/24 dev net1\n      - cmd: ip addr add 77.2.0.1/24 dev net2\n      - cmd: >-\n          nohup bash -c \"source rift-python/env/bin/activate;\n          python rift-python/rift --telnet-port-file /rift config.yaml\" &\n  - name: Serv1\n    cmds:\n      - cmd: ip addr add 77.1.0.2/24 dev net0\n      - cmd: ip route add default via 77.1.0.1\n  - name: Serv2\n    cmds:\n      - cmd: ip addr add 77.2.0.2/24 dev net0\n      - cmd: ip route add default via 77.2.0.1\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: echo slankdev slankdev\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_rtbh/README.md",
    "content": "\n# RTBH: Remotely-Triggered Black Hole Routing\n\n![](./topo.png)\n\ncreate test traffic\n```\nhost# docker exec -it C2 ping 10.0.0.2 -i0.1\n...(snip)\n64 bytes from 10.0.0.2: icmp_seq=766 ttl=62 time=0.092 ms\n64 bytes from 10.0.0.2: icmp_seq=767 ttl=62 time=0.089 ms\n64 bytes from 10.0.0.2: icmp_seq=768 ttl=62 time=0.071 ms\n64 bytes from 10.0.0.2: icmp_seq=769 ttl=62 time=0.093 ms\n64 bytes from 10.0.0.2: icmp_seq=770 ttl=62 t\n...(snip)\n```\n\ncheck traffic\n```\nR1# watch -n0.1 ip -s link\n\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000\n    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n    RX: bytes  packets  errors  dropped overrun mcast\n    0          0        0       0       0       0\n    TX: bytes  packets  errors  dropped carrier collsns\n    0          0        0       0       0       0\n2: net0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000\n    link/ether 16:7d:a4:a4:1c:4c brd ff:ff:ff:ff:ff:ff link-netnsid 0\n    RX: bytes  packets  errors  dropped overrun mcast\n    77770      799      0       0       0       0\n    TX: bytes  packets  errors  dropped carrier collsns\n    74338      765      0       0       0       0\n3: net1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000\n    link/ether d6:70:d3:e4:e0:74 brd ff:ff:ff:ff:ff:ff link-netnsid 1\n    RX: bytes  packets  errors  dropped overrun mcast\n    72618      745      0       0       0       0\n    TX: bytes  packets  errors  dropped carrier collsns\n    72618      745      0       0       0       0\n4: net2@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000\n    link/ether a2:6c:f6:ee:ce:59 brd ff:ff:ff:ff:ff:ff link-netnsid 2\n    RX: bytes  packets  errors  dropped overrun mcast\n    1607       21       0       0       0       0\n    TX: bytes  packets  errors  dropped carrier collsns\n    1467       19       0       0       0       0\n```\n\nRTBH operation\n```\nroot@RR# vtysh\n\nHello, this is FRRouting (version 6.0).\nCopyright 1996-2005 Kunihiro Ishiguro, et al.\n\nRR# configure terminal\nRR(config)# ip route 10.0.0.2/32 192.2.0.1     // RTBH on\nRR(config)# no ip route 10.0.0.2/32 192.2.0.1  // RTBH off\n```\n\nreferences\n- http://irs.ietf.to/past/docs_20071011/20071011-irs14-rtbh.pdf page4 discribe fine.\n"
  },
  {
    "path": "examples/basic_rtbh/spec.yaml",
    "content": "\nnodes:\n  ## AS65001\n  - name: R1\n    type: docker\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: RR#net0 }\n\n  ## AS65001\n  - name: RR\n    type: docker\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n\n  ## AS65001\n  - name: C1\n    type: docker\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n\n  ## AS65002\n  - name: R2\n    type: docker\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n\n  ## AS65002\n  - name: C2\n    type: docker\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: ip addr add 30.0.0.1/24 dev net0\n      - cmd: ip addr add 10.0.0.1/24 dev net1\n      - cmd: ip addr add 10.254.0.1/24 dev net2\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65001\"\n          -c \" bgp router-id 30.0.0.1\"\n          -c \" neighbor 30.0.0.2 remote-as 65002\"\n          -c \" bgp router-id 10.254.0.2\"\n          -c \" neighbor 10.254.0.2 remote-as 65001\"\n          -c \" network 10.0.0.0/8\"\n          -c \" exit\"\n          -c \"ip route 192.2.0.1/32 blackhole\"\n\n  - name: RR\n    cmds:\n      - cmd: ip addr add 10.254.0.2/24 dev net0\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65001\"\n          -c \" bgp router-id 10.254.0.1\"\n          -c \" neighbor 10.254.0.1 remote-as 65001\"\n          -c \" address-family ipv4 unicast\"\n          -c \"  redistribute static\"\n          -c \"  exit-address-family\"\n          -c \" exit\"\n          -c \"ip route 192.2.0.1/32 blackhole\"\n\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route add default via 10.0.0.1\n\n  - name: R2\n    cmds:\n      - cmd: ip addr add 30.0.0.2/24 dev net0\n      - cmd: ip addr add 20.0.0.1/24 dev net1\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"router bgp 65002\"\n          -c \" bgp router-id 30.0.0.2\"\n          -c \" neighbor 30.0.0.1 remote-as 65001\"\n          -c \" network 20.0.0.0/8\"\n          -c \" exit\"\n          -c \"ip route 192.2.0.1/32 blackhole\"\n\n  - name: C2\n    cmds:\n      - cmd: ip addr add 20.0.0.2/24 dev net0\n      - cmd: ip route add default via 20.0.0.1\n\n# test:\n#   - name: p2p\n#     cmds:\n#     - cmd: docker exec C0 ping -c2 10.0.0.2\n#     - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_source_routing/README.md",
    "content": "\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 exec R1 ip rule add from 192.168.1.3 table 20\ndocker exec R1 ip route add 192.168.2.0/24 via 10.0.0.2\ndocker exec R1 ip route add 192.168.2.0/24 via 10.0.0.2 table 10\ndocker exec R1 ip route add 192.168.2.0/24 via 10.0.0.2 table 20\n```\n\ncheck networking\n```\ndocker exec -it R1 tcpdump -Qout -ni net0\ndocker exec -it R1 tcpdump -Qout -ni net1\n```\n\n"
  },
  {
    "path": "examples/basic_source_routing/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: direct, args: R4#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R3#net1 }\n      - { name: net2, type: direct, args: R5#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: R2#net1 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n  - name: R5\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/30 dev net0\n      - cmd: ip addr add 10.0.0.5/30 dev net1\n      - cmd: ip addr add 192.168.1.1/24 dev net2\n      - cmd: ip route add 192.168.2.0/24 via 10.0.0.2\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.2/30 dev net0\n      - cmd: ip addr add 10.0.0.9/30 dev net1\n      - cmd: ip addr add 192.168.2.1/24 dev net2\n      - cmd: ip route add 192.168.1.0/24 via 10.0.0.1\n  - name: R3\n    cmds:\n      - cmd: ip addr add 10.0.0.6/30 dev net0\n      - cmd: ip addr add 10.0.0.10/30 dev net1\n      - cmd: ip route add 192.168.1.0/24 via 10.0.0.5\n      - cmd: ip route add 192.168.2.0/24 via 10.0.0.9\n  - name: R4\n    cmds:\n      - cmd: ip addr add 192.168.1.2/24 dev net0\n      - cmd: ip addr add 192.168.1.3/24 dev net0\n      - cmd: ip addr add 192.168.1.4/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.1.1\n  - name: R5\n    cmds:\n      - cmd: ip addr add 192.168.2.2/24 dev net0\n      - cmd: ip addr add 192.168.2.3/24 dev net0\n      - cmd: ip addr add 192.168.2.4/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.2.1\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec R1 ping -c2 10.0.0.1\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.0.0.5\n    - cmd: docker exec R1 ping -c2 10.0.0.6\n    - cmd: docker exec R1 ping -c2 192.168.1.1\n    - cmd: docker exec R1 ping -c2 192.168.1.2\n    - cmd: docker exec R1 ping -c2 192.168.1.3\n    - cmd: docker exec R1 ping -c2 192.168.1.4\n\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.2\n    - cmd: docker exec R2 ping -c2 10.0.0.9\n    - cmd: docker exec R2 ping -c2 192.168.2.1\n    - cmd: docker exec R2 ping -c2 192.168.2.2\n    - cmd: docker exec R2 ping -c2 192.168.2.3\n    - cmd: docker exec R2 ping -c2 192.168.2.4\n\n    - cmd: docker exec R3 ping -c2 10.0.0.5\n    - cmd: docker exec R3 ping -c2 10.0.0.6\n    - cmd: docker exec R3 ping -c2 10.0.0.9\n    - cmd: docker exec R3 ping -c2 10.0.0.10\n\n    - cmd: docker exec R4 ping -c2 192.168.1.1\n    - cmd: docker exec R4 ping -c2 192.168.1.2\n    - cmd: docker exec R4 ping -c2 192.168.1.3\n    - cmd: docker exec R4 ping -c2 192.168.1.4\n\n    - cmd: docker exec R5 ping -c2 192.168.2.1\n    - cmd: docker exec R5 ping -c2 192.168.2.2\n    - cmd: docker exec R5 ping -c2 192.168.2.3\n    - cmd: docker exec R5 ping -c2 192.168.2.4\n\n  - name: remote\n    cmds:\n    - cmd: docker exec R4 ping -c2 -I 10.0.0.14 10.0.0.22\n    - cmd: docker exec R4 ping -c2 -I 10.0.0.15 10.0.0.22\n\n"
  },
  {
    "path": "examples/basic_srmpls/spec.yaml",
    "content": "# http://www.asciiflow.com\n\npreinit:\n  - cmds:\n    - cmd: modprobe mpls_router\n    - cmd: modprobe mpls_gso\n    - cmd: modprobe mpls_iptunnel\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n    - { name: net0, type: direct, args: R1#net0 }\n    - { name: net1, type: direct, args: R4#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n    - { name: net0, type: direct, args: R1#net0 }\n    - { name: net1, type: direct, args: R3#net0 }\n    - { name: net2, type: direct, args: R4#net2 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n    - { name: net0, type: direct, args: R2#net1 }\n    - { name: net1, type: direct, args: R4#net1 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n    - { name: net0, type: direct, args: R1#net1 }\n    - { name: net1, type: direct, args: R3#net1 }\n    - { name: net2, type: direct, args: R2#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.1/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.1/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.9/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.1'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.1'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.1/32 index 1001'\n          -c 'exit'\n\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.conf.net2.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.2/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.2/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.5/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 10.0.0.13/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.2'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.2'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.2/32 index 1002'\n          -c 'exit'\n\n  - name: R3\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.3/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.6/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.17/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.3'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.3'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.3/32 index 1003'\n          -c 'exit'\n\n  - name: R4\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n      - cmd: sysctl -w net.ipv4.ip_forward=1\n      - cmd: sysctl -w net.mpls.conf.lo.input=1\n      - cmd: sysctl -w net.mpls.conf.net0.input=1\n      - cmd: sysctl -w net.mpls.conf.net1.input=1\n      - cmd: sysctl -w net.mpls.conf.net2.input=1\n      - cmd: sysctl -w net.mpls.platform_labels=1048575\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.4/32'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net0'\n          -c ' ip address 10.0.0.10/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net1'\n          -c ' ip address 10.0.0.18/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'interface net2'\n          -c ' ip address 10.0.0.14/30'\n          -c ' ip ospf area 0.0.0.0'\n          -c 'exit'\n          -c 'router ospf'\n          -c ' ospf router-id 10.255.0.4'\n          -c ' router-info area 0.0.0.0'\n          -c ' passive-interface lo'\n          -c ' capability opaque'\n          -c ' mpls-te on'\n          -c ' mpls-te router-address 10.255.0.4'\n          -c ' segment-routing on'\n          -c ' segment-routing global-block 16000 19999'\n          -c ' segment-routing node-msd 8'\n          -c ' segment-routing prefix 10.255.0.4/32 index 1004'\n          -c 'exit'\n\ntest:\n  - cmds:\n    ## Basic P2P-Link's Test\n    # - cmd: docker exec R1 ping -c2 10.0.0.2\n    # - cmd: docker exec R1 ping -c2 10.0.0.10\n    # - cmd: docker exec R2 ping -c2 10.0.0.1\n    # - cmd: docker exec R2 ping -c2 10.0.0.6\n    # - cmd: docker exec R2 ping -c2 10.0.0.14\n    # - cmd: docker exec R3 ping -c2 10.0.0.5\n    # - cmd: docker exec R3 ping -c2 10.0.0.18\n    # - cmd: docker exec R4 ping -c2 10.0.0.9\n    # - cmd: docker exec R4 ping -c2 10.0.0.17\n    # - cmd: docker exec R4 ping -c2 10.0.0.13\n    ## Basic Routing Test\n    # - cmd: docker exec R1 ping -c2 10.255.0.2\n    # - cmd: docker exec R1 ping -c2 10.255.0.3\n    # - cmd: docker exec R1 ping -c2 10.255.0.4\n    # - cmd: docker exec R2 ping -c2 10.255.0.1\n    # - cmd: docker exec R2 ping -c2 10.255.0.3\n    # - cmd: docker exec R2 ping -c2 10.255.0.4\n    # - cmd: docker exec R3 ping -c2 10.255.0.1\n    # - cmd: docker exec R3 ping -c2 10.255.0.2\n    # - cmd: docker exec R3 ping -c2 10.255.0.4\n    # - cmd: docker exec R4 ping -c2 10.255.0.1\n    # - cmd: docker exec R4 ping -c2 10.255.0.2\n    # - cmd: docker exec R4 ping -c2 10.255.0.3\n    ## SR-MPLS Operation\n    - cmd: docker exec R1 ip route add 10.255.0.3/32 encap mpls 17004/17003 via 10.0.0.2\n    - cmd: docker exec R3 ip route add 10.255.0.1/32 encap mpls 17002/17001 via 10.0.0.18\n    ## SR-MPLS Test\n    - cmd: docker exec R1 ping -c2 10.255.0.3 -I 10.255.0.1\n\n\n"
  },
  {
    "path": "examples/basic_srv6/README.md",
    "content": "\n# Segment Routing IPv6 Examples\n\n- **vpn-v4-per-ce**: IPv4 L3VPN [T.Encaps, End, End.DX4]\n- **vpn-v6-per-ce**: IPv6 L3VPN [T.Encaps, End, End.DX6]\n- **vpn-v4-per-vrf**: IPv4 L3VPN [T.Encaps, End, End.DT4]  (WIP)\n- **vpn-v6-per-vrf**: IPv6 L3VPN [T.Encaps, End, End.DT6]\n- **l2vpn**: L2VPN [T.Encaps.L2, End, End.DX4]   (XXX)\n- **transit**: Transit Function Test with FRR, [T.Encaps, T.Insert, End, End.X]\n- **vrf-redirect**: End.T Evaluation linux only without FRR, [End.T]  (XXX)\n- **binding-sid**: End.B6,End.B6.Encaps Evaluation. [End.B6, End.B6.Encaps]  (WIP End.B6.Insert)\n<!-- - **sfc**: Service Chaining with End.AM -->\n\n## Functions I want to test on linux\n- [x] T.Insert: I don't understand how-to-use\n- [x] T.Encaps\n- [x] T.Encaps.L2: I don't understand how-to-use\n- [x] End\n- [x] End.X\n- [ ] End.T: linux kernel can't perform End.T fine. (XXX)\n- [x] End.DX6\n- [x] End.DX4\n- [x] End.DX2\n- [x] End.DT6\n- [ ] End.DT4: linux kernel isn't support yet\n- [x] End.B6: linux kernel isn't working fine..? or I don't understand how-to-use.\n- [x] End.B6.Encaps\n- [ ] End.AM: linux kernel isn't support yet. **srext only** masquerading proxy\n- [ ] End.AD: linux kernel isn't support yes. **srext only** dynamic proxy\n- [ ] End.AS2: linux kernel isn't support yes. static proxy\n- [ ] End.AS4: linux kernel isn't support yes. static proxy\n- [ ] End.AS6: linux kernel isn't support yes. static proxy\n\n## Funcに関しての説明\n- **T.Encaps:**<br>\n  この操作はトランジットノード\n\t(すなわち、パケットを通してSRv6をサポートするルーターですが、\n\tノード自体はSegmentリストにありません)で実行され、\n\tIPv6ヘッダーとSRHヘッダーをパケットの外側の層に追加し、\n\t新しいものを定義できます。セグメントのリスト。\n\tパケットは、新しいIPv6ヘッダーのSRHに従って最初に転送されます。\n- **End:**<br>\n  この操作では、Segment Leftを0（最後のホップではない）\n\tにする必要があります。これにより、Segment Leftが1減少し、\n\tIPv6パケットの宛先アドレスが最も一般的なSRv6操作である次の\n\tSegmentに更新されます。SR MPLSのプレフィックスSIDと同等です。\n- **End.X:**<br>\n  この操作は基本的にEnd操作と同じですが、\n  処理したパケットを指定したネクストホップアドレスに\n\t送信できる点が異なります。\n\tSR MPLSのAdj-SIDと同じです。\n- **End.DX4:**<br>\n  この操作ではSegment Leftが0であり、\n\tパケットがIPv4パケットをカプセル化しているため、\n\t外側のIPv6ヘッダーは削除され、内部のIPv4パケットは\n\t指定されたネクストホップアドレスに転送されます。\n\tVPNv4のCEごとのラベルに相当します。\n- **End.DX6:**<br>\n  この操作では、Segment Leftを0にしてIPv6パケットを\n\tパケットにカプセル化し、外側のIPv6ヘッダーを削除して、\n\t内部IPv6パケットを指定されたネクストホップアドレスに転送します。\n\tVPNv6 Per-CEラベルと同等です。\n- **End.B6:**<br>\n  既存のSRHに基づいて新しいSRHを挿入し、\n\t新しいSegment listを定義すると、挿入された新しいSRHに\n\t従ってデータパケットが最初に転送されます。Binding-SIDと同等です。\n- **End.B6.Encaps:**<br>\n  この操作は基本的にEnd.B6と同じですが、違いは、\n\tこの操作では単にSRHルーティングヘッダーを追加するのではなく、\n\t新しいIPv6ヘッダーとSRHをパケットの外側のレイヤーに追加することです。\n\n## 参照\n\n**Funcの概要に関してはこれらの画像がわかりやすい.(thx kamataさん)**<br>\n\n| Function | Location | Description | Works-for |\n| :------- | :------- | :---------- | :-------- |\n| End           | Core | DestとSRHを書き換えて, Next-hopをRIBから探して送る                    | Prefix-SID            |\n| End.X         | Core | DestとSRHを書き換えて, 決められたNextHopへ送る                        | Adjacency-SID         |\n| End.T         | Core | DestとSRHを書き換えて, NextHopを指定したRIBから探して送る             | Multi-table Operation |\n| End.DX2       | Edge | SRHを外して, 決められた送信IFへ送る (NH=59)                           | L2VPN                 |\n| End.DX6       | Edge | SRHを外して, 決められたIPv6 NextHopへ送る (NH=41)                     | VPNv6 Per-CE Label    |\n| End.DX4       | Edge | SRHを外して, 決められたIPv4 NextHopへ送る (NH=4)                      | VPNv4 Per-CE Label    |\n| End.DT6       | Edge | SRHを外して, IPv6 NextHopを指定したRIBから探して送る (NH=41)          | VPNv6 Per-VRF Label   |\n| End.DT4       | Edge | SRHを外して, IPv4 NextHopを指定したRIBから探して送る (NH=4)           | VPNv4 Per-VRF Label   |\n| End.B6        | Edge | SRHは触らず, 新しいSID List(SRH)を挿入して, その先頭に送る            | Binding SID           |\n| End.B6.Encaps | Edge | SRHを書き換えて, 新しいSID List(OuterHdr)でEncapして, その先頭に送る  | Binding SID (Encap)   |\n| End.BM        | Edge | DestとSRHを書き換えて, Labelを付与して, その先頭に送る                | SRv6/SR-MPLS Binding  |\n| End.S         | Core | 一番最後(or複数)のSIDでTable検索し, NextHopを探して送る               | ICN                   |\n| End.AS        | Core | OuterHdrを外して, 決められた送信IFへ送る. <br>決められた受信IFに入ってきたPktにOuterHdrを付与し, その先頭へ送る| Service-Chaining (Proxy)  |\n| End.AM        | Core | DestとSRHを書き換えて, 決められた送信IFへ送る. <br>決められた受信IFに入ってきたPktにSRHを付与し, その先頭に送る. | Service-Chaining (Masq) |\n| T             | Core | 通常のIPv6 Routing                                    | - |\n| T.Insert      | Core | 新しいSRHを挿入して, その先頭に送る                   | - |\n| T.Encaps      | Core | 新しいIPv6 Hdr(SRHつき)を挿入して, その先頭に送る(L3)􏲟| - |\n| T.Encaps.L2   | Core | 新しいIPv6 Hdr(SRHつき)を挿入して, その先頭に送る(L2)􏲟| - |\n\n**iproute2 CLIに関してはこれらがわかりやすい.(thx ebikenさん)**<br>\n```\n# ip -6 route add <segment> encap seg6local action <action> <params> (dev <device> | via <nexthop>) [table localsid]\n# ip -6 route add fc00::1/128 encap seg6local \\\n\t\t\taction End                                    via 2001:db8::1\n\t\t\taction End.X         nh6 fc00::1:1            via 2001:db8::1\n\t\t\taction End.T         table 100                via 2001:db8::1\n\t\t\taction End.DX2       oif lxcbr0               via 2001:db8::1\n\t\t\taction End.DX4       nh4 10.0.3.254           via 2001:db8::1\n\t\t\taction End.DX6       nh6 fc00::1:1            via 2001:db8::1\n\t\t\taction End.DT6       table 100                via 2001:db8::1\n\t\t\taction End.B6        srh segs beaf::1,beaf::2 via 2001:db8::1\n\t\t\taction End.B6.Encaps srh segs beaf::1,beaf::2 via 2001:db8::1\n\n# ip -6 route add <prefix> encap seg6 mode <encapmode> segs <segments> [hmac <keyid>] (dev <device> | via <nexthop>)\n# ip -6 route add fc00:b::10/128 encap seg6 mode inline segs fc00:3::11,fc00:3::12,fc00:3::13 via fc00:a::a\n# ip -6 route add fc00:b::10/128 encap seg6 mode encap  segs fc00:3::11,fc00:3::12,fc00:3::13 via fc00:a::a\n\n# ip sr tunsrc set <addr>\n# ip sr hmac set <keyid> <algorithm>\n```\n\n- https://www.sdnlab.com/22842.html\n- https://www.janog.gr.jp/meeting/janog40/application/files/2415/0051/7614/janog40-sr-kamata-takeda-00.pdf\n- https://www.slideshare.net/kentaroebisawa/zebra-srv6-cli-on-linux-dataplane-enog49\n- http://www.segment-routing.net/open-software/linux/\n- http://www.segment-routing.net/open-software/vpp/\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/bgp_vpnv6/spec.yaml",
    "content": "postinit:\n  cmds:\n  - cmd: |\n      cat <<EOF >/tmp/daemons\n      zebra=yes\n      bgpd=yes\n      sharpd=yes\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/frr.r1.conf\n      !\n      log file /tmp/frr.log\n      debug bgp neighbor-events\n      debug bgp zebra\n      debug bgp vnc verbose\n      debug bgp update-groups\n      debug bgp updates in\n      debug bgp updates out\n      debug bgp vpn label\n      debug bgp vpn leak-from-vrf\n      debug bgp vpn leak-to-vrf\n      debug bgp vpn rmap-event\n      !\n      segment-routing\n       srv6\n        locators\n         locator default\n           prefix 2001:1111::/64\n         !\n        !\n       !\n      !\n      router bgp 1\n       bgp router-id 1.1.1.1\n       no bgp ebgp-requires-policy\n       no bgp default ipv4-unicast\n       neighbor 2001:ffff::2 remote-as 2\n       neighbor 2001:ffff::2 timers connect 1\n       !\n       address-family ipv6 vpn\n        neighbor 2001:ffff::2 activate\n       exit-address-family\n       !\n       segment-routing srv6\n        locator default\n       !\n      !\n      router bgp 1 vrf vrf100\n       bgp router-id 1.1.1.1\n       no bgp ebgp-requires-policy\n       no bgp default ipv4-unicast\n       neighbor 2001:bb11::2 remote-as 10\n       neighbor 2001:bb11::2 timers connect 1\n       !\n       address-family ipv6 unicast\n        sid vpn export auto\n        rd vpn export 1:100\n        rt vpn export 99:99\n        rt vpn import 99:99\n        import vpn\n        export vpn\n        redistribute connected\n        neighbor 2001:bb11::2 activate\n       exit-address-family\n      !\n      ipv6 route 2001:2222::/64 2001:ffff::2\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/frr.r2.conf\n      segment-routing\n       srv6\n        locators\n         locator default\n           prefix 2001:2222::/64\n         !\n        !\n       !\n      !\n      router bgp 2\n       bgp router-id 2.2.2.2\n       no bgp ebgp-requires-policy\n       no bgp default ipv4-unicast\n       neighbor 2001:ffff::1 remote-as 1\n       neighbor 2001:ffff::1 timers connect 1\n       !\n       address-family ipv6 vpn\n        neighbor 2001:ffff::1 activate\n       exit-address-family\n       !\n       segment-routing srv6\n        locator default\n       !\n      !\n      router bgp 2 vrf vrf100\n       bgp router-id 2.2.2.2\n       no bgp ebgp-requires-policy\n       no bgp default ipv4-unicast\n       neighbor 2001:bb22::2 remote-as 20\n       neighbor 2001:bb22::2 timers connect 1\n       !\n       address-family ipv6 unicast\n        sid vpn export auto\n        rd vpn export 2:100\n        rt vpn export 99:99\n        rt vpn import 99:99\n        import vpn\n        export vpn\n        redistribute connected\n        neighbor 2001:bb22::2 activate\n       exit-address-family\n      !\n      ipv6 route 2001:1111::/64 2001:ffff::1\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/frr.c1.conf\n      router bgp 10\n       bgp router-id 1.1.0.0\n       no bgp ebgp-requires-policy\n       no bgp default ipv4-unicast\n       neighbor 2001:bb11::1 remote-as 1\n       !\n       address-family ipv6 unicast\n        redistribute connected\n        neighbor 2001:bb11::1 activate\n       exit-address-family\n      !\n      EOF\n  - cmd: |\n      cat <<EOF >/tmp/frr.c2.conf\n      router bgp 20\n       bgp router-id 2.2.0.0\n       no bgp ebgp-requires-policy\n       no bgp default ipv4-unicast\n       neighbor 2001:bb22::1 remote-as 2\n       !\n       address-family ipv6 unicast\n        redistribute connected\n        neighbor 2001:bb22::1 activate\n       exit-address-family\n      !\n      EOF\n  - cmd: docker cp /tmp/daemons R1:/etc/frr/daemons\n  - cmd: docker cp /tmp/daemons R2:/etc/frr/daemons\n  - cmd: docker cp /tmp/daemons C1:/etc/frr/daemons\n  - cmd: docker cp /tmp/daemons C2:/etc/frr/daemons\n  - cmd: docker cp /tmp/frr.r1.conf R1:/etc/frr/frr.conf\n  - cmd: docker cp /tmp/frr.r2.conf R2:/etc/frr/frr.conf\n  - cmd: docker cp /tmp/frr.c1.conf C1:/etc/frr/frr.conf\n  - cmd: docker cp /tmp/frr.c2.conf C2:/etc/frr/frr.conf\n\nnodes:\n- name: R1\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n- name: R2\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C2#net0 }\n- name: C1\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: tinynetwork/frr:develop\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n  - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n  - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n  - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n  - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n  - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n  - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n  - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n\n  - cmd: ip addr add 2001:ffff::1/64 dev net0\n  - cmd: ip link add vrf100 type vrf table 100\n  - cmd: ip link set vrf100 up\n  - cmd: ip link set dev net1 vrf vrf100\n  - cmd: ip addr add 2001:bb11::1/64 dev net1\n  - cmd: /usr/lib/frr/frrinit.sh start\n\n- name: R2\n  cmds:\n  - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n  - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n  - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n  - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n  - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n  - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n  - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n  - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n  - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n\n  - cmd: ip addr add 2001:ffff::2/64 dev net0\n  - cmd: ip link add vrf100 type vrf table 100\n  - cmd: ip link set vrf100 up\n  - cmd: ip link set dev net1 vrf vrf100\n  - cmd: ip addr add 2001:bb22::1/64 dev net1\n  - cmd: /usr/lib/frr/frrinit.sh start\n\n- name: C1\n  cmds:\n  - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n  - cmd: ip addr add 2001:bb11::2/64 dev net0\n  - cmd: /usr/lib/frr/frrinit.sh start\n\n- name: C2\n  cmds:\n  - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n  - cmd: ip addr add 2001:bb22::2/64 dev net0\n  - cmd: /usr/lib/frr/frrinit.sh start\n"
  },
  {
    "path": "examples/basic_srv6/linux/binding_sid/README.md",
    "content": "\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 | sudo sh\n$ tn conf | sudo sh\n$ tn test p2p | sudo sh\n$ tn test blue | sudo sh\n$ tn test green | sudo sh\n```\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/binding_sid/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: net1, type: direct, args: S11#net0 }\n      - { name: net2, type: direct, args: S21#net0 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: S12#net0 }\n      - { name: net2, type: direct, args: S22#net0 }\n  - name: S11\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n  - name: S12\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R4#net1 }\n  - name: S21\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n  - name: S22\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R4#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip addr add fc00:1::1/64 dev lo\n      - cmd: ip addr add 2000::1/64 dev net0\n      - cmd: ip addr add 2001::1/64 dev net1\n      - cmd: ip -6 route add fc00:2::/64 via 2000::2\n      - cmd: ip -6 route add fc00:3::/64 via 2001::2\n      ##\n      - cmd: ip sr tunsrc set fc00:1::1\n      - cmd: ip -6 route add fc00:1::10 encap seg6local action End.B6.Encaps srh segs fc00:2::10 dev net0\n      - cmd: ip -6 route add fc00:1::11 encap seg6local action End.DX6 nh6 2001::2 dev net0\n      ##\n      # ip -6 route add fc00:1::20 encap seg6local action End.B6 srh segs fc00:2::20 dev net0\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip addr add fc00:2::1/64 dev lo\n      - cmd: ip addr add 2000::2/64 dev net0\n      - cmd: ip addr add 2001::10/64 dev net1\n      - cmd: ip -6 route add fc00:1::/64 via 2000::1\n      - cmd: ip -6 route add fc00:4::/64 via 2001::20\n      ##\n      - cmd: ip sr tunsrc set fc00:2::1\n      - cmd: ip -6 route add fc00:2::10 encap seg6local action End.DX6 nh6 2001::20 dev net1\n      - cmd: ip -6 route add fc00:2::11 encap seg6local action End.B6.Encaps srh segs fc00:1::11 dev net0\n      ##\n      #?XXX ip -6 route add fc00:2::20 encap seg6local action End via 2001::20\n  - name: R3\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net2.rp_filter=0'\n      - cmd: ip addr add fc00:3::1/64 dev lo\n      - cmd: ip addr add 2001::2/64 dev net0\n      - cmd: ip addr add 10.10.1.1/24 dev net1\n      - cmd: ip addr add 10.20.1.1/24 dev net2\n      - cmd: ip -6 route add fc00:1::/64 via 2001::1\n      ##\n      - cmd: ip sr tunsrc set fc00:3::1\n      - cmd: ip route add 10.10.2.0/24 encap seg6 mode encap segs fc00:1::10,fc00:4::10 dev net0\n      - cmd: ip -6 route add fc00:3::11 encap seg6local action End.DX4 nh4 10.10.1.2 dev net0\n      ##\n      # ip route add 10.20.2.0/24 encap seg6 mode encap segs fc00:1::20,fc00:4::20 dev net0\n  - name: R4\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net2.rp_filter=0'\n      - cmd: ip addr add fc00:4::1/64 dev lo\n      - cmd: ip addr add 2001::20/64 dev net0\n      - cmd: ip addr add 10.10.2.1/24 dev net1\n      - cmd: ip addr add 10.20.2.1/24 dev net2\n      - cmd: ip -6 route add fc00:2::/64 via 2001::10\n      ##\n      - cmd: ip sr tunsrc set fc00:4::1\n      - cmd: ip -6 route add fc00:4::10 encap seg6local action End.DX4 nh4 10.10.2.2 dev net0\n      - cmd: ip route add 10.10.1.0/24 encap seg6 mode encap segs fc00:2::11,fc00:3::11 dev net0\n\n  - name: S11\n    cmds:\n      - cmd: ip addr add 10.10.1.2/24 dev net0\n      - cmd: ip route replace default via 10.10.1.1\n  - name: S12\n    cmds:\n      - cmd: ip addr add 10.10.2.2/24 dev net0\n      - cmd: ip route replace default via 10.10.2.1\n  - name: S21\n    cmds:\n      - cmd: ip addr add 10.20.1.2/24 dev net0\n      - cmd: ip route replace default via 10.20.1.1\n  - name: S22\n    cmds:\n      - cmd: ip addr add 10.20.2.2/24 dev net0\n      - cmd: ip route replace default via 10.20.2.1\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec S11 ping -c2 10.10.1.1\n      - cmd: docker exec S11 ping -c2 10.10.1.2\n      - cmd: docker exec S12 ping -c2 10.10.2.1\n      - cmd: docker exec S12 ping -c2 10.10.2.2\n      - cmd: docker exec S21 ping -c2 10.20.1.1\n      - cmd: docker exec S21 ping -c2 10.20.1.2\n      - cmd: docker exec S22 ping -c2 10.20.2.1\n      - cmd: docker exec S22 ping -c2 10.20.2.2\n      - cmd: docker exec R1 ping -c2 2000::1\n      - cmd: docker exec R1 ping -c2 2000::2\n      - cmd: docker exec R1 ping -c2 2001::1\n      - cmd: docker exec R1 ping -c2 2001::2\n      - cmd: docker exec R2 ping -c2 2000::1\n      - cmd: docker exec R2 ping -c2 2000::2\n      - cmd: docker exec R2 ping -c2 2001::10\n      - cmd: docker exec R2 ping -c2 2001::20\n      - cmd: docker exec R3 ping -c2 2001::1\n      - cmd: docker exec R3 ping -c2 2001::2\n      - cmd: docker exec R3 ping -c2 10.10.1.1\n      - cmd: docker exec R3 ping -c2 10.10.1.2\n      - cmd: docker exec R3 ping -c2 10.20.1.1\n      - cmd: docker exec R3 ping -c2 10.20.1.2\n      - cmd: docker exec R4 ping -c2 2001::10\n      - cmd: docker exec R4 ping -c2 2001::20\n      - cmd: docker exec R4 ping -c2 10.10.2.1\n      - cmd: docker exec R4 ping -c2 10.10.2.2\n      - cmd: docker exec R4 ping -c2 10.20.2.1\n      - cmd: docker exec R4 ping -c2 10.20.2.2\n  - name: bb\n    cmds:\n      - cmd: docker exec R1 ping -c2 fc00:1::1\n      - cmd: docker exec R1 ping -c2 fc00:2::1\n      - cmd: docker exec R1 ping -c2 fc00:3::1\n      - cmd: docker exec R2 ping -c2 fc00:1::1\n      - cmd: docker exec R2 ping -c2 fc00:2::1\n      - cmd: docker exec R2 ping -c2 fc00:4::1\n      - cmd: docker exec R3 ping -c2 fc00:1::1\n      - cmd: docker exec R3 ping -c2 fc00:3::1\n      - cmd: docker exec R4 ping -c2 fc00:2::1\n      - cmd: docker exec R4 ping -c2 fc00:4::1\n  - name: vpn\n    cmds:\n      - cmd: docker exec S11 ping -c2 10.10.2.2\n      # - cmd: docker exec S12 ping -c2 10.10.1.2\n      # - cmd: docker exec S21 ping -c2 10.20.2.2\n      # - cmd: docker exec S22 ping -c2 10.20.1.2\n\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/Makefile",
    "content": "\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:2::20 encap seg6local action End.BPF \\\n\t\tendpoint object /filter.o section prog dev lo\n\ndel:\n\tdocker exec R2 \\\n\t\tip -6 route del fc00:2::20\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/bpf_helpers.h",
    "content": "#ifndef __BPF_HELPERS_H\n#define __BPF_HELPERS_H\n\n/* helper macro to place programs, maps, license in\n * different sections in elf_bpf file. Section names\n * are interpreted by elf_bpf loader\n */\n#define SEC(NAME) __attribute__((section(NAME), used))\n\n/* helper functions called from eBPF programs written in C */\nstatic void *(*bpf_map_lookup_elem)(void *map, void *key) =\n\t(void *) BPF_FUNC_map_lookup_elem;\nstatic int (*bpf_map_update_elem)(void *map, void *key, void *value,\n\t\t\t\t  unsigned long long flags) =\n\t(void *) BPF_FUNC_map_update_elem;\nstatic int (*bpf_map_delete_elem)(void *map, void *key) =\n\t(void *) BPF_FUNC_map_delete_elem;\nstatic int (*bpf_probe_read)(void *dst, int size, void *unsafe_ptr) =\n\t(void *) BPF_FUNC_probe_read;\nstatic unsigned long long (*bpf_ktime_get_ns)(void) =\n\t(void *) BPF_FUNC_ktime_get_ns;\nstatic int (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =\n\t(void *) BPF_FUNC_trace_printk;\nstatic void (*bpf_tail_call)(void *ctx, void *map, int index) =\n\t(void *) BPF_FUNC_tail_call;\nstatic unsigned long long (*bpf_get_smp_processor_id)(void) =\n\t(void *) BPF_FUNC_get_smp_processor_id;\nstatic unsigned long long (*bpf_get_current_pid_tgid)(void) =\n\t(void *) BPF_FUNC_get_current_pid_tgid;\nstatic unsigned long long (*bpf_get_current_uid_gid)(void) =\n\t(void *) BPF_FUNC_get_current_uid_gid;\nstatic int (*bpf_get_current_comm)(void *buf, int buf_size) =\n\t(void *) BPF_FUNC_get_current_comm;\nstatic int (*bpf_perf_event_read)(void *map, int index) =\n\t(void *) BPF_FUNC_perf_event_read;\nstatic int (*bpf_clone_redirect)(void *ctx, int ifindex, int flags) =\n\t(void *) BPF_FUNC_clone_redirect;\nstatic int (*bpf_redirect)(int ifindex, int flags) =\n\t(void *) BPF_FUNC_redirect;\nstatic int (*bpf_perf_event_output)(void *ctx, void *map,\n\t\t\t\t    unsigned long long flags, void *data,\n\t\t\t\t    int size) =\n\t(void *) BPF_FUNC_perf_event_output;\nstatic int (*bpf_get_stackid)(void *ctx, void *map, int flags) =\n\t(void *) BPF_FUNC_get_stackid;\nstatic int (*bpf_probe_write_user)(void *dst, void *src, int size) =\n\t(void *) BPF_FUNC_probe_write_user;\nstatic int (*bpf_current_task_under_cgroup)(void *map, int index) =\n\t(void *) BPF_FUNC_current_task_under_cgroup;\nstatic int (*bpf_skb_get_tunnel_key)(void *ctx, void *key, int size, int flags) =\n\t(void *) BPF_FUNC_skb_get_tunnel_key;\nstatic int (*bpf_skb_set_tunnel_key)(void *ctx, void *key, int size, int flags) =\n\t(void *) BPF_FUNC_skb_set_tunnel_key;\nstatic int (*bpf_skb_get_tunnel_opt)(void *ctx, void *md, int size) =\n\t(void *) BPF_FUNC_skb_get_tunnel_opt;\nstatic int (*bpf_skb_set_tunnel_opt)(void *ctx, void *md, int size) =\n\t(void *) BPF_FUNC_skb_set_tunnel_opt;\nstatic unsigned long long (*bpf_get_prandom_u32)(void) =\n\t(void *) BPF_FUNC_get_prandom_u32;\nstatic int (*bpf_xdp_adjust_head)(void *ctx, int offset) =\n\t(void *) BPF_FUNC_xdp_adjust_head;\n\n/* llvm builtin functions that eBPF C program may use to\n * emit BPF_LD_ABS and BPF_LD_IND instructions\n */\nstruct sk_buff;\nunsigned long long load_byte(void *skb,\n\t\t\t     unsigned long long off) asm(\"llvm.bpf.load.byte\");\nunsigned long long load_half(void *skb,\n\t\t\t     unsigned long long off) asm(\"llvm.bpf.load.half\");\nunsigned long long load_word(void *skb,\n\t\t\t     unsigned long long off) asm(\"llvm.bpf.load.word\");\n\n/* a helper structure used by eBPF C program\n * to describe map attributes to elf_bpf loader\n */\nstruct bpf_map_def {\n\tunsigned int type;\n\tunsigned int key_size;\n\tunsigned int value_size;\n\tunsigned int max_entries;\n\tunsigned int map_flags;\n\tunsigned int inner_map_idx;\n};\n\nstatic int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) =\n\t(void *) BPF_FUNC_skb_load_bytes;\nstatic int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) =\n\t(void *) BPF_FUNC_skb_store_bytes;\nstatic int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flags) =\n\t(void *) BPF_FUNC_l3_csum_replace;\nstatic int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flags) =\n\t(void *) BPF_FUNC_l4_csum_replace;\nstatic int (*bpf_skb_under_cgroup)(void *ctx, void *map, int index) =\n\t(void *) BPF_FUNC_skb_under_cgroup;\nstatic int (*bpf_skb_change_head)(void *, int len, int flags) =\n\t(void *) BPF_FUNC_skb_change_head;\n\n#if defined(__x86_64__)\n\n#define PT_REGS_PARM1(x) ((x)->di)\n#define PT_REGS_PARM2(x) ((x)->si)\n#define PT_REGS_PARM3(x) ((x)->dx)\n#define PT_REGS_PARM4(x) ((x)->cx)\n#define PT_REGS_PARM5(x) ((x)->r8)\n#define PT_REGS_RET(x) ((x)->sp)\n#define PT_REGS_FP(x) ((x)->bp)\n#define PT_REGS_RC(x) ((x)->ax)\n#define PT_REGS_SP(x) ((x)->sp)\n#define PT_REGS_IP(x) ((x)->ip)\n\n#elif defined(__s390x__)\n\n#define PT_REGS_PARM1(x) ((x)->gprs[2])\n#define PT_REGS_PARM2(x) ((x)->gprs[3])\n#define PT_REGS_PARM3(x) ((x)->gprs[4])\n#define PT_REGS_PARM4(x) ((x)->gprs[5])\n#define PT_REGS_PARM5(x) ((x)->gprs[6])\n#define PT_REGS_RET(x) ((x)->gprs[14])\n#define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */\n#define PT_REGS_RC(x) ((x)->gprs[2])\n#define PT_REGS_SP(x) ((x)->gprs[15])\n#define PT_REGS_IP(x) ((x)->psw.addr)\n\n#elif defined(__aarch64__)\n\n#define PT_REGS_PARM1(x) ((x)->regs[0])\n#define PT_REGS_PARM2(x) ((x)->regs[1])\n#define PT_REGS_PARM3(x) ((x)->regs[2])\n#define PT_REGS_PARM4(x) ((x)->regs[3])\n#define PT_REGS_PARM5(x) ((x)->regs[4])\n#define PT_REGS_RET(x) ((x)->regs[30])\n#define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */\n#define PT_REGS_RC(x) ((x)->regs[0])\n#define PT_REGS_SP(x) ((x)->sp)\n#define PT_REGS_IP(x) ((x)->pc)\n\n#elif defined(__powerpc__)\n\n#define PT_REGS_PARM1(x) ((x)->gpr[3])\n#define PT_REGS_PARM2(x) ((x)->gpr[4])\n#define PT_REGS_PARM3(x) ((x)->gpr[5])\n#define PT_REGS_PARM4(x) ((x)->gpr[6])\n#define PT_REGS_PARM5(x) ((x)->gpr[7])\n#define PT_REGS_RC(x) ((x)->gpr[3])\n#define PT_REGS_SP(x) ((x)->sp)\n#define PT_REGS_IP(x) ((x)->nip)\n\n#elif defined(__sparc__)\n\n#define PT_REGS_PARM1(x) ((x)->u_regs[UREG_I0])\n#define PT_REGS_PARM2(x) ((x)->u_regs[UREG_I1])\n#define PT_REGS_PARM3(x) ((x)->u_regs[UREG_I2])\n#define PT_REGS_PARM4(x) ((x)->u_regs[UREG_I3])\n#define PT_REGS_PARM5(x) ((x)->u_regs[UREG_I4])\n#define PT_REGS_RET(x) ((x)->u_regs[UREG_I7])\n#define PT_REGS_RC(x) ((x)->u_regs[UREG_I0])\n#define PT_REGS_SP(x) ((x)->u_regs[UREG_FP])\n#if defined(__arch64__)\n#define PT_REGS_IP(x) ((x)->tpc)\n#else\n#define PT_REGS_IP(x) ((x)->pc)\n#endif\n\n#endif\n\n#ifdef __powerpc__\n#define BPF_KPROBE_READ_RET_IP(ip, ctx)\t\t({ (ip) = (ctx)->link; })\n#define BPF_KRETPROBE_READ_RET_IP\t\tBPF_KPROBE_READ_RET_IP\n#elif defined(__sparc__)\n#define BPF_KPROBE_READ_RET_IP(ip, ctx)\t\t({ (ip) = PT_REGS_RET(ctx); })\n#define BPF_KRETPROBE_READ_RET_IP\t\tBPF_KPROBE_READ_RET_IP\n#else\n#define BPF_KPROBE_READ_RET_IP(ip, ctx)\t\t({\t\t\t\t\\\n\t\tbpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })\n#define BPF_KRETPROBE_READ_RET_IP(ip, ctx)\t({\t\t\t\t\\\n\t\tbpf_probe_read(&(ip), sizeof(ip),\t\t\t\t\\\n\t\t\t\t(void *)(PT_REGS_FP(ctx) + sizeof(ip))); })\n#endif\n\n#endif\n"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/filter.c",
    "content": "#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>\n#include \"bpf_helpers.h\"\n#ifndef __section\n#define __section(NAME) \\\n  __attribute__((section(NAME), used))\n#endif\n\n__section(\"prog\")\nint filter(struct __sk_buff *skb)\n{\n  /* void *data_end = (void *)(long)skb->data_end; */\n\t/* void *data = (void *)(long)skb->data; */\n  /* if ((data + 0x0060 + 10) < data_end) { */\n  /*   unsigned char* ptr = data; */\n  /*   ptr[0x0060] = 'X'; */\n  /* } */\n\n  struct data {\n    uint8_t r0;\n    uint8_t r1;\n    uint8_t r2;\n    uint8_t r3;\n  };\n  struct data from;\n  from.r0 = 1;\n\n  /* int off = offsetof(struct iphdr, protocol); */\n  int off = 40;\n  int index = bpf_skb_store_bytes(skb, ETH_HLEN, &from, sizeof(from), 0);\n\n  return BPF_OK;\n  /* return BPF_OK; */\n}\nchar __license[] __section(\"license\") = \"GPL\";\n"
  },
  {
    "path": "examples/basic_srv6/linux/end_bpf_WIP/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n      - cmd: make\n      - cmd: docker cp filter.o R2:/filter.o\n\nnodes:\n  - name: R1\n    image: slankdev/ubuntu:18.10\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: R2\n    image: slankdev/ubuntu:18.10\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R2#net0 }\n  - name: R3\n    image: slankdev/ubuntu:18.10\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      - cmd: ip -6 addr add 2001:12::3/64 dev net0\n      - cmd: ip -6 route replace default via 2001:12::1\n      - cmd: >-\n          ip -6 route add 2001:23::2 encap seg6 mode encap\n          segs fc00:2::1,fc00:2::20,fc00:2::1 dev net0\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add 2001:12::1/64 dev net0\n      - cmd: ip -6 addr add 2001:23::1/64 dev net1\n      - cmd: ip -6 addr add fc00:2::1/128 dev lo\n      # - cmd: ip -6 route add fc00:2::10 encap seg6local action End dev lo\n      - cmd: >-\n          ip -6 route add fc00:2::20 encap seg6local action End.BPF\n          endpoint object /filter.o section prog dev lo\n  - name: R3\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: ip -6 addr add 2001:23::2/64 dev net0\n      - cmd: ip -6 addr add 2001:23::3/64 dev net0\n      - cmd: ip -6 route replace default via 2001:23::1\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec R1 ping -c2 2001:12::1\n      - cmd: docker exec R1 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 2001:23::1\n      - cmd: docker exec R2 ping -c2 2001:23::2\n      - cmd: docker exec R3 ping -c2 2001:23::1\n      - cmd: docker exec R3 ping -c2 2001:23::2\n  - name: remote\n    cmds:\n      - cmd: docker exec R1 ping -c2 2001:23::2\n      - cmd: docker exec R3 ping -c2 2001:12::1\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/hands_on/README.md",
    "content": "\n# SRv6 Hands-on\n\n![](img.png)\n"
  },
  {
    "path": "examples/basic_srv6/linux/hands_on/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net0 }\n      - { name: net1, type: direct, args: R1#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R4#net0 }\n      - { name: net2, type: direct, args: R6#net0 }\n      - { name: net3, type: direct, args: R7#net0 }\n      - { name: net4, type: direct, args: R8#net0 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n      - { name: net1, type: direct, args: R5#net0 }\n  - name: R5\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R4#net1 }\n  - name: R6\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net2 }\n  - name: R7\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net3 }\n  - name: R8\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net4 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:1::1/64 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:1::/64\"\n          -c \"router ospf6\"\n          -c \" interface lo area 0.0.0.0\"\n          -c ' ospf6 router-id 10.255.0.1'\n          -c \" interface net0 area 0.0.0.0\"\n\n  - name: R2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:2::2/64 dev net0\n      - cmd: ip addr add cafe:1::2/64 dev net1\n      - cmd: ip -6 route add default via cafe:2::3\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:2::/64\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.2'\n          -c \" interface lo area 0.0.0.0\"\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n      - cmd: ip route add cafe:4::5 encap seg6 mode encap segs fc00:6::1,fc00:7::1,fc00:4::1 dev net0\n\n  - name: R3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:2::3/64 dev net0\n      - cmd: ip addr add cafe:3::3/64 dev net1\n      - cmd: ip addr add cafe:5::3/64 dev net2\n      - cmd: ip addr add cafe:6::3/64 dev net3\n      - cmd: ip addr add cafe:7::3/64 dev net4\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:3::/64\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.3'\n          -c \" interface lo area 0.0.0.0\"\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n          -c \" interface net2 area 0.0.0.0\"\n          -c \" interface net3 area 0.0.0.0\"\n          -c \" interface net4 area 0.0.0.0\"\n\n  - name: R4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:3::4/64 dev net0\n      - cmd: ip addr add cafe:4::4/64 dev net1\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:4::/64\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.4'\n          -c \" interface lo area 0.0.0.0\"\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n      - cmd: ip route add fc00:4::1/128 encap seg6local action End.DX6 nh6 cafe:4::5 dev net0\n\n  - name: R5\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:4::5/64 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:5::/64\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.5'\n          -c \" interface lo area 0.0.0.0\"\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface net1 area 0.0.0.0\"\n\n  - name: R6\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:5::6/64 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:6::/64\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.6'\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface lo area 0.0.0.0\"\n      - cmd: ip route add fc00:6::1/128 encap seg6local action End dev net0\n\n  - name: R7\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:6::7/64 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:7::/64\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.7'\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface lo area 0.0.0.0\"\n      - cmd: ip route add fc00:7::1/128 encap seg6local action End dev net0\n\n  - name: R8\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: /usr/lib/frr/frr start\n      - cmd: ip addr add cafe:7::8/64 dev net0\n      - cmd: >-\n          vtysh -c \"conf t\"\n          -c \"interface lo\"\n          -c \" ipv6 address fc00:8::/64\"\n          -c \"router ospf6\"\n          -c ' ospf6 router-id 10.255.0.8'\n          -c \" interface net0 area 0.0.0.0\"\n          -c \" interface lo area 0.0.0.0\"\n      - cmd: ip route add fc00:8::1/128 encap seg6local action End dev net0\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/l2vpn/README.md",
    "content": "\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 tinet/examples/basic_srv6/l2vpn\n$ tn up | sudo sh # create network nodes.\n$ tn conf | sudo sh # execute configuration to each nodes\n$ docker ps # you can check some nodes exist.\n$ tn test p2p | sudo sh # execute point-to-point link's ping.\n$ tn test vpn | sudo sh # execute L2VPN ping. // can't be success\n```\n"
  },
  {
    "path": "examples/basic_srv6/linux/l2vpn/spec.yaml",
    "content": "\n# postinit:\n#   - cmds:\n#     - cmd: make -C /home/vagrant/git/srdump install_container2\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n  - name: C1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: C2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n\n      - cmd: ip -6 addr add fc00:1::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::1/64 dev net0\n      - cmd: ip addr add 10.0.0.1/24 dev net1\n      - cmd: ip sr tunsrc set fc00:1::1\n      - cmd: ip route add fc00:2::/64 via 2001:12::2\n\n      - cmd: ip route replace 10.0.0.0/24 encap seg6 mode l2encap segs fc00:2::10 dev net0\n      - cmd: ip -6 route add fc00:1::10/128 encap seg6local action End.DX2 oif net1 dev net0\n      - cmd: ip link set net1 down\n      - cmd: ip link set net1 address 52:54:00:22:22:22\n      - cmd: ip link set net1 up\n      - cmd: sysctl -w net.ipv4.conf.net1.proxy_arp=1\n\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n\n      - cmd: ip -6 addr add fc00:2::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      - cmd: ip addr add 10.0.0.2/24 dev net1\n      - cmd: ip sr tunsrc set fc00:2::1\n      - cmd: ip route add fc00:1::/64 via 2001:12::1\n\n      - cmd: ip route replace 10.0.0.0/24 encap seg6 mode l2encap segs fc00:1::10 dev net0\n      - cmd: ip -6 route add fc00:2::10/128 encap seg6local action End.DX2 oif net1 dev net0\n      - cmd: ip link set net1 down\n      - cmd: ip link set net1 address 52:54:00:11:11:11\n      - cmd: ip link set net1 up\n      - cmd: sysctl -w net.ipv4.conf.net1.proxy_arp=1\n\n  - name: C1\n    cmds:\n      - cmd: ip link set net0 down\n      - cmd: ip link set net0 address 52:54:00:11:11:11\n      - cmd: ip link set net0 up\n      - cmd: ip addr add 10.0.0.10/24 dev net0\n      - cmd: ip route replace default via 10.0.0.1\n\n  - name: C2\n    cmds:\n      - cmd: ip link set net0 down\n      - cmd: ip link set net0 address 52:54:00:22:22:22\n      - cmd: ip link set net0 up\n      - cmd: ip addr add 10.0.0.20/24 dev net0\n      - cmd: ip route replace default via 10.0.0.2\n\ntest:\n  - name: l2vpn\n    cmds:\n      - cmd: docker exec C1 ping -c2 10.0.0.20\n      - cmd: docker exec C2 ping -c2 10.0.0.10\n\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/sfc/README.md",
    "content": "\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:3::2 2001:1::1\ndocker exec -it R4 ping -I 2001:3::10 2001:1::1\ndocker exec -it R4 ping -I 2001:3::11 2001:1::1\n```\n\ncheck networking\n```\ndocker exec -it R10 tcpdump -ni net0\ndocker exec -it R11 tcpdump -ni net0\n```\n\nSRv6 Configuration\n```\n//decoder @R2\nip route add fc00:2::5 encap seg6local action End via 2001:1::1\nip route add 2001:3::10 encap seg6 mode inline segs fc00:10::1,fc00:3::1 via 2001:2::1\nip route add 2001:3::11 encap seg6 mode inline segs fc00:11::1,fc00:3::1 via 2001:2::1\n\n//encoder @R3\necho 10 blue >> /etc/iproute2/rt_tables\necho 11 green >> /etc/iproute2/rt_tables\nip -6 rule add from 2001:3::10 table blue\nip -6 rule add from 2001:3::11 table green\nip route add 2001:1::0/64 encap seg6 mode inline segs fc00:10::1,fc00:2::1 via 2001:2::1 table blue\nip route add 2001:1::0/64 encap seg6 mode inline segs fc00:11::1,fc00:2::1 via 2001:2::1 table green\n```\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/sfc/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: bridge, args: SW }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R4#net0 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R3#net1 }\n  - name: R10\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: SW }\n  - name: R11\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: SW }\n\nswitches:\n  - name: SW\n    interfaces:\n      - { name: net2, type: docker, args: R2 }\n      - { name: net0, type: docker, args: R10 }\n      - { name: net0, type: docker, args: R11 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo' -c 'ipv6 addr fc00:1::1/64' -c 'exit'\n          -c 'int net0' -c 'ipv6 addr 2001:1::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.1'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c 'exit'\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net2.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo' -c 'ipv6 addr fc00:2::1/64' -c 'exit'\n          -c 'int net0' -c 'ipv6 addr 2001:1::2/64' -c 'exit'\n          -c 'int net1' -c 'ipv6 addr 2001:2::1/64' -c 'exit'\n          -c 'int net2' -c 'ipv6 addr 2001:4::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.2'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c ' interface net2 area 0.0.0.0'\n          -c 'exit'\n\n      # SRv6 Configuration\n      - cmd: ip route add 2001:3::10 encap seg6 mode inline segs fc00:10::1,fc00:3::1 via 2001:2::2\n      - cmd: ip route add 2001:3::11 encap seg6 mode inline segs fc00:11::1,fc00:3::1 via 2001:2::2\n\n  - name: R3\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo' -c 'ipv6 addr fc00:3::1/64' -c 'exit'\n          -c 'int net0' -c 'ipv6 addr 2001:2::2/64' -c 'exit'\n          -c 'int net1' -c 'ipv6 addr 2001:3::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.3'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c 'exit'\n\n      # SRv6 Configuration\n      - cmd: bash -c \"echo 10 blue >> /etc/iproute2/rt_tables\"\n      - cmd: bash -c \"echo 11 green >> /etc/iproute2/rt_tables\"\n      - cmd: ip -6 rule add from 2001:3::10 table blue\n      - cmd: ip -6 rule add from 2001:3::11 table green\n      - cmd: ip route add 2001:1::0/64 encap seg6 mode inline segs fc00:10::1,fc00:2::1 via 2001:2::1 dev net0 table blue\n      - cmd: ip route add 2001:1::0/64 encap seg6 mode inline segs fc00:11::1,fc00:2::1 via 2001:2::1 dev net0 table green\n\n  - name: R4\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo' -c 'ipv6 addr fc00:4::1/64' -c 'exit'\n          -c 'int net0'\n          -c ' ipv6 addr 2001:3::2/64'\n          -c ' ipv6 addr 2001:3::10/64'\n          -c ' ipv6 addr 2001:3::11/64'\n          -c ' exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.4'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c 'exit'\n  - name: R10\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo' -c 'ipv6 addr fc00:10::1/64' -c 'exit'\n          -c 'int net0' -c 'ipv6 addr 2001:4::10/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.10'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c 'exit'\n  - name: R11\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int lo' -c 'ipv6 addr fc00:11::1/64' -c 'exit'\n          -c 'int net0' -c 'ipv6 addr 2001:4::11/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 10.255.0.11'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c 'exit'\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec R1 ping -c2 2001:1::1\n      - cmd: docker exec R1 ping -c2 2001:1::2\n      - cmd: docker exec R2 ping -c2 2001:1::1\n      - cmd: docker exec R2 ping -c2 2001:1::2\n      - cmd: docker exec R2 ping -c2 2001:2::1\n      - cmd: docker exec R2 ping -c2 2001:2::2\n      - cmd: docker exec R2 ping -c2 2001:4::1\n      - cmd: docker exec R2 ping -c2 2001:4::10\n      - cmd: docker exec R2 ping -c2 2001:4::11\n      - cmd: docker exec R3 ping -c2 2001:2::1\n      - cmd: docker exec R3 ping -c2 2001:2::2\n      - cmd: docker exec R3 ping -c2 2001:3::1\n      - cmd: docker exec R3 ping -c2 2001:3::2\n      - cmd: docker exec R3 ping -c2 2001:3::10\n      - cmd: docker exec R3 ping -c2 2001:3::11\n      - cmd: docker exec R4 ping -c2 2001:3::1\n      - cmd: docker exec R4 ping -c2 2001:3::2\n      - cmd: docker exec R4 ping -c2 2001:3::10\n      - cmd: docker exec R4 ping -c2 2001:3::11\n      - cmd: docker exec R10 ping -c2 2001:4::1\n      - cmd: docker exec R10 ping -c2 2001:4::10\n      - cmd: docker exec R10 ping -c2 2001:4::11\n      - cmd: docker exec R11 ping -c2 2001:4::1\n      - cmd: docker exec R11 ping -c2 2001:4::10\n      - cmd: docker exec R11 ping -c2 2001:4::11\n  - name: remote\n    cmds:\n      - cmd: docker exec R4 ping -c2 -I 2001:3::10 2001:1::1\n      - cmd: docker exec R4 ping -c2 -I 2001:3::11 2001:1::1\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/README.md",
    "content": "\n# SRv6 Unaware Evaluation\n\n![](./topo.jpeg)\n\nsend icmp traffic including `emacs` at R1\n```\nR1# ping 10.0.0.2 -p `echo \"emacs\" | xxd -p`\nR1# ping 10.0.0.2 -p 656d6163732c\nPATTERN: 0x656d6163732c\nPING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.\n64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.038 ms\n64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.075 ms\n...\n```\n\ncheck traffic at R2\n```\nroot@R2:/# tcpdump -ni net0 -X icmp\ntcpdump: verbose output suppressed, use -v or -vv for full protocol decode\nlistening on net0, link-type EN10MB (Ethernet), capture size 262144 bytes\n14:04:45.602478 IP 10.0.0.2 > 10.0.0.1: ICMP echo reply, id 79, seq 3, length 64\n        0x0000:  c688 a57b 07bd b6e5 b767 af7b 0800 4500  ...{.....g.{..E.\n        0x0010:  0054 4a54 0000 4001 1c53 0a00 0002 0a00  .TJT..@..S......\n        0x0020:  0001 0000 35be 004f 0003 fdc6 665c 0000  ....5..O....f\\..\n        0x0030:  0000 2931 0900 0000 0000 730a 656d 6163  ..)1......s.emac\n        0x0040:  730a 656d 6163 730a 656d 6163 730a 656d  s.emacs.emacs.em\n        0x0050:  6163 730a 656d 6163 730a 656d 6163 730a  acs.emacs.emacs.\n```\n\nConfig filter @F1\n```\n// Apply filter\nmake -C filter\ndocker exec F1 ip link set net0 xdp obj /filter/net0\ndocker exec F1 ip link set net1 xdp obj /filter/net1\n\n// Reset filter\ndocker exec F1 ip link set net0 xdp off\ndocker exec F1 ip link set net1 xdp off\n```\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/function/Makefile",
    "content": "\nCXXFLAGS += -std=c++11 -I$(HOME)/git/libslankdev\nLDFLAGS +=\n\nSRC = main.cc\nOBJ = $(SRC:.cc=.o)\nTARGET = a.out\n\ndef: install_docker\n\nall: $(OBJ)\n\t$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJ) $(LDFLAGS)\n\nclean:\n\trm -f $(OBJ) $(TARGET)\n\ninstall_docker: all\n\tdocker cp a.out F1:/\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/function/main.cc",
    "content": "\r\n#include <netinet/in.h>\r\n#include <errno.h>\r\n#include <netdb.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n#include <unistd.h>\r\n#include <stdio.h>\r\n#include <netinet/tcp.h>\r\n#include <netinet/ip.h>\r\n#include <sys/socket.h>\r\n#include <arpa/inet.h>\r\n#include <sys/ioctl.h>\r\n#include <net/if.h>\r\n#include <net/ethernet.h>\r\n#include <netpacket/packet.h>\r\n#include <sys/time.h>\r\n#include <algorithm>\r\n#include <slankdev/socketfd.h>\r\n#include <slankdev/poll.h>\r\n#include <slankdev/net/hdr.h>\r\n\r\nstruct policy {\r\n  int input_fd;\r\n  int output_fd;\r\n  const char* match;\r\n  const char* apply;\r\n} policies[] = {\r\n  { -1, -1, \"nttcom\", \"hanpen\" },\r\n  { -1, -1, \"hanpen\", \"nttcom\" },\r\n};\r\n\r\nstatic void\r\nprocess_packet(uint8_t* pkt, size_t len, int inputfd)\r\n{\r\n  slankdev::ether* eh = reinterpret_cast<slankdev::ether*>(pkt);\r\n  slankdev::ip* ih = reinterpret_cast<slankdev::ip*>(eh + 1);\r\n  slankdev::icmp* ich = reinterpret_cast<slankdev::icmp*>(ih->get_next());\r\n  if (ntohs(eh->type) == 0x0800 && ih->proto == 1) {\r\n    /* Apply Policy */\r\n    for (size_t i=0; i<2; i++) {\r\n      if (policies[i].input_fd == inputfd) {\r\n        const char* match = policies[i].match;\r\n        const char* apply = policies[i].apply;\r\n        for (size_t i=0; i<len-strlen(match); i++) {\r\n          int diff = memcmp(pkt+i, match, strlen(match));\r\n          if (diff == 0)\r\n            memcpy(pkt+i, apply, strlen(apply));\r\n        }\r\n        /* Update Checksum */\r\n        size_t icmp_tot_len = ntohs(ih->tot_len) - ih->hdr_len();\r\n        ich->checksum = 0;\r\n        ich->checksum = slankdev::checksum(ich, icmp_tot_len);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nstatic void\r\nforward_frame(int sockA, int sockB)\r\n{\r\n  printf(\"start forwarding %d <--> %d\\n\", sockA, sockB);\r\n  slankdev::pollfd pfd;\r\n  pfd.append_fd(sockA, POLLIN|POLLERR);\r\n  pfd.append_fd(sockB, POLLIN|POLLERR);\r\n  while (true) {\r\n\r\n    pfd.poll(-1);\r\n    for (size_t i=0; i<2; i++) {\r\n\r\n      struct sockaddr_ll rll;\r\n      if (pfd.get_revents(i) & POLLIN) {\r\n        int input_fd = pfd.get_fd(i);\r\n        int output_fd = pfd.get_fd(i^1);\r\n        memset(&rll, 0, sizeof(rll));\r\n        socklen_t rll_size = sizeof(rll);\r\n\r\n        uint8_t buffer[8000];\r\n        ssize_t frame_len = recvfrom(input_fd, &buffer, sizeof(buffer),\r\n              0, (struct sockaddr *)&rll, &rll_size);\r\n        if (frame_len < 0) {\r\n          perror(\"recvfrom\");\r\n          exit(1);\r\n        }\r\n\r\n        if(rll.sll_pkttype!=PACKET_OUTGOING) {\r\n          process_packet(buffer, frame_len, input_fd);\r\n          ssize_t send_len = send(output_fd, &buffer, frame_len, 0);\r\n          if (send_len < 0) {\r\n            perror(\"send\");\r\n            exit(1);\r\n          }\r\n        }\r\n      }\r\n\r\n    } // for\r\n  }\r\n}\r\n\r\nstatic int\r\nopen_raw_sock(const char* devname)\r\n{\r\n  int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));\r\n  if (sock < 0 ) {\r\n    perror(\"socket\");\r\n    exit(1);\r\n  }\r\n\r\n  struct ifreq ifr;\r\n  memset(&ifr, 0, sizeof(struct ifreq));\r\n  strcpy(ifr.ifr_name, devname);\r\n  int ret = ioctl(sock, SIOCGIFINDEX, &ifr);\r\n  if (ret < 0 ) {\r\n    perror(\"ioctl\");\r\n    exit(1);\r\n  }\r\n\r\n  struct sockaddr_ll sa;\r\n  sa.sll_family=AF_PACKET;\r\n  sa.sll_protocol=htons(ETH_P_ALL);\r\n  sa.sll_ifindex=ifr.ifr_ifindex;\r\n  ret = bind(sock, (struct sockaddr *)&sa, sizeof(sa));\r\n  if (ret < 0) {\r\n    perror(\"bind\");\r\n    close(sock);\r\n    exit(1);\r\n  }\r\n\r\n  struct packet_mreq mreq;\r\n  mreq.mr_type = PACKET_MR_PROMISC;\r\n  mreq.mr_ifindex = ifr.ifr_ifindex;\r\n  mreq.mr_alen = 0;\r\n  mreq.mr_address[0] ='\\0';\r\n  ret = setsockopt(sock, SOL_PACKET,\r\n        PACKET_ADD_MEMBERSHIP,\r\n        (void *)&mreq, sizeof(mreq));\r\n  if (ret < 0) {\r\n    perror(\"setsockopt\");\r\n    exit(1);\r\n  }\r\n  return sock;\r\n}\r\n\r\nint\r\nmain(int argc, char *argv[])\r\n{\r\n  if(argc < 3){\r\n    fprintf(stderr, \"Usage: %s <interface1>\"\r\n        \" <interface2>\\n\", argv[0]);\r\n    return 1;\r\n  }\r\n\r\n  int sockA = open_raw_sock(argv[1]);\r\n  int sockB = open_raw_sock(argv[2]);\r\n  policies[0].input_fd = sockA;\r\n  policies[1].input_fd = sockB;\r\n  policies[0].output_fd = sockB;\r\n  policies[1].output_fd = sockA;\r\n\r\n  printf(\"Interface1: %s\\n\", argv[1]);\r\n  printf(\"Interface2: %s\\n\", argv[2]);\r\n  forward_frame(sockA, sockB);\r\n}\r\n\r\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/function1/Makefile",
    "content": "\nCXXFLAGS += -std=c++11 -I$(HOME)/git/libslankdev\nLDFLAGS +=\n\nSRC = main.cc\nOBJ = $(SRC:.cc=.o)\nTARGET = a.out\n\ndef:\n\t$(CXX) $(CXXFLAGS) -o edenman_chikuwa.out edenman_chikuwa.cc $(LDFLAGS)\n\t$(CXX) $(CXXFLAGS) -o ntt_ipa.out ntt_ipa.cc $(LDFLAGS)\n\tdocker cp ntt_ipa.out R8:/usr/bin/ntt_ipa\n\tdocker cp edenman_chikuwa.out R9:/usr/bin/edenman_chikuwa\n\n\nall: $(OBJ)\n\t$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJ) $(LDFLAGS)\n\nclean:\n\trm -f $(OBJ) $(TARGET)\n\ninstall_docker: all\n\tfor c in `docker ps --format \"{{.Names}}\"`; do\\\n\t\tdocker cp a.out $$c:/usr/bin/filter ; done\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/function1/edenman_chikuwa.cc",
    "content": "\r\n#include <netinet/in.h>\r\n#include <errno.h>\r\n#include <netdb.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n#include <unistd.h>\r\n#include <stdio.h>\r\n#include <netinet/tcp.h>\r\n#include <netinet/ip.h>\r\n#include <sys/socket.h>\r\n#include <arpa/inet.h>\r\n#include <sys/ioctl.h>\r\n#include <net/if.h>\r\n#include <net/ethernet.h>\r\n#include <netpacket/packet.h>\r\n#include <sys/time.h>\r\n#include <algorithm>\r\n#include <slankdev/socketfd.h>\r\n#include <slankdev/poll.h>\r\n#include <slankdev/net/hdr.h>\r\n\r\nstruct policy {\r\n  int input_fd;\r\n  int output_fd;\r\n  const char* match;\r\n  const char* apply;\r\n} policies[] = {\r\n  { -1, -1, \"edenman\", \"chikuwa\" },\r\n};\r\n\r\nstatic int\r\nprocess_packet(uint8_t* pkt, size_t len, int inputfd)\r\n{\r\n  // printf(\"%s\\n\", __func__);\r\n  slankdev::ether* eh = reinterpret_cast<slankdev::ether*>(pkt);\r\n  if (ntohs(eh->type) != 0x86dd) return -1;\r\n\r\n  struct in6_addr match_src;\r\n  inet_pton(AF_INET6, \"2001:34::00\", &match_src);\r\n  slankdev::ip6* ih = reinterpret_cast<slankdev::ip6*>(eh + 1);\r\n  if (memcmp(&ih->src, &match_src, 8) != 0) return -1;\r\n\r\n  char src[100],dst[100];\r\n  inet_ntop(AF_INET6, &ih->src, src, sizeof(src));\r\n  inet_ntop(AF_INET6, &ih->dst, dst, sizeof(dst));\r\n  printf(\"match flow %s->%s\\n\", src, dst);\r\n\r\n  for (size_t i=0; i<1; i++) {\r\n    if (policies[i].input_fd == inputfd) {\r\n      const char* match = policies[i].match;\r\n      const char* apply = policies[i].apply;\r\n      for (size_t i=0; i<len-strlen(match); i++) {\r\n        // if (pkt[i] == 'n') printf(\"slank\\n\");\r\n        int diff = memcmp(pkt+i, match, strlen(match));\r\n        if (diff == 0) {\r\n          printf(\"KAKIKAE!!!\\n\");\r\n          memcpy(pkt+i, apply, strlen(apply));\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return 0;\r\n}\r\n\r\nstatic void\r\nforward_frame(int sockA)\r\n{\r\n  // printf(\"start forwarding %d <--> %d\\n\", sockA, sockB);\r\n  slankdev::pollfd pfd;\r\n  pfd.append_fd(sockA, POLLIN|POLLERR);\r\n  while (true) {\r\n\r\n    pfd.poll(-1);\r\n    for (size_t i=0; i<1; i++) {\r\n\r\n      struct sockaddr_ll rll;\r\n      if (pfd.get_revents(i) & POLLIN) {\r\n        int input_fd = pfd.get_fd(i);\r\n        int output_fd = pfd.get_fd(i);\r\n        memset(&rll, 0, sizeof(rll));\r\n        socklen_t rll_size = sizeof(rll);\r\n\r\n        uint8_t buffer[8000];\r\n        ssize_t frame_len = recvfrom(input_fd, &buffer, sizeof(buffer),\r\n              0, (struct sockaddr *)&rll, &rll_size);\r\n        if (frame_len < 0) {\r\n          perror(\"recvfrom\");\r\n          exit(1);\r\n        }\r\n\r\n        if(rll.sll_pkttype!=PACKET_OUTGOING) {\r\n          int ret = process_packet(buffer, frame_len, input_fd);\r\n          if (ret < 0)\r\n            continue;\r\n\r\n          uint8_t dst[] = { 0x52, 0x54, 0x00, 0x86, 0x6a, 0xef };\r\n          uint8_t src[] = { 0xc6, 0xca, 0xdf, 0x4b, 0x95, 0xba };\r\n          memcpy(buffer  , dst, 6);\r\n          memcpy(buffer+6, src, 6);\r\n\r\n          printf(\"REFLECT\\n\");\r\n          ssize_t send_len = send(output_fd, &buffer, frame_len, 0);\r\n          if (send_len < 0) {\r\n            perror(\"send\");\r\n            exit(1);\r\n          }\r\n        }\r\n      }\r\n\r\n    } // for\r\n  }\r\n}\r\n\r\nstatic int\r\nopen_raw_sock(const char* devname)\r\n{\r\n  int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));\r\n  if (sock < 0 ) {\r\n    perror(\"socket\");\r\n    exit(1);\r\n  }\r\n\r\n  struct ifreq ifr;\r\n  memset(&ifr, 0, sizeof(struct ifreq));\r\n  strcpy(ifr.ifr_name, devname);\r\n  int ret = ioctl(sock, SIOCGIFINDEX, &ifr);\r\n  if (ret < 0 ) {\r\n    perror(\"ioctl\");\r\n    exit(1);\r\n  }\r\n\r\n  struct sockaddr_ll sa;\r\n  sa.sll_family=AF_PACKET;\r\n  sa.sll_protocol=htons(ETH_P_ALL);\r\n  sa.sll_ifindex=ifr.ifr_ifindex;\r\n  ret = bind(sock, (struct sockaddr *)&sa, sizeof(sa));\r\n  if (ret < 0) {\r\n    perror(\"bind\");\r\n    close(sock);\r\n    exit(1);\r\n  }\r\n\r\n  struct packet_mreq mreq;\r\n  mreq.mr_type = PACKET_MR_PROMISC;\r\n  mreq.mr_ifindex = ifr.ifr_ifindex;\r\n  mreq.mr_alen = 0;\r\n  mreq.mr_address[0] ='\\0';\r\n  ret = setsockopt(sock, SOL_PACKET,\r\n        PACKET_ADD_MEMBERSHIP,\r\n        (void *)&mreq, sizeof(mreq));\r\n  if (ret < 0) {\r\n    perror(\"setsockopt\");\r\n    exit(1);\r\n  }\r\n  return sock;\r\n}\r\n\r\nint\r\nmain(int argc, char *argv[])\r\n{\r\n  if(argc < 2){\r\n    fprintf(stderr, \"Usage: %s <interface1>\\n\", argv[0]);\r\n    return 1;\r\n  }\r\n\r\n  int sockA = open_raw_sock(argv[1]);\r\n  policies[0].input_fd = sockA;\r\n  policies[0].output_fd = sockA;\r\n\r\n  printf(\"Interface1: %s\\n\", argv[1]);\r\n  // printf(\"Interface2: %s\\n\", argv[2]);\r\n  forward_frame(sockA);\r\n}\r\n\r\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/function1/main.cc",
    "content": "\r\n#include <netinet/in.h>\r\n#include <errno.h>\r\n#include <netdb.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n#include <unistd.h>\r\n#include <stdio.h>\r\n#include <netinet/tcp.h>\r\n#include <netinet/ip.h>\r\n#include <sys/socket.h>\r\n#include <arpa/inet.h>\r\n#include <sys/ioctl.h>\r\n#include <net/if.h>\r\n#include <net/ethernet.h>\r\n#include <netpacket/packet.h>\r\n#include <sys/time.h>\r\n#include <algorithm>\r\n#include <slankdev/socketfd.h>\r\n#include <slankdev/poll.h>\r\n#include <slankdev/net/hdr.h>\r\n\r\nstruct policy {\r\n  int input_fd;\r\n  int output_fd;\r\n  const char* match;\r\n  const char* apply;\r\n} policies[] = {\r\n  { -1, -1, \"ntt\", \"ipa\" },\r\n  // { -1, -1, \"kamuee\", \"manuke\" },\r\n};\r\n\r\nstatic int\r\nprocess_packet(uint8_t* pkt, size_t len, int inputfd)\r\n{\r\n  // printf(\"%s\\n\", __func__);\r\n  slankdev::ether* eh = reinterpret_cast<slankdev::ether*>(pkt);\r\n  if (ntohs(eh->type) != 0x86dd) return -1;\r\n\r\n  struct in6_addr match_src;\r\n  inet_pton(AF_INET6, \"2001:34::00\", &match_src);\r\n  slankdev::ip6* ih = reinterpret_cast<slankdev::ip6*>(eh + 1);\r\n  if (memcmp(&ih->src, &match_src, 8) != 0) return -1;\r\n\r\n  char src[100],dst[100];\r\n  inet_ntop(AF_INET6, &ih->src, src, sizeof(src));\r\n  inet_ntop(AF_INET6, &ih->dst, dst, sizeof(dst));\r\n  printf(\"match flow %s->%s\\n\", src, dst);\r\n\r\n  for (size_t i=0; i<1; i++) {\r\n    if (policies[i].input_fd == inputfd) {\r\n      const char* match = policies[i].match;\r\n      const char* apply = policies[i].apply;\r\n      for (size_t i=0; i<len-strlen(match); i++) {\r\n        // if (pkt[i] == 'n') printf(\"slank\\n\");\r\n        int diff = memcmp(pkt+i, match, strlen(match));\r\n        if (diff == 0) {\r\n          printf(\"KAKIKAE!!!\\n\");\r\n          memcpy(pkt+i, apply, strlen(apply));\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return 0;\r\n}\r\n\r\nstatic void\r\nforward_frame(int sockA)\r\n{\r\n  // printf(\"start forwarding %d <--> %d\\n\", sockA, sockB);\r\n  slankdev::pollfd pfd;\r\n  pfd.append_fd(sockA, POLLIN|POLLERR);\r\n  while (true) {\r\n\r\n    pfd.poll(-1);\r\n    for (size_t i=0; i<1; i++) {\r\n\r\n      struct sockaddr_ll rll;\r\n      if (pfd.get_revents(i) & POLLIN) {\r\n        int input_fd = pfd.get_fd(i);\r\n        int output_fd = pfd.get_fd(i);\r\n        memset(&rll, 0, sizeof(rll));\r\n        socklen_t rll_size = sizeof(rll);\r\n\r\n        uint8_t buffer[8000];\r\n        ssize_t frame_len = recvfrom(input_fd, &buffer, sizeof(buffer),\r\n              0, (struct sockaddr *)&rll, &rll_size);\r\n        if (frame_len < 0) {\r\n          perror(\"recvfrom\");\r\n          exit(1);\r\n        }\r\n\r\n        if(rll.sll_pkttype!=PACKET_OUTGOING) {\r\n          int ret = process_packet(buffer, frame_len, input_fd);\r\n          if (ret < 0)\r\n            continue;\r\n\r\n          uint8_t dst[] = { 0x52, 0x54, 0x00, 0x86, 0x6a, 0xef };\r\n          uint8_t src[] = { 0xc6, 0xca, 0xdf, 0x4b, 0x95, 0xba };\r\n          memcpy(buffer  , dst, 6);\r\n          memcpy(buffer+6, src, 6);\r\n\r\n          printf(\"REFLECT\\n\");\r\n          ssize_t send_len = send(output_fd, &buffer, frame_len, 0);\r\n          if (send_len < 0) {\r\n            perror(\"send\");\r\n            exit(1);\r\n          }\r\n        }\r\n      }\r\n\r\n    } // for\r\n  }\r\n}\r\n\r\nstatic int\r\nopen_raw_sock(const char* devname)\r\n{\r\n  int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));\r\n  if (sock < 0 ) {\r\n    perror(\"socket\");\r\n    exit(1);\r\n  }\r\n\r\n  struct ifreq ifr;\r\n  memset(&ifr, 0, sizeof(struct ifreq));\r\n  strcpy(ifr.ifr_name, devname);\r\n  int ret = ioctl(sock, SIOCGIFINDEX, &ifr);\r\n  if (ret < 0 ) {\r\n    perror(\"ioctl\");\r\n    exit(1);\r\n  }\r\n\r\n  struct sockaddr_ll sa;\r\n  sa.sll_family=AF_PACKET;\r\n  sa.sll_protocol=htons(ETH_P_ALL);\r\n  sa.sll_ifindex=ifr.ifr_ifindex;\r\n  ret = bind(sock, (struct sockaddr *)&sa, sizeof(sa));\r\n  if (ret < 0) {\r\n    perror(\"bind\");\r\n    close(sock);\r\n    exit(1);\r\n  }\r\n\r\n  struct packet_mreq mreq;\r\n  mreq.mr_type = PACKET_MR_PROMISC;\r\n  mreq.mr_ifindex = ifr.ifr_ifindex;\r\n  mreq.mr_alen = 0;\r\n  mreq.mr_address[0] ='\\0';\r\n  ret = setsockopt(sock, SOL_PACKET,\r\n        PACKET_ADD_MEMBERSHIP,\r\n        (void *)&mreq, sizeof(mreq));\r\n  if (ret < 0) {\r\n    perror(\"setsockopt\");\r\n    exit(1);\r\n  }\r\n  return sock;\r\n}\r\n\r\nint\r\nmain(int argc, char *argv[])\r\n{\r\n  if(argc < 2){\r\n    fprintf(stderr, \"Usage: %s <interface1>\\n\", argv[0]);\r\n    return 1;\r\n  }\r\n\r\n  int sockA = open_raw_sock(argv[1]);\r\n  policies[0].input_fd = sockA;\r\n  policies[0].output_fd = sockA;\r\n\r\n  printf(\"Interface1: %s\\n\", argv[1]);\r\n  // printf(\"Interface2: %s\\n\", argv[2]);\r\n  forward_frame(sockA);\r\n}\r\n\r\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/function1/ntt_ipa.cc",
    "content": "\r\n#include <netinet/in.h>\r\n#include <errno.h>\r\n#include <netdb.h>\r\n#include <stdlib.h>\r\n#include <string.h>\r\n#include <unistd.h>\r\n#include <stdio.h>\r\n#include <netinet/tcp.h>\r\n#include <netinet/ip.h>\r\n#include <sys/socket.h>\r\n#include <arpa/inet.h>\r\n#include <sys/ioctl.h>\r\n#include <net/if.h>\r\n#include <net/ethernet.h>\r\n#include <netpacket/packet.h>\r\n#include <sys/time.h>\r\n#include <algorithm>\r\n#include <slankdev/socketfd.h>\r\n#include <slankdev/poll.h>\r\n#include <slankdev/net/hdr.h>\r\n\r\nstruct policy {\r\n  int input_fd;\r\n  int output_fd;\r\n  const char* match;\r\n  const char* apply;\r\n} policies[] = {\r\n  { -1, -1, \"ntt\", \"ipa\" },\r\n};\r\n\r\nstatic int\r\nprocess_packet(uint8_t* pkt, size_t len, int inputfd)\r\n{\r\n  // printf(\"%s\\n\", __func__);\r\n  slankdev::ether* eh = reinterpret_cast<slankdev::ether*>(pkt);\r\n  if (ntohs(eh->type) != 0x86dd) return -1;\r\n\r\n  struct in6_addr match_src;\r\n  inet_pton(AF_INET6, \"2001:34::00\", &match_src);\r\n  slankdev::ip6* ih = reinterpret_cast<slankdev::ip6*>(eh + 1);\r\n  if (memcmp(&ih->src, &match_src, 8) != 0) return -1;\r\n\r\n  char src[100],dst[100];\r\n  inet_ntop(AF_INET6, &ih->src, src, sizeof(src));\r\n  inet_ntop(AF_INET6, &ih->dst, dst, sizeof(dst));\r\n  printf(\"match flow %s->%s\\n\", src, dst);\r\n\r\n  for (size_t i=0; i<1; i++) {\r\n    if (policies[i].input_fd == inputfd) {\r\n      const char* match = policies[i].match;\r\n      const char* apply = policies[i].apply;\r\n      for (size_t i=0; i<len-strlen(match); i++) {\r\n        // if (pkt[i] == 'n') printf(\"slank\\n\");\r\n        int diff = memcmp(pkt+i, match, strlen(match));\r\n        if (diff == 0) {\r\n          printf(\"KAKIKAE!!!\\n\");\r\n          memcpy(pkt+i, apply, strlen(apply));\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return 0;\r\n}\r\n\r\nstatic void\r\nforward_frame(int sockA)\r\n{\r\n  // printf(\"start forwarding %d <--> %d\\n\", sockA, sockB);\r\n  slankdev::pollfd pfd;\r\n  pfd.append_fd(sockA, POLLIN|POLLERR);\r\n  while (true) {\r\n\r\n    pfd.poll(-1);\r\n    for (size_t i=0; i<1; i++) {\r\n\r\n      struct sockaddr_ll rll;\r\n      if (pfd.get_revents(i) & POLLIN) {\r\n        int input_fd = pfd.get_fd(i);\r\n        int output_fd = pfd.get_fd(i);\r\n        memset(&rll, 0, sizeof(rll));\r\n        socklen_t rll_size = sizeof(rll);\r\n\r\n        uint8_t buffer[8000];\r\n        ssize_t frame_len = recvfrom(input_fd, &buffer, sizeof(buffer),\r\n              0, (struct sockaddr *)&rll, &rll_size);\r\n        if (frame_len < 0) {\r\n          perror(\"recvfrom\");\r\n          exit(1);\r\n        }\r\n\r\n        if(rll.sll_pkttype!=PACKET_OUTGOING) {\r\n          int ret = process_packet(buffer, frame_len, input_fd);\r\n          if (ret < 0)\r\n            continue;\r\n\r\n          uint8_t dst[] = { 0x52, 0x54, 0x00, 0x86, 0x6a, 0xef };\r\n          uint8_t src[] = { 0xc6, 0xca, 0xdf, 0x4b, 0x95, 0xba };\r\n          memcpy(buffer  , dst, 6);\r\n          memcpy(buffer+6, src, 6);\r\n\r\n          printf(\"REFLECT\\n\");\r\n          ssize_t send_len = send(output_fd, &buffer, frame_len, 0);\r\n          if (send_len < 0) {\r\n            perror(\"send\");\r\n            exit(1);\r\n          }\r\n        }\r\n      }\r\n\r\n    } // for\r\n  }\r\n}\r\n\r\nstatic int\r\nopen_raw_sock(const char* devname)\r\n{\r\n  int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));\r\n  if (sock < 0 ) {\r\n    perror(\"socket\");\r\n    exit(1);\r\n  }\r\n\r\n  struct ifreq ifr;\r\n  memset(&ifr, 0, sizeof(struct ifreq));\r\n  strcpy(ifr.ifr_name, devname);\r\n  int ret = ioctl(sock, SIOCGIFINDEX, &ifr);\r\n  if (ret < 0 ) {\r\n    perror(\"ioctl\");\r\n    exit(1);\r\n  }\r\n\r\n  struct sockaddr_ll sa;\r\n  sa.sll_family=AF_PACKET;\r\n  sa.sll_protocol=htons(ETH_P_ALL);\r\n  sa.sll_ifindex=ifr.ifr_ifindex;\r\n  ret = bind(sock, (struct sockaddr *)&sa, sizeof(sa));\r\n  if (ret < 0) {\r\n    perror(\"bind\");\r\n    close(sock);\r\n    exit(1);\r\n  }\r\n\r\n  struct packet_mreq mreq;\r\n  mreq.mr_type = PACKET_MR_PROMISC;\r\n  mreq.mr_ifindex = ifr.ifr_ifindex;\r\n  mreq.mr_alen = 0;\r\n  mreq.mr_address[0] ='\\0';\r\n  ret = setsockopt(sock, SOL_PACKET,\r\n        PACKET_ADD_MEMBERSHIP,\r\n        (void *)&mreq, sizeof(mreq));\r\n  if (ret < 0) {\r\n    perror(\"setsockopt\");\r\n    exit(1);\r\n  }\r\n  return sock;\r\n}\r\n\r\nint\r\nmain(int argc, char *argv[])\r\n{\r\n  if(argc < 2){\r\n    fprintf(stderr, \"Usage: %s <interface1>\\n\", argv[0]);\r\n    return 1;\r\n  }\r\n\r\n  int sockA = open_raw_sock(argv[1]);\r\n  policies[0].input_fd = sockA;\r\n  policies[0].output_fd = sockA;\r\n\r\n  printf(\"Interface1: %s\\n\", argv[1]);\r\n  // printf(\"Interface2: %s\\n\", argv[2]);\r\n  forward_frame(sockA);\r\n}\r\n\r\n"
  },
  {
    "path": "examples/basic_srv6/linux/srv6_unaware/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: F1#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: F1#net1 }\n  - name: F1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R2#net0 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n  - name: F1\n    cmds:\n      - cmd: ip link add br0 type bridge\n      - cmd: ip link set br0 up\n      - cmd: ip link set net0 master br0\n      - cmd: ip link set net1 master br0\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: docker exec R1 ping -c2 10.0.0.1\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.0.0.2\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/transit/README.md",
    "content": "\n# Transit and End test\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 | sudo sh\n$ tn conf | sudo sh\n$ tn test p2p    | sudo sh\n$ tn test blue   | sudo sh\n$ tn test green  | sudo sh\n$ tn test red    | sudo sh\n$ tn test purple | sudo sh\n```\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/transit/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R6#net0 }\n      - { name: net2, type: direct, args: R3#net0 }\n      - { name: net3, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n      - { name: net1, type: direct, args: R6#net1 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net3 }\n      - { name: net1, type: direct, args: R5#net0 }\n  - name: R5\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R4#net1 }\n      - { name: net1, type: direct, args: R6#net2 }\n  - name: R6\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n      - { name: net1, type: direct, args: R3#net1 }\n      - { name: net2, type: direct, args: R5#net1 }\n      - { name: net3, type: direct, args: R7#net0 }\n  - name: R7\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R6#net3 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'   -c 'ipv6 address fc00:1::1/64'  -c 'exit'\n          -c 'interface net0' -c 'ipv6 address 2001:12::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 1.1.1.1'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c 'exit'\n      - cmd: >-\n          ip -6 route add fc00:7::10/128 encap seg6 mode encap\n          segs fc00:2::1,fc00:3::1,fc00:6::1,fc00:7::1 dev net0\n      - cmd: >-\n          ip -6 route add fc00:7::20/128 encap seg6 mode encap\n          segs fc00:2::1,fc00:2::4,fc00:6::1,fc00:7::1 dev net0\n      - cmd: >-\n          ip -6 route add fc00:7::30/128 encap seg6 mode encap\n          segs fc00:2::1,fc00:2::3,fc00:6::1,fc00:7::1 dev net0\n\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net2.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net3.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net3.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'   -c 'ipv6 address fc00:2::1/64'  -c 'exit'\n          -c 'interface net0' -c 'ipv6 address 2001:12::2/64' -c 'exit'\n          -c 'interface net1' -c 'ipv6 address 2001:26::1/64' -c 'exit'\n          -c 'interface net2' -c 'ipv6 address 2001:23::1/64' -c 'exit'\n          -c 'interface net3' -c 'ipv6 address 2001:24::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 2.2.2.2'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c ' interface net2 area 0.0.0.0'\n          -c ' interface net3 area 0.0.0.0'\n          -c 'exit'\n      - cmd: >-\n          ip -6 route add fc00:2::3 encap seg6local\n          action End.X nh6 fc00:3::1 dev net2\n      - cmd: >-\n          ip -6 route add fc00:2::4 encap seg6local\n          action End.X nh6 fc00:4::1 dev net3\n\n  - name: R3\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'   -c 'ipv6 address fc00:3::1/64'  -c 'exit'\n          -c 'interface net0' -c 'ipv6 address 2001:23::2/64' -c 'exit'\n          -c 'interface net1' -c 'ipv6 address 2001:36::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 3.3.3.3'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c 'exit'\n  - name: R4\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'   -c 'ipv6 address fc00:4::1/64'  -c 'exit'\n          -c 'interface net0' -c 'ipv6 address 2001:24::2/64' -c 'exit'\n          -c 'interface net1' -c 'ipv6 address 2001:45::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 4.4.4.4'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c 'exit'\n  - name: R5\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'   -c 'ipv6 address fc00:5::1/64'  -c 'exit'\n          -c 'interface net0' -c 'ipv6 address 2001:45::2/64' -c 'exit'\n          -c 'interface net1' -c 'ipv6 address 2001:56::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 5.5.5.5'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c 'exit'\n  - name: R6\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net2.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net3.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net3.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'   -c 'ipv6 address fc00:6::1/64'  -c 'exit'\n          -c 'interface net0' -c 'ipv6 address 2001:26::2/64' -c 'exit'\n          -c 'interface net1' -c 'ipv6 address 2001:36::2/64' -c 'exit'\n          -c 'interface net2' -c 'ipv6 address 2001:56::2/64' -c 'exit'\n          -c 'interface net3' -c 'ipv6 address 2001:67::1/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 6.6.6.6'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c ' interface net1 area 0.0.0.0'\n          -c ' interface net2 area 0.0.0.0'\n          -c ' interface net3 area 0.0.0.0'\n          -c 'exit'\n  - name: R7\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ipv6 address fc00:7::1/64'\n          -c ' ipv6 address fc00:7::10/64'\n          -c ' ipv6 address fc00:7::20/64'\n          -c ' ipv6 address fc00:7::30/64'\n          -c ' ipv6 address fc00:7::40/64'\n          -c 'exit'\n          -c 'interface net0' -c 'ipv6 address 2001:67::2/64' -c 'exit'\n          -c 'router ospf6'\n          -c ' ospf6 router-id 7.7.7.7'\n          -c ' interface lo area 0.0.0.0'\n          -c ' interface net0 area 0.0.0.0'\n          -c 'exit'\n\n      # - cmd: ip -6 addr add fc00:2::1/64 dev lo\n      # - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      # - cmd: ip link add vrf101 type vrf table 101\n      # - cmd: ip link add vrf110 type vrf table 110\n      # - cmd: ip link set vrf101 up\n      # - cmd: ip link set vrf110 up\n      # - cmd: ip link set dev net1 master vrf101\n      # - cmd: ip link set dev net2 master vrf110\n      # - cmd: ip -4 addr add 10.0.2.1/24 dev net1\n      # - cmd: ip -4 addr add 10.0.2.1/24 dev net2\n      # - cmd: ip sr tunsrc set fc00:2::1\n      # - cmd: ip route add fc00:1::/64 via 2001:12::1\n      # - cmd: >-\n      #     ip -4 route add 10.0.1.0/24 encap seg6\n      #     mode encap segs fc00:1::101 dev net0 table 101\n      # - cmd: >-\n      #     ip -4 route add 10.0.1.0/24 encap seg6\n      #     mode encap segs fc00:1::110 dev net0 table 110\n      # - cmd: >-\n      #     ip -6 route add fc00:2::101/128 encap seg6local\n      #     action End.DT4 table 101 dev net0\n      # - cmd: >-\n      #     ip -6 route add fc00:2::110/128 encap seg6local\n      #     action End.DT4 table 110 dev net0\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec R1 ping -c2 2001:12::1\n      - cmd: docker exec R1 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 2001:12::1\n      - cmd: docker exec R2 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 2001:23::1\n      - cmd: docker exec R2 ping -c2 2001:23::2\n      - cmd: docker exec R2 ping -c2 2001:24::1\n      - cmd: docker exec R2 ping -c2 2001:24::2\n      - cmd: docker exec R2 ping -c2 2001:26::1\n      - cmd: docker exec R2 ping -c2 2001:26::2\n      - cmd: docker exec R3 ping -c2 2001:23::1\n      - cmd: docker exec R3 ping -c2 2001:23::2\n      - cmd: docker exec R3 ping -c2 2001:36::1\n      - cmd: docker exec R3 ping -c2 2001:36::2\n      - cmd: docker exec R4 ping -c2 2001:24::1\n      - cmd: docker exec R4 ping -c2 2001:24::2\n      - cmd: docker exec R4 ping -c2 2001:45::1\n      - cmd: docker exec R4 ping -c2 2001:45::2\n      - cmd: docker exec R5 ping -c2 2001:45::1\n      - cmd: docker exec R5 ping -c2 2001:45::2\n      - cmd: docker exec R5 ping -c2 2001:56::1\n      - cmd: docker exec R5 ping -c2 2001:56::2\n      - cmd: docker exec R6 ping -c2 2001:26::1\n      - cmd: docker exec R6 ping -c2 2001:26::2\n      - cmd: docker exec R6 ping -c2 2001:36::1\n      - cmd: docker exec R6 ping -c2 2001:36::2\n      - cmd: docker exec R6 ping -c2 2001:56::1\n      - cmd: docker exec R6 ping -c2 2001:56::2\n      - cmd: docker exec R6 ping -c2 2001:67::1\n      - cmd: docker exec R6 ping -c2 2001:67::2\n      - cmd: docker exec R7 ping -c2 2001:67::1\n      - cmd: docker exec R7 ping -c2 2001:67::2\n  - name: lo\n    cmds:\n      - cmd: docker exec R1 ping -c2 fc00:1::1\n      - cmd: docker exec R1 ping -c2 fc00:2::1\n      - cmd: docker exec R1 ping -c2 fc00:3::1\n      - cmd: docker exec R1 ping -c2 fc00:4::1\n      - cmd: docker exec R1 ping -c2 fc00:5::1\n      - cmd: docker exec R1 ping -c2 fc00:6::1\n      - cmd: docker exec R1 ping -c2 fc00:7::1\n      - cmd: docker exec R2 ping -c2 fc00:1::1\n      - cmd: docker exec R2 ping -c2 fc00:2::1\n      - cmd: docker exec R2 ping -c2 fc00:3::1\n      - cmd: docker exec R2 ping -c2 fc00:4::1\n      - cmd: docker exec R2 ping -c2 fc00:5::1\n      - cmd: docker exec R2 ping -c2 fc00:6::1\n      - cmd: docker exec R2 ping -c2 fc00:7::1\n      - cmd: docker exec R3 ping -c2 fc00:1::1\n      - cmd: docker exec R3 ping -c2 fc00:2::1\n      - cmd: docker exec R3 ping -c2 fc00:3::1\n      - cmd: docker exec R3 ping -c2 fc00:4::1\n      - cmd: docker exec R3 ping -c2 fc00:5::1\n      - cmd: docker exec R3 ping -c2 fc00:6::1\n      - cmd: docker exec R3 ping -c2 fc00:7::1\n      - cmd: docker exec R4 ping -c2 fc00:1::1\n      - cmd: docker exec R4 ping -c2 fc00:2::1\n      - cmd: docker exec R4 ping -c2 fc00:3::1\n      - cmd: docker exec R4 ping -c2 fc00:4::1\n      - cmd: docker exec R4 ping -c2 fc00:5::1\n      - cmd: docker exec R4 ping -c2 fc00:6::1\n      - cmd: docker exec R4 ping -c2 fc00:7::1\n      - cmd: docker exec R5 ping -c2 fc00:1::1\n      - cmd: docker exec R5 ping -c2 fc00:2::1\n      - cmd: docker exec R5 ping -c2 fc00:3::1\n      - cmd: docker exec R5 ping -c2 fc00:4::1\n      - cmd: docker exec R5 ping -c2 fc00:5::1\n      - cmd: docker exec R5 ping -c2 fc00:6::1\n      - cmd: docker exec R5 ping -c2 fc00:7::1\n      - cmd: docker exec R6 ping -c2 fc00:1::1\n      - cmd: docker exec R6 ping -c2 fc00:2::1\n      - cmd: docker exec R6 ping -c2 fc00:3::1\n      - cmd: docker exec R6 ping -c2 fc00:4::1\n      - cmd: docker exec R6 ping -c2 fc00:5::1\n      - cmd: docker exec R6 ping -c2 fc00:6::1\n      - cmd: docker exec R6 ping -c2 fc00:7::1\n      - cmd: docker exec R7 ping -c2 fc00:1::1\n      - cmd: docker exec R7 ping -c2 fc00:2::1\n      - cmd: docker exec R7 ping -c2 fc00:3::1\n      - cmd: docker exec R7 ping -c2 fc00:4::1\n      - cmd: docker exec R7 ping -c2 fc00:5::1\n      - cmd: docker exec R7 ping -c2 fc00:6::1\n      - cmd: docker exec R7 ping -c2 fc00:7::1\n  - name: blue\n    cmds:\n      - cmd: docker exec R1 ping fc00:7::10 -c2\n  - name: green\n    cmds:\n      - cmd: docker exec R1 ping fc00:7::20 -c2\n  - name: red\n    cmds:\n      - cmd: docker exec R1 ping fc00:7::30 -c2\n  - name: purple\n    cmds:\n      - cmd: docker exec R1 ping fc00:7::40 -c2\n  - name: all\n    cmds:\n      - cmd: docker exec R1 ping fc00:7::10 -c2\n      - cmd: docker exec R1 ping fc00:7::20 -c2\n      - cmd: docker exec R1 ping fc00:7::30 -c2\n      - cmd: docker exec R1 ping fc00:7::40 -c2\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v4_per_ce/README.md",
    "content": "\n# SRv6 Tiny L3VPN(IPv4) Demonstration\n- Hiroki Shirokura <slankdev@coe.ad.jp>\n- 2018.12.30\n\n![img](./topo.jpeg)\n\n```\n$ cd tinet/projects/basic_srv6/l3vpn\n$ tn up | sudo sh # create network nodes.\n$ tn conf | sudo sh # execute configuration to each nodes\n$ docker ps # you can check some nodes exist.\n$ tn test p2p | sudo sh # execute point-to-point link's ping.\n$ tn test vpn | sudo sh # execute L3VPN ping.\n```\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v4_per_ce/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n  - name: C1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: C2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:1::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::1/64 dev net0\n      - cmd: ip addr add 10.0.0.1/24 dev net1\n      - cmd: ip sr tunsrc set fc00:1::1\n      - cmd: ip route add fc00:2::/64 via 2001:12::2\n      - cmd: ip route add 10.0.1.0/24 encap seg6 mode encap segs fc00:2::10 dev net0\n      - cmd: ip -6 route add fc00:1::10/128 encap seg6local action End.DX4 nh4 10.0.0.2 dev net0\n\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:2::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      - cmd: ip addr add 10.0.1.1/24 dev net1\n      - cmd: ip sr tunsrc set fc00:2::1\n      - cmd: ip route add fc00:1::/64 via 2001:12::1\n      - cmd: ip route add 10.0.0.0/24 encap seg6 mode encap segs fc00:1::10 dev net0\n      - cmd: ip -6 route add fc00:2::10/128 encap seg6local action End.DX4 nh4 10.0.1.2 dev net0\n\n  - name: C1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route replace default via 10.0.0.1\n  - name: C2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add 10.0.1.2/24 dev net0\n      - cmd: ip route replace default via 10.0.1.1\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec R1 ping -c2 2001:12::1\n      - cmd: docker exec R1 ping -c2 2001:12::2\n      - cmd: docker exec R1 ping -c2 10.0.0.1\n      - cmd: docker exec R1 ping -c2 10.0.0.2\n      - cmd: docker exec R2 ping -c2 2001:12::1\n      - cmd: docker exec R2 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 10.0.1.1\n      - cmd: docker exec R2 ping -c2 10.0.1.2\n      - cmd: docker exec C1 ping -c2 10.0.0.1\n      - cmd: docker exec C1 ping -c2 10.0.0.2\n      - cmd: docker exec C2 ping -c2 10.0.1.1\n      - cmd: docker exec C2 ping -c2 10.0.1.2\n  - name: vpn\n    cmds:\n      - cmd: docker exec C1 ping -c2 10.0.1.2\n      - cmd: docker exec C2 ping -c2 10.0.0.2\n\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v4_per_vrf/README.md",
    "content": "\n# VPNv4 per-VRF using SRv6\n**VERY-IMPORTANT-NOTICE:**<br>\nCurrentry latest-stable(4.15), End.DT4 isn't supported.\nSo, this example can't be working.\n\n- Hiroki Shirokura <slankdev@coe.ad.jp>\n- 2018.12.31\n\n![img](./topo.jpeg)\n\n```\n$ cd tinet/projects/basic_srv6/l3vpn\n$ tn up | sudo sh # create network nodes.\n$ tn conf | sudo sh # execute configuration to each nodes\n$ docker ps # you can check some nodes exist.\n$ tn test p2p | sudo sh # execute point-to-point link's ping.\n$ tn test vpn | sudo sh # execute L3VPN ping.\n```\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v4_per_vrf/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C10#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C20#net0 }\n  - name: C1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: C2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: C10\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n  - name: C20\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:1::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::1/64 dev net0\n      - cmd: ip link add vrf101 type vrf table 101\n      - cmd: ip link add vrf110 type vrf table 110\n      - cmd: ip link set vrf101 up\n      - cmd: ip link set vrf110 up\n      - cmd: ip link set dev net1 master vrf101\n      - cmd: ip link set dev net2 master vrf110\n      - cmd: ip -4 addr add 10.0.1.1/24 dev net1\n      - cmd: ip -4 addr add 10.0.1.1/24 dev net2\n      - cmd: ip sr tunsrc set fc00:1::1\n      - cmd: ip route add fc00:2::/64 via 2001:12::2\n      - cmd: ip -4 route add 10.0.2.0/24 encap seg6 mode encap segs fc00:2::101 dev net0 table 101\n      - cmd: ip -4 route add 10.0.2.0/24 encap seg6 mode encap segs fc00:2::110 dev net0 table 110\n      - cmd: echo \"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\"\n      - cmd: echo \"@ NOTICE!!! @@@@@@@@@@@@@@@@@@@@@\"\n      - cmd: echo \"@ End.DT4 isn't implemented yet @\"\n      - cmd: echo \"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\"\n      - cmd: ip -6 route add fc00:1::101/128 encap seg6local action End.DT4 table 101 dev net0\n      - cmd: ip -6 route add fc00:1::110/128 encap seg6local action End.DT4 table 110 dev net0\n\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:2::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      - cmd: ip link add vrf101 type vrf table 101\n      - cmd: ip link add vrf110 type vrf table 110\n      - cmd: ip link set vrf101 up\n      - cmd: ip link set vrf110 up\n      - cmd: ip link set dev net1 master vrf101\n      - cmd: ip link set dev net2 master vrf110\n      - cmd: ip -4 addr add 10.0.2.1/24 dev net1\n      - cmd: ip -4 addr add 10.0.2.1/24 dev net2\n      - cmd: ip sr tunsrc set fc00:2::1\n      - cmd: ip route add fc00:1::/64 via 2001:12::1\n      - cmd: ip -4 route add 10.0.1.0/24 encap seg6 mode encap segs fc00:1::101 dev net0 table 101\n      - cmd: ip -4 route add 10.0.1.0/24 encap seg6 mode encap segs fc00:1::110 dev net0 table 110\n      - cmd: echo \"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\"\n      - cmd: echo \"@ NOTICE!!! @@@@@@@@@@@@@@@@@@@@@\"\n      - cmd: echo \"@ End.DT4 isn't implemented yet @\"\n      - cmd: echo \"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\"\n      - cmd: ip -6 route add fc00:2::101/128 encap seg6local action End.DT4 table 101 dev net0\n      - cmd: ip -6 route add fc00:2::110/128 encap seg6local action End.DT4 table 110 dev net0\n\n  - name: C1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add 10.0.1.2/24 dev net0\n      - cmd: ip route replace default via 10.0.1.1\n  - name: C10\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add 10.0.1.2/24 dev net0\n      - cmd: ip route replace default via 10.0.1.1\n  - name: C2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add 10.0.2.2/24 dev net0\n      - cmd: ip route replace default via 10.0.2.1\n\n  - name: C20\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add 10.0.2.2/24 dev net0\n      - cmd: ip route replace default via 10.0.2.1\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: echo TEST-BACKBONE[R1,R2]\n      - cmd: docker exec R1 ping -c2 2001:12::1\n      - cmd: docker exec R1 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 2001:12::1\n      - cmd: docker exec R2 ping -c2 2001:12::2\n      - cmd: echo TEST[R1,C1,C10]\n      - cmd: docker exec R1 ping -c2 -I vrf101 10.0.1.1\n      - cmd: docker exec R1 ping -c2 -I vrf101 10.0.1.2\n      - cmd: docker exec R1 ping -c2 -I vrf110 10.0.1.1\n      - cmd: docker exec R1 ping -c2 -I vrf110 10.0.1.2\n      - cmd: docker exec C1  ping -c2 10.0.1.1\n      - cmd: docker exec C1  ping -c2 10.0.1.2\n      - cmd: docker exec C10 ping -c2 10.0.1.1\n      - cmd: docker exec C10 ping -c2 10.0.1.2\n      - cmd: echo TEST[R2,C2,C20]\n      - cmd: docker exec R2 ping -c2 -I vrf101 10.0.2.1\n      - cmd: docker exec R2 ping -c2 -I vrf101 10.0.2.2\n      - cmd: docker exec R2 ping -c2 -I vrf110 10.0.2.1\n      - cmd: docker exec R2 ping -c2 -I vrf110 10.0.2.2\n      - cmd: docker exec C2 ping  -c2 10.0.2.1\n      - cmd: docker exec C2 ping  -c2 10.0.2.2\n      - cmd: docker exec C20 ping -c2 10.0.2.1\n      - cmd: docker exec C20 ping -c2 10.0.2.2\n  - name: vpn\n    cmds:\n      - cmd: docker exec C1 ping  -c2 10.0.2.2\n      - cmd: docker exec C2 ping  -c2 10.0.1.2\n      - cmd: docker exec C10 ping -c2 10.0.2.2\n      - cmd: docker exec C20 ping -c2 10.0.1.2\n\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v6_per_ce/README.md",
    "content": "\n# SRv6 Tiny L3VPN(IPv6) Demonstration\n- Hiroki Shirokura <slankdev@coe.ad.jp>\n- 2018.12.31\n\n![img](./topo.jpeg)\n\n```\n$ cd tinet/projects/basic_srv6/l3vpn\n$ tn up | sudo sh # create network nodes.\n$ tn conf | sudo sh # execute configuration to each nodes\n$ docker ps # you can check some nodes exist.\n$ tn test p2p | sudo sh # execute point-to-point link's ping.\n$ tn test vpn | sudo sh # execute L3VPN ping.\n```\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v6_per_ce/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_container2\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C3#net0 }\n  - name: C1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: C2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: C3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:1::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::1/64 dev net0\n      - cmd: ip -6 addr add fd00:1::1/64 dev net1\n      - cmd: ip sr tunsrc set fc00:1::1\n      - cmd: ip -6 route add fc00:2::/64 via 2001:12::2\n      - cmd: ip -6 route add fd00:2::/64 encap seg6 mode encap segs fc00:2::10 dev net0\n      - cmd: ip -6 route add fd00:3::/64 encap seg6 mode encap segs fc00:2::20 dev net0\n      - cmd: ip -6 route add fc00:1::10/128 encap seg6local action End.DX6 nh6 fd00:1::2 dev net0\n\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:2::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      - cmd: ip -6 addr add fd00:2::1/64 dev net1\n      - cmd: ip -6 addr add fd00:3::1/64 dev net2\n      - cmd: ip sr tunsrc set fc00:2::1\n      - cmd: ip -6 route add fc00:1::/64 via 2001:12::1\n      - cmd: ip -6 route add fd00:1::/64 encap seg6 mode encap segs fc00:1::10 dev net0\n      - cmd: ip -6 route add fc00:2::10/128 encap seg6local action End.DX6 nh6 fd00:2::2 dev net0\n      - cmd: ip -6 route add fc00:2::20/128 encap seg6local action End.DX6 nh6 fd00:3::2 dev net0\n\n  - name: C1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add fd00:1::2/64 dev net0\n      - cmd: ip -6 route add default via fd00:1::1\n  - name: C2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add fd00:2::2/64 dev net0\n      - cmd: ip -6 route add default via fd00:2::1\n  - name: C3\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add fd00:3::2/64 dev net0\n      - cmd: ip -6 route add default via fd00:3::1\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec R1 ping -c2 2001:12::1\n      - cmd: docker exec R1 ping -c2 2001:12::2\n      - cmd: docker exec R1 ping -c2 fd00:1::1\n      - cmd: docker exec R1 ping -c2 fd00:1::2\n      - cmd: docker exec R2 ping -c2 2001:12::1\n      - cmd: docker exec R2 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 fd00:2::1\n      - cmd: docker exec R2 ping -c2 fd00:2::2\n      - cmd: docker exec R2 ping -c2 fd00:3::1\n      - cmd: docker exec R2 ping -c2 fd00:3::2\n      - cmd: docker exec C1 ping -c2 fd00:1::1\n      - cmd: docker exec C1 ping -c2 fd00:1::2\n      - cmd: docker exec C2 ping -c2 fd00:2::1\n      - cmd: docker exec C2 ping -c2 fd00:2::2\n      - cmd: docker exec C2 ping -c2 fd00:3::1\n      - cmd: docker exec C2 ping -c2 fd00:3::2\n  - name: vpn\n    cmds:\n      - cmd: docker exec C1 ping -c2 fd00:2::2\n      - cmd: docker exec C1 ping -c2 fd00:3::2\n      - cmd: docker exec C2 ping -c2 fd00:1::2\n      - cmd: docker exec C3 ping -c2 fd00:1::2\n\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v6_per_vrf/README.md",
    "content": "\n# VPNv4 per-VRF using SRv6\n- Hiroki Shirokura <slankdev@coe.ad.jp>\n- 2018.12.31\n\n![img](./topo.jpeg)\n\n```\n$ cd tinet/projects/basic_srv6/l3vpn\n$ tn up | sudo sh # create network nodes.\n$ tn conf | sudo sh # execute configuration to each nodes\n$ docker ps # you can check some nodes exist.\n$ tn test p2p | sudo sh # execute point-to-point link's ping.\n$ tn test vpn | sudo sh # execute L3VPN ping.\n```\n"
  },
  {
    "path": "examples/basic_srv6/linux/vpn_v6_per_vrf/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C10#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C20#net0 }\n  - name: C1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: C2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: C10\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n  - name: C20\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:1::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::1/64 dev net0\n      - cmd: ip link add vrf101 type vrf table 101\n      - cmd: ip link add vrf110 type vrf table 110\n      - cmd: ip link set vrf101 up\n      - cmd: ip link set vrf110 up\n      - cmd: ip link set dev net1 master vrf101\n      - cmd: ip link set dev net2 master vrf110\n      - cmd: ip -6 addr add fd00:1::1/64 dev net1\n      - cmd: ip -6 addr add fd00:1::1/64 dev net2\n      - cmd: ip sr tunsrc set fc00:1::1\n      - cmd: ip route add fc00:2::/64 via 2001:12::2\n      - cmd: ip -6 route add fd00:2::/64 encap seg6 mode encap segs fc00:2::101 dev net0 table 101\n      - cmd: ip -6 route add fd00:2::/64 encap seg6 mode encap segs fc00:2::110 dev net0 table 110\n      - cmd: ip -6 route add fc00:1::101/128 encap seg6local action End.DT6 table 101 dev net0\n      - cmd: ip -6 route add fc00:1::110/128 encap seg6local action End.DT6 table 110 dev net0\n\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: ip -6 addr add fc00:2::1/64 dev lo\n      - cmd: ip -6 addr add 2001:12::2/64 dev net0\n      - cmd: ip link add vrf101 type vrf table 101\n      - cmd: ip link add vrf110 type vrf table 110\n      - cmd: ip link set vrf101 up\n      - cmd: ip link set vrf110 up\n      - cmd: ip link set dev net1 master vrf101\n      - cmd: ip link set dev net2 master vrf110\n      - cmd: ip -6 addr add fd00:2::1/64 dev net1\n      - cmd: ip -6 addr add fd00:2::1/64 dev net2\n      - cmd: ip sr tunsrc set fc00:2::1\n      - cmd: ip route add fc00:1::/64 via 2001:12::1\n      - cmd: ip -6 route add fd00:1::/64 encap seg6 mode encap segs fc00:1::101 dev net0 table 101\n      - cmd: ip -6 route add fd00:1::/64 encap seg6 mode encap segs fc00:1::110 dev net0 table 110\n      - cmd: ip -6 route add fc00:2::101/128 encap seg6local action End.DT6 table 101 dev net0\n      - cmd: ip -6 route add fc00:2::110/128 encap seg6local action End.DT6 table 110 dev net0\n\n\n  - name: C1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add fd00:1::2/64 dev net0\n      - cmd: ip route replace default via fd00:1::1\n  - name: C10\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add fd00:1::2/64 dev net0\n      - cmd: ip route replace default via fd00:1::1\n  - name: C2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add fd00:2::2/64 dev net0\n      - cmd: ip route replace default via fd00:2::1\n  - name: C20\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: ip addr add fd00:2::2/64 dev net0\n      - cmd: ip route replace default via fd00:2::1\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: echo TEST-BACKBONE[R1,R2]\n      - cmd: docker exec R1 ping -c2 2001:12::1\n      - cmd: docker exec R1 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 2001:12::1\n      - cmd: docker exec R2 ping -c2 2001:12::2\n      - cmd: echo TEST[R1,C1,C10]\n      - cmd: docker exec R1 ping -c2 -I net1 fd00:1::1\n      - cmd: docker exec R1 ping -c2 -I net1 fd00:1::2\n      - cmd: docker exec R1 ping -c2 -I net2 fd00:1::1\n      - cmd: docker exec R1 ping -c2 -I net2 fd00:1::2\n      - cmd: docker exec C1 ping -c2 fd00:1::1\n      - cmd: docker exec C1 ping -c2 fd00:1::2\n      - cmd: docker exec C10 ping -c2 fd00:1::1\n      - cmd: docker exec C10 ping -c2 fd00:1::2\n      - cmd: echo TEST[R2,C2,C20]\n      - cmd: docker exec R2 ping -c2 -I net1 fd00:2::1\n      - cmd: docker exec R2 ping -c2 -I net1 fd00:2::2\n      - cmd: docker exec R2 ping -c2 -I net2 fd00:2::1\n      - cmd: docker exec R2 ping -c2 -I net2 fd00:2::2\n      - cmd: docker exec C2 ping -c2 fd00:2::1\n      - cmd: docker exec C2 ping -c2 fd00:2::2\n      - cmd: docker exec C20 ping -c2 fd00:2::1\n      - cmd: docker exec C20 ping -c2 fd00:2::2\n  - name: vpn\n    cmds:\n      - cmd: docker exec C1 ping -c2 fd00:2::2\n      - cmd: docker exec C2 ping -c2 fd00:1::2\n      - cmd: docker exec C10 ping -c2 fd00:2::2\n      - cmd: docker exec C20 ping -c2 fd00:1::2\n\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/vrf_redirect/README.md",
    "content": "\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 | sudo sh\n$ tn conf | sudo sh\n$ tn test p2p | sudo sh\n$ tn test blue | sudo sh\n$ tn test green | sudo sh\n```\n\n"
  },
  {
    "path": "examples/basic_srv6/linux/vrf_redirect/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: make -C /home/vagrant/git/srdump install_docker\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n      - { name: net2, type: direct, args: R4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n  - name: R4\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: ip addr add fc00:1::1/64 dev lo\n      - cmd: ip addr add 2001:12::1/64 dev net0\n      - cmd: ip -6 route add default via 2001:12::2\n      ## For fc00:4::/64 reachability for End.T\n      - cmd: ip -6 route add fc00:4::1 encap seg6 mode encap segs fc00:2::10 dev net0\n  - name: R2\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net1.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net1.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net2.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net2.rp_filter=0'\n      - cmd: ip addr add fc00:2::1/64 dev lo\n      - cmd: ip addr add 2001:12::2/64 dev net0\n      - cmd: ip addr add 2001:23::1/64 dev net1\n      - cmd: ip addr add 2001:24::1/64 dev net2\n      - cmd: ip -6 route add fc00:1::1 via 2001:12::1\n      - cmd: ip -6 route add fc00:3::1 via 2001:23::2\n      - cmd: ip -6 route add fc00:4::1 via 2001:24::2\n      ## Add VRF and config net2\n      - cmd: ip -6 route del fc00:4::1\n      - cmd: ip link add vrf10 type vrf table 10\n      - cmd: ip link set dev vrf10 up\n      - cmd: ip link set dev net2 master vrf10\n      - cmd: ip addr add 2001:24::1/64 dev net2\n      - cmd: ip -6 route add fc00:4::1 via 2001:24::2 table 10\n      ## For fc00:4::/64 reachability for End.T\n      - cmd: ip -6 route add fc00:2::10 encap seg6local action End.T table 10 dev net2\n  - name: R3\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: ip addr add fc00:3::1/64 dev lo\n      - cmd: ip addr add 2001:23::2/64 dev net0\n      - cmd: ip -6 route add default via 2001:23::1\n  - name: R4\n    cmds:\n      - cmd: sysctl -w 'net.ipv6.conf.all.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.all.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.all.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.all.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.forwarding=1'\n      - cmd: sysctl -w 'net.ipv6.conf.default.disable_ipv6=0'\n      - cmd: sysctl -w 'net.ipv6.conf.default.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.default.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.lo.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.lo.rp_filter=0'\n      - cmd: sysctl -w 'net.ipv6.conf.net0.seg6_enabled=1'\n      - cmd: sysctl -w 'net.ipv4.conf.net0.rp_filter=0'\n      - cmd: ip addr add fc00:4::1/64 dev lo\n      - cmd: ip addr add 2001:24::2/64 dev net0\n      - cmd: ip -6 route add default via 2001:24::1\n\ntest:\n  - name: p2p\n    cmds:\n      - cmd: docker exec R1 ping -c2 2001:12::1\n      - cmd: docker exec R1 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 2001:12::1\n      - cmd: docker exec R2 ping -c2 2001:12::2\n      - cmd: docker exec R2 ping -c2 2001:23::1\n      - cmd: docker exec R2 ping -c2 2001:23::2\n      - cmd: docker exec R2 ping -c2 -I net2 2001:24::1\n      - cmd: docker exec R2 ping -c2 -I net2 2001:24::2\n      - cmd: docker exec R3 ping -c2 2001:23::1\n      - cmd: docker exec R3 ping -c2 2001:23::2\n      - cmd: docker exec R4 ping -c2 2001:24::1\n      - cmd: docker exec R4 ping -c2 2001:24::2\n  - name: lo\n    cmds:\n      - cmd: docker exec R1 ping -c2 fc00:1::1\n      - cmd: docker exec R1 ping -c2 fc00:2::1\n      - cmd: docker exec R1 ping -c2 fc00:3::1\n      - cmd: docker exec R2 ping -c2 fc00:1::1\n      - cmd: docker exec R2 ping -c2 fc00:2::1\n      - cmd: docker exec R2 ping -c2 fc00:3::1\n      - cmd: docker exec R3 ping -c2 fc00:1::1\n      - cmd: docker exec R3 ping -c2 fc00:2::1\n      - cmd: docker exec R3 ping -c2 fc00:3::1\n  - name: vrf\n    cmds:\n      ## Fail\n      ## - R2 receive packet from net0\n      ## - R2 doesn't forward packet each interfaces\n      ## - So, I check R2 cann't perform End.T\n      - cmd: docker exec R1 ping -c2 fc00:4::1\n\n"
  },
  {
    "path": "examples/basic_srv6/vpp/vpn4_per_ce/README.md",
    "content": "\n# VPNv4 per CE\n\n![](topo.png)\n"
  },
  {
    "path": "examples/basic_srv6/vpp/vpn4_per_ce/spec.yaml",
    "content": "postinit:\n  cmds:\n  - cmd: |\n      cat <<EOF > /tmp/r1_exec.vpp\n      create host-interface name net0\n      create host-interface name net1\n      set int state host-net0 up\n      set int state host-net1 up\n      set int ip addr host-net0 cafe::1/64\n      set int ip addr host-net0 10.10.0.1/24\n      set int ip addr host-net1 10.11.0.1/24\n      ip route add f2::/64 via cafe::2\n      sr localsid address f1::10 behavior end\n      sr localsid address f1::11 behavior end.dx4 host-net1 10.11.0.2\n      set sr encaps source addr f1::0\n      sr policy add bsid 1::0 next f2::10 next f2::11 encap\n      sr steer l3 10.12.0.0/24 via bsid 1::0\n      EOF\n  - cmd: |\n      cat <<EOF > /tmp/r2_exec.vpp\n      create host-interface name net0\n      create host-interface name net1\n      set int state host-net0 up\n      set int state host-net1 up\n      set int ip addr host-net0 cafe::2/64\n      set int ip addr host-net0 10.10.0.2/24\n      set int ip addr host-net1 10.12.0.1/24\n      ip route add f1::/64 via cafe::1\n      sr localsid address f2::10 behavior end\n      sr localsid address f2::11 behavior end.dx4 host-net1 10.12.0.2\n      set sr encaps source addr f2::0\n      sr policy add bsid 1::0 next f1::10 next f1::11 encap\n      sr steer l3 10.11.0.0/24 via bsid 1::0\n      EOF\n  - cmd: docker cp /tmp/r1_exec.vpp R1:/etc/vpp/exec.vpp\n  - cmd: docker cp /tmp/r2_exec.vpp R2:/etc/vpp/exec.vpp\n\nnodes:\n- name: R1\n  image: slankdev/vpp:19.04\n  # image: ligato/vpp-base:master\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: R3#net0 }\n- name: R2\n  image: slankdev/vpp:19.04\n  # image: ligato/vpp-base:master\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n- name: R3\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: R4\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: nohup vpp -c /etc/vpp/startup.conf &\n- name: R2\n  cmds:\n  - cmd: nohup vpp -c /etc/vpp/startup.conf &\n- name: R3\n  cmds:\n  - cmd: ip addr add 10.11.0.2/24 dev net0\n  - cmd: ip route add default via 10.11.0.1\n- name: R4\n  cmds:\n  - cmd: ip addr add 10.12.0.2/24 dev net0\n  - cmd: ip route add default via 10.12.0.1\n"
  },
  {
    "path": "examples/basic_sysctl/README.md",
    "content": "\n# sysctl example\n```\ntinet up | sh\n\ntinet test all | sh\necho R1 sysctl state\ndocker exec R1 sysctl net.ipv4.ip_forward\ndocker exec R1 sysctl net.ipv4.ip_forward_use_pmtu\ndocker exec R1 sysctl net.ipv6.conf.all.forwarding\ndocker exec R1 sysctl net.ipv6.conf.all.disable_ipv6\necho R2 sysctl state\ndocker exec R2 sysctl net.ipv4.ip_forward\ndocker exec R2 sysctl net.ipv4.ip_forward_use_pmtu\ndocker exec R2 sysctl net.ipv6.conf.all.forwarding\ndocker exec R2 sysctl net.ipv6.conf.all.disable_ipv6\n```\n"
  },
  {
    "path": "examples/basic_sysctl/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n    sysctls:\n      - { sysctl: net.ipv4.ip_forward=1 }\n      - { sysctl: net.ipv4.ip_forward_use_pmtu=1 }\n      - { sysctl: net.ipv6.conf.all.forwarding=1 }\n      - { sysctl: net.ipv6.conf.all.disable_ipv6=1 }\n\n  - name: R2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n    sysctls:\n      - { sysctl: net.ipv4.ip_forward=0 }\n      - { sysctl: net.ipv4.ip_forward_use_pmtu=0 }\n      - { sysctl: net.ipv6.conf.all.forwarding=0 }\n      - { sysctl: net.ipv6.conf.all.disable_ipv6=0 }\n\ntest:\n  - name: all\n    cmds:\n      - cmd: echo R1 sysctl state\n      - cmd: docker exec R1 sysctl net.ipv4.ip_forward\n      - cmd: docker exec R1 sysctl net.ipv4.ip_forward_use_pmtu\n      - cmd: docker exec R1 sysctl net.ipv6.conf.all.forwarding\n      - cmd: docker exec R1 sysctl net.ipv6.conf.all.disable_ipv6\n      - cmd: echo R2 sysctl state\n      - cmd: docker exec R2 sysctl net.ipv4.ip_forward\n      - cmd: docker exec R2 sysctl net.ipv4.ip_forward_use_pmtu\n      - cmd: docker exec R2 sysctl net.ipv6.conf.all.forwarding\n      - cmd: docker exec R2 sysctl net.ipv6.conf.all.disable_ipv6\n\n"
  },
  {
    "path": "examples/basic_tc/spec.yaml",
    "content": "# http://www.asciiflow.com\nnodes:                                             \n  - name: C0                                       \n    image: slankdev/ubuntu:18.04                   \n    interfaces:                                    \n      - { name: net0, type: direct, args: C1#net0 }\n  - name: C1                                       \n    image: slankdev/ubuntu:18.04                   \n    interfaces:                                    \n      - { name: net0, type: direct, args: C0#net0 }\n                                                   \nnode_configs:                                      \n  - name: C0                                       \n    cmds:                                          \n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: tc qdisc replace dev net0 root netem delay 10ms\n  - name: C1                                       \n    cmds:                                          \n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: tc qdisc replace dev net0 root netem delay 10ms\n                                                   \ntest:                                              \n  - cmds:                                          \n    - cmd: docker exec C0 ping -c2 10.0.0.2        \n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/Corefile",
    "content": ".:53 {\n\thosts {\n\t\t1.1.1.1 one.example.com\n\t\t2.2.2.2 two.example.com\n\t\t3.3.3.3 three.example.com\n\t\tlog\n\t}\n}\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/Dockerfile.coredns",
    "content": "FROM coredns/coredns\n\n# Use debian-based image just for installing iproute2\nFROM debian:stretch\n\nCOPY --from=0 /coredns /coredns\n\nRUN apt-get update\nRUN apt-get -y install iproute2\n\nEXPOSE 53 53/udp\nENTRYPOINT [\"/coredns\"]\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/Dockerfile.dns-interceptor",
    "content": "FROM golang:stretch\n\nRUN apt-get update\nRUN apt-get install -y gcc iproute2 iptables curl tcpdump\n\nWORKDIR /opt\n\nADD go.mod /opt\nADD go.sum /opt\nADD session-udp.go /opt\nADD main.go /opt\nRUN go build -o /usr/local/bin/dns-interceptor\n\nCMD dns-interceptor\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/README.md",
    "content": "# DNS interception with TPROXY\n\n![](./topo.png)\n\nThis example implements a very simple DNS transparent proxy using TPROXY. It intercepts both of UDP and TCP query and dumps the request/response to stdout.\n\nBuild `dns-interceptor:latest` docker image\n\n```\ntinet build | sudo bash\n```\n\nRun demo\n\n```\ntinet test | sudo bash\n```\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/go.mod",
    "content": "module dns-interceptor\n\ngo 1.17\n\nrequire (\n\tgithub.com/cilium/dns v1.1.4-0.20190417235132-8e25ec9a0ff3\n\tgolang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985\n\tgolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c\n)\n\nrequire (\n\tgithub.com/miekg/dns v1.1.45 // indirect\n\tgolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect\n\tgolang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect\n)\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/go.sum",
    "content": "github.com/cilium/dns v1.1.4-0.20190417235132-8e25ec9a0ff3 h1:wenYMyWJ08dgEUUj0Ija8qdK/V9vL3ThAD5sjOYlFlg=\ngithub.com/cilium/dns v1.1.4-0.20190417235132-8e25ec9a0ff3/go.mod h1:cXN7jgo+gsGlNvQ7Vqu2ELdc3f7i7PPgupHqSkLzzBo=\ngithub.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk=\ngithub.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8=\ngolang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=\ngolang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"net\"\n\t\"syscall\"\n\t\"time\"\n\n\t// Use miekg/dns patched with TPROXY support provided by Cilium.\n\t// Here they summarized the brief overview of what they did.\n\t// https://github.com/cilium/cilium/commit/4eb97b91843981b999f39e4acebf59681571f91f\n\t\"github.com/cilium/dns\"\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc setupTransparentSocket(network, address string, c syscall.RawConn) error {\n\tvar sysErr error\n\n\terr := c.Control(func(fd uintptr) {\n\t\tsysErr = unix.SetsockoptInt(int(fd), unix.SOL_IP, unix.IP_TRANSPARENT, 1)\n\t\tif sysErr != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsysErr = unix.SetsockoptInt(int(fd), unix.SOL_IP, unix.IP_RECVORIGDSTADDR, 1)\n\t\tif sysErr != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsysErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)\n\t\tif sysErr != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsysErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)\n\t\tif sysErr != nil {\n\t\t\treturn\n\t\t}\n\t})\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn sysErr\n}\n\ntype DNSInterceptor struct {\n}\n\nfunc (di *DNSInterceptor) NewFQDNFirewall() {\n}\n\nfunc (di *DNSInterceptor) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {\n\tsrc := w.RemoteAddr().String()\n\tdst := w.LocalAddr().String()\n\tproto := w.LocalAddr().Network()\n\n\tlog.Printf(\"Request (from %s to %s proto %s) ===\\n%s\\n\", src, dst, proto, req.String())\n\n\tvar client *dns.Client\n\tswitch proto {\n\tcase \"udp\":\n\t\tclient = &dns.Client{Net: \"udp\", SingleInflight: false}\n\tcase \"tcp\":\n\t\tclient = &dns.Client{Net: \"tcp\", SingleInflight: false}\n\tdefault:\n\t\tpanic(\"got DNS query from unknown network\")\n\t}\n\n\t// preserve original ID for later response and use another ID for outgoing request\n\torigId := req.Id\n\treq.Id = dns.Id()\n\n\tres, _, err := client.Exchange(req, dst)\n\tif err != nil {\n\t\tlog.Println(\"Failed to forward DNS query\")\n\t\treturn\n\t}\n\n\tlog.Printf(\"Response (from %s to %s proto %s) ===\\n%s\\n\", dst, src, proto, res.String())\n\n\tres.Id = origId\n\tw.WriteMsg(res)\n}\n\nfunc main() {\n\tlistenConf := &net.ListenConfig{\n\t\tControl: setupTransparentSocket,\n\t}\n\n\ttcpListener, err := listenConf.Listen(context.Background(), \"tcp4\", \":53\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tudpListener, err := listenConf.ListenPacket(context.Background(), \"udp4\", \":53\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tdi := &DNSInterceptor{}\n\n\ttcpServer := &dns.Server{\n\t\tNet:      \"tcp4\",\n\t\tListener: tcpListener,\n\t\tHandler:  di,\n\t}\n\n\tudpServer := &dns.Server{\n\t\tNet:        \"udp4\",\n\t\tPacketConn: udpListener,\n\t\tHandler:    di,\n\t\tSessionUDPFactory: &SessionUDPFactory{ipv4Enabled: true, ipv6Enabled: false},\n\t}\n\n\tgo tcpServer.ActivateAndServe()\n\tgo udpServer.ActivateAndServe()\n\n\tlog.Println(\"Listening...\")\n\n\tfor {\n\t\ttime.Sleep(1 * time.Second)\n\t}\n}\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/session-udp.go",
    "content": "// SPDX-License-Identifier: Apache-2.0\n// Copyright 2019 Authors of Cilium\n\npackage main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\t\"log\"\n\t\"strconv\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/cilium/dns\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n\t\"golang.org/x/sys/unix\"\n)\n\n// This is the required size of the OOB buffer to pass to ReadMsgUDP.\nvar udpOOBSize = func() int {\n\tvar hdr unix.Cmsghdr\n\tvar addr unix.RawSockaddrInet6\n\treturn int(unsafe.Sizeof(hdr) + unsafe.Sizeof(addr))\n}()\n\ntype SessionUDPFactory struct {\n\t// A pool for UDP message buffers.\n\tudpPool sync.Pool\n\n\t// ipv4Enabled and ipv6Enabled are used when setting up the proxy sockets\n\t// later, and determine if we bind to 127.0.0.1 and ::1, respectively.\n\t// See SessionUDPFactory.SetSocketOptions\n\tipv4Enabled, ipv6Enabled bool\n}\n\n// sessionUDP implements the dns.SessionUDP, holding the remote address and the associated\n// out-of-band data.\ntype sessionUDP struct {\n\tf     *SessionUDPFactory // owner\n\tconn  *net.UDPConn       // UDP socket for receiving both IPv4 and IPv6\n\traddr *net.UDPAddr\n\tladdr *net.UDPAddr\n\tm     []byte\n\toob   []byte\n}\n\nvar rawconn4 *net.IPConn // raw socket for sending IPv4\nvar rawconn6 *net.IPConn // raw socket for sending IPv6\n\n// Set the socket options needed for tranparent proxying for the listening socket\n// IP(V6)_TRANSPARENT allows socket to receive packets with any destination address/port\n// IP(V6)_RECVORIGDSTADDR tells the kernel to pass the original destination address/port on recvmsg\n// The socket may be receiving both IPv4 and IPv6 data, so set both options, if enabled.\nfunc transparentSetsockopt(fd int, ipv4, ipv6 bool) error {\n\tvar err4, err6 error\n\tif ipv6 {\n\t\terr6 = unix.SetsockoptInt(fd, unix.SOL_IPV6, unix.IPV6_TRANSPARENT, 1)\n\t\tif err6 == nil {\n\t\t\terr6 = unix.SetsockoptInt(fd, unix.SOL_IPV6, unix.IPV6_RECVORIGDSTADDR, 1)\n\t\t}\n\t\tif err6 != nil {\n\t\t\treturn err6\n\t\t}\n\t}\n\tif ipv4 {\n\t\terr4 = unix.SetsockoptInt(fd, unix.SOL_IP, unix.IP_TRANSPARENT, 1)\n\t\tif err4 == nil {\n\t\t\terr4 = unix.SetsockoptInt(fd, unix.SOL_IP, unix.IP_RECVORIGDSTADDR, 1)\n\t\t}\n\t\tif err4 != nil {\n\t\t\treturn err4\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc listenConfig(mark int, ipv4, ipv6 bool) *net.ListenConfig {\n\treturn &net.ListenConfig{\n\t\tControl: func(network, address string, c syscall.RawConn) error {\n\t\t\tvar opErr error\n\t\t\terr := c.Control(func(fd uintptr) {\n\t\t\t\topErr = transparentSetsockopt(int(fd), ipv4, ipv6)\n\t\t\t\tif opErr == nil && mark != 0 {\n\t\t\t\t\topErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_MARK, mark)\n\t\t\t\t}\n\t\t\t\tif opErr == nil {\n\t\t\t\t\topErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)\n\t\t\t\t}\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn opErr\n\t\t}}\n}\n\nfunc bindUDP(addr string, ipv4, ipv6 bool) *net.IPConn {\n\t// Mark outgoing packets as proxy egress return traffic (0x0b00)\n\tconn, err := listenConfig(0xb00, ipv4, ipv6).ListenPacket(context.Background(), \"ip:udp\", addr)\n\tif err != nil {\n\t\tlog.Printf(\"bindUDP failed for address %s\\n\", addr)\n\t\treturn nil\n\t}\n\treturn conn.(*net.IPConn)\n}\n\n// NOTE: udpOnce is used in SetSocketOptions below, but assumes we have a\n// global singleton SessionUDPFactory. This is created in StartDNSProxy in\n// order to have option.Config.EnableIPv{4,6} parsed correctly.\nvar udpOnce sync.Once\n\n// SetSocketOptions set's up 'conn' to be used with a SessionUDP.\nfunc (f *SessionUDPFactory) SetSocketOptions(conn *net.UDPConn) error {\n\t// Set up the raw socket for sending responses.\n\t// - Must use a raw UDP socket for sending responses so that we can send\n\t//   from a specific port without binding to it.\n\t// - The raw UDP socket must be bound to a specific IP address to prevent\n\t//   it receiving ALL UDP packets on the host.\n\t// - We use oob data to override the source IP address when sending\n\t// - Must use separate sockets for IPv4/IPv6, as sending to a v6-mapped\n\t//   v4 address from a socket bound to \"::1\" does not work due to kernel\n\t//   checking that a route exists from the source address before\n\t//   the source address is replaced with the (transparently) changed one\n\tudpOnce.Do(func() {\n\t\tif f.ipv4Enabled {\n\t\t\trawconn4 = bindUDP(\"127.0.0.1\", f.ipv4Enabled, false) // raw socket for sending IPv4\n\t\t}\n\t\tif f.ipv6Enabled {\n\t\t\trawconn6 = bindUDP(\"::1\", false, f.ipv6Enabled) // raw socket for sending IPv6\n\t\t}\n\t})\n\tif (f.ipv4Enabled && rawconn4 == nil) || (f.ipv6Enabled && rawconn6 == nil) {\n\t\treturn fmt.Errorf(\"Unable to open raw UDP sockets for DNS Proxy\")\n\t}\n\treturn nil\n}\n\n// InitPool initializes a pool of buffers to be used with SessionUDP.\nfunc (f *SessionUDPFactory) InitPool(msgSize int) {\n\tf.udpPool.New = func() interface{} {\n\t\treturn &sessionUDP{\n\t\t\tf:   f,\n\t\t\tm:   make([]byte, msgSize),\n\t\t\toob: make([]byte, udpOOBSize),\n\t\t}\n\t}\n}\n\n// ReadRequest reads a single request from 'conn' and returns the request context\nfunc (f *SessionUDPFactory) ReadRequest(conn *net.UDPConn) ([]byte, dns.SessionUDP, error) {\n\ts := f.udpPool.Get().(*sessionUDP)\n\tn, oobn, _, raddr, err := conn.ReadMsgUDP(s.m, s.oob)\n\tif err != nil {\n\t\ts.Discard()\n\t\treturn nil, nil, err\n\t}\n\ts.conn = conn\n\ts.raddr = raddr\n\ts.m = s.m[:n]        // Re-slice to the actual size\n\ts.oob = s.oob[:oobn] // Re-slice to the actual size\n\ts.laddr, err = parseDstFromOOB(s.oob)\n\tif err != nil {\n\t\ts.Discard()\n\t\treturn nil, nil, err\n\t}\n\treturn s.m, s, err\n}\n\n// Discard returns 's' to the factory pool\nfunc (s *sessionUDP) Discard() {\n\ts.conn = nil\n\ts.raddr = nil\n\ts.laddr = nil\n\ts.m = s.m[:cap(s.m)]\n\ts.oob = s.oob[:cap(s.oob)]\n\n\ts.f.udpPool.Put(s)\n}\n\n// RemoteAddr returns the remote network address.\nfunc (s *sessionUDP) RemoteAddr() net.Addr { return s.raddr }\n\n// LocalAddr returns the local network address for the current request.\nfunc (s *sessionUDP) LocalAddr() net.Addr { return s.laddr }\n\n// WriteResponse writes a response to a request received earlier\nfunc (s *sessionUDP) WriteResponse(b []byte) (int, error) {\n\t// Must give the UDP header to get the source port right.\n\t// Reuse the msg buffer, figure out if golang can do gatter-scather IO\n\t// with raw sockets?\n\tl := len(b)\n\tbb := bytes.NewBuffer(s.m[:0])\n\tbinary.Write(bb, binary.BigEndian, uint16(s.laddr.Port))\n\tbinary.Write(bb, binary.BigEndian, uint16(s.raddr.Port))\n\tbinary.Write(bb, binary.BigEndian, uint16(8+l))\n\tbinary.Write(bb, binary.BigEndian, uint16(0)) // checksum\n\tbb.Write(b)\n\tbuf := bb.Bytes()\n\n\tvar n int\n\tvar err error\n\tdst := net.IPAddr{\n\t\tIP: s.raddr.IP,\n\t}\n\tif s.raddr.IP.To4() == nil {\n\t\tn, _, err = rawconn6.WriteMsgIP(buf, s.controlMessage(s.laddr), &dst)\n\t} else {\n\t\tn, _, err = rawconn4.WriteMsgIP(buf, s.controlMessage(s.laddr), &dst)\n\t}\n\tif err != nil {\n\t\tlog.Println(\"WriteMsgIP failed\")\n\t}\n\treturn n, err\n}\n\n// parseDstFromOOB takes oob data and returns the destination IP.\nfunc parseDstFromOOB(oob []byte) (*net.UDPAddr, error) {\n\tmsgs, err := unix.ParseSocketControlMessage(oob)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing socket control message: %s\", err)\n\t}\n\n\tfor _, msg := range msgs {\n\t\tif msg.Header.Level == unix.SOL_IP && msg.Header.Type == unix.IP_ORIGDSTADDR {\n\t\t\tpp := &unix.RawSockaddrInet4{}\n\t\t\t// Address family is in native byte order\n\t\t\tfamily := *(*uint16)(unsafe.Pointer(&msg.Data[unsafe.Offsetof(pp.Family)]))\n\t\t\tif family != unix.AF_INET {\n\t\t\t\treturn nil, fmt.Errorf(\"original destination is not IPv4.\")\n\t\t\t}\n\t\t\t// Port is in big-endian byte order\n\t\t\tif err = binary.Read(bytes.NewReader(msg.Data), binary.BigEndian, pp); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"reading original destination address: %s\", err)\n\t\t\t}\n\t\t\tladdr := &net.UDPAddr{\n\t\t\t\tIP:   net.IPv4(pp.Addr[0], pp.Addr[1], pp.Addr[2], pp.Addr[3]),\n\t\t\t\tPort: int(pp.Port),\n\t\t\t}\n\t\t\treturn laddr, nil\n\t\t}\n\t\tif msg.Header.Level == unix.SOL_IPV6 && msg.Header.Type == unix.IPV6_ORIGDSTADDR {\n\t\t\tpp := &unix.RawSockaddrInet6{}\n\t\t\t// Address family is in native byte order\n\t\t\tfamily := *(*uint16)(unsafe.Pointer(&msg.Data[unsafe.Offsetof(pp.Family)]))\n\t\t\tif family != unix.AF_INET6 {\n\t\t\t\treturn nil, fmt.Errorf(\"original destination is not IPv6.\")\n\t\t\t}\n\t\t\t// Scope ID is in native byte order\n\t\t\tscopeId := *(*uint32)(unsafe.Pointer(&msg.Data[unsafe.Offsetof(pp.Scope_id)]))\n\t\t\t// Rest of the data is big-endian (port)\n\t\t\tif err = binary.Read(bytes.NewReader(msg.Data), binary.BigEndian, pp); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"reading original destination address: %s\", err)\n\t\t\t}\n\t\t\tladdr := &net.UDPAddr{\n\t\t\t\tIP:   net.IP(pp.Addr[:]),\n\t\t\t\tPort: int(pp.Port),\n\t\t\t\tZone: strconv.Itoa(int(scopeId)),\n\t\t\t}\n\t\t\treturn laddr, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"No original destination found!\")\n}\n\n// correctSource returns the oob data with the given source address\nfunc (s *sessionUDP) controlMessage(src *net.UDPAddr) []byte {\n\t// If the src is definitely an IPv6, then use ipv6's ControlMessage to\n\t// respond otherwise use ipv4's because ipv6's marshal ignores ipv4\n\t// addresses.\n\tif src.IP.To4() == nil {\n\t\tcm := new(ipv6.ControlMessage)\n\t\tcm.Src = src.IP\n\t\treturn cm.Marshal()\n\t}\n\tcm := new(ipv4.ControlMessage)\n\tcm.Src = src.IP\n\treturn cm.Marshal()\n}\n"
  },
  {
    "path": "examples/basic_tproxy/dns_interceptor/spec.yaml",
    "content": "nodes:\n- name: C0\n  image: nicolaka/netshoot\n  interfaces:\n  - name: net0\n    type: direct\n    args: R0#net0\n- name: R0\n  image: dns-interceptor:latest\n  buildfile: Dockerfile.dns-interceptor\n  buildcontext: .\n  interfaces:\n  - name: net0\n    type: direct\n    args: C0#net0\n  - name: net1\n    type: direct\n    args: R1#net1\n- name: R1\n  image: nicolaka/netshoot\n  interfaces:\n  - name: net0\n    type: direct\n    args: C1#net0\n  - name: net1\n    type: direct\n    args: R0#net1\n- name: C1\n  image: mycoredns:latest\n  buildfile: Dockerfile.coredns\n  buildcontext: .\n  interfaces:\n  - name: net0\n    type: direct\n    args: R1#net0\n  docker_run_extra_args: \"--mount type=bind,source=$(pwd)/Corefile,target=/Corefile\"\nnode_configs:\n- name: C0\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: R0\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip link set net1 up\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip addr add 192.168.0.1/24 dev net1\n  - cmd: ip route add 10.0.1.0/24 via 192.168.0.2\n  - cmd: ip rule add fwmark 0x1 table 100\n  - cmd: ip route add local 0.0.0.0/0 dev lo table 100\n  - cmd: iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j MARK --set-mark 0x1\n  - cmd: iptables -t mangle -A PREROUTING -p udp -m socket --transparent -j MARK --set-mark 0x1\n  - cmd: iptables -t mangle -A PREROUTING -p tcp --dport 53 -j TPROXY --on-port 53 --tproxy-mark 0x1\n  - cmd: iptables -t mangle -A PREROUTING -p udp --dport 53 -j TPROXY --on-port 53 --tproxy-mark 0x1\n- name: R1\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip link set net1 up\n  - cmd: ip addr add 10.0.1.1/24 dev net0\n  - cmd: ip addr add 192.168.0.2/24 dev net1\n  - cmd: ip route add 10.0.0.0/24 via 192.168.0.1\n- name: C1\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 10.0.1.2/24 dev net0\n  - cmd: ip route add default via 10.0.1.1\ntest:\n- cmds:\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"dig'ing from C0 to C1 with UDP\"\n  - cmd: echo \"===============================================\"\n  - cmd: docker exec C0 dig @10.0.1.2 one.example.com\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"dig'ing from C0 to C1 with TCP\"\n  - cmd: echo \"===============================================\"\n  - cmd: docker exec C0 dig @10.0.1.2 one.example.com +tcp\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"Below shows the log of the proxy server on R0\"\n  - cmd: echo \"===============================================\"\n  - cmd: docker logs R0\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"You should see the proxy surely intercepts\"\n  - cmd: echo \"===============================================\"\n"
  },
  {
    "path": "examples/basic_tproxy/http_interceptor/Dockerfile",
    "content": "FROM golang:stretch\n\nRUN apt-get update\nRUN apt-get install -y iproute2 iptables\n\nWORKDIR /opt\n\nADD go.mod /opt\nADD go.sum /opt\nADD http_interceptor.go /opt\nRUN go build -o /usr/local/bin/http-interceptor\n\nCMD http-interceptor\n"
  },
  {
    "path": "examples/basic_tproxy/http_interceptor/README.md",
    "content": "# Simple TPROXY example\n\n![](./topo.png)\n\nThis example demonstrates the basic cocept of TPROXY (a.k.a. transparent proxy). The very simple proxy server (http_interceptor.c) transparently intercepts the HTTP traffic between C0 and C1 and dumps the request/response to stdout.\n\nBuild `http-interceptor:latest` docker image\n\n```\ntinet build | sudo bash\n```\n\nRun demo\n\n```\ntinet test | sudo bash\n```\n"
  },
  {
    "path": "examples/basic_tproxy/http_interceptor/go.mod",
    "content": "module http-interceptor\n\ngo 1.17\n\nrequire golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27\n"
  },
  {
    "path": "examples/basic_tproxy/http_interceptor/go.sum",
    "content": "golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\n"
  },
  {
    "path": "examples/basic_tproxy/http_interceptor/http_interceptor.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"net\"\n\t\"syscall\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc setupTransparentSocket(network, address string, c syscall.RawConn) error {\n\tvar sysErr error\n\n\terr := c.Control(func(fd uintptr) {\n\t\tsysErr = unix.SetsockoptInt(int(fd), unix.SOL_IP, unix.IP_TRANSPARENT, 1)\n\t\tif sysErr != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsysErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)\n\t\tif sysErr != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsysErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)\n\t\tif sysErr != nil {\n\t\t\treturn\n\t\t}\n\t})\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn sysErr\n}\n\nfunc dialContextWithTransparentSocket(ctx context.Context, network, address string) (net.Conn, error) {\n\treturn (&net.Dialer{\n\t\tControl: setupTransparentSocket,\n\t}).DialContext(ctx, network, address)\n}\n\ntype HTTPInterceptor struct {\n}\n\nfunc (hi *HTTPInterceptor) ServeHTTP(w http.ResponseWriter, req *http.Request) {\n\tsrc := req.RemoteAddr\n\tdst := req.Context().Value(http.LocalAddrContextKey)\n\n\treqBin, err := httputil.DumpRequest(req, true)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to dump http request: %s\\n\", err)\n\t\treturn\n\t}\n\n\tlog.Printf(\"Request (from %s to %s) ===\\n%s\\n\", src, dst, string(reqBin))\n\n\t// We are only listerning on the http (80), so this works\n\treq.RequestURI = \"\"\n\treq.URL.Scheme = \"http\"\n\treq.URL.Host = req.Host\n\n\ttr := &http.Transport{\n\t\tDialContext: dialContextWithTransparentSocket,\n\t}\n\n\tclient := &http.Client{Transport: tr}\n\n\tres, err := client.Do(req)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to forward HTTP request (from %s to %s): %s\\n\", src, dst, err)\n\t\treturn\n\t}\n\n\tdefer res.Body.Close()\n\n\tresBin, err := httputil.DumpResponse(res, true)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to dump http response: %s\\n\", err)\n\t\treturn\n\t}\n\n\tlog.Printf(\"Response (from %s to %s) ===\\n%s\\n\", dst, src, string(resBin))\n\n\tres.Write(w)\n}\n\nfunc main() {\n\tlistenConf := &net.ListenConfig{\n\t\tControl: setupTransparentSocket,\n\t}\n\n\tlistener, err := listenConf.Listen(context.Background(), \"tcp4\", \":80\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tserver := &http.Server{\n\t\tHandler: &HTTPInterceptor{},\n\t}\n\n\tserver.Serve(listener)\n}\n"
  },
  {
    "path": "examples/basic_tproxy/http_interceptor/spec.yaml",
    "content": "nodes:\n- name: C0\n  image: nicolaka/netshoot\n  interfaces:\n  - name: net0\n    type: direct\n    args: R0#net0\n- name: R0\n  image: http-interceptor:latest\n  buildfile: Dockerfile\n  buildcontext: .\n  interfaces:\n  - name: net0\n    type: direct\n    args: C0#net0\n  - name: net1\n    type: direct\n    args: R1#net1\n- name: R1\n  image: nicolaka/netshoot\n  interfaces:\n  - name: net0\n    type: direct\n    args: C1#net0\n  - name: net1\n    type: direct\n    args: R0#net1\n- name: C1\n  image: nicolaka/netshoot\n  interfaces:\n  - name: net0\n    type: direct\n    args: R1#net0\nnode_configs:\n- name: C0\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: R0\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip link set net1 up\n  - cmd: ip addr add 10.0.0.1/24 dev net0\n  - cmd: ip addr add 192.168.0.1/24 dev net1\n  - cmd: ip route add 10.0.1.0/24 via 192.168.0.2\n  - cmd: ip rule add fwmark 0x1 table 100\n  - cmd: ip route add local 0.0.0.0/0 dev lo table 100\n  - cmd: iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j MARK --set-mark 0x1\n  - cmd: iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --on-port 80 --tproxy-mark 0x1\n- name: R1\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip link set net1 up\n  - cmd: ip addr add 10.0.1.1/24 dev net0\n  - cmd: ip addr add 192.168.0.2/24 dev net1\n  - cmd: ip route add 10.0.0.0/24 via 192.168.0.1\n- name: C1\n  cmds:\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 10.0.1.2/24 dev net0\n  - cmd: ip route add default via 10.0.1.1\ntest:\n- cmds:\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"Starting HTTP server on C1\"\n  - cmd: echo \"===============================================\"\n  - cmd: docker exec C1 python3 -m http.server 80 &\n  - cmd: sleep 10\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"curl'ing from C0 to C1\"\n  - cmd: echo \"===============================================\"\n  - cmd: docker exec C0 curl -s http://10.0.1.2\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"Stopping HTTP server on C1\"\n  - cmd: echo \"===============================================\"\n  - cmd: docker exec C1 pkill python3\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"Below shows the log of the proxy server on R0\"\n  - cmd: echo \"===============================================\"\n  - cmd: docker logs R0\n  - cmd: echo \"===============================================\"\n  - cmd: echo \"You should see the proxy surely intercepts\"\n  - cmd: echo \"===============================================\"\n"
  },
  {
    "path": "examples/basic_vpnv4/README.md",
    "content": "\n# BGP-based VPNv4 per vrf\n\nWIP\n\n![](topo.png)\n"
  },
  {
    "path": "examples/basic_vpnv4/spec.yaml",
    "content": "\nprecmd:\n  - cmds:\n      - cmd: export IMAGE=slankdev/frr\n      # - cmd: export IMAGE=slankdev/gobgp\n      # - cmd: export IMAGE=slankdev/ubuntu:18.04\n\nnodes:\n  - name: R1\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C2#net0 }\n  - name: R2\n    image: $IMAGE\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C3#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n  - name: C1\n    image: $IMAGE\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: $IMAGE\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C3\n    image: $IMAGE\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C4\n    image: $IMAGE\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sysctl -w net.ipv4.tcp_l3mdev_accept=1\n      - cmd: sysctl -w net.ipv4.udp_l3mdev_accept=1\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link set dev red up\n      - cmd: ip link set dev blu up\n      - cmd: ip link set net0 vrf red\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.1/32'\n          -c 'interface net0 vrf red'\n          -c ' ip address 10.0.0.1/24'\n          -c 'router bgp 65011 vrf red'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' neighbor 10.0.0.2 remote-as external'\n          -c 'router bgp 65021 vrf blu'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' neighbor 10.0.0.2 remote-as external'\n  - name: R2\n    cmds:\n      - cmd: sysctl -w net.ipv4.tcp_l3mdev_accept=1\n      - cmd: sysctl -w net.ipv4.udp_l3mdev_accept=1\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link set dev red up\n      - cmd: ip link set dev blu up\n      - cmd: ip link set net0 vrf red\n      - cmd: /usr/lib/frr/frr start\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c ' ip address 10.255.0.2/32'\n          -c 'interface net0 vrf red'\n          -c ' ip address 10.0.0.2/24'\n          -c 'router bgp 65012 vrf red'\n          -c ' bgp router-id 10.255.0.2'\n          -c ' neighbor 10.0.0.1 remote-as external'\n          -c 'router bgp 65022 vrf blu'\n          -c ' bgp router-id 10.255.0.1'\n          -c ' neighbor 10.0.0.2 remote-as external'\n\ntest:\n  - name: p2p\n    cmds:\n    - cmd: echo slankdev slankdev\n    - cmd: echo slankdev slankdev\n\n"
  },
  {
    "path": "examples/basic_vpp/README.md",
    "content": "\n# Running VPP on TiNET\n\n![](./topo.png)\n\n"
  },
  {
    "path": "examples/basic_vpp/nat.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/vpp:19.08\n    # image: ligato/vpp-base:master\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: R3\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sh -c \"echo nat { deterministic } >> /etc/vpp/startup.conf\"\n      - cmd: sh -c \"echo create host-interface name net0 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo create host-interface name net1 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int state host-net0 up >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int state host-net1 up >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int ip addr host-net0 10.100.0.1/24 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int ip addr host-net1 192.168.0.1/24 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set interface nat44 in host-net1 out host-net0 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo nat44 deterministic add in 192.168.0.0/24 out 10.100.0.1/32 >> /etc/vpp/exec.vpp\"\n      - cmd: nohup vpp -c /etc/vpp/startup.conf &\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.100.0.2/24 dev net0\n  - name: R3\n    cmds:\n      - cmd: ip addr add 192.168.0.2/24 dev net0\n      - cmd: ip route add default via 192.168.0.1\n\n"
  },
  {
    "path": "examples/basic_vpp/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/vpp:19.08\n    # image: ligato/vpp-base:master\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: R3\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: sh -c \"echo create host-interface name net0 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo create host-interface name net1 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int state host-net0 up >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int state host-net1 up >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int ip addr host-net0 10.100.0.1/24 >> /etc/vpp/exec.vpp\"\n      - cmd: sh -c \"echo set int ip addr host-net1 10.101.0.1/24 >> /etc/vpp/exec.vpp\"\n      - cmd: nohup vpp -c /etc/vpp/startup.conf &\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.100.0.2/24 dev net0\n      - cmd: ip route add default via 10.100.0.1\n  - name: R3\n    cmds:\n      - cmd: ip addr add 10.101.0.2/24 dev net0\n      - cmd: ip route add default via 10.101.0.1\n\n"
  },
  {
    "path": "examples/basic_vrf/README.md",
    "content": "\n# VRF based static VPN\n\n![](./topo.png)\n\nThere are 2 version of this.\n```\n- iproute2.spec.yaml\n- frr.spec.yaml\n```\n"
  },
  {
    "path": "examples/basic_vrf/frr.spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C3\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C4\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n\n      # following operation can't be executed by FRR.\n      - cmd: ip link add link net0 name net0.10 type vlan id 10\n      - cmd: ip link add link net0 name net0.20 type vlan id 20\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link set dev net1 vrf red\n      - cmd: ip link set dev net2 vrf blu\n      - cmd: ip link set dev net0.10 vrf red\n      - cmd: ip link set dev net0.20 vrf blu\n\n      # configure FRR\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int net0.10 vrf red'\n          -c ' ip address 10.10.255.1/24'\n          -c ' no shutdown'\n          -c 'int net0.20 vrf blu'\n          -c ' ip address 10.20.255.1/24'\n          -c ' no shutdown'\n          -c 'int net1 vrf red'\n          -c ' ip address 10.10.1.1/24'\n          -c ' no shutdown'\n          -c 'int net2 vrf blu'\n          -c ' ip address 10.20.1.1/24'\n          -c ' no shutdown'\n          -c 'int red'\n          -c ' no shutdown'\n          -c 'int blu'\n          -c ' no shutdown'\n          -c 'ip route 10.10.2.0/24 10.10.255.2 vrf red'\n          -c 'ip route 10.20.2.0/24 10.20.255.2 vrf blu'\n\n  - name: R2\n    cmds:\n      - cmd: /usr/lib/frr/frr start\n\n      # following operation can't be executed by FRR.\n      - cmd: ip link add link net0 name net0.10 type vlan id 10\n      - cmd: ip link add link net0 name net0.20 type vlan id 20\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link set dev net1 vrf red\n      - cmd: ip link set dev net2 vrf blu\n      - cmd: ip link set dev net0.10 vrf red\n      - cmd: ip link set dev net0.20 vrf blu\n\n      # configure FRR\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'int net0.10 vrf red'\n          -c ' ip address 10.10.255.2/24'\n          -c ' no shutdown'\n          -c 'int net0.20 vrf blu'\n          -c ' ip address 10.20.255.2/24'\n          -c ' no shutdown'\n          -c 'int net1 vrf red'\n          -c ' ip address 10.10.2.1/24'\n          -c ' no shutdown'\n          -c 'int net2 vrf blu'\n          -c ' ip address 10.20.2.1/24'\n          -c ' no shutdown'\n          -c 'int red'\n          -c ' no shutdown'\n          -c 'int blu'\n          -c ' no shutdown'\n          -c 'ip route 10.10.1.0/24 10.10.255.1 vrf red'\n          -c 'ip route 10.20.1.0/24 10.20.255.1 vrf blu'\n\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.10.1.2/24 dev net0\n      - cmd: ip route add default via 10.10.1.1\n  - name: C2\n    cmds:\n      - cmd: ip addr add 10.10.2.2/24 dev net0\n      - cmd: ip route add default via 10.10.2.1\n  - name: C3\n    cmds:\n      - cmd: ip addr add 10.20.1.2/24 dev net0\n      - cmd: ip route add default via 10.20.1.1\n  - name: C4\n    cmds:\n      - cmd: ip addr add 10.20.2.2/24 dev net0\n      - cmd: ip route add default via 10.20.2.1\n\ntest:\n  - name: remote\n    cmds:\n    - cmd: docker exec C1 ping -c2 10.10.2.2\n    - cmd: docker exec C2 ping -c2 10.10.1.2\n    - cmd: docker exec C3 ping -c2 10.20.2.2\n    - cmd: docker exec C4 ping -c2 10.20.1.2\n\n"
  },
  {
    "path": "examples/basic_vrf/iproute2.spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C3\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C4\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: ip link add link net0 name net0.10 type vlan id 10\n      - cmd: ip link add link net0 name net0.20 type vlan id 20\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link set dev net1 vrf red\n      - cmd: ip link set dev net2 vrf blu\n      - cmd: ip link set dev net0.10 vrf red\n      - cmd: ip link set dev net0.20 vrf blu\n      - cmd: ip link set dev red up\n      - cmd: ip link set dev blu up\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev net0.10 up\n      - cmd: ip link set dev net0.20 up\n\n      - cmd: ip addr add 10.10.255.1/24 dev net0.10\n      - cmd: ip addr add 10.20.255.1/24 dev net0.20\n      - cmd: ip addr add 10.10.1.1/24 dev net1\n      - cmd: ip addr add 10.20.1.1/24 dev net2\n      - cmd: ip route add 10.10.2.0/24 via 10.10.255.2 vrf red\n      - cmd: ip route add 10.20.2.0/24 via 10.20.255.2 vrf blu\n\n  - name: R2\n    cmds:\n      - cmd: ip link add link net0 name net0.10 type vlan id 10\n      - cmd: ip link add link net0 name net0.20 type vlan id 20\n      - cmd: ip link add red type vrf table 10\n      - cmd: ip link add blu type vrf table 20\n      - cmd: ip link set dev net1 vrf red\n      - cmd: ip link set dev net2 vrf blu\n      - cmd: ip link set dev net0.10 vrf red\n      - cmd: ip link set dev net0.20 vrf blu\n      - cmd: ip link set dev red up\n      - cmd: ip link set dev blu up\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev net0.10 up\n      - cmd: ip link set dev net0.20 up\n\n      - cmd: ip addr add 10.10.255.2/24 dev net0.10\n      - cmd: ip addr add 10.20.255.2/24 dev net0.20\n      - cmd: ip addr add 10.10.2.1/24 dev net1\n      - cmd: ip addr add 10.20.2.1/24 dev net2\n      - cmd: ip route add 10.10.1.0/24 via 10.10.255.1 vrf red\n      - cmd: ip route add 10.20.1.0/24 via 10.20.255.1 vrf blu\n\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.10.1.2/24 dev net0\n      - cmd: ip route add default via 10.10.1.1\n  - name: C2\n    cmds:\n      - cmd: ip addr add 10.10.2.2/24 dev net0\n      - cmd: ip route add default via 10.10.2.1\n  - name: C3\n    cmds:\n      - cmd: ip addr add 10.20.1.2/24 dev net0\n      - cmd: ip route add default via 10.20.1.1\n  - name: C4\n    cmds:\n      - cmd: ip addr add 10.20.2.2/24 dev net0\n      - cmd: ip route add default via 10.20.2.1\n\ntest:\n  - name: remote\n    cmds:\n    - cmd: docker exec C1 ping -c2 10.10.2.2\n    - cmd: docker exec C2 ping -c2 10.10.1.2\n    - cmd: docker exec C3 ping -c2 10.20.2.2\n    - cmd: docker exec C4 ping -c2 10.20.1.2\n\n"
  },
  {
    "path": "examples/basic_vrf2/spec.yaml",
    "content": "\nnodes:\n- name: R1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n  - { name: net2, type: direct, args: C3#net0 }\n- name: R2\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C2#net0 }\n  - { name: net2, type: direct, args: C4#net0 }\n  - { name: net3, type: direct, args: C0#net0 }\n\n- name: C0\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\n- name: C1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n- name: C3\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: C4\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip link add link net0 name net0.10 type vlan id 10\n  - cmd: ip link add link net0 name net0.20 type vlan id 20\n  - cmd: ip link set net0.10 up\n  - cmd: ip link set net0.20 up\n  - cmd: ip addr add 10.0.0.1/24 dev net0.10\n  - cmd: ip addr add 10.0.0.1/24 dev net0.20\n\n  - cmd: ip link add vrf10 type vrf table 10\n  - cmd: ip link add vrf20 type vrf table 20\n  - cmd: ip link set vrf10 up\n  - cmd: ip link set vrf20 up\n\n  - cmd: ip link set net0.10 vrf vrf10\n  - cmd: ip link set net1 vrf vrf10\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n  - cmd: ip route add 10.2.0.0/24 via 10.0.0.2 dev net0.10 vrf vrf10\n\n  - cmd: ip link set net0.20 vrf vrf20\n  - cmd: ip link set net2 vrf vrf20\n  - cmd: ip addr add 10.1.0.1/24 dev net2\n  - cmd: ip route add 10.2.0.0/24 via 10.0.0.2 dev net0.20 vrf vrf20\n\n- name: R2\n  cmds:\n  - cmd: ip link add link net0 name net0.10 type vlan id 10\n  - cmd: ip link add link net0 name net0.20 type vlan id 20\n  - cmd: ip link set net0.10 up\n  - cmd: ip link set net0.20 up\n  - cmd: ip addr add 10.0.0.2/24 dev net0.10\n  - cmd: ip addr add 10.0.0.2/24 dev net0.20\n\n  - cmd: ip link add vrf10 type vrf table 10\n  - cmd: ip link add vrf20 type vrf table 20\n  - cmd: ip link set vrf10 up\n  - cmd: ip link set vrf20 up\n\n  - cmd: ip link set net0.10 vrf vrf10\n  - cmd: ip link set net1 vrf vrf10\n  - cmd: ip addr add 10.2.0.1/24 dev net1\n  - cmd: ip route add 10.1.0.0/24 via 10.0.0.1 dev net0.10 vrf vrf10\n\n  - cmd: ip link set net0.20 vrf vrf20\n  - cmd: ip link set net2 vrf vrf20\n  - cmd: ip addr add 10.2.0.1/24 dev net2\n  - cmd: ip route add 10.1.0.0/24 via 10.0.0.1 dev net0.20 vrf vrf20\n\n  - cmd: ip link add vrf90 type vrf table 90\n  - cmd: ip link set vrf90 up\n  - cmd: ip link set net3 vrf vrf90\n  - cmd: ip link set net3 up\n  - cmd: ip addr add 10.2.0.1/24 dev net3\n  - cmd: iptables -t raw -A PREROUTING -s 10.1.0.2/32 -p udp --dport 1000 -j MARK --set-mark 0x10\n  - cmd: ip rule add prio 100 fwmark 0x10 lookup 90\n  - cmd: ip route add default dev vrf10\n\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n- name: C3\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n- name: C4\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n\n- name: C0\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n"
  },
  {
    "path": "examples/basic_vrrp/conntrack/keepalived.conf.R1",
    "content": "#\n# Simple script for primary-backup setups\n#\n\nvrrp_sync_group G1 {   # must be before vrrp_instance declaration\n  group {\n    VI_1\n    VI_2\n  }\n  #notify_master \"/etc/conntrackd/primary-backup.sh primary\"\n  #notify_backup \"/etc/conntrackd/primary-backup.sh backup\"\n  #notify_fault \"/etc/conntrackd/primary-backup.sh fault\"\n}\n\nvrrp_instance VI_1 {\n    interface net0\n    state SLAVE\n    virtual_router_id 61\n    priority 80\n    advert_int 3\n    virtual_ipaddress {\n        10.0.0.254/24 brd 10.0.0.255\n    }\n}\n\nvrrp_instance VI_2 {\n    interface net1\n    state SLAVE\n    virtual_router_id 62\n    priority 80\n    advert_int 3\n    virtual_ipaddress {\n        10.1.0.254/24 brd 10.1.0.255\n    }\n}\n"
  },
  {
    "path": "examples/basic_vrrp/conntrack/keepalived.conf.R2",
    "content": "global_defs {\n}\nvrrp_instance VI_1 {\n    state MASTER\n    interface net0\n    virtual_router_id 52\n    priority 100\n    advert_int 1\n    virtual_ipaddress {\n        10.0.0.254/24\n    }\n}\n"
  },
  {
    "path": "examples/basic_vrrp/conntrack/spec.yaml",
    "content": "\npostinit:\n  - cmds:\n    - cmd: docker exec R1 mkdir -p /etc/keepalived\n    - cmd: docker exec R2 mkdir -p /etc/keepalived\n    - cmd: docker cp keepalived.conf.R1 R1:/etc/keepalived/keepalived.conf\n    - cmd: docker cp keepalived.conf.R2 R2:/etc/keepalived/keepalived.conf\n\nnodes:\n  - name: R1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: bridge, args: S1 }\n      - { name: net1, type: bridge, args: S2 }\n  - name: R2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: bridge, args: S1 }\n      - { name: net1, type: bridge, args: S2 }\n\n  - name: C1\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: bridge, args: S1 }\n  - name: C2\n    image: slankdev/conntrack:centos-7\n    interfaces:\n      - { name: net0, type: bridge, args: S2 }\n\nswitches:\n  - name: S1\n    interfaces:\n      - { name: net0, type: docker, args: R1 }\n      - { name: net0, type: docker, args: R2 }\n      - { name: net0, type: docker, args: C1 }\n  - name: S2\n    interfaces:\n      - { name: net1, type: docker, args: R1 }\n      - { name: net1, type: docker, args: R2 }\n      - { name: net0, type: docker, args: C2 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 10.1.0.1/24 dev net1\n      - cmd: keepalived -f /etc/keepalived/keepalived.conf\n\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip addr add 10.1.0.2/24 dev net1\n      - cmd: keepalived -f /etc/keepalived/keepalived.conf\n\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.0.0.10/24 dev net0\n      - cmd: ip route add default via 10.0.0.254\n  - name: C2\n    cmds:\n      - cmd: ip addr add 10.1.0.10/24 dev net0\n      - cmd: ip route add default via 10.1.0.254\n\n"
  },
  {
    "path": "examples/basic_vrrp/simple/spec.yaml",
    "content": "\n# DESCRIPTION: Keepalived test\n#\n# TOPO:\n#\n#                 .2   .2\n#   10.0.0.0/24    +---------+    10.1.0.0/24\n#         +--[net0]|   S0    |[net1]--+\n#         |        | 1.1.1.1 |        |\n#       .1|        +---------+        |.2\n#      [net0]                       [net0]\n#   +---------+                  +---------+\n#   |    R0   |                  |    R1   |\n#   | 2.2.2.2 |Master       Slave| 3.3.3.3 |\n#   +---------+      (vip).1     +---------+\n#      [net1]                       [net1]\n#      .10|                           |.11\n#         +------------B0-------------+\n#                      |        192.168.0.0/24\n#                  .100|\n#                   [net0]\n#                  +------+\n#                  |  C0  |\n#                  +------+\n#\n\n\nnodes:\n  - name: R0\n    # image: slankdev/frr\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: S0#net0 }\n      - { name: net1, type: bridge, args: B0 }\n  - name: R1\n    # image: slankdev/frr\n    image: tmp\n    interfaces:\n      - { name: net0, type: direct, args: S0#net1 }\n      - { name: net1, type: bridge, args: B0 }\n  - name: S0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R0#net0 }\n      - { name: net1, type: direct, args: R1#net0 }\n  - name: C0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: B0 }\n\nswitches:\n  - name: B0\n    interfaces:\n      - { type: container, args: R0, name: net1 }\n      - { type: container, args: R1, name: net1 }\n      - { type: container, args: C0, name: net0 }\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: echo R0 config\n      - cmd: ip addr add 2.2.2.2/32 dev lo\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 192.168.0.10/24 dev net1\n      - cmd: ip route add 1.1.1.1 via 10.0.0.2\n      - cmd: >-\n            iptables -t nat -A POSTROUTING\n            -s 192.168.0.0/24 -j MASQUERADE\n      - cmd: mkdir -p /etc/keepalived/\n      - cmd: bash -c 'echo \"global_defs {            \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"}                        \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"vrrp_instance VI_1 {     \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    state MASTER         \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    interface net1       \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    virtual_router_id 51 \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    priority 200         \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    advert_int 1         \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    virtual_ipaddress {  \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"        192.168.0.1/24   \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    }                    \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"}                        \" >> /etc/keepalived/keepalived.conf'\n      - cmd: keepalived\n\n  - name: R1\n    cmds:\n      - cmd: echo R1 config\n      - cmd: ip addr add 3.3.3.3/32 dev lo\n      - cmd: ip addr add 10.1.0.1/24 dev net0\n      - cmd: ip addr add 192.168.0.11/24 dev net1\n      - cmd: ip route add 1.1.1.1 via 10.1.0.2\n      - cmd: >-\n            iptables -t nat -A POSTROUTING\n            -s 192.168.0.0/24 -j MASQUERADE\n      - cmd: mkdir -p /etc/keepalived/\n      - cmd: bash -c 'echo \"global_defs {            \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"}                        \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"vrrp_instance VI_1 {     \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    state MASTER         \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    interface net1       \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    virtual_router_id 51 \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    priority 100         \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    advert_int 1         \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    virtual_ipaddress {  \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"        192.168.0.1/24   \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"    }                    \" >> /etc/keepalived/keepalived.conf'\n      - cmd: bash -c 'echo \"}                        \" >> /etc/keepalived/keepalived.conf'\n      - cmd: keepalived\n\n  - name: S0\n    cmds:\n      - cmd: echo S0 config\n      - cmd: ip addr add 1.1.1.1/32 dev lo\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip addr add 10.1.0.2/24 dev net1\n  - name: C0\n    cmds:\n      - cmd: echo C0 config\n      - cmd: ip addr add 192.168.0.100/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.0.1\n\ntest:\n  - cmds:\n      - cmd: echo ping\n      - cmd: docker exec R0 ping -c2 10.0.0.1\n      - cmd: docker exec R0 ping -c2 10.0.0.2\n      - cmd: docker exec R0 ping -c2 192.168.0.10\n      - cmd: docker exec R0 ping -c2 192.168.0.11\n      - cmd: docker exec R0 ping -c2 192.168.0.100\n      - cmd: docker exec R1 ping -c2 10.1.0.1\n      - cmd: docker exec R1 ping -c2 10.1.0.2\n      - cmd: docker exec R1 ping -c2 192.168.0.11\n      - cmd: docker exec R1 ping -c2 192.168.0.10\n      - cmd: docker exec R1 ping -c2 192.168.0.100\n      - cmd: docker exec S0 ping -c2 10.0.0.2\n      - cmd: docker exec S0 ping -c2 10.0.0.1\n      - cmd: docker exec S0 ping -c2 10.1.0.2\n      - cmd: docker exec S0 ping -c2 10.1.0.1\n      - cmd: docker exec C0 ping -c2 192.168.0.100\n      - cmd: docker exec C0 ping -c2 192.168.0.10\n      - cmd: docker exec C0 ping -c2 192.168.0.11\n\n"
  },
  {
    "path": "examples/basic_vxlan/vxlan_mcast.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C3#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C3\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C4\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n\nswitches:\n  - name: BB_SW\n    interfaces:\n      - { name: net0, type: container, args: R1 }\n      - { name: net0, type: container, args: R2 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:01:00\n      - cmd: ip link set net1 address 52:54:00:aa:01:01\n      - cmd: ip link set net2 address 52:54:00:aa:01:02\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 10.100.0.1/16 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan\n          id 100 dstport 4789\n          group 239.0.1.1 dev net0\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 10.200.0.1/16 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan\n          id 200 dstport 4789\n          group 239.0.1.1 dev net0\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: ip addr add 10.255.0.1/32 dev lo\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip route add 10.255.0.2/32 via 10.0.0.2\n\n  - name: R2\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:02:00\n      - cmd: ip link set net1 address 52:54:00:aa:02:01\n      - cmd: ip link set net2 address 52:54:00:aa:02:02\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 10.100.0.2/16 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan\n          id 100 dstport 4789\n          group 239.0.1.1 dev net0\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 10.200.0.2/16 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan\n          id 200 dstport 4789\n          group 239.0.1.1 dev net0\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: ip addr add 10.255.0.2/32 dev lo\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route add 10.255.0.1/32 via 10.0.0.1\n\n  - name: C1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:01:00\n      - cmd: ip addr add 10.100.1.1/16 dev net0\n  - name: C2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:02:00\n      - cmd: ip addr add 10.200.1.2/16 dev net0\n  - name: C3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:03:00\n      - cmd: ip addr add 10.100.2.3/16 dev net0\n  - name: C4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:04:00\n      - cmd: ip addr add 10.200.2.4/16 dev net0\n\n\n"
  },
  {
    "path": "examples/basic_vxlan/vxlan_ucast.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C3#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C3\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C4\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n\nswitches:\n  - name: BB_SW\n    interfaces:\n      - { name: net0, type: container, args: R1 }\n      - { name: net0, type: container, args: R2 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:01:00\n      - cmd: ip link set net1 address 52:54:00:aa:01:01\n      - cmd: ip link set net2 address 52:54:00:aa:01:02\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 10.100.0.1/16 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan\n          id 100 dstport 4789\n          local 10.0.0.1 remote 10.0.0.2\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 10.200.0.1/16 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan\n          id 200 dstport 4789\n          local 10.0.0.1 remote 10.0.0.2\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: ip addr add 10.255.0.1/32 dev lo\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip route add 10.255.0.2/32 via 10.0.0.2\n\n  - name: R2\n    cmds:\n\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:02:00\n      - cmd: ip link set net1 address 52:54:00:aa:02:01\n      - cmd: ip link set net2 address 52:54:00:aa:02:02\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 10.100.0.2/16 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan\n          id 100 dstport 4789\n          local 10.0.0.2 remote 10.0.0.1\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 10.200.0.2/16 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan\n          id 200 dstport 4789\n          local 10.0.0.2 remote 10.0.0.1\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: ip addr add 10.255.0.2/32 dev lo\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip route add 10.255.0.1/32 via 10.0.0.1\n\n  - name: C1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:01:00\n      - cmd: ip addr add 10.100.1.1/16 dev net0\n  - name: C2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:02:00\n      - cmd: ip addr add 10.200.1.2/16 dev net0\n  - name: C3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:03:00\n      - cmd: ip addr add 10.100.2.3/16 dev net0\n  - name: C4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:04:00\n      - cmd: ip addr add 10.200.2.4/16 dev net0\n\n\n"
  },
  {
    "path": "examples/basic_vxlan_mcast_v6/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C3#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C5#net0 }\n      - { name: net2, type: direct, args: C6#net0 }\n\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C3\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C4\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n  - name: C5\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R3#net1 } ]\n  - name: C6\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R3#net2 } ]\n\nswitches:\n  - name: BB_SW\n    interfaces:\n      - { name: net0, type: container, args: R1 }\n      - { name: net0, type: container, args: R2 }\n      - { name: net0, type: container, args: R3 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:01:00\n      - cmd: ip link set net1 address 52:54:00:aa:01:01\n      - cmd: ip link set net2 address 52:54:00:aa:01:02\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 2001:111::1/64 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 group ff08::1 dev net0\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 2001:222::1/64 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 group ff08::2 dev net0\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n  - name: R2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:02:00\n      - cmd: ip link set net1 address 52:54:00:aa:02:01\n      - cmd: ip link set net2 address 52:54:00:aa:02:02\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 2001:111::2/64 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 group ff08::1 dev net0\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 2001:222::2/64 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 group ff08::2 dev net0\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n  - name: R3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:03:00\n      - cmd: ip link set net1 address 52:54:00:aa:03:01\n      - cmd: ip link set net2 address 52:54:00:aa:03:02\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: ip addr add 2001:111::3/64 dev br100\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 group ff08::1 dev net0\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: ip addr add 2001:222::3/64 dev br200\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 group ff08::2 dev net0\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n  - name: C1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:01:00\n      - cmd: ip addr add 2001:111::c1/64 dev net0\n  - name: C2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:02:00\n      - cmd: ip addr add 2001:222::c2/64 dev net0\n  - name: C3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:03:00\n      - cmd: ip addr add 2001:111::c3/64 dev net0\n  - name: C4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:04:00\n      - cmd: ip addr add 2001:222::c4/64 dev net0\n  - name: C5\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:05:00\n      - cmd: ip addr add 2001:111::c5/64 dev net0\n  - name: C6\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:06:00\n      - cmd: ip addr add 2001:222::c6/64 dev net0\n\ntest:\n  - cmds:\n    - cmd: docker exec C1 ping -c2 2001:111::c3\n    - cmd: docker exec C1 ping -c2 2001:111::c5\n    - cmd: docker exec C3 ping -c2 2001:111::c5\n    - cmd: docker exec C2 ping -c2 2001:222::c4\n    - cmd: docker exec C2 ping -c2 2001:222::c6\n    - cmd: docker exec C4 ping -c2 2001:222::c6\n\n\n"
  },
  {
    "path": "examples/basic_vxlan_v6/README.md",
    "content": "\n# VXLAN over IPv6\n\n![](./topo.png)"
  },
  {
    "path": "examples/basic_vxlan_v6/spec.yaml",
    "content": "\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: C2#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C3#net0 }\n      - { name: net2, type: direct, args: C4#net0 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: bridge, args: BB_SW }\n      - { name: net1, type: direct, args: C5#net0 }\n      - { name: net2, type: direct, args: C6#net0 }\n\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net1 } ]\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R1#net2 } ]\n  - name: C3\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net1 } ]\n  - name: C4\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R2#net2 } ]\n  - name: C5\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R3#net1 } ]\n  - name: C6\n    image: slankdev/ubuntu:18.04\n    interfaces: [ { name: net0, type: direct, args: R3#net2 } ]\n\nswitches:\n  - name: BB_SW\n    interfaces:\n      - { name: net0, type: container, args: R1 }\n      - { name: net0, type: container, args: R2 }\n      - { name: net0, type: container, args: R3 }\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:01:00\n      - cmd: ip link set net1 address 52:54:00:aa:01:01\n      - cmd: ip link set net2 address 52:54:00:aa:01:02\n\n      - cmd: ip addr add 2001:aaa::1 dev lo\n      - cmd: ip addr add 2001::1/64 dev net0\n      - cmd: ip route add 2001:bbb::1 via 2001::2 dev net0\n      - cmd: ip route add 2001:ccc::1 via 2001::3 dev net0\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 local 2001:aaa::1\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 local 2001:aaa::1\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: bridge fdb add 00:00:00:00:00:00 dev vxlan100 self dst 2001:bbb::1 vni 100 port 4789\n      - cmd: bridge fdb append 00:00:00:00:00:00 dev vxlan100 self dst 2001:ccc::1 vni 100 port 4789\n      - cmd: bridge fdb add 00:00:00:00:00:00 dev vxlan200 self dst 2001:bbb::1 vni 200 port 4789\n      - cmd: bridge fdb append 00:00:00:00:00:00 dev vxlan200 self dst 2001:ccc::1 vni 200 port 4789\n\n  - name: R2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:02:00\n      - cmd: ip link set net1 address 52:54:00:aa:02:01\n      - cmd: ip link set net2 address 52:54:00:aa:02:02\n\n      - cmd: ip addr add 2001:bbb::1 dev lo\n      - cmd: ip addr add 2001::2/64 dev net0\n      - cmd: ip route add 2001:aaa::1 via 2001::1 dev net0\n      - cmd: ip route add 2001:ccc::1 via 2001::3 dev net0\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 local 2001:bbb::1\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 local 2001:bbb::1\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: bridge fdb add 00:00:00:00:00:00 dev vxlan100 self dst 2001:aaa::1 vni 100 port 4789\n      - cmd: bridge fdb append 00:00:00:00:00:00 dev vxlan100 self dst 2001:ccc::1 vni 100 port 4789\n      - cmd: bridge fdb add 00:00:00:00:00:00 dev vxlan200 self dst 2001:aaa::1 vni 200 port 4789\n      - cmd: bridge fdb append 00:00:00:00:00:00 dev vxlan200 self dst 2001:ccc::1 vni 200 port 4789\n\n  - name: R3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:aa:03:00\n      - cmd: ip link set net1 address 52:54:00:aa:03:01\n      - cmd: ip link set net2 address 52:54:00:aa:03:02\n\n      - cmd: ip addr add 2001:ccc::1 dev lo\n      - cmd: ip addr add 2001::3/64 dev net0\n      - cmd: ip route add 2001:aaa::1 via 2001::1 dev net0\n      - cmd: ip route add 2001:bbb::1 via 2001::2 dev net0\n\n      - cmd: ip link add br100 type bridge\n      - cmd: ip link set dev br100 up\n      - cmd: >-\n          ip link add vxlan100 type vxlan id 100\n          dstport 4789 local 2001:ccc::1\n\n      - cmd: ip link add br200 type bridge\n      - cmd: ip link set dev br200 up\n      - cmd: >-\n          ip link add vxlan200 type vxlan id 200\n          dstport 4789 local 2001:ccc::1\n\n      - cmd: ip link set dev net1 master br100\n      - cmd: ip link set dev net1 promisc on\n      - cmd: ip link set dev net1 up\n      - cmd: ip link set dev vxlan100 master br100\n      - cmd: ip link set dev vxlan100 promisc on\n      - cmd: ip link set dev vxlan100 up\n\n      - cmd: ip link set dev net2 master br200\n      - cmd: ip link set dev net2 promisc on\n      - cmd: ip link set dev net2 up\n      - cmd: ip link set dev vxlan200 master br200\n      - cmd: ip link set dev vxlan200 promisc on\n      - cmd: ip link set dev vxlan200 up\n\n      - cmd: bridge fdb add 00:00:00:00:00:00 dev vxlan100 self dst 2001:aaa::1 vni 100 port 4789\n      - cmd: bridge fdb append 00:00:00:00:00:00 dev vxlan100 self dst 2001:bbb::1 vni 100 port 4789\n      - cmd: bridge fdb add 00:00:00:00:00:00 dev vxlan200 self dst 2001:aaa::1 vni 200 port 4789\n      - cmd: bridge fdb append 00:00:00:00:00:00 dev vxlan200 self dst 2001:bbb::1 vni 200 port 4789\n\n  - name: C1\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:01:00\n      - cmd: ip addr add 2001:111::c1/64 dev net0\n  - name: C2\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:02:00\n      - cmd: ip addr add 2001:222::c2/64 dev net0\n  - name: C3\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:03:00\n      - cmd: ip addr add 2001:111::c3/64 dev net0\n  - name: C4\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:04:00\n      - cmd: ip addr add 2001:222::c4/64 dev net0\n  - name: C5\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:05:00\n      - cmd: ip addr add 2001:111::c5/64 dev net0\n  - name: C6\n    cmds:\n      - cmd: bash -c \"enable_seg6_router.py | sh\"\n      - cmd: ip link set net0 address 52:54:00:bb:06:00\n      - cmd: ip addr add 2001:222::c6/64 dev net0\n\ntest:\n  - cmds:\n    - cmd: docker exec C1 ping -c2 2001:111::c3\n    - cmd: docker exec C1 ping -c2 2001:111::c5\n    - cmd: docker exec C3 ping -c2 2001:111::c5\n    - cmd: docker exec C2 ping -c2 2001:222::c4\n    - cmd: docker exec C2 ping -c2 2001:222::c6\n    - cmd: docker exec C4 ping -c2 2001:222::c6\n"
  },
  {
    "path": "examples/basic_xdp/Dockerfile",
    "content": "\nFROM slankdev/ubuntu:18.04\n\nRUN apt update \\\n && apt install -y libc6-dev-i386 clang\n\n\n"
  },
  {
    "path": "examples/basic_xdp/Makefile",
    "content": "\nall:\n\tclang -O2 -Wall -target bpf -c filter.c\n"
  },
  {
    "path": "examples/basic_xdp/filter.c",
    "content": "#include <linux/bpf.h>\n#ifndef __section\n#define __section(NAME) \\\n  __attribute__((section(NAME), used))\n#endif\n\n__section(\"prog\")\nint filter(struct xdp_md *ctx) \n{ \n  /* return XDP_DROP;  */\n  return XDP_TX; \n}\nchar __license[] __section(\"license\") = \"GPL\";\n"
  },
  {
    "path": "examples/basic_xdp/spec.yaml",
    "content": "# http://www.asciiflow.com\n\npreinit:\n  - cmds:\n    - cmd: docker build -t xdptmp .\n\nnodes:\n  - name: C0\n    image: xdptmp\n    interfaces:\n      - { name: net0, type: direct, args: C1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: C0#net0 }\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: C0#net1 }\n\npreconf:\n  - cmds:\n    - cmd: docker cp filter.c C0:/root/filter.c\n\nnode_configs:\n  - name: C0\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: clang -O2 -Wall -target bpf -c /root/filter.c\n      - cmd: ip link set net0 xdp obj filter.o\n  - name: C1\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n\ntest:\n  - cmds:\n    - cmd: docker exec C0 ping -c2 10.0.0.2\n"
  },
  {
    "path": "examples/bgp_test/dut.conf",
    "content": "!\ninterface port-0-6-0\n ip address 10.2.0.2/24\n ipv6 nd suppress-ra\n no link-detect\n!\ninterface port-0-7-0\n ip address 10.3.0.2/24\n ipv6 nd suppress-ra\n no link-detect\n!\ninterface port-0-8-0\n ip address 192.168.20.1/24\n ipv6 nd suppress-ra\n no link-detect\n!\nrouter bgp 400\n bgp router-id 4.4.4.4\n network 10.2.0.0/24\n network 10.3.0.0/24\n network 192.168.20.0/24\n neighbor 10.2.0.1 remote-as 200\n neighbor 10.3.0.1 remote-as 300\n!\n"
  },
  {
    "path": "examples/bgp_test/spec.yaml",
    "content": "\n# Description: Testing attach physical netif to Container\n# INIT:\n#    cns init | sudo sh\n#    cns conf | sudo sh\n#    cns test | sudo sh\n# FINI:\n#    cns fini | sudo sh\n# TOPO:\n#\n#              C1\n#      (net0).2|\n#              | 192.168.10.0/24\n#              |\n#      (net0).1|  .1(net1)      .2(net0)\n#          R1(AS100)------------------R2(AS200)\n#      (net2).1|       10.0.0.0/24        |.1(vnet1)\n#              |                          |\n#  10.1.0.0/24 |                          | 10.2.0.0/24\n#              |                          |\n#      (net0).2|       10.3.0.0/24        |.2(ens6)\n#          R3(AS300)------------------DUT(AS400)\n#                 .1(vnet2)      .2(ens7) |.1(ens8)\n#                                         |\n#                         192.168.20.0/24 |\n#                                         |.2(vnet3)\n#                                         C2\n\n# preinit:\n#  - cmds:\n#    - cmd: ovs-vsctl del-port ovs-dum vnet1\n#    - cmd: ovs-vsctl del-port ovs-dum vnet2\n#    - cmd: ovs-vsctl del-port ovs-dum vnet3\n#\n#postfini:\n#  - cmds:\n#    - cmd: ovs-vsctl add-port ovs-dum vnet1\n#    - cmd: ovs-vsctl add-port ovs-dum vnet2\n#    - cmd: ovs-vsctl add-port ovs-dum vnet3\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: C1#net0 }\n      - { name: net1, type: direct, args: R2#net0 }\n      - { name: net2, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: vnet1, type: direct, args: DUT#ens6 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n      - { name: vnet2, type: direct, args: DUT#ens7 }\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: vnet3, type: direct, args: DUT#ens8 }\n\n  - name: DUT\n    image: slankdev/frr\n    interfaces:\n      - { name: ens6, type: direct, args: R2#vnet1}\n      - { name: ens7, type: direct, args: R3#vnet2 }\n      - { name: ens8, type: direct, args: C2#vnet3 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: echo R1 config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface net0'\n          -c '  ip address 192.168.10.1/24'\n          -c 'exit'\n          -c 'interface net1'\n          -c '  ip address 10.0.0.1/24'\n          -c 'exit'\n          -c 'interface net2'\n          -c '  ip address 10.1.0.1/24'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c '  bgp router-id 1.1.1.1'\n          -c '  neighbor 10.0.0.2 remote-as 200'\n          -c '  neighbor 10.1.0.2 remote-as 300'\n          -c '  network 192.168.10.0/24'\n          -c '  network 10.0.0.0/24'\n          -c '  network 10.1.0.0/24'\n          -c 'exit'\n\n  - name: R2\n    cmds:\n      - cmd: echo R2 config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface net0'\n          -c '  ip address 10.0.0.2/24'\n          -c 'exit'\n          -c 'interface vnet1'\n          -c '  ip address 10.2.0.1/24'\n          -c 'exit'\n          -c 'router bgp 200'\n          -c '  bgp router-id 2.2.2.2'\n          -c '  neighbor 10.0.0.1 remote-as 100'\n          -c '  neighbor 10.2.0.2 remote-as 400'\n          -c '  network 10.0.0.0/24'\n          -c '  network 10.2.0.0/24'\n          -c 'exit'\n\n  - name: R3\n    cmds:\n      - cmd: echo R3 config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface net0'\n          -c '  ip address 10.1.0.2/24'\n          -c 'exit'\n          -c 'interface vnet2'\n          -c '  ip address 10.3.0.1/24'\n          -c 'exit'\n          -c 'router bgp 300'\n          -c '  bgp router-id 3.3.3.3'\n          -c '  neighbor 10.1.0.1 remote-as 100'\n          -c '  neighbor 10.3.0.2 remote-as 400'\n          -c '  network 10.1.0.0/24'\n          -c '  network 10.3.0.0/24'\n          -c 'exit'\n\n  - name: C1\n    cmds:\n      - cmd: echo C1 config\n      - cmd: ip addr add 192.168.10.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.10.1\n  - name: C2\n    cmds:\n      - cmd: echo C2 config\n      - cmd: ip addr add 192.168.20.2/24 dev vnet3\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.20.1\n\n  - name: DUT\n    cmds:\n      - cmd: echo DUT config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface ens6'\n          -c ' ip address 10.2.0.2/24'\n          -c ' ipv6 nd suppress-ra'\n          -c ' no link-detect'\n          -c 'exit'\n          -c 'interface ens7'\n          -c ' ip address 10.3.0.2/24'\n          -c ' ipv6 nd suppress-ra'\n          -c ' no link-detect'\n          -c 'exit'\n          -c 'interface ens8'\n          -c ' ip address 192.168.20.1/24'\n          -c ' ipv6 nd suppress-ra'\n          -c ' no link-detect'\n          -c 'exit'\n          -c 'router bgp 400'\n          -c ' bgp router-id 4.4.4.4'\n          -c ' network 10.2.0.0/24'\n          -c ' network 10.3.0.0/24'\n          -c ' network 192.168.20.0/24'\n          -c ' neighbor 10.2.0.1 remote-as 200'\n          -c ' neighbor 10.3.0.1 remote-as 300'\n          -c 'exit'\n\ntest:\n  - cmds:\n    - cmd: echo each link test\n    - cmd: docker exec C1 ping -c2 192.168.10.1\n    - cmd: docker exec R1 ping -c2 192.168.10.2\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.1.0.2\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.2.0.2\n    - cmd: docker exec R3 ping -c2 10.1.0.1\n    - cmd: docker exec R3 ping -c2 10.3.0.2\n    - cmd: docker exec C2 ping -c2 192.168.20.1\n    - cmd: echo bgp route test\n    - cmd: docker exec C2 ping -c2 192.168.10.2\n\n"
  },
  {
    "path": "examples/bgp_test2/spec.yaml",
    "content": "\n# Description: Testing attach physical netif to Container\n# INIT:\n#    cns init | sudo sh\n#    cns conf | sudo sh\n#    cns test | sudo sh\n# FINI:\n#    cns fini | sudo sh\n# TOPO:\n#\n#              C1\n#      (net0).2|\n#              | 192.168.10.0/24\n#              |\n#      (net0).1|  .1(net1)      .2(net0)\n#        +-----+-----+              +-----------+\n#        | R1(AS100) |--------------| R2(AS100) |\n#        | 1.1.1.1   |              | 2.2.2.2   |\n#        +-----+-----+              +-----+-----+\n#      (net2).1|       10.0.0.0/24        |.1(vnet1)\n#              |                          |\n#  10.1.0.0/24 |                          | 10.2.0.0/24\n#              |                          |\n#      (net0).2|       10.3.0.0/24        |.2(ens6)\n#        +-----+-----+              +-----+-----+\n#        | R3(AS100) |--------------| DUT(AS100)|\n#        | 3.3.3.3   |              | 4.4.4.4   |\n#        +-----------+              +-----+-----+\n#                 .1(vnet2)      .2(ens7) |.1(ens8)\n#                                         |\n#                         192.168.20.0/24 |\n#                                         |.2(vnet3)\n#                                         C2\n\n# preinit:\n#  - cmds:\n#    - cmd: ovs-vsctl del-port ovs-dum vnet1\n#    - cmd: ovs-vsctl del-port ovs-dum vnet2\n#    - cmd: ovs-vsctl del-port ovs-dum vnet3\n#\n#postfini:\n#  - cmds:\n#    - cmd: ovs-vsctl add-port ovs-dum vnet1\n#    - cmd: ovs-vsctl add-port ovs-dum vnet2\n#    - cmd: ovs-vsctl add-port ovs-dum vnet3\n\nnodes:\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: C1#net0 }\n      - { name: net1, type: direct, args: R2#net0 }\n      - { name: net2, type: direct, args: R3#net0 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n      - { name: vnet1, type: direct, args: DUT#ens6 }\n  - name: R3\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net2 }\n      - { name: vnet2, type: direct, args: DUT#ens7 }\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n  - name: C2\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: vnet3, type: direct, args: DUT#ens8 }\n\n  - name: DUT\n    image: slankdev/frr\n    interfaces:\n      - { name: ens6, type: direct, args: R2#vnet1}\n      - { name: ens7, type: direct, args: R3#vnet2 }\n      - { name: ens8, type: direct, args: C2#vnet3 }\n\nnode_configs:\n\n  - name: R1\n    cmds:\n      - cmd: echo R1 config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c '  ip address 1.1.1.1/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c '  ip address 192.168.10.1/24'\n          -c 'exit'\n          -c 'interface net1'\n          -c '  ip address 10.0.0.1/24'\n          -c 'exit'\n          -c 'interface net2'\n          -c '  ip address 10.1.0.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c '  network 10.0.0.0/24 area 0'\n          -c '  network 10.1.0.0/24 area 0'\n          -c '  network 1.1.1.1/32 area 0'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c '  bgp router-id 1.1.1.1'\n          -c '  neighbor 2.2.2.2 remote-as 100'\n          -c '  neighbor 2.2.2.2 update-source lo'\n          -c '  neighbor 3.3.3.3 remote-as 100'\n          -c '  neighbor 3.3.3.3 update-source lo'\n          -c '  neighbor 4.4.4.4 remote-as 100'\n          -c '  neighbor 4.4.4.4 update-source lo'\n          -c '  network 192.168.10.0/24'\n          -c 'exit'\n\n  - name: R2\n    cmds:\n      - cmd: echo R2 config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c '  ip address 2.2.2.2/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c '  ip address 10.0.0.2/24'\n          -c 'exit'\n          -c 'interface vnet1'\n          -c '  ip address 10.2.0.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c '  network 10.0.0.0/24 area 0'\n          -c '  network 10.2.0.0/24 area 0'\n          -c '  network 2.2.2.2/32 area 0'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c '  bgp router-id 2.2.2.2'\n          -c '  neighbor 1.1.1.1 remote-as 100'\n          -c '  neighbor 1.1.1.1 update-source lo'\n          -c '  neighbor 3.3.3.3 remote-as 100'\n          -c '  neighbor 3.3.3.3 update-source lo'\n          -c '  neighbor 4.4.4.4 remote-as 100'\n          -c '  neighbor 4.4.4.4 update-source lo'\n          -c 'exit'\n\n  - name: R3\n    cmds:\n      - cmd: echo R3 config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c '  ip address 3.3.3.3/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c '  ip address 10.1.0.2/24'\n          -c 'exit'\n          -c 'interface vnet2'\n          -c '  ip address 10.3.0.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c '  network 10.1.0.0/24 area 0'\n          -c '  network 10.3.0.0/24 area 0'\n          -c '  network 3.3.3.3/32 area 0'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c '  bgp router-id 3.3.3.3'\n          -c '  neighbor 1.1.1.1 remote-as 100'\n          -c '  neighbor 1.1.1.1 update-source lo'\n          -c '  neighbor 2.2.2.2 remote-as 100'\n          -c '  neighbor 2.2.2.2 update-source lo'\n          -c '  neighbor 4.4.4.4 remote-as 100'\n          -c '  neighbor 4.4.4.4 update-source lo'\n          -c 'exit'\n\n  - name: C1\n    cmds:\n      - cmd: echo C1 config\n      - cmd: ip addr add 192.168.10.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.10.1\n  - name: C2\n    cmds:\n      - cmd: echo C2 config\n      - cmd: ip addr add 192.168.20.2/24 dev vnet3\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.20.1\n\n  - name: DUT\n    cmds:\n      - cmd: echo DUT config\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c '  ip address 4.4.4.4/32'\n          -c 'exit'\n          -c 'interface ens6'\n          -c ' ip address 10.2.0.2/24'\n          -c ' ipv6 nd suppress-ra'\n          -c ' no link-detect'\n          -c 'exit'\n          -c 'interface ens7'\n          -c ' ip address 10.3.0.2/24'\n          -c ' ipv6 nd suppress-ra'\n          -c ' no link-detect'\n          -c 'exit'\n          -c 'interface ens8'\n          -c ' ip address 192.168.20.1/24'\n          -c ' ipv6 nd suppress-ra'\n          -c ' no link-detect'\n          -c 'exit'\n          -c 'router ospf'\n          -c '  network 10.2.0.0/24 area 0'\n          -c '  network 10.3.0.0/24 area 0'\n          -c '  network 4.4.4.4/32 area 0'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c ' bgp router-id 4.4.4.4'\n          -c ' neighbor 1.1.1.1 remote-as 100'\n          -c ' neighbor 1.1.1.1 update-source lo'\n          -c ' neighbor 2.2.2.2 remote-as 100'\n          -c ' neighbor 2.2.2.2 update-source lo'\n          -c ' neighbor 3.3.3.3 remote-as 100'\n          -c ' neighbor 3.3.3.3 update-source lo'\n          -c ' network 192.168.20.0/24'\n          -c 'exit'\n\ntest:\n  - cmds:\n    - cmd: echo each link test\n    - cmd: docker exec C1 ping -c2 192.168.10.1\n    - cmd: docker exec R1 ping -c2 192.168.10.2\n    - cmd: docker exec R1 ping -c2 10.0.0.2\n    - cmd: docker exec R1 ping -c2 10.1.0.2\n    - cmd: docker exec R2 ping -c2 10.0.0.1\n    - cmd: docker exec R2 ping -c2 10.2.0.2\n    - cmd: docker exec R3 ping -c2 10.1.0.1\n    - cmd: docker exec R3 ping -c2 10.3.0.2\n    - cmd: docker exec C2 ping -c2 192.168.20.1\n\n    - cmd: echo ospf loopback ping\n    - cmd: docker exec R1 ping -c2 2.2.2.2\n    - cmd: docker exec R1 ping -c2 3.3.3.3\n    - cmd: docker exec R1 ping -c2 4.4.4.4\n    - cmd: docker exec R2 ping -c2 1.1.1.1\n    - cmd: docker exec R2 ping -c2 3.3.3.3\n    - cmd: docker exec R2 ping -c2 4.4.4.4\n    - cmd: docker exec R3 ping -c2 1.1.1.1\n    - cmd: docker exec R3 ping -c2 2.2.2.2\n    - cmd: docker exec R3 ping -c2 4.4.4.4\n    - cmd: docker exec DUT ping -c2 1.1.1.1\n    - cmd: docker exec DUT ping -c2 2.2.2.2\n    - cmd: docker exec DUT ping -c2 3.3.3.3\n\n    - cmd: echo bgp route test\n    - cmd: docker exec C2 ping -c2 192.168.10.2\n\n"
  },
  {
    "path": "examples/bridge_tc/README.md",
    "content": "# Bridge TC Demo\n\nThis example shows the effect of attaching tc to bridge device and the device enslaved to the bridge.\n\n![](topo.png)\n"
  },
  {
    "path": "examples/bridge_tc/spec.yaml",
    "content": "---\nnodes:\n- name: N1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: B1#net0 }\n- name: N2\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: B1#net1 }\n- name: N3\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: B1#net2 }\n- name: B1\n  image: nicolaka/netshoot\n  interfaces:\n  - { name: net0, type: direct, args: N1#net0 }\n  - { name: net1, type: direct, args: N2#net0 }\n  - { name: net2, type: direct, args: N3#net0 }\n\n\nnode_configs:\n- name: N1\n  cmds:\n  - cmd: ip addr add 10.0.0.2/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: N2\n  cmds:\n  - cmd: ip addr add 10.0.0.3/24 dev net0\n  - cmd: ip route add default via 10.0.0.1\n- name: N3\n  cmds:\n  - cmd: ip addr add 10.0.1.2/24 dev net0\n  - cmd: ip route add default via 10.0.1.1\n- name: B1\n  cmds:\n  - cmd: ip link add br0 type bridge\n  - cmd: ip link set br0 up\n  - cmd: ip addr add 10.0.0.1/24 dev br0\n  - cmd: ip link set net0 master br0\n  - cmd: ip link set net1 master br0\n  - cmd: ip addr add 10.0.1.1/24 dev net2\n  - cmd: sysctl -w net.ipv4.ip_forward=1\n\ntest:\n- cmds:\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Connectivity test from N1 (10.0.0.2)\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N1 ping -c 1 10.0.0.1\n  - cmd: docker exec N1 ping -c 1 10.0.0.3\n  - cmd: docker exec N1 ping -c 1 10.0.1.1\n  - cmd: docker exec N1 ping -c 1 10.0.1.2\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Connectivity test from N2 (10.0.0.3)\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 ping -c 1 10.0.0.1\n  - cmd: docker exec N2 ping -c 1 10.0.0.2\n  - cmd: docker exec N1 ping -c 1 10.0.1.1\n  - cmd: docker exec N1 ping -c 1 10.0.1.2\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Connectivity test from N3 (10.0.1.2)\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N3 ping -c 1 10.0.1.1\n  - cmd: docker exec N3 ping -c 1 10.0.0.1\n  - cmd: docker exec N3 ping -c 1 10.0.0.2\n  - cmd: docker exec N3 ping -c 1 10.0.0.3\n\n  # 帯域制限が効いているかを確認するためにベースラインを見ておきます\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Baseline iperf number on server side\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec N1 iperf -c 10.0.0.3 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N2 pkill -KILL iperf\n  \n  # bridgeデバイスそのものにtcで帯域制限をかけた場合host -> bridge networkとforward -> bridgeのケースで帯域制限が効きます。bridgeデバイスに向かってパケットが入っていくトラフィックに対して帯域制限がかかるイメージです。\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case1 Attach tc to bridge device itself\"\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"tc qdisc add dev br0 root netem rate 100kbit\"\n  - cmd: docker exec B1 tc qdisc add dev br0 root netem rate 100kbit\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case1-1 iperf from N1 to N2\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec N1 iperf -c 10.0.0.3 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N2 pkill -KILL iperf\n  - cmd: sleep 3\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case1-2 iperf from B1 to N2\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec B1 iperf -c 10.0.0.3 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N2 pkill -KILL iperf\n  - cmd: sleep 3\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case1-3 iperf from N3 to N2\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec N3 iperf -c 10.0.0.3 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N2 pkill -KILL iperf\n  - cmd: sleep 3\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"End of Case1\"\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"tc qdisc del dev br0 root\"\n  - cmd: docker exec B1 tc qdisc del dev br0 root\n\n  # bridgeにenslaveされたデバイスにtcで帯域制限をかけた場合bridge経由でそのデバイスに向かっていくすべてのパケットに対して帯域制限が効きます。\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case2 Attach tc to enslaved veth\"\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"tc qdisc add dev net1 root netem rate 100kbit\"\n  - cmd: docker exec B1 tc qdisc add dev net1 root netem rate 100kbit\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case2-1 iperf from N1 to N2\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec N1 iperf -c 10.0.0.3 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N2 pkill -KILL iperf\n  - cmd: sleep 3\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case2-2 iperf from B1 to N2\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec B1 iperf -c 10.0.0.3 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N2 pkill -KILL iperf\n  - cmd: sleep 3\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case2-3 iperf from N3 to N2\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N2 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec N3 iperf -c 10.0.0.3 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N2 pkill -KILL iperf\n  - cmd: sleep 3\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"Case2-4 iperf from N3 to N1\"\n  - cmd: echo \"==========================================\"\n  - cmd: docker exec N1 iperf -s -i 1 &\n  - cmd: sleep 3\n  - cmd: docker exec N3 iperf -c 10.0.0.2 -t 3 2>&1 > /dev/null\n  - cmd: docker exec N1 pkill -KILL iperf\n  - cmd: sleep 3\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"End of Case2\"\n  - cmd: echo \"==========================================\"\n  - cmd: echo \"tc qdisc del dev br0 root\"\n  - cmd: docker exec B1 tc qdisc del dev net1 root\n"
  },
  {
    "path": "examples/flowspec/spec.yaml",
    "content": "\n# DESCRIPTION: BGP Flowspec test using FRR/iptables\n# INIT:\n#    cns spec.yaml init | sudo sh\n#    cns spec.yaml conf | sudo sh\n#    cns spec.yaml test | sudo sh\n# FINI:\n#    cns spec.yaml fini | sudo sh\n# TOPO:\n#\n#            10.1.0.0/24  +-----------+  10.2.0.0/24\n#                 +----[net0]  R2   [net1]-----+\n#                 |     .2| lo3.3.3.3 |.2      |\n#                 |       +-----------+        |\n#                 |.1                        .1|\n#   192.168.    [net2]                       [net2]    192.168.\n#   10.0/24  +-----------+  10.0.0.0/24  +-----------+ 20.0/24\n# C0------[net1]  R0   [net0]---------[net0]  R1  [net1]------C1\n#   .2     .1| Lo1.1.1.1 |.1           .2| lo2.2.2.2 |.1      .2\n#            +-----------+               +-----------+\n#\n\nnodes:\n  - name: R0\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C0#net0 }\n      - { name: net2, type: direct, args: R2#net0 }\n  - name: R1\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R0#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n      - { name: net2, type: direct, args: R2#net1 }\n  - name: R2\n    image: slankdev/frr\n    interfaces:\n      - { name: net0, type: direct, args: R0#net2 }\n      - { name: net1, type: direct, args: R1#net2 }\n  - name: C0\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R0#net1 }\n  - name: C1\n    image: slankdev/ubuntu:18.04\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n\nnode_configs:\n  - name: R0\n    cmds:\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c '  ip address 1.1.1.1/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c '  ip address 10.0.0.1/24'\n          -c 'exit'\n          -c 'interface net1'\n          -c '  ip address 192.168.10.1/24'\n          -c 'exit'\n          -c 'interface net2'\n          -c '  ip address 10.1.0.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c '  network 10.0.0.0/24 area 0'\n          -c '  network 10.1.0.0/24 area 0'\n          -c '  network 1.1.1.1/32 area 0'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c '  bgp router-id 1.1.1.1'\n          -c '  neighbor 2.2.2.2 remote-as 100'\n          -c '  neighbor 2.2.2.2 update-source lo'\n          -c '  neighbor 3.3.3.3 remote-as 100'\n          -c '  neighbor 3.3.3.3 update-source lo'\n          -c '  network 192.168.10.0/24'\n          -c 'exit'\n\n  - name: R1\n    cmds:\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c '  ip address 2.2.2.2/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c '  ip address 10.0.0.2/24'\n          -c 'exit'\n          -c 'interface net1'\n          -c '  ip address 192.168.20.1/24'\n          -c 'exit'\n          -c 'interface net2'\n          -c '  ip address 10.2.0.1/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c '  network 10.0.0.0/24 area 0'\n          -c '  network 10.2.0.0/24 area 0'\n          -c '  network 2.2.2.2/32 area 0'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c '  bgp router-id 2.2.2.2'\n          -c '  neighbor 1.1.1.1 remote-as 100'\n          -c '  neighbor 1.1.1.1 update-source lo'\n          -c '  neighbor 3.3.3.3 remote-as 100'\n          -c '  neighbor 3.3.3.3 update-source lo'\n          -c '  network 192.168.20.0/24'\n          -c 'exit'\n\n  - name: R2\n    cmds:\n      - cmd: >-\n          vtysh -c 'conf t'\n          -c 'interface lo'\n          -c '  ip address 3.3.3.3/32'\n          -c 'exit'\n          -c 'interface net0'\n          -c '  ip address 10.1.0.2/24'\n          -c 'exit'\n          -c 'interface net1'\n          -c '  ip address 10.2.0.2/24'\n          -c 'exit'\n          -c 'router ospf'\n          -c '  network 10.1.0.0/24 area 0'\n          -c '  network 10.2.0.0/24 area 0'\n          -c '  network 3.3.3.3/32 area 0'\n          -c 'exit'\n          -c 'router bgp 100'\n          -c '  bgp router-id 3.3.3.3'\n          -c '  neighbor 1.1.1.1 remote-as 100'\n          -c '  neighbor 1.1.1.1 update-source lo'\n          -c '  neighbor 2.2.2.2 remote-as 100'\n          -c '  neighbor 2.2.2.2 update-source lo'\n          -c 'exit'\n\n  - name: C0\n    cmds:\n      - cmd: ip addr add 192.168.10.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.10.1\n  - name: C1\n    cmds:\n      - cmd: ip addr add 192.168.20.2/24 dev net0\n      - cmd: ip route del default\n      - cmd: ip route add default via 192.168.20.1\n\ntest:\n  - cmds:\n    - cmd: echo 'Local Link Test'\n    - cmd: docker exec R0 ping -c2 -w4 10.0.0.2\n    - cmd: docker exec R0 ping -c2 -w4 10.1.0.2\n    - cmd: docker exec R0 ping -c2 -w4 192.168.10.2\n    - cmd: docker exec R1 ping -c2 -w4 10.0.0.1\n    - cmd: docker exec R1 ping -c2 -w4 10.2.0.2\n    - cmd: docker exec R1 ping -c2 -w4 192.168.20.2\n    - cmd: docker exec R2 ping -c2 -w4 10.1.0.1\n    - cmd: docker exec R2 ping -c2 -w4 10.2.0.1\n    - cmd: docker exec C0 ping -c2 -w4 192.168.10.1\n    - cmd: docker exec C1 ping -c2 -w4 192.168.20.1\n    - cmd: echo 'Remote Link Test'\n    - cmd: docker exec C0 ping -c2 -w4 192.168.20.2\n    - cmd: docker exec C1 ping -c2 -w4 192.168.10.2\n\n"
  },
  {
    "path": "examples/gobgp-grpc/README.md",
    "content": "# gobgp-grpc-demo\n\n**The experimental environment was prepared with [tinet](https://github.com/ak1ra24/tinet-go)**\n\n## Directory Tree\n```\n.\n├── README.md\n├── add_path01.py\n├── add_path02.py\n├── gobgp01.conf\n├── gobgp02.conf\n└── spec.yaml\n```\n\n## Topo\n![demo-topo](./demo.png)\n\n## How to Use\n* C1\n```\ndocker exec -it C1 bash\ncd gobgp/api\npython3 add_path.py\n```\n\n* C2\n```\ndocker exec -it C2 bash\ncd gobgp/api\npython3 add_path.py\n```\n\n* R1\n```\ndocker exec -it R1 bash\nroot@R1:~# gobgp g r\n   Network              Next Hop             AS_PATH              Age        Attrs\n*> 192.168.10.0/24      0.0.0.0                                   00:56:16   [{Origin: ?}]\n*> 192.168.20.0/24      10.0.0.2             65001                00:56:05   [{Origin: ?}]\n```\n\n## Test\n* C1\n```\ndocker exec -it C1 ping -c2 192.168.20.2\n```\n\n* C2\n```\ndocker exec -it C2 ping -c2 192.168.20.2\n```"
  },
  {
    "path": "examples/gobgp-grpc/add_path01.py",
    "content": "#!/usr/bin/env python\n\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport grpc\nfrom google.protobuf.any_pb2 import Any\n\nimport gobgp_pb2\nimport gobgp_pb2_grpc\nimport attribute_pb2\n\n_TIMEOUT_SECONDS = 1000\n\n\ndef run():\n    channel = grpc.insecure_channel('192.168.10.1:50051')\n    stub = gobgp_pb2_grpc.GobgpApiStub(channel)\n\n    nlri = Any()\n    nlri.Pack(attribute_pb2.IPAddressPrefix(\n        prefix_len=24,\n        prefix=\"192.168.10.0\",\n    ))\n    origin = Any()\n    origin.Pack(attribute_pb2.OriginAttribute(\n        origin=2,  # INCOMPLETE\n    ))\n    next_hop = Any()\n    next_hop.Pack(attribute_pb2.NextHopAttribute(\n        next_hop=\"0.0.0.0\",\n    ))\n    attributes = [origin, next_hop]\n\n    stub.AddPath(\n        gobgp_pb2.AddPathRequest(\n            table_type=gobgp_pb2.GLOBAL,\n            path=gobgp_pb2.Path(\n                nlri=nlri,\n                pattrs=attributes,\n                family=gobgp_pb2.Family(afi=gobgp_pb2.Family.AFI_IP, safi=gobgp_pb2.Family.SAFI_UNICAST),\n            )\n        ),\n        _TIMEOUT_SECONDS,\n    )\n\nif __name__ == '__main__':\n    run()\n"
  },
  {
    "path": "examples/gobgp-grpc/add_path02.py",
    "content": "#!/usr/bin/env python\n\nfrom __future__ import absolute_import\nfrom __future__ import print_function\n\nimport grpc\nfrom google.protobuf.any_pb2 import Any\n\nimport gobgp_pb2\nimport gobgp_pb2_grpc\nimport attribute_pb2\n\n_TIMEOUT_SECONDS = 1000\n\n\ndef run():\n    channel = grpc.insecure_channel('192.168.20.1:50051')\n    stub = gobgp_pb2_grpc.GobgpApiStub(channel)\n\n    nlri = Any()\n    nlri.Pack(attribute_pb2.IPAddressPrefix(\n        prefix_len=24,\n        prefix=\"192.168.20.0\",\n    ))\n    origin = Any()\n    origin.Pack(attribute_pb2.OriginAttribute(\n        origin=2,  # INCOMPLETE\n    ))\n    next_hop = Any()\n    next_hop.Pack(attribute_pb2.NextHopAttribute(\n        next_hop=\"0.0.0.0\",\n    ))\n    attributes = [origin, next_hop]\n\n    stub.AddPath(\n        gobgp_pb2.AddPathRequest(\n            table_type=gobgp_pb2.GLOBAL,\n            path=gobgp_pb2.Path(\n                nlri=nlri,\n                pattrs=attributes,\n                family=gobgp_pb2.Family(afi=gobgp_pb2.Family.AFI_IP, safi=gobgp_pb2.Family.SAFI_UNICAST),\n            )\n        ),\n        _TIMEOUT_SECONDS,\n    )\n\nif __name__ == '__main__':\n    run()\n"
  },
  {
    "path": "examples/gobgp-grpc/gobgp01.conf",
    "content": "[global.config]\n  as = 65000\n  router-id = \"10.0.0.1\"\n\n[[neighbors]]\n  [neighbors.config]\n    neighbor-address = \"10.0.0.2\"\n    peer-as = 65001\n\n[zebra]\n    [zebra.config]\n        enabled = true\n        url = \"unix:/var/run/frr/zserv.api\"\n        redistribute-route-type-list = [\"connect\"]\n        version = 6\n        software-name = frr7.2\n"
  },
  {
    "path": "examples/gobgp-grpc/gobgp02.conf",
    "content": "[global.config]\n  as = 65001\n  router-id = \"10.0.0.2\"\n\n[[neighbors]]\n  [neighbors.config]\n    neighbor-address = \"10.0.0.1\"\n    peer-as = 65000\n\n[zebra]\n    [zebra.config]\n        enabled = true\n        url = \"unix:/var/run/frr/zserv.api\"\n        redistribute-route-type-list = [\"connect\"]\n        version = 6\n        software-name = frr7.2\n"
  },
  {
    "path": "examples/gobgp-grpc/spec.yaml",
    "content": "postinit:\n  - cmds:\n      - cmd: docker cp gobgp01.conf R1:/root/gobgpd.conf\n      - cmd: docker cp gobgp02.conf R2:/root/gobgpd.conf\n      - cmd: docker cp add_path01.py C1:/root/gobgp/api/add_path.py\n      - cmd: docker cp add_path02.py C2:/root/gobgp/api/add_path.py\n\nnodes:\n  - name: R1\n    image: akiranet24/gobgp-frr:7.2\n    interfaces:\n      - { name: net0, type: direct, args: R2#net0 }\n      - { name: net1, type: direct, args: C1#net0 }\n  - name: R2\n    image: akiranet24/gobgp-frr:7.2\n    interfaces:\n      - { name: net0, type: direct, args: R1#net0 }\n      - { name: net1, type: direct, args: C2#net0 }\n  - name: C1\n    image: akiranet24/gobgp-grpc-client\n    interfaces:\n      - { name: net0, type: direct, args: R1#net1 }\n  - name: C2\n    image: akiranet24/gobgp-grpc-client\n    interfaces:\n      - { name: net0, type: direct, args: R2#net1 }\n\n\nnode_configs:\n  - name: R1\n    cmds:\n      - cmd: ip addr add 10.0.0.1/24 dev net0\n      - cmd: ip addr add 192.168.10.1/24 dev net1\n      - cmd: /etc/init.d/frr start\n      - cmd: nohup gobgpd -f /root/gobgpd.conf &\n  - name: R2\n    cmds:\n      - cmd: ip addr add 10.0.0.2/24 dev net0\n      - cmd: ip addr add 192.168.20.1/24 dev net1\n      - cmd: /etc/init.d/frr start\n      - cmd: nohup gobgpd -f /root/gobgpd.conf &\n  - name: C1\n    cmds:\n      - cmd: ip addr add 192.168.10.2/24 dev net0\n      - cmd: ip r del default\n      - cmd: ip r add default via 192.168.10.1\n  - name: C2\n    cmds:\n      - cmd: ip addr add 192.168.20.2/24 dev net0\n      - cmd: ip r del default\n      - cmd: ip r add default via 192.168.20.1\n"
  },
  {
    "path": "examples/ovs_port_vlan/spec.yaml",
    "content": "\n# DESCRIPTION: OVS port-vlan test\n# TOPO:\n#                       192.168.10.0/24\n#   C0------------------+            +-----------------C2\n#     .1(net0)     swp0 | swp2       | swp0    .2(net0)\n#                   [SW0]----------[SW1]\n#     .1(net0)     swp1 |      swp2  | swp1    .2(net0)\n#   C1------------------+            +-----------------C3\n#                       192.168.20.0/24\n#\n\nnodes:\n  - name: C0\n    image: slankdev/ubuntu:16.04\n    interfaces: [{ name: net0, type: direct, args: SW0#swp0 }]\n  - name: C1\n    image: slankdev/ubuntu:16.04\n    interfaces: [{ name: net0, type: direct, args: SW0#swp1 }]\n\n  - name: C2\n    image: slankdev/ubuntu:16.04\n    interfaces: [{ name: net0, type: direct, args: SW1#swp0 }]\n  - name: C3\n    image: slankdev/ubuntu:16.04\n    interfaces: [{ name: net0, type: direct, args: SW1#swp1 }]\n\n  - name: SW0\n    image: slankdev/ovs\n    interfaces:\n      - { name: swp0, type: direct, args: C0#net0 }\n      - { name: swp1, type: direct, args: C1#net0 }\n      - { name: swp2, type: direct, args: SW1#swp2 }\n  - name: SW1\n    image: slankdev/ovs\n    interfaces:\n      - { name: swp0, type: direct, args: C2#net0 }\n      - { name: swp1, type: direct, args: C3#net0 }\n      - { name: swp2, type: direct, args: SW0#swp2 }\n\nnode_configs:\n  - { name: C0, cmds: [ cmd: 'ip addr add 192.168.10.1/24 dev net0' ] }\n  - { name: C1, cmds: [ cmd: 'ip addr add 192.168.20.1/24 dev net0' ] }\n  - { name: C2, cmds: [ cmd: 'ip addr add 192.168.10.2/24 dev net0' ] }\n  - { name: C3, cmds: [ cmd: 'ip addr add 192.168.20.2/24 dev net0' ] }\n  - name: SW0\n    cmds:\n      - cmd: ovs-vsctl add-br ovs0\n      - cmd: ovs-vsctl add-port ovs0 swp0\n      - cmd: ovs-vsctl add-port ovs0 swp1\n      - cmd: ovs-vsctl add-port ovs0 swp2\n      - cmd: ovs-vsctl set port swp0 tag=10\n      - cmd: ovs-vsctl set port swp1 tag=20\n      - cmd: ovs-vsctl set port swp2 trunk=10,20\n      - cmd: ip link set ovs0 up\n  - name: SW1\n    cmds:\n      - cmd: ovs-vsctl add-br ovs0\n      - cmd: ovs-vsctl add-port ovs0 swp0\n      - cmd: ovs-vsctl add-port ovs0 swp1\n      - cmd: ovs-vsctl add-port ovs0 swp2\n      - cmd: ovs-vsctl set port swp0 tag=10\n      - cmd: ovs-vsctl set port swp1 tag=20\n      - cmd: ovs-vsctl set port swp2 trunk=10,20\n      - cmd: ip link set ovs0 up\n\ntest:\n  - cmds:\n    - cmd: docker exec C0 ping -c2 192.168.10.2\n    - cmd: docker exec C1 ping -c2 192.168.20.2\n\n"
  },
  {
    "path": "examples/simple/topo2/spec.yaml",
    "content": "nodes:\n- name: R1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: C1#net0 }\n  - { name: net2, type: direct, args: C2#net0 }\n- name: R2\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: C3#net0 }\n  - { name: net2, type: direct, args: C4#net0 }\n- name: C1\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n- name: C2\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: C3\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n- name: C4\n  image: slankdev/frr\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 10.255.1.1/24 dev net0\n  - cmd: ip addr add 10.1.0.1/24 dev net1\n  - cmd: ip addr add 10.2.0.1/24 dev net2\n  - cmd: ip route add 10.3.0.0/24 via 10.255.1.2\n  - cmd: ip route add 10.4.0.0/24 via 10.255.1.2\n- name: R2\n  cmds:\n  - cmd: ip addr add 10.255.1.2/24 dev net0\n  - cmd: ip addr add 10.3.0.1/24 dev net1\n  - cmd: ip addr add 10.4.0.1/24 dev net2\n  - cmd: ip route add 10.1.0.0/24 via 10.255.1.1\n  - cmd: ip route add 10.2.0.0/24 via 10.255.1.1\n- name: C1\n  cmds:\n  - cmd: ip addr add 10.1.0.2/24 dev net0\n  - cmd: ip route add default via 10.1.0.1\n- name: C2\n  cmds:\n  - cmd: ip addr add 10.2.0.2/24 dev net0\n  - cmd: ip route add default via 10.2.0.1\n- name: C3\n  cmds:\n  - cmd: ip addr add 10.3.0.2/24 dev net0\n  - cmd: ip route add default via 10.3.0.1\n- name: C4\n  cmds:\n  - cmd: ip addr add 10.4.0.2/24 dev net0\n  - cmd: ip route add default via 10.4.0.1\n"
  },
  {
    "path": "examples/srmpls_l2vpn_static_linux/README.md",
    "content": "# L2VPN using SR-MPLS static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srmpls_l2vpn_static_linux/spec.yaml",
    "content": "preinit:\n- cmds:\n  - cmd: modprobe mpls_router\n  - cmd: modprobe mpls_gso\n  - cmd: modprobe mpls_iptunnel\n\nnodes:\n- name: R1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: ip addr add 10.255.0.1/32 dev lo\n  - cmd: ip addr add 10.0.0.1/30 dev net0\n  - cmd: ip addr add 10.0.0.9/30 dev net1\n  - cmd: >-\n      ip -M route add 17002 as 17002\n      nexthop via inet 10.0.0.2 dev net0\n      nexthop via inet 10.0.0.10 dev net1\n  - cmd: ip -M route add 17003 via inet 10.0.0.2 dev net0\n  - cmd: ip -M route add 17004 via inet 10.0.0.10 dev net1\n  - cmd: >-\n      ip route add 10.255.0.2/32\n      nexthop encap mpls 17002 via inet 10.0.0.2 dev net0\n      nexthop encap mpls 17002 via inet 10.0.0.10 dev net1\n  - cmd: ip route add 10.255.0.3/32 via 10.0.0.2 dev net0\n  - cmd: ip route add 10.255.0.4/32 via 10.0.0.10 dev net1\n\n  ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type bridge\n  - cmd: ip link add CUST-B type bridge\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n\n  ## L2VPN Encap/Decap Configuration\n  ## TODO(slankdev): there is no l2 encap configurability in MPLS\n  - cmd: ip -M route add 80 dev CUST-A\n  - cmd: ip -M route add 81 dev CUST-B\n\n- name: R2\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: ip addr add 10.255.0.2/32 dev lo\n  - cmd: ip addr add 10.0.0.6/30 dev net0\n  - cmd: ip addr add 10.0.0.17/30 dev net1\n  - cmd: >-\n      ip -M route add 17001 as 17001\n      nexthop via inet 10.0.0.5 dev net0\n      nexthop via inet 10.0.0.18 dev net1\n  - cmd: ip -M route add 17003 via inet 10.0.0.5 dev net0\n  - cmd: ip -M route add 17004 via inet 10.0.0.18 dev net1\n  - cmd: >-\n      ip route add 10.255.0.1/32\n      nexthop encap mpls 17001 via inet 10.0.0.5 dev net0\n      nexthop encap mpls 17001 via inet 10.0.0.18 dev net1\n  - cmd: ip route add 10.255.0.3/32 via 10.0.0.5 dev net0\n  - cmd: ip route add 10.255.0.4/32 via 10.0.0.18 dev net1\n\n  ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type bridge\n  - cmd: ip link add CUST-B type bridge\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n\n  ## L2VPN Encap/Decap Configuration\n  ## TODO(slankdev): there is no l2 encap configurability in MPLS\n  - cmd: ip -M route add 80 dev CUST-A\n  - cmd: ip -M route add 81 dev CUST-B\n\n- name: R3\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: sysctl -w net.mpls.conf.net2.input=1\n  - cmd: ip addr add 10.255.0.3/32 dev lo\n  - cmd: ip addr add 10.0.0.2/30 dev net0\n  - cmd: ip addr add 10.0.0.5/30 dev net1\n  - cmd: ip addr add 10.0.0.13/30 dev net2\n  - cmd: ip -M route add 17001 via inet 10.0.0.1 dev net0\n  - cmd: ip -M route add 17002 via inet 10.0.0.6 dev net1\n  - cmd: ip -M route add 17004 via inet 10.0.0.14 dev net2\n  - cmd: ip route add 10.255.0.1/32 via 10.0.0.1 dev net0\n  - cmd: ip route add 10.255.0.2/32 via 10.0.0.6 dev net1\n  - cmd: ip route add 10.255.0.4/32 via 10.0.0.14 dev net2\n\n- name: R4\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: sysctl -w net.mpls.conf.net2.input=1\n  - cmd: ip addr add 10.255.0.4/32 dev lo\n  - cmd: ip addr add 10.0.0.10/30 dev net0\n  - cmd: ip addr add 10.0.0.18/30 dev net1\n  - cmd: ip addr add 10.0.0.14/30 dev net2\n  - cmd: ip -M route add 17001 via inet 10.0.0.9 dev net0\n  - cmd: ip -M route add 17002 via inet 10.0.0.17 dev net1\n  - cmd: ip -M route add 17003 via inet 10.0.0.13 dev net2\n  - cmd: ip route add 10.255.0.1/32 via 10.0.0.9 dev net0\n  - cmd: ip route add 10.255.0.2/32 via 10.0.0.17 dev net1\n  - cmd: ip route add 10.255.0.3/32 via 10.0.0.13 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostA2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n- name: HostB1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostB2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n"
  },
  {
    "path": "examples/srmpls_l3vpnv4_static_linux/README.md",
    "content": "# L3VPNv4 using SR-MPLS\n\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srmpls_l3vpnv4_static_linux/spec.yaml",
    "content": "preinit:\n- cmds:\n  - cmd: modprobe mpls_router\n  - cmd: modprobe mpls_gso\n  - cmd: modprobe mpls_iptunnel\n\nnodes:\n- name: R1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R2#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R3#net0 }\n  - { name: net2, type: direct, args: R4#net1 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R2#net1 }\n  - { name: net1, type: direct, args: R4#net2 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net2 }\n  - { name: net2, type: direct, args: R3#net1 }\n- name: HostA1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R3#net2 }\n- name: HostB1\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: slankdev/ubuntu:18.04\n  interfaces:\n  - { name: net0, type: direct, args: R3#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 10.0.0.1/30 dev net0\n  - cmd: ip addr add 10.0.0.9/30 dev net1\n  - cmd: ip addr add 192.168.0.1/24 dev net2\n  - cmd: ip addr add 192.168.0.1/24 dev net3\n  - cmd: ip -M route add 80 dev CUST-A\n  - cmd: ip -M route add 81 dev CUST-B\n  - cmd: ip -M route add 17002 via inet 10.0.0.2 dev net0\n  - cmd: ip -M route add 17004 via inet 10.0.0.10 dev net0\n  - cmd: >\n      ip -M route add 17003 as 17003\n      nexthop via inet 10.0.0.2 dev net0\n      nexthop via inet 10.0.0.10 dev net1\n  - cmd: ip route add 192.168.1.0/24 vrf CUST-A\n      nexthop encap mpls 17003/80 via inet 10.0.0.2 dev net0\n      nexthop encap mpls 17003/80 via inet 10.0.0.10 dev net1\n  - cmd: ip route add 192.168.1.0/24 vrf CUST-B\n      nexthop encap mpls 17003/81 via inet 10.0.0.2 dev net0\n      nexthop encap mpls 17003/81 via inet 10.0.0.10 dev net1\n\n- name: R2\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: sysctl -w net.mpls.conf.net2.input=1\n  - cmd: ip addr add 10.0.0.2/30 dev net0\n  - cmd: ip addr add 10.0.0.12/30 dev net1\n  - cmd: ip addr add 10.0.0.4/30 dev net2\n  - cmd: ip -M route add 17001 via inet 10.0.0.1 dev net0\n  - cmd: ip -M route add 17003 via inet 10.0.0.3 dev net2\n  - cmd: ip -M route add 17004 via inet 10.0.0.14 dev net1\n\n- name: R3\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 10.0.0.7/30 dev net0\n  - cmd: ip addr add 10.0.0.17/30 dev net1\n  - cmd: ip addr add 192.168.1.1/24 dev net2\n  - cmd: ip addr add 192.168.1.1/24 dev net3\n  - cmd: ip -M route add 80 dev CUST-A\n  - cmd: ip -M route add 81 dev CUST-B\n  - cmd: >\n      ip -M route add 17001 as 17001\n      nexthop via inet 10.0.0.5 dev net0\n      nexthop via inet 10.0.0.18 dev net1\n  - cmd: ip -M route add 17002 via inet 10.0.0.5 dev net0\n  - cmd: ip -M route add 17004 via inet 10.0.0.18 dev net1\n  - cmd: ip route add 192.168.0.0/24 vrf CUST-A\n      nexthop encap mpls 17001/80 via inet 10.0.0.5 dev net0\n      nexthop encap mpls 17001/80 via inet 10.0.0.18 dev net1\n  - cmd: ip route add 192.168.0.0/24 vrf CUST-B\n      nexthop encap mpls 17001/81 via inet 10.0.0.5 dev net0\n      nexthop encap mpls 17001/81 via inet 10.0.0.18 dev net1\n\n- name: R4\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: sysctl -w net.mpls.conf.net2.input=1\n  - cmd: ip addr add 10.0.0.10/30 dev net0\n  - cmd: ip addr add 10.0.0.14/30 dev net1\n  - cmd: ip addr add 10.0.0.18/30 dev net2\n  - cmd: ip -M route add 17001 via inet 10.0.0.9 dev net0\n  - cmd: ip -M route add 17002 via inet 10.0.0.13 dev net1\n  - cmd: ip -M route add 17003 via inet 10.0.0.17 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostA2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n- name: HostB1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostB2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n\ntest:\n- cmds:\n  ## SR-MPLS Operation\n  - cmd: >\n      docker exec R1 ip route add 10.255.0.3/32\n      encap mpls 17004/17003 via 10.0.0.2\n  - cmd: >\n      docker exec R3 ip route add 10.255.0.1/32\n      encap mpls 17002/17001 via 10.0.0.18\n  ## SR-MPLS Test\n  - cmd: docker exec HostA1 ping -c2 192.168.1.2\n"
  },
  {
    "path": "examples/srmpls_l3vpnv4_static_vpp/README.md",
    "content": "# L3VPN using SR-MPLS static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srmpls_l3vpnv4_static_vpp/spec.yaml",
    "content": "postinit:\n  cmds:\n  - cmd: modprobe vrf\n  - cmd: modprobe mpls_router\n  - cmd: modprobe mpls_gso\n  - cmd: modprobe mpls_iptunnel\n  - cmd: |\n      cat <<EOF > /tmp/r1_exec.vpp\n      create host-interface name net0\n      create host-interface name net1\n      create host-interface name net2\n      create host-interface name net3\n      mpls table add 0\n      set interface mpls host-net0 enable\n      set interface mpls host-net1 enable\n      set int state host-net0 up\n      set int state host-net1 up\n      set int state host-net2 up\n      set int state host-net3 up\n      ip table add 10\n      ip table add 20\n      set int ip table host-net2 10\n      set int ip table host-net3 20\n\n      set int ip addr host-net0 10.0.0.1/30\n      set int ip addr host-net1 10.0.0.9/30\n      set int ip addr host-net2 192.168.0.1/24\n      set int ip addr host-net3 192.168.0.1/24\n\n      mpls local-label add 80 eos via ip4-lookup-in-table 10\n      mpls local-label add 81 eos via ip4-lookup-in-table 20\n      ip route add 192.168.1.0/24 table 10 via 10.0.0.2 host-net0 out-labels 17002 80\n      ip route add 192.168.1.0/24 table 20 via 10.0.0.2 host-net0 out-labels 17002 81\n      EOF\n  - cmd: |\n      cat <<EOF > /tmp/r2_exec.vpp\n      EOF\n  - cmd: docker exec R1 mkdir -p /etc/vpp\n  - cmd: docker exec R2 mkdir -p /etc/vpp\n  - cmd: docker cp /tmp/r1_exec.vpp R1:/etc/vpp/exec.vpp\n  - cmd: docker cp /tmp/r2_exec.vpp R2:/etc/vpp/exec.vpp\n\nnodes:\n- name: R1\n  image: slankdev/vpp:19.04\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.mpls.platform_labels=1048575\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: nohup vpp -c /etc/vpp/startup.conf &\n\n- name: R2\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 10.0.0.6/30 dev net0\n  - cmd: ip addr add 10.0.0.17/30 dev net1\n  - cmd: ip addr add 192.168.1.1/24 dev net2\n  - cmd: ip addr add 192.168.1.1/24 dev net3\n  - cmd: ip -M route add 80 dev CUST-A\n  - cmd: ip -M route add 81 dev CUST-B\n  - cmd: >\n      ip -M route add 17001 as 17001\n      nexthop via inet 10.0.0.5 dev net0\n      nexthop via inet 10.0.0.18 dev net1\n  - cmd: ip -M route add 17003 via inet 10.0.0.5 dev net0\n  - cmd: ip -M route add 17004 via inet 10.0.0.18 dev net1\n  - cmd: ip route add 192.168.0.0/24 vrf CUST-A\n      nexthop encap mpls 17001/80 via inet 10.0.0.5 dev net0\n      nexthop encap mpls 17001/80 via inet 10.0.0.18 dev net1\n  - cmd: ip route add 192.168.0.0/24 vrf CUST-B\n      nexthop encap mpls 17001/81 via inet 10.0.0.5 dev net0\n      nexthop encap mpls 17001/81 via inet 10.0.0.18 dev net1\n\n- name: R3\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: sysctl -w net.mpls.conf.net2.input=1\n  - cmd: ip addr add 10.0.0.2/30 dev net0\n  - cmd: ip addr add 10.0.0.5/30 dev net1\n  - cmd: ip addr add 10.0.0.13/30 dev net2\n  - cmd: ip -M route add 17001 via inet 10.0.0.1 dev net0\n  - cmd: ip -M route add 17002 via inet 10.0.0.6 dev net1\n  - cmd: ip -M route add 17004 via inet 10.0.0.14 dev net2\n\n- name: R4\n  cmds:\n  - cmd: sysctl -w net.mpls.conf.lo.input=1\n  - cmd: sysctl -w net.mpls.conf.net0.input=1\n  - cmd: sysctl -w net.mpls.conf.net1.input=1\n  - cmd: sysctl -w net.mpls.conf.net2.input=1\n  - cmd: ip addr add 10.0.0.10/30 dev net0\n  - cmd: ip addr add 10.0.0.18/30 dev net1\n  - cmd: ip addr add 10.0.0.14/30 dev net2\n  - cmd: ip -M route add 17001 via inet 10.0.0.9 dev net0\n  - cmd: ip -M route add 17002 via inet 10.0.0.17 dev net1\n  - cmd: ip -M route add 17003 via inet 10.0.0.13 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostA2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n- name: HostB1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostB2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n"
  },
  {
    "path": "examples/srv6_l2vpn_static_linux_hack/README.md",
    "content": "# L2VPN using SRv6 static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srv6_l2vpn_static_linux_hack/spec.yaml",
    "content": "preinit:\n- cmds:\n  - cmd: modprobe vrf\n\nnodes:\n- name: R1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip link set net2 down\n  - cmd: ip link set net2 address 52:54:00:00:00:A2\n  - cmd: ip link set net2 up\n\n  - cmd: ip addr add 2001:13::1/64 dev net0\n  - cmd: ip addr add 2001:14::1/64 dev net1\n  - cmd: >-\n      ip route add fc00:2::/64\n      nexthop via 2001:13::3 dev net0\n      nexthop via 2001:14::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:13::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:14::4 dev net1\n\n  ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type bridge\n  - cmd: ip link add CUST-B type bridge\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n\n  - cmd: ip route add fc00:1::10/128 encap seg6local action End.DX2 oif CUST-A dev CUST-A\n  - cmd: ip route add fc00:1::20/128 encap seg6local action End.DX2 oif CUST-B dev CUST-B\n  - cmd: >-\n      ip route add 2001:db8::/64 table 10\n      nexthop encap seg6 mode l2encap segs fc00:2::10 via 2001:13::3 dev net0\n      nexthop encap seg6 mode l2encap segs fc00:2::10 via 2001:14::4 dev net1\n  - cmd: >-\n      ip route add 2001:db8::/64 table 20\n      nexthop encap seg6 mode l2encap segs fc00:2::20 via 2001:13::3 dev net0\n      nexthop encap seg6 mode l2encap segs fc00:2::20 via 2001:14::4 dev net1\n\n- name: R2\n  cmds:\n  - cmd: ip link set net2 down\n  - cmd: ip link set net2 address 52:54:00:00:00:A1\n  - cmd: ip link set net2 up\n\n  - cmd: ip addr add 2001:23::2/64 dev net0\n  - cmd: ip addr add 2001:24::2/64 dev net1\n  - cmd: >-\n      ip route add fc00:1::/64\n      nexthop via 2001:23::3 dev net0\n      nexthop via 2001:24::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:23::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:24::4 dev net1\n\n  # ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type bridge\n  - cmd: ip link add CUST-B type bridge\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n\n  - cmd: ip route add fc00:2::10/128 encap seg6local action End.DX2 oif CUST-A dev CUST-A\n  - cmd: ip route add fc00:2::20/128 encap seg6local action End.DX2 oif CUST-B dev CUST-B\n  - cmd: >-\n      ip route add 2001:db8::/64 table 10\n      nexthop encap seg6 mode l2encap segs fc00:1::10 via 2001:23::3 dev net0\n      nexthop encap seg6 mode l2encap segs fc00:1::10 via 2001:24::4 dev net1\n  - cmd: >-\n      ip route add 2001:db8::/64 table 20\n      nexthop encap seg6 mode l2encap segs fc00:1::20 via 2001:23::3 dev net0\n      nexthop encap seg6 mode l2encap segs fc00:1::20 via 2001:24::4 dev net1\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 2001:13::3/64 dev net0\n  - cmd: ip addr add 2001:23::3/64 dev net1\n  - cmd: ip addr add 2001:34::3/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:13::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:23::2 dev net1\n  - cmd: ip route add fc00:4::/64 via 2001:34::4 dev net2\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 2001:14::4/64 dev net0\n  - cmd: ip addr add 2001:24::4/64 dev net1\n  - cmd: ip addr add 2001:34::4/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:14::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:24::2 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:34::3 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:A1\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::1/64 dev net0\n  - cmd: ip nei replace 2001:db8::2 lladdr 52:54:00:00:00:A2 dev net0\n- name: HostA2\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:A2\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::2/64 dev net0\n  - cmd: ip nei replace 2001:db8::1 lladdr 52:54:00:00:00:A1 dev net0\n- name: HostB1\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:B1\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::1/64 dev net0\n  - cmd: ip nei replace 2001:db8::2 lladdr 52:54:00:00:00:A2 dev net0\n- name: HostB2\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:B2\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::2/64 dev net0\n  - cmd: ip nei replace 2001:db8::1 lladdr 52:54:00:00:00:A1 dev net0\n"
  },
  {
    "path": "examples/srv6_l2vpn_static_vpp/README.md",
    "content": "# L2VPN using SRv6 static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srv6_l2vpn_static_vpp/spec.yaml",
    "content": "postinit:\n  cmds:\n  - cmd: modprobe vrf\n  - cmd: |\n      cat <<EOF > /tmp/r1_exec.vpp\n      create host-interface name net0\n      create host-interface name net1\n      create host-interface name net2\n      create host-interface name net3\n      set int state host-net0 up\n      set int state host-net1 up\n      set int state host-net2 up\n      set int state host-net3 up\n\n      set int ip addr host-net0 2001:13::1/64\n      set int ip addr host-net1 2001:14::1/64\n      ip route add fc00:2::/64 via 2001:13::3\n      ip route add fc00:2::/64 via 2001:14::4\n      ip route add fc00:3::/64 via 2001:13::3\n      ip route add fc00:4::/64 via 2001:14::4\n\n      sr localsid address fc00:1:: behavior end\n      sr localsid address fc00:1::10 behavior end.dx2 host-net2\n      sr localsid address fc00:1::20 behavior end.dx2 host-net3\n      set sr encaps source addr fc00:1::\n\n      sr policy add bsid cafe::10 next fc00:2::10 fib-table 0\n      sr policy add bsid cafe::20 next fc00:2::20 fib-table 0\n      sr steer l2 host-net2 via bsid cafe::10\n      sr steer l2 host-net3 via bsid cafe::20\n      EOF\n  - cmd: |\n      cat <<EOF > /tmp/r2_exec.vpp\n      create host-interface name net0\n      create host-interface name net1\n      create host-interface name net2\n      create host-interface name net3\n      set int state host-net0 up\n      set int state host-net1 up\n      set int state host-net2 up\n      set int state host-net3 up\n\n      set int ip addr host-net0 2001:23::2/64\n      set int ip addr host-net1 2001:24::2/64\n      ip route add fc00:1::/64 via 2001:23::3\n      ip route add fc00:1::/64 via 2001:24::4\n      ip route add fc00:3::/64 via 2001:23::3\n      ip route add fc00:4::/64 via 2001:24::4\n\n      sr localsid address fc00:2:: behavior end\n      sr localsid address fc00:2::10 behavior end.dx2 host-net2\n      sr localsid address fc00:2::20 behavior end.dx2 host-net3\n      set sr encaps source addr fc00:2::\n\n      sr policy add bsid cafe::10 next fc00:1::10 fib-table 0\n      sr policy add bsid cafe::20 next fc00:1::20 fib-table 0\n      sr steer l2 host-net2 via bsid cafe::10\n      sr steer l2 host-net3 via bsid cafe::20\n      EOF\n  - cmd: docker exec R1 mkdir -p /etc/vpp\n  - cmd: docker exec R2 mkdir -p /etc/vpp\n  - cmd: docker cp /tmp/r1_exec.vpp R1:/etc/vpp/exec.vpp\n  - cmd: docker cp /tmp/r2_exec.vpp R2:/etc/vpp/exec.vpp\n\nnodes:\n- name: R1\n  image: slankdev/vpp:19.04 # ligato/vpp-base:master\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: slankdev/vpp:19.04 # ligato/vpp-base:master\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: nohup vpp -c /etc/vpp/startup.conf &\n\n- name: R2\n  cmds:\n  - cmd: nohup vpp -c /etc/vpp/startup.conf &\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 2001:13::3/64 dev net0\n  - cmd: ip addr add 2001:23::3/64 dev net1\n  - cmd: ip addr add 2001:34::3/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:13::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:23::2 dev net1\n  - cmd: ip route add fc00:4::/64 via 2001:34::4 dev net2\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 2001:14::4/64 dev net0\n  - cmd: ip addr add 2001:24::4/64 dev net1\n  - cmd: ip addr add 2001:34::4/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:14::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:24::2 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:34::3 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:A1\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::1/64 dev net0\n  - cmd: ip nei replace 2001:db8::2 lladdr 52:54:00:00:00:A2 dev net0\n- name: HostA2\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:A2\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::2/64 dev net0\n  - cmd: ip nei replace 2001:db8::1 lladdr 52:54:00:00:00:A1 dev net0\n- name: HostB1\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:B1\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::1/64 dev net0\n  - cmd: ip nei replace 2001:db8::2 lladdr 52:54:00:00:00:A2 dev net0\n- name: HostB2\n  cmds:\n  - cmd: ip link set net0 down\n  - cmd: ip link set net0 address 52:54:00:00:00:B2\n  - cmd: ip link set net0 up\n  - cmd: ip addr add 2001:db8::2/64 dev net0\n  - cmd: ip nei replace 2001:db8::1 lladdr 52:54:00:00:00:A1 dev net0\n"
  },
  {
    "path": "examples/srv6_l3vpnv4_static_linux/README.md",
    "content": "# L3VPN using SRv6 static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srv6_l3vpnv4_static_linux/spec.yaml",
    "content": "preinit:\n- cmds:\n  - cmd: modprobe vrf\n\nnodes:\n- name: R1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 2001:13::1/64 dev net0\n  - cmd: ip addr add 2001:14::1/64 dev net1\n  - cmd: >-\n      ip route add fc00:2::/64\n      nexthop via 2001:13::3 dev net0\n      nexthop via 2001:14::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:13::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:14::4 dev net1\n\n  ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 192.168.0.1/24 dev net2\n  - cmd: ip addr add 192.168.0.1/24 dev net3\n\n  - cmd: ip route add fc00:1::10/128 encap seg6local action End.DT4 vrftable 10 dev CUST-A\n  - cmd: ip route add fc00:1::20/128 encap seg6local action End.DT4 vrftable 20 dev CUST-B\n  - cmd: >-\n      ip route add 192.168.1.0/24 vrf CUST-A\n      nexthop encap seg6 mode encap segs fc00:2::10 dev net0\n      nexthop encap seg6 mode encap segs fc00:2::10 dev net1\n  - cmd: >-\n      ip route add 192.168.1.0/24 vrf CUST-B\n      nexthop encap seg6 mode encap segs fc00:2::20 dev net0\n      nexthop encap seg6 mode encap segs fc00:2::20 dev net1\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 2001:23::2/64 dev net0\n  - cmd: ip addr add 2001:24::2/64 dev net1\n  - cmd: >-\n      ip route add fc00:1::/64\n      nexthop via 2001:23::3 dev net0\n      nexthop via 2001:24::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:23::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:24::4 dev net1\n\n  # ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 192.168.1.1/24 dev net2\n  - cmd: ip addr add 192.168.1.1/24 dev net3\n\n  - cmd: ip route add fc00:2::10/128 encap seg6local action End.DT4 vrftable 10 dev CUST-A\n  - cmd: ip route add fc00:2::20/128 encap seg6local action End.DT4 vrftable 20 dev CUST-B\n  - cmd: >-\n      ip route add 192.168.0.0/24 vrf CUST-A\n      nexthop encap seg6 mode encap segs fc00:1::10 dev net0\n      nexthop encap seg6 mode encap segs fc00:1::10 dev net1\n  - cmd: >-\n      ip route add 192.168.0.0/24 vrf CUST-B\n      nexthop encap seg6 mode encap segs fc00:1::20 dev net0\n      nexthop encap seg6 mode encap segs fc00:1::20 dev net1\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 2001:13::3/64 dev net0\n  - cmd: ip addr add 2001:23::3/64 dev net1\n  - cmd: ip addr add 2001:34::3/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:13::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:23::2 dev net1\n  - cmd: ip route add fc00:4::/64 via 2001:34::4 dev net2\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 2001:14::4/64 dev net0\n  - cmd: ip addr add 2001:24::4/64 dev net1\n  - cmd: ip addr add 2001:34::4/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:14::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:24::2 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:34::3 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostA2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n- name: HostB1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostB2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n"
  },
  {
    "path": "examples/srv6_l3vpnv4_static_linux_pseudo_dt4/README.md",
    "content": "# L3VPN using SRv6 static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srv6_l3vpnv4_static_linux_pseudo_dt4/spec.yaml",
    "content": "preinit:\n- cmds:\n  - cmd: modprobe vrf\n\nnodes:\n- name: R1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 2001:13::1/64 dev net0\n  - cmd: ip addr add 2001:14::1/64 dev net1\n  - cmd: >-\n      ip route add fc00:2::/64\n      nexthop via 2001:13::3 dev net0\n      nexthop via 2001:14::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:13::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:14::4 dev net1\n\n  ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 192.168.0.1/24 dev net2\n  - cmd: ip addr add 192.168.0.1/24 dev net3\n\n  - cmd: ip route add 169.254.0.10 dev CUST-A\n  - cmd: ip route add 169.254.0.20 dev CUST-B\n  - cmd: ip route add fc00:1::10/128 encap seg6local action End.DX4 nh4 169.254.0.10 dev CUST-A\n  - cmd: ip route add fc00:1::20/128 encap seg6local action End.DX4 nh4 169.254.0.20 dev CUST-B\n  - cmd: >-\n      ip route add 192.168.1.0/24 vrf CUST-A\n      nexthop encap seg6 mode encap segs fc00:2::10 dev net0\n      nexthop encap seg6 mode encap segs fc00:2::10 dev net1\n  - cmd: >-\n      ip route add 192.168.1.0/24 vrf CUST-B\n      nexthop encap seg6 mode encap segs fc00:2::20 dev net0\n      nexthop encap seg6 mode encap segs fc00:2::20 dev net1\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 2001:23::2/64 dev net0\n  - cmd: ip addr add 2001:24::2/64 dev net1\n  - cmd: >-\n      ip route add fc00:1::/64\n      nexthop via 2001:23::3 dev net0\n      nexthop via 2001:24::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:23::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:24::4 dev net1\n\n  # ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 192.168.1.1/24 dev net2\n  - cmd: ip addr add 192.168.1.1/24 dev net3\n\n  - cmd: ip route add 169.254.0.10 dev CUST-A\n  - cmd: ip route add 169.254.0.20 dev CUST-B\n  - cmd: ip route add fc00:2::10/128 encap seg6local action End.DX4 nh4 169.254.0.10 dev CUST-A\n  - cmd: ip route add fc00:2::20/128 encap seg6local action End.DX4 nh4 169.254.0.20 dev CUST-B\n  - cmd: >-\n      ip route add 192.168.0.0/24 vrf CUST-A\n      nexthop encap seg6 mode encap segs fc00:1::10 dev net0\n      nexthop encap seg6 mode encap segs fc00:1::10 dev net1\n  - cmd: >-\n      ip route add 192.168.0.0/24 vrf CUST-B\n      nexthop encap seg6 mode encap segs fc00:1::20 dev net0\n      nexthop encap seg6 mode encap segs fc00:1::20 dev net1\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 2001:13::3/64 dev net0\n  - cmd: ip addr add 2001:23::3/64 dev net1\n  - cmd: ip addr add 2001:34::3/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:13::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:23::2 dev net1\n  - cmd: ip route add fc00:4::/64 via 2001:34::4 dev net2\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 2001:14::4/64 dev net0\n  - cmd: ip addr add 2001:24::4/64 dev net1\n  - cmd: ip addr add 2001:34::4/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:14::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:24::2 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:34::3 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostA2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n- name: HostB1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostB2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n"
  },
  {
    "path": "examples/srv6_l3vpnv4_static_vpp/README.md",
    "content": "# L3VPN using SRv6 static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srv6_l3vpnv4_static_vpp/spec.yaml",
    "content": "postinit:\n  cmds:\n  - cmd: modprobe vrf\n  - cmd: |\n      cat <<EOF > /tmp/r1_exec.vpp\n      create host-interface name net0\n      create host-interface name net1\n      create host-interface name net2\n      create host-interface name net3\n      set int state host-net0 up\n      set int state host-net1 up\n      set int state host-net2 up\n      set int state host-net3 up\n      ip table add 10\n      ip table add 20\n      set int ip table host-net2 10\n      set int ip table host-net3 20\n\n      set int ip addr host-net0 2001:13::1/64\n      set int ip addr host-net1 2001:14::1/64\n      set int ip addr host-net2 192.168.0.1/24\n      set int ip addr host-net3 192.168.0.1/24\n      ip route add fc00:2::/64 via 2001:13::3\n      ip route add fc00:2::/64 via 2001:14::4\n      ip route add fc00:3::/64 via 2001:13::3\n      ip route add fc00:4::/64 via 2001:14::4\n\n      sr localsid address fc00:1:: behavior end\n      sr localsid address fc00:1::10 behavior end.dt4 10\n      sr localsid address fc00:1::20 behavior end.dt4 20\n      set sr encaps source addr fc00:1::\n\n      sr policy add bsid cafe::10 next fc00:2::10 fib-table 0\n      sr policy add bsid cafe::20 next fc00:2::20 fib-table 0\n      sr steer l3 192.168.1.0/24 via bsid cafe::10 fib-table 10\n      sr steer l3 192.168.1.0/24 via bsid cafe::20 fib-table 20\n      EOF\n  - cmd: |\n      cat <<EOF > /tmp/r2_exec.vpp\n      create host-interface name net0\n      create host-interface name net1\n      create host-interface name net2\n      create host-interface name net3\n      set int state host-net0 up\n      set int state host-net1 up\n      set int state host-net2 up\n      set int state host-net3 up\n      ip table add 10\n      ip table add 20\n      set int ip table host-net2 10\n      set int ip table host-net3 20\n\n      set int ip addr host-net0 2001:23::2/64\n      set int ip addr host-net1 2001:24::2/64\n      set int ip addr host-net2 192.168.1.1/24\n      set int ip addr host-net3 192.168.1.1/24\n      ip route add fc00:1::/64 via 2001:23::3\n      ip route add fc00:1::/64 via 2001:24::4\n      ip route add fc00:3::/64 via 2001:23::3\n      ip route add fc00:4::/64 via 2001:24::4\n\n      sr localsid address fc00:2:: behavior end\n      sr localsid address fc00:2::10 behavior end.dt4 10\n      sr localsid address fc00:2::20 behavior end.dt4 20\n      set sr encaps source addr fc00:2::\n\n      sr policy add bsid cafe::10 next fc00:1::10 fib-table 0\n      sr policy add bsid cafe::20 next fc00:1::20 fib-table 0\n      sr steer l3 192.168.0.0/24 via bsid cafe::10 fib-table 10\n      sr steer l3 192.168.0.0/24 via bsid cafe::20 fib-table 20\n      EOF\n  - cmd: docker exec R1 mkdir -p /etc/vpp\n  - cmd: docker exec R2 mkdir -p /etc/vpp\n  - cmd: docker cp /tmp/r1_exec.vpp R1:/etc/vpp/exec.vpp\n  - cmd: docker cp /tmp/r2_exec.vpp R2:/etc/vpp/exec.vpp\n\nnodes:\n- name: R1\n  image: slankdev/vpp:19.04 # ligato/vpp-base:master\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  # image: nicolaka/netshoot\n  image: slankdev/vpp:19.04 # ligato/vpp-base:master\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: nohup vpp -c /etc/vpp/startup.conf &\n\n- name: R2\n  cmds:\n  - cmd: nohup vpp -c /etc/vpp/startup.conf &\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 2001:13::3/64 dev net0\n  - cmd: ip addr add 2001:23::3/64 dev net1\n  - cmd: ip addr add 2001:34::3/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:13::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:23::2 dev net1\n  - cmd: ip route add fc00:4::/64 via 2001:34::4 dev net2\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 2001:14::4/64 dev net0\n  - cmd: ip addr add 2001:24::4/64 dev net1\n  - cmd: ip addr add 2001:34::4/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:14::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:24::2 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:34::3 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostA2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n- name: HostB1\n  cmds:\n  - cmd: ip addr add 192.168.0.2/24 dev net0\n  - cmd: ip route add default via 192.168.0.1\n- name: HostB2\n  cmds:\n  - cmd: ip addr add 192.168.1.2/24 dev net0\n  - cmd: ip route add default via 192.168.1.1\n"
  },
  {
    "path": "examples/srv6_l3vpnv6_static_linux/README.md",
    "content": "# L3VPNv6 using SRv6 static config\n![](./topo.drawio.png)\n"
  },
  {
    "path": "examples/srv6_l3vpnv6_static_linux/spec.yaml",
    "content": "preinit:\n- cmds:\n  - cmd: modprobe vrf\n\nnodes:\n- name: R1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net0 }\n  - { name: net1, type: direct, args: R4#net0 }\n  - { name: net2, type: direct, args: HostA1#net0 }\n  - { name: net3, type: direct, args: HostB1#net0 }\n- name: R2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.vrf.strict_mode=1\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R3#net1 }\n  - { name: net1, type: direct, args: R4#net1 }\n  - { name: net2, type: direct, args: HostA2#net0 }\n  - { name: net3, type: direct, args: HostB2#net0 }\n- name: R3\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net0 }\n  - { name: net1, type: direct, args: R2#net0 }\n  - { name: net2, type: direct, args: R4#net2 }\n- name: R4\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n  - sysctl: net.ipv4.conf.all.rp_filter=0\n  - sysctl: net.ipv4.conf.default.rp_filter=0\n  - sysctl: net.ipv6.conf.all.forwarding=1\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.all.seg6_enabled=1\n  - sysctl: net.ipv6.conf.default.forwarding=1\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.seg6_enabled=1\n  interfaces:\n  - { name: net0, type: direct, args: R1#net1 }\n  - { name: net1, type: direct, args: R2#net1 }\n  - { name: net2, type: direct, args: R3#net2 }\n- name: HostA1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R1#net2 }\n- name: HostA2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R2#net2 }\n- name: HostB1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R1#net3 }\n- name: HostB2\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  sysctls:\n  - sysctl: net.ipv6.conf.all.disable_ipv6=0\n  - sysctl: net.ipv6.conf.default.disable_ipv6=0\n  interfaces:\n  - { name: net0, type: direct, args: R2#net3 }\n\nnode_configs:\n- name: R1\n  cmds:\n  - cmd: ip addr add 2001:13::1/64 dev net0\n  - cmd: ip addr add 2001:14::1/64 dev net1\n  - cmd: >-\n      ip route add fc00:2::/64\n      nexthop via 2001:13::3 dev net0\n      nexthop via 2001:14::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:13::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:14::4 dev net1\n\n  ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 2001:db8:1::1/64 dev net2\n  - cmd: ip addr add 2001:db8:1::1/64 dev net3\n\n  - cmd: ip route add fc00:1::10/128 encap seg6local action End.DT6 table 10 dev CUST-A\n  - cmd: ip route add fc00:1::20/128 encap seg6local action End.DT6 table 20 dev CUST-B\n  - cmd: >-\n      ip route add 2001:db8:2::/64 vrf CUST-A\n      nexthop encap seg6 mode encap segs fc00:2::10 via 2001:13::3 dev net0\n      nexthop encap seg6 mode encap segs fc00:2::10 via 2001:14::4 dev net1\n  - cmd: >-\n      ip route add 2001:db8:2::/64 vrf CUST-B\n      nexthop encap seg6 mode encap segs fc00:2::20 via 2001:13::3 dev net0\n      nexthop encap seg6 mode encap segs fc00:2::20 via 2001:14::4 dev net1\n\n- name: R2\n  cmds:\n  - cmd: ip addr add 2001:23::2/64 dev net0\n  - cmd: ip addr add 2001:24::2/64 dev net1\n  - cmd: >-\n      ip route add fc00:1::/64\n      nexthop via 2001:23::3 dev net0\n      nexthop via 2001:24::4 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:23::3 dev net0\n  - cmd: ip route add fc00:4::/64 via 2001:24::4 dev net1\n\n  # ## L2VPN Base Interface Configuration\n  - cmd: ip link add CUST-A type vrf table 10\n  - cmd: ip link add CUST-B type vrf table 20\n  - cmd: ip link set CUST-A up\n  - cmd: ip link set CUST-B up\n  - cmd: ip link set net2 master CUST-A\n  - cmd: ip link set net3 master CUST-B\n  - cmd: ip addr add 2001:db8:2::1/64 dev net2\n  - cmd: ip addr add 2001:db8:2::1/64 dev net3\n\n  - cmd: ip route add fc00:2::10/128 encap seg6local action End.DT6 table 10 dev CUST-A\n  - cmd: ip route add fc00:2::20/128 encap seg6local action End.DT6 table 20 dev CUST-B\n  - cmd: >-\n      ip route add 2001:db8:1::/64 vrf CUST-A\n      nexthop encap seg6 mode encap segs fc00:1::10 via 2001:23::3 dev net0\n      nexthop encap seg6 mode encap segs fc00:1::10 via 2001:24::4 dev net1\n  - cmd: >-\n      ip route add 2001:db8:1::/64 vrf CUST-B\n      nexthop encap seg6 mode encap segs fc00:1::20 via 2001:23::3 dev net0\n      nexthop encap seg6 mode encap segs fc00:1::20 via 2001:24::4 dev net1\n\n- name: R3\n  cmds:\n  - cmd: ip addr add 2001:13::3/64 dev net0\n  - cmd: ip addr add 2001:23::3/64 dev net1\n  - cmd: ip addr add 2001:34::3/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:13::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:23::2 dev net1\n  - cmd: ip route add fc00:4::/64 via 2001:34::4 dev net2\n\n- name: R4\n  cmds:\n  - cmd: ip addr add 2001:14::4/64 dev net0\n  - cmd: ip addr add 2001:24::4/64 dev net1\n  - cmd: ip addr add 2001:34::4/64 dev net2\n  - cmd: ip route add fc00:1::/64 via 2001:14::1 dev net0\n  - cmd: ip route add fc00:2::/64 via 2001:24::2 dev net1\n  - cmd: ip route add fc00:3::/64 via 2001:34::3 dev net2\n\n- name: HostA1\n  cmds:\n  - cmd: ip addr add 2001:db8:1::2/64 dev net0\n  - cmd: ip -6 route add default via 2001:db8:1::1\n- name: HostA2\n  cmds:\n  - cmd: ip addr add 2001:db8:2::2/64 dev net0\n  - cmd: ip -6 route add default via 2001:db8:2::1\n- name: HostB1\n  cmds:\n  - cmd: ip addr add 2001:db8:1::2/64 dev net0\n  - cmd: ip -6 route add default via 2001:db8:1::1\n- name: HostB2\n  cmds:\n  - cmd: ip addr add 2001:db8:2::2/64 dev net0\n  - cmd: ip -6 route add default via 2001:db8:2::1\n"
  },
  {
    "path": "examples/trex/dual_node_single_instance/README.md",
    "content": "# TRex\n\n```\ntinet upconf | sudo sh -xe\ndocker exec -it T2 ./t-rex-64 --astf --astf-server-only -f tcp_open.py --cfg server.yaml\ndocker exec -it T1 ./t-rex-64 --astf --astf-client-mask 0x1 -f tcp_open.py --cfg client.yaml\n```\n"
  },
  {
    "path": "examples/trex/dual_node_single_instance/client.yaml",
    "content": "- port_limit: 2\n  version: 2\n  interfaces:\n  - \"net0\"\n  - \"dum0\"\n  platform:\n    master_thread_id: 3\n    latency_thread_id: 4\n    dual_if:\n    - socket: 0\n      threads: [5]\n"
  },
  {
    "path": "examples/trex/dual_node_single_instance/server.yaml",
    "content": "- port_limit: 2\n  version: 2\n  interfaces:\n  - \"dum0\"\n  - \"net0\"\n  platform:\n    master_thread_id: 0\n    latency_thread_id: 1\n    dual_if:\n    - socket: 0\n      threads: [2]\n"
  },
  {
    "path": "examples/trex/dual_node_single_instance/spec.yaml",
    "content": "nodes:\n- name: T1\n  #image: nicolaka/netshoot\n  image: tinynetwork/trex:develop\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: T2#net0 }\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n- name: T2\n  image: tinynetwork/trex:develop\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: T1#net0 }\n\nnode_configs:\n- name: T1\n  cmds:\n  - cmd: ip link add dum0 type dummy\n  - cmd: ip link set dum0 up\n- name: T2\n  cmds:\n  - cmd: ip link add dum0 type dummy\n  - cmd: ip link set dum0 up\n\npostinit:\n  cmds:\n  - cmd: mkdir -p /var/run/netns\n  - cmd: ln -s /proc/$(docker inspect T1 -f {{.State.Pid}})/ns/net /var/run/netns/T1\n  - cmd: ln -s /proc/$(docker inspect T2 -f {{.State.Pid}})/ns/net /var/run/netns/T2\n  - cmd: docker cp client.yaml T1:/opt/trex\n  - cmd: docker cp tcp_open.py T1:/opt/trex\n  - cmd: docker cp tcp_openclose.py T1:/opt/trex\n  - cmd: docker cp server.yaml T2:/opt/trex\n  - cmd: docker cp tcp_open.py T2:/opt/trex\n  - cmd: docker cp tcp_openclose.py T2:/opt/trex\n"
  },
  {
    "path": "examples/trex/dual_node_single_instance/tcp_open.py",
    "content": "from trex.astf.api import *\nimport argparse\n\n\nclass Prof1():\n    def __init__(self):\n        pass  # tunables\n\n    def create_profile(self, cps):\n        prog_c = ASTFProgram()\n        prog_c.connect()\n        prog_c.reset()\n        prog_s = ASTFProgram()\n        prog_s.wait_for_peer_close()\n\n        # ip generator\n        ip_gen_c = ASTFIPGenDist(ip_range=[\"20.0.0.0\", \"20.0.255.255\"], distribution=\"seq\")\n        ip_gen_s = ASTFIPGenDist(ip_range=[\"30.0.0.0\", \"30.0.255.255\"], distribution=\"seq\")\n        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset=\"1.0.0.0\"),\n                           dist_client=ip_gen_c,\n                           dist_server=ip_gen_s)\n\n        # template\n        temp_c = ASTFTCPClientTemplate(program=prog_c,  ip_gen=ip_gen, cps=cps)\n        temp_s = ASTFTCPServerTemplate(program=prog_s)\n        template = ASTFTemplate(client_template=temp_c, server_template=temp_s)\n\n        # profile\n        profile = ASTFProfile(default_ip_gen=ip_gen,\n                              templates=template)\n        return profile\n\n    def get_profile(self, tunables, **kwargs):\n        parser = argparse.ArgumentParser(\n            description='Argparser for {}'.format(os.path.basename(__file__)),\n            formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n        parser.add_argument('--cps', type=int, default=1)\n        args = parser.parse_args(tunables)\n        return self.create_profile(args.cps)\n\n\ndef register():\n    return Prof1()\n"
  },
  {
    "path": "examples/trex/dual_node_single_instance/tcp_openclose.py",
    "content": "from trex.astf.api import *\nimport argparse\n\n\nclass Prof1():\n    def __init__(self):\n        pass  # tunables\n\n    def create_profile(self, cps):\n        prog_c = ASTFProgram()\n        prog_c.connect()\n        prog_s = ASTFProgram()\n        prog_s.wait_for_peer_close()\n\n        # ip generator\n        ip_gen_c = ASTFIPGenDist(ip_range=[\"20.0.0.0\", \"20.0.255.255\"], distribution=\"seq\")\n        ip_gen_s = ASTFIPGenDist(ip_range=[\"30.0.0.0\", \"30.0.255.255\"], distribution=\"seq\")\n        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset=\"1.0.0.0\"),\n                           dist_client=ip_gen_c,\n                           dist_server=ip_gen_s)\n\n        # template\n        temp_c = ASTFTCPClientTemplate(program=prog_c,  ip_gen=ip_gen, cps=cps)\n        temp_s = ASTFTCPServerTemplate(program=prog_s)\n        template = ASTFTemplate(client_template=temp_c, server_template=temp_s)\n\n        # profile\n        profile = ASTFProfile(default_ip_gen=ip_gen,\n                              templates=template)\n        return profile\n\n    def get_profile(self, tunables, **kwargs):\n        parser = argparse.ArgumentParser(\n            description='Argparser for {}'.format(os.path.basename(__file__)),\n            formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n        parser.add_argument('--cps', type=int, default=1)\n        args = parser.parse_args(tunables)\n        return self.create_profile(args.cps)\n\n\ndef register():\n    return Prof1()\n"
  },
  {
    "path": "examples/trex/simple/README.md",
    "content": "# TRex\n\n```\ntinet upconf | sudo sh -xe\ndocker exec -it T1\n./t-rex-64 -i --astf --cfg ./cfg.yaml\n./trex-console\ntrex>start -f http_eflow.py -t cps=10\n```\n"
  },
  {
    "path": "examples/trex/simple/cfg.yaml",
    "content": "- port_limit: 2\n  version: 2\n  interfaces:\n  - \"net0\"\n  - \"net1\"\n"
  },
  {
    "path": "examples/trex/simple/new_connection_test.py",
    "content": "# Location\n# /opt/trex/automation/trex_control_plane/interactive/trex/examples/astf\nimport astf_path\nfrom trex.astf.api import *\nimport pprint\nimport argparse\nimport os\nimport sys\nimport time\n\n\nclass Prof1():\n    def create_profile(self, cps):\n        prog_c = ASTFProgram()\n        prog_c.connect()\n        prog_c.reset()\n        prog_s = ASTFProgram()\n        prog_s.wait_for_peer_close()\n\n        # ip generator\n        ip_gen_c = ASTFIPGenDist(ip_range=[\"20.0.0.0\", \"20.0.255.255\"], distribution=\"seq\")\n        ip_gen_s = ASTFIPGenDist(ip_range=[\"30.0.0.0\", \"30.0.255.255\"], distribution=\"seq\")\n        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset=\"1.0.0.0\"),\n                           dist_client=ip_gen_c,\n                           dist_server=ip_gen_s)\n\n        # template\n        temp_c = ASTFTCPClientTemplate(program=prog_c,  ip_gen=ip_gen, cps=cps)\n        temp_s = ASTFTCPServerTemplate(program=prog_s)\n        template = ASTFTemplate(client_template=temp_c, server_template=temp_s)\n\n        # profile\n        profile = ASTFProfile(default_ip_gen=ip_gen,\n                              templates=template)\n        return profile\n\n\n\nparser = argparse.ArgumentParser()\nparser.add_argument('--mult', \"-m\", default=1, type=int)\nargs = parser.parse_args()\n\nc = ASTFClient()\nc.connect()\nc.reset()\nprint(\"astfclient initialized\")\n\nc.load_profile(Prof1().create_profile(1))\nc.clear_stats()\nc.start(mult=args.mult, duration=3600)\nprint(\"started\")\n\ndef dig(d, keys):\n    for key in keys:\n        d = d.get(key, None)\n        if d is None:\n            return 0\n            break\n    return d\n\nsv_tcps_connects = 0\ncl_tcps_connects = 0\nlast_sv_tcps_connects = 0\nlast_cl_tcps_connects = 0\nwhile True:\n    stats = c.get_stats()\n    last_sv_tcps_connects = sv_tcps_connects\n    last_cl_tcps_connects = cl_tcps_connects\n    cl_tcps_connects = dig(stats, [\"traffic\", \"client\", \"tcps_connects\"])\n    sv_tcps_connects = dig(stats, [\"traffic\", \"server\", \"tcps_connects\"])\n    rate_sv_tcps_connects = sv_tcps_connects - last_sv_tcps_connects\n    rate_cl_tcps_connects = cl_tcps_connects - last_cl_tcps_connects\n    print(\"global.tx_cps: {}\".format(stats.get(\"global\", {}).get(\"tx_cps\", {})))\n    print(\"global.cpu_util: {}\".format(stats.get(\"global\", {}).get(\"cpu_util\", {})))\n    print(\"global.rx_drop_bps: {}\".format(stats.get(\"global\", {}).get(\"rx_drop_bps\", {})))\n    print(\"traffic.client.tcps_connattempt: {}\".format(dig(stats, [\"traffic\", \"client\", \"tcps_connattempt\"])))\n    print(\"traffic.client.tcps_connects: {}\".format(dig(stats, [\"traffic\", \"client\", \"tcps_connects\"])))\n    print(\"traffic.server.tcps_connects: {}\".format(dig(stats, [\"traffic\", \"server\", \"tcps_connects\"])))\n    print(\"rate traffic.client.tcps_connects: {}\".format(rate_cl_tcps_connects))\n    print(\"rate traffic.server.tcps_connects: {}\".format(rate_sv_tcps_connects))\n    print(\"---\")\n    time.sleep(1)\n"
  },
  {
    "path": "examples/trex/simple/spec.yaml",
    "content": "nodes:\n- name: DUT1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: T1#net0 }\n  - { name: net1, type: direct, args: T1#net1 }\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n- name: T1\n  image: tinynetwork/trex:develop\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: DUT1#net0 }\n  - { name: net1, type: direct, args: DUT1#net1 }\n\nnode_configs:\n- name: DUT1\n  cmds:\n  - cmd: ip link add br0 type bridge\n  - cmd: ip link set br0 up\n  - cmd: ip link set net0 master br0\n  - cmd: ip link set net1 master br0\n\npostinit:\n  cmds:\n  - cmd: mkdir -p /var/run/netns\n  - cmd: ln -s /proc/$(docker inspect T1 -f {{.State.Pid}})/ns/net /var/run/netns/T1\n  - cmd: docker cp cfg.yaml T1:/opt/trex\n  - cmd: docker cp tcp_open.py T1:/opt/trex\n  - cmd: docker cp tcp_openclose.py T1:/opt/trex\n"
  },
  {
    "path": "examples/trex/simple/tcp_open.py",
    "content": "from trex.astf.api import *\nimport argparse\n\n\nclass Prof1():\n    def __init__(self):\n        pass  # tunables\n\n    def create_profile(self, cps):\n        prog_c = ASTFProgram()\n        prog_c.connect()\n        prog_c.reset()\n        prog_s = ASTFProgram()\n        prog_s.wait_for_peer_close()\n\n        # ip generator\n        ip_gen_c = ASTFIPGenDist(ip_range=[\"20.0.0.0\", \"20.0.255.255\"], distribution=\"seq\")\n        ip_gen_s = ASTFIPGenDist(ip_range=[\"30.0.0.0\", \"30.0.255.255\"], distribution=\"seq\")\n        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset=\"1.0.0.0\"),\n                           dist_client=ip_gen_c,\n                           dist_server=ip_gen_s)\n\n        # template\n        temp_c = ASTFTCPClientTemplate(program=prog_c,  ip_gen=ip_gen, cps=cps)\n        temp_s = ASTFTCPServerTemplate(program=prog_s)\n        template = ASTFTemplate(client_template=temp_c, server_template=temp_s)\n\n        # profile\n        profile = ASTFProfile(default_ip_gen=ip_gen,\n                              templates=template)\n        return profile\n\n    def get_profile(self, tunables, **kwargs):\n        parser = argparse.ArgumentParser(\n            description='Argparser for {}'.format(os.path.basename(__file__)),\n            formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n        parser.add_argument('--cps', type=int, default=1)\n        args = parser.parse_args(tunables)\n        return self.create_profile(args.cps)\n\n\ndef register():\n    return Prof1()\n"
  },
  {
    "path": "examples/trex/simple/tcp_openclose.py",
    "content": "from trex.astf.api import *\nimport argparse\n\n\nclass Prof1():\n    def __init__(self):\n        pass  # tunables\n\n    def create_profile(self, cps):\n        prog_c = ASTFProgram()\n        prog_c.connect()\n        prog_s = ASTFProgram()\n        prog_s.wait_for_peer_close()\n\n        # ip generator\n        ip_gen_c = ASTFIPGenDist(ip_range=[\"20.0.0.0\", \"20.0.255.255\"], distribution=\"seq\")\n        ip_gen_s = ASTFIPGenDist(ip_range=[\"30.0.0.0\", \"30.0.255.255\"], distribution=\"seq\")\n        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset=\"1.0.0.0\"),\n                           dist_client=ip_gen_c,\n                           dist_server=ip_gen_s)\n\n        # template\n        temp_c = ASTFTCPClientTemplate(program=prog_c,  ip_gen=ip_gen, cps=cps)\n        temp_s = ASTFTCPServerTemplate(program=prog_s)\n        template = ASTFTemplate(client_template=temp_c, server_template=temp_s)\n\n        # profile\n        profile = ASTFProfile(default_ip_gen=ip_gen,\n                              templates=template)\n        return profile\n\n    def get_profile(self, tunables, **kwargs):\n        parser = argparse.ArgumentParser(\n            description='Argparser for {}'.format(os.path.basename(__file__)),\n            formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n        parser.add_argument('--cps', type=int, default=1)\n        args = parser.parse_args(tunables)\n        return self.create_profile(args.cps)\n\n\ndef register():\n    return Prof1()\n"
  },
  {
    "path": "examples/trex/single_node_dual_instance/README.md",
    "content": "# TRex\n\n```\ntinet upconf | sudo sh -xe\ndocker exec -it T1 ./t-rex-64 --astf --astf-server-only -f tcp_open.py --cfg server.yaml\ndocker exec -it T1 ./t-rex-64 --astf --astf-client-mask 0x1 -f tcp_open.py --cfg client.yaml\n```\n"
  },
  {
    "path": "examples/trex/single_node_dual_instance/client.yaml",
    "content": "- port_limit: 2\n  version: 2\n  prefix: client\n  zmq_pub_port: 4600\n  zmq_rpc_port: 4601\n  interfaces:\n  - \"net0\"\n  - \"dum0\"\n  platform:\n    master_thread_id: 3\n    latency_thread_id: 4\n    dual_if:\n    - socket: 0\n      threads: [5]\n"
  },
  {
    "path": "examples/trex/single_node_dual_instance/server.yaml",
    "content": "- port_limit: 2\n  version: 2\n  prefix: server\n  zmq_pub_port: 4700\n  zmq_rpc_port: 4701\n  interfaces:\n  - \"dum1\"\n  - \"net1\"\n  platform:\n    master_thread_id: 0\n    latency_thread_id: 1\n    dual_if:\n    - socket: 0\n      threads: [2]\n"
  },
  {
    "path": "examples/trex/single_node_dual_instance/spec.yaml",
    "content": "nodes:\n- name: DUT1\n  image: nicolaka/netshoot\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: T1#net0 }\n  - { name: net1, type: direct, args: T1#net1 }\n  sysctls:\n  - sysctl: net.ipv4.ip_forward=1\n- name: T1\n  image: tinynetwork/trex:develop\n  docker_run_extra_args: --entrypoint bash\n  interfaces:\n  - { name: net0, type: direct, args: DUT1#net0 }\n  - { name: net1, type: direct, args: DUT1#net1 }\n\nnode_configs:\n- name: T1\n  cmds:\n  - cmd: ip link add dum0 type dummy\n  - cmd: ip link add dum1 type dummy\n  - cmd: ip link set dum0 up\n  - cmd: ip link set dum1 up\n- name: DUT1\n  cmds:\n  - cmd: ip link add br0 type bridge\n  - cmd: ip link set br0 up\n  - cmd: ip link set net0 master br0\n  - cmd: ip link set net1 master br0\n\npostinit:\n  cmds:\n  - cmd: mkdir -p /var/run/netns\n  - cmd: ln -s /proc/$(docker inspect T1 -f {{.State.Pid}})/ns/net /var/run/netns/T1\n  - cmd: docker cp client.yaml T1:/opt/trex\n  - cmd: docker cp server.yaml T1:/opt/trex\n  - cmd: docker cp tcp_open.py T1:/opt/trex\n  - cmd: docker cp tcp_openclose.py T1:/opt/trex\n"
  },
  {
    "path": "examples/trex/single_node_dual_instance/tcp_open.py",
    "content": "from trex.astf.api import *\nimport argparse\n\n\nclass Prof1():\n    def __init__(self):\n        pass  # tunables\n\n    def create_profile(self, cps):\n        prog_c = ASTFProgram()\n        prog_c.connect()\n        prog_c.reset()\n        prog_s = ASTFProgram()\n        prog_s.wait_for_peer_close()\n\n        # ip generator\n        ip_gen_c = ASTFIPGenDist(ip_range=[\"20.0.0.0\", \"20.0.255.255\"], distribution=\"seq\")\n        ip_gen_s = ASTFIPGenDist(ip_range=[\"30.0.0.0\", \"30.0.255.255\"], distribution=\"seq\")\n        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset=\"1.0.0.0\"),\n                           dist_client=ip_gen_c,\n                           dist_server=ip_gen_s)\n\n        # template\n        temp_c = ASTFTCPClientTemplate(program=prog_c,  ip_gen=ip_gen, cps=cps)\n        temp_s = ASTFTCPServerTemplate(program=prog_s)\n        template = ASTFTemplate(client_template=temp_c, server_template=temp_s)\n\n        # profile\n        profile = ASTFProfile(default_ip_gen=ip_gen,\n                              templates=template)\n        return profile\n\n    def get_profile(self, tunables, **kwargs):\n        parser = argparse.ArgumentParser(\n            description='Argparser for {}'.format(os.path.basename(__file__)),\n            formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n        parser.add_argument('--cps', type=int, default=1)\n        args = parser.parse_args(tunables)\n        return self.create_profile(args.cps)\n\n\ndef register():\n    return Prof1()\n"
  },
  {
    "path": "examples/trex/single_node_dual_instance/tcp_openclose.py",
    "content": "from trex.astf.api import *\nimport argparse\n\n\nclass Prof1():\n    def __init__(self):\n        pass  # tunables\n\n    def create_profile(self, cps):\n        prog_c = ASTFProgram()\n        prog_c.connect()\n        prog_s = ASTFProgram()\n        prog_s.wait_for_peer_close()\n\n        # ip generator\n        ip_gen_c = ASTFIPGenDist(ip_range=[\"20.0.0.0\", \"20.0.255.255\"], distribution=\"seq\")\n        ip_gen_s = ASTFIPGenDist(ip_range=[\"30.0.0.0\", \"30.0.255.255\"], distribution=\"seq\")\n        ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset=\"1.0.0.0\"),\n                           dist_client=ip_gen_c,\n                           dist_server=ip_gen_s)\n\n        # template\n        temp_c = ASTFTCPClientTemplate(program=prog_c,  ip_gen=ip_gen, cps=cps)\n        temp_s = ASTFTCPServerTemplate(program=prog_s)\n        template = ASTFTemplate(client_template=temp_c, server_template=temp_s)\n\n        # profile\n        profile = ASTFProfile(default_ip_gen=ip_gen,\n                              templates=template)\n        return profile\n\n    def get_profile(self, tunables, **kwargs):\n        parser = argparse.ArgumentParser(\n            description='Argparser for {}'.format(os.path.basename(__file__)),\n            formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n        parser.add_argument('--cps', type=int, default=1)\n        args = parser.parse_args(tunables)\n        return self.create_profile(args.cps)\n\n\ndef register():\n    return Prof1()\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/tinynetwork/tinet\n\ngo 1.13\n\nrequire (\n\tgithub.com/emicklei/dot v1.6.0\n\tgithub.com/sirupsen/logrus v1.4.2\n\tgithub.com/spf13/viper v1.6.2\n\tgithub.com/urfave/cli/v2 v2.1.1\n\tgopkg.in/yaml.v2 v2.2.8\n)\n"
  },
  {
    "path": "go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=\ngithub.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=\ngithub.com/emicklei/dot v0.10.2 h1:vDUudhCSkKr1G3kieHqm3CiP7AsvaM25qk+46kb1i5Q=\ngithub.com/emicklei/dot v0.10.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=\ngithub.com/emicklei/dot v1.6.0 h1:vUzuoVE8ipzS7QkES4UfxdpCwdU2U97m2Pb2tQCoYRY=\ngithub.com/emicklei/dot v1.6.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=\ngithub.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=\ngithub.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=\ngithub.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=\ngithub.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=\ngithub.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=\ngithub.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=\ngithub.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=\ngithub.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=\ngithub.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=\ngithub.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=\ngithub.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=\ngithub.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=\ngithub.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=\ngithub.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=\ngithub.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=\ngithub.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=\ngithub.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=\ngithub.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=\ngithub.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=\ngithub.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=\ngo.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=\ngo.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=\ngopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=\ngopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\n"
  },
  {
    "path": "internal/pkg/shell/shell.go",
    "content": "// Package shell generate shell script\npackage shell\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"text/template\"\n\n\tl \"github.com/sirupsen/logrus\"\n\t\"gopkg.in/yaml.v2\"\n\n\t\"github.com/tinynetwork/tinet/internal/pkg/utils\"\n)\n\nvar log = l.New()\n\n// Tn tinet config\ntype Tn struct {\n\tPreCmd      []PreCmd     `yaml:\"precmd\"`\n\tPreInit     []PreInit    `yaml:\"preinit\"`\n\tPreConf     []PreConf    `yaml:\"preconf\"`\n\tPostInit    []PostInit   `yaml:\"postinit\"`\n\tPostFini    []PostFini   `yaml:\"postfini\"`\n\tNodes       []Node       `yaml:\"nodes\" mapstructure:\"nodes\"`\n\tSwitches    []Switch     `yaml:\"switches\" mapstructure:\"switches\"`\n\tNodeConfigs []NodeConfig `yaml:\"node_configs\" mapstructure:\"node_configs\"`\n\tTest        []Test       `yaml:\"test\"`\n}\n\n// PreCmd\ntype PreCmd struct {\n\t// Cmds []Cmd `yaml:\"cmds\"`\n\tCmds []Cmd `yaml:\"cmds\" mapstructure:\"cmds\"`\n}\n\n// PreInit\ntype PreInit struct {\n\tCmds []Cmd `yaml:\"cmds\" mapstructure:\"cmds\"`\n}\n\n// PreConf\ntype PreConf struct {\n\tCmds []Cmd `yaml:\"cmds\" mapstructure:\"cmds\"`\n}\n\n// PostInit\ntype PostInit struct {\n\tCmds []Cmd `yaml:\"cmds\" mapstructure:\"cmds\"`\n}\n\n// PostFini\ntype PostFini struct {\n\tCmds []Cmd `yaml:\"cmds\" mapstructure:\"cmds\"`\n}\n\n// Node\ntype Node struct {\n\tName           string                 `yaml:\"name\" mapstructure:\"name\"`\n\tType           string                 `yaml:\"type\" mapstructure:\"type\"`\n\tNetBase        string                 `yaml:\"net_base\" mapstructure:\"net_base\"`\n\tVolumeBase     string                 `yaml:\"volume\" mapstructure:\"volume\"`\n\tImage          string                 `yaml:\"image\" mapstructure:\"image\"`\n\tBuildFile      string                 `yaml:\"buildfile\" mapstructure:\"buildfile\"`\n\tBuildContext   string                 `yaml:\"buildcontext\" mapstructure:\"buildcontext\"`\n\tInterfaces     []Interface            `yaml:\"interfaces\" mapstructure:\"interfaces\"`\n\tSysctls        []Sysctl               `yaml:\"sysctls\" mapstructure:\"sysctls\"`\n\tMounts         []string               `yaml:\"mounts,flow\" mapstructure:\"mounts,flow\"`\n\tDNS            []string               `yaml:\"dns,flow\" mapstructure:\"dns,flow\"`\n\tDNSSearches    []string               `yaml:\"dns_search,flow\" mapstructure:\"dns_search,flow\"`\n\tHostNameIgnore bool                   `yaml:\"hostname_ignore\" mapstructure:\"hostname_ignore\"`\n\tEntryPoint     string                 `yaml:\"entrypoint\" mapstructure:\"entrypoint\"`\n\tExtraArgs      string                 `yaml:\"docker_run_extra_args\" mapstructure:\"docker_run_extra_args\"`\n\tVars           map[string]interface{} `yaml:\"vars\" mapstructure:\"vars\"`\n\tTemplates      []Template             `yaml:\"templates\" mapstructure:\"templates\"`\n}\n\n// Interface\ntype Interface struct {\n\tName  string `yaml:\"name\"`\n\tType  string `yaml:\"type\"`\n\tArgs  string `yaml:\"args\"`\n\tAddr  string `yaml:\"addr\"`\n\tLabel string `yaml:\"label\"`\n}\n\n// Sysctl\ntype Sysctl struct {\n\tSysctl string `yaml:\"string\"`\n}\n\ntype Template struct {\n\tSrc     string `yaml:\"src\"`\n\tDst     string `yaml:\"dst\"`\n\tContent string `yaml:\"content\"`\n}\n\n// Switch\ntype Switch struct {\n\tName       string      `yaml:\"name\"`\n\tInterfaces []Interface `yaml:\"interfaces\" mapstructure:\"interfaces\"`\n}\n\n// NodeConfig\ntype NodeConfig struct {\n\tName string `yaml:\"name\"`\n\tCmds []Cmd  `yaml:\"cmds\" mapstructure:\"cmds\"`\n}\n\n// Cmd\ntype Cmd struct {\n\tCmd string `yaml:\"cmd\"`\n}\n\n// Test\ntype Test struct {\n\tName string\n\tCmds []Cmd `yaml:\"cmds\" mapstructure:\"cmds\"`\n}\n\n// BuildCmd\nfunc (node *Node) BuildCmd() (buildCmd string) {\n\n\tbuildContext := \".\"\n\tif node.BuildContext != \"\" {\n\t\tbuildContext = node.BuildContext\n\t}\n\n\tif node.BuildFile != \"\" {\n\t\tbuildCmd = fmt.Sprintf(\"docker build -t %s -f %s %s\\n\", node.Image, node.BuildFile, buildContext)\n\t}\n\n\treturn buildCmd\n}\n\n// ExecConf Execute NodeConfig command\nfunc (nodeConfig *NodeConfig) ExecConf(nodeType string) (execConfCmds []string) {\n\n\tfor _, nodeConfigCmd := range nodeConfig.Cmds {\n\t\tvar execConfCmd string\n\t\tif nodeType == \"docker\" {\n\t\t\texecConfCmd = fmt.Sprintf(\"docker exec %s %s\", nodeConfig.Name, nodeConfigCmd.Cmd)\n\t\t} else if nodeType == \"netns\" {\n\t\t\texecConfCmd = fmt.Sprintf(\"ip netns exec %s %s\", nodeConfig.Name, nodeConfigCmd.Cmd)\n\t\t} else if nodeType == \"\" {\n\t\t\texecConfCmd = fmt.Sprintf(\"docker exec %s %s\", nodeConfig.Name, nodeConfigCmd.Cmd)\n\t\t} else {\n\t\t\t// err := fmt.Errorf(\"not supported node type...\")\n\t\t\t// log.Fatal(err)\n\t\t\treturn []string{\"\"}\n\t\t}\n\t\t// fmt.Println(execConfigCmd)\n\t\texecConfCmds = append(execConfCmds, execConfCmd)\n\t}\n\n\treturn execConfCmds\n}\n\n// DeleteNode Delete docker and netns\nfunc (node *Node) DeleteNode() (deleteNodeCmds []string) {\n\n\tvar deleteCmd string\n\n\tif node.Type == \"docker\" || node.Type == \"\" {\n\t\tdeleteCmd = fmt.Sprintf(\"docker rm -f %s || true\", node.Name)\n\t} else if node.Type == \"netns\" {\n\t\tdeleteCmd = fmt.Sprintf(\"ip netns del %s\", node.Name)\n\t} else {\n\t\treturn []string{\"\"}\n\t}\n\n\tdeleteNsCmd := fmt.Sprintf(\"rm -rf /var/run/netns/%s\", node.Name)\n\n\tdeleteNodeCmds = []string{deleteCmd, deleteNsCmd}\n\n\treturn deleteNodeCmds\n}\n\n// DeleteSwitch Delete bridge\nfunc (br *Switch) DeleteSwitch() (deleteBrCmd string) {\n\n\tdeleteBrCmd = fmt.Sprintf(\"ovs-vsctl del-br %s\", br.Name)\n\n\treturn deleteBrCmd\n}\n\n// Exec Select Node exec command\nfunc (tnconfig *Tn) Exec(nodeName string, Cmds []string) (execCommand string) {\n\n\tvar selectedNode *Node\n\n\tfor i, node := range tnconfig.Nodes {\n\t\tif node.Name == nodeName {\n\t\t\tselectedNode = &tnconfig.Nodes[i]\n\t\t}\n\t}\n\n\tif selectedNode == nil {\n\t\terr := fmt.Errorf(\"no such node...\\n\")\n\t\tlog.Error(err)\n\t} else {\n\t\tif selectedNode.Type == \"docker\" {\n\t\t\texecCommand = fmt.Sprintf(\"docker exec %s\", nodeName)\n\t\t} else if selectedNode.Type == \"netns\" {\n\t\t\texecCommand = fmt.Sprintf(\"ip netns exec %s\", nodeName)\n\t\t} else if selectedNode.Type == \"\" {\n\t\t\texecCommand = fmt.Sprintf(\"docker exec %s\", nodeName)\n\t\t} else {\n\t\t\terr := fmt.Errorf(\"no such node type...\\n\")\n\t\t\tlog.Error(err)\n\t\t}\n\n\t\tvar cmdStr string\n\t\tfor _, cmd := range Cmds {\n\t\t\tcmdStr += fmt.Sprintf(\" %s\", cmd)\n\t\t}\n\t\texecCommand += cmdStr\n\t}\n\n\treturn execCommand\n}\n\n// GenerateFile Generate tinet template config file\nfunc GenerateFile() (genContent string, err error) {\n\n\tprecmd := PreCmd{\n\t\tCmds: []Cmd{\n\t\t\tCmd{\n\t\t\t\tCmd: \"\",\n\t\t\t},\n\t\t},\n\t}\n\n\tpreinit := PreInit{\n\t\tCmds: []Cmd{\n\t\t\tCmd{\n\t\t\t\tCmd: \"\",\n\t\t\t},\n\t\t},\n\t}\n\tpreconf := PreConf{\n\t\tCmds: []Cmd{\n\t\t\tCmd{\n\t\t\t\tCmd: \"\",\n\t\t\t},\n\t\t},\n\t}\n\tpostinit := PostInit{\n\t\tCmds: []Cmd{\n\t\t\tCmd{\n\t\t\t\tCmd: \"echo hoge\",\n\t\t\t},\n\t\t},\n\t}\n\n\tpostfini := PostFini{\n\t\tCmds: []Cmd{\n\t\t\tCmd{\n\t\t\t\tCmd: \"\",\n\t\t\t},\n\t\t},\n\t}\n\n\tnodes := Node{\n\t\tName:    \"R1\",\n\t\tImage:   \"slankdev/ubuntu18.04\",\n\t\tNetBase: \"\",\n\t\tInterfaces: []Interface{\n\t\t\tInterface{\n\t\t\t\tName: \"net0\",\n\t\t\t\tType: \"direct\",\n\t\t\t\tArgs: \"C1#net0\",\n\t\t\t},\n\t\t\tInterface{\n\t\t\t\tName: \"net1\",\n\t\t\t\tType: \"bridge\",\n\t\t\t\tArgs: \"B0\",\n\t\t\t},\n\t\t\tInterface{\n\t\t\t\tName: \"net2\",\n\t\t\t\tType: \"veth\",\n\t\t\t\tArgs: \"peer0\",\n\t\t\t},\n\t\t\tInterface{\n\t\t\t\tName: \"net3\",\n\t\t\t\tType: \"phys\",\n\t\t\t},\n\t\t},\n\t}\n\n\tswitches := Switch{\n\t\tName: \"B0\",\n\t\tInterfaces: []Interface{\n\t\t\tInterface{\n\t\t\t\tName: \"net0\",\n\t\t\t\tType: \"docker\",\n\t\t\t\tArgs: \"R1\",\n\t\t\t},\n\t\t\tInterface{\n\t\t\t\tName: \"net0\",\n\t\t\t\tType: \"netns\",\n\t\t\t\tArgs: \"R2\",\n\t\t\t},\n\t\t},\n\t}\n\n\tnodeConfigs := []NodeConfig{\n\t\tNodeConfig{\n\t\t\tName: \"C0\",\n\t\t\tCmds: []Cmd{\n\t\t\t\tCmd{\n\t\t\t\t\tCmd: \"ip link set dev net0 up\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tNodeConfig{\n\t\t\tName: \"C1\",\n\t\t\tCmds: []Cmd{\n\t\t\t\tCmd{\n\t\t\t\t\tCmd: \"echo slankdev slankdev\",\n\t\t\t\t},\n\t\t\t\tCmd{\n\t\t\t\t\tCmd: \"echo slankdev &&\\necho slankdev\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\ttests := []Test{\n\t\tTest{\n\t\t\tName: \"p2p\",\n\t\t\tCmds: []Cmd{\n\t\t\t\tCmd{\n\t\t\t\t\tCmd: \"docker exec C0 ping -c2 10.0.0.2\",\n\t\t\t\t},\n\t\t\t\tCmd{\n\t\t\t\t\tCmd: \"echo hoge\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tTest{\n\t\t\tName: \"lo\",\n\t\t\tCmds: []Cmd{\n\t\t\t\tCmd{\n\t\t\t\t\tCmd: \"docker exec C0 ping -c2 10.255.0.1\",\n\t\t\t\t},\n\t\t\t\tCmd{\n\t\t\t\t\tCmd: \"echo hoge\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\ttnconfig := &Tn{\n\t\tPreCmd:      []PreCmd{precmd},\n\t\tPreInit:     []PreInit{preinit},\n\t\tPreConf:     []PreConf{preconf},\n\t\tPostInit:    []PostInit{postinit},\n\t\tPostFini:    []PostFini{postfini},\n\t\tNodes:       []Node{nodes},\n\t\tSwitches:    []Switch{switches},\n\t\tNodeConfigs: nodeConfigs,\n\t\tTest:        tests,\n\t}\n\n\tdata, err := yaml.Marshal(tnconfig)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tgenContent = string(data)\n\n\treturn genContent, err\n}\n\n// DockerPs Show docker ps\nfunc DockerPs(all bool) (dockerPsCmd string) {\n\n\tdockerPsCmd = \"docker ps --format 'table {{.ID}}\\\\t{{.Names}}\\\\t{{.Status}}\\\\t{{.Networks}}'\"\n\n\tif all {\n\t\tdockerPsCmd += \" -a\"\n\t}\n\n\treturn dockerPsCmd\n}\n\n// NetnsPs Show ip netns list\nfunc NetnsPs() (netnsListCmd string) {\n\n\tnetnsListCmd = \"ip netns list\"\n\n\treturn netnsListCmd\n}\n\n// Pull pull Docker Image\nfunc Pull(nodes []Node) (pullCmds []string) {\n\n\tvar images []string\n\n\tfor _, node := range nodes {\n\t\timages = append(images, node.Image)\n\t}\n\n\timages = utils.RemoveDuplicatesString(images)\n\n\tfor _, image := range images {\n\t\tpullCmd := fmt.Sprintf(\"docker pull %s\", image)\n\t\tpullCmds = append(pullCmds, pullCmd)\n\t}\n\n\treturn pullCmds\n}\n\n// TnTestCmdExec Execute test cmds\nfunc (t *Test) TnTestCmdExec() (tnTestCmds []string) {\n\n\tfor _, testCmd := range t.Cmds {\n\t\ttnTestCmds = append(tnTestCmds, testCmd.Cmd)\n\t}\n\n\treturn tnTestCmds\n}\n\n// ExecCmd Execute cmds\nfunc ExecCmd(cmds []Cmd) (execCmds []string) {\n\n\tfor _, cmd := range cmds {\n\t\texecCmds = append(execCmds, cmd.Cmd)\n\t}\n\n\treturn execCmds\n}\n\n// CreateNode Create nodes set in config\nfunc (node *Node) CreateNode() (createNodeCmds []string) {\n\n\tvar createNodeCmd string\n\n\tif node.NetBase == \"\" {\n\t\tnode.NetBase = \"none\"\n\t}\n\n\tif node.Type == \"docker\" || node.Type == \"\" {\n\t\tcreateNodeCmd = fmt.Sprintf(\"docker run -td --net %s --name %s --rm --privileged \", node.NetBase, node.Name)\n\n\t\tif !node.HostNameIgnore {\n\t\t\tcreateNodeCmd += fmt.Sprintf(\"--hostname %s \", node.Name)\n\t\t}\n\n\t\tif len(node.Sysctls) != 0 {\n\t\t\tfor _, sysctl := range node.Sysctls {\n\t\t\t\tcreateNodeCmd += fmt.Sprintf(\"--sysctl %s \", sysctl.Sysctl)\n\t\t\t}\n\t\t}\n\n\t\tif node.EntryPoint != \"\" {\n\t\t\tcreateNodeCmd += fmt.Sprintf(\"--entrypoint %s \", node.EntryPoint)\n\t\t}\n\n\t\tif node.VolumeBase == \"\" {\n\t\t\tcreateNodeCmd += \"-v /tmp/tinet:/tinet \"\n\t\t} else {\n\t\t\tcreateNodeCmd += fmt.Sprintf(\"-v %s:/tinet \", node.VolumeBase)\n\t\t}\n\n\t\tif len(node.Mounts) != 0 {\n\t\t\tfor _, mount := range node.Mounts {\n\t\t\t\tcreateNodeCmd += fmt.Sprintf(\"-v %s \", mount)\n\t\t\t}\n\t\t}\n\n\t\tif len(node.DNS) != 0 {\n\t\t\tfor _, dns := range node.DNS {\n\t\t\t\tcreateNodeCmd += fmt.Sprintf(\"--dns=%s \", dns)\n\t\t\t}\n\t\t}\n\n\t\tif len(node.DNSSearches) != 0 {\n\t\t\tfor _, dns_search := range node.DNSSearches {\n\t\t\t\tcreateNodeCmd += fmt.Sprintf(\"--dns-search=%s \", dns_search)\n\t\t\t}\n\t\t}\n\n\t\tif node.ExtraArgs != \"\" {\n\t\t\tcreateNodeCmd += fmt.Sprintf(\"%s \", node.ExtraArgs)\n\t\t}\n\n\t\tcreateNodeCmd += node.Image\n\t} else if node.Type == \"netns\" {\n\t\tcreateNodeCmd = fmt.Sprintf(\"ip netns add %s\", node.Name)\n\t} else {\n\t\tcreateNodeCmd = fmt.Sprintf(\"unknown nodetype %s\", node.Type)\n\t}\n\n\tcreateNodeCmds = append(createNodeCmds, createNodeCmd)\n\n\tif node.Type == \"netns\" {\n\t\tif len(node.Sysctls) != 0 {\n\t\t\tfor _, sysctl := range node.Sysctls {\n\t\t\t\tsysctlNsCmd := fmt.Sprintf(\"ip netns exec %s sysctl -w %s\", node.Name, sysctl.Sysctl)\n\t\t\t\tcreateNodeCmds = append(createNodeCmds, sysctlNsCmd)\n\t\t\t}\n\t\t}\n\t\tinfloUpCmd := fmt.Sprintf(\"ip netns exec %s ip link set lo up\", node.Name)\n\t\tcreateNodeCmds = append(createNodeCmds, infloUpCmd)\n\t}\n\n\treturn createNodeCmds\n}\n\n// HostLinkUp Link up link of host\nfunc HostLinkUp(linkName string) (linkUpCmd string) {\n\n\tlinkUpCmd = fmt.Sprintf(\"ip link set %s up\", linkName)\n\n\treturn linkUpCmd\n}\n\n// NetnsLinkUp Link up link of netns\nfunc NetnsLinkUp(netnsName string, linkName string) (netnsLinkUpCmd string) {\n\n\tnetnsLinkUpCmd = fmt.Sprintf(\"ip netns exec %s ip link set %s up\", netnsName, linkName)\n\n\treturn netnsLinkUpCmd\n}\n\nfunc (inf *Interface) AddrSet(nodeName string) (addrSetCmd string) {\n\n\taddrSetCmd = fmt.Sprintf(\"ip netns exec %s ip link set %s address %s\", nodeName, inf.Name, inf.Addr)\n\n\treturn addrSetCmd\n}\n\n// CreateSwitch Create bridge set in config\nfunc (bridge *Switch) CreateSwitch() (createSwitchCmds []string) {\n\n\taddSwitchCmd := fmt.Sprintf(\"ovs-vsctl add-br %s\", bridge.Name)\n\tcreateSwitchCmds = append(createSwitchCmds, addSwitchCmd)\n\n\tbridgeUpCmd := HostLinkUp(bridge.Name)\n\tcreateSwitchCmds = append(createSwitchCmds, bridgeUpCmd)\n\n\treturn createSwitchCmds\n}\n\n// N2nLink Connect links between nodes\nfunc (inf *Interface) N2nLink(nodeName string) (n2nLinkCmds []string) {\n\n\tnodeinf := inf.Name\n\tpeerinfo := strings.Split(inf.Args, \"#\")\n\tpeerNode := peerinfo[0]\n\tpeerinf := peerinfo[1]\n\tn2nlinkCmd := fmt.Sprintf(\"ip link add %s netns %s type veth peer name %s netns %s\", nodeinf, nodeName, peerinf, peerNode)\n\tn2nLinkCmds = append(n2nLinkCmds, n2nlinkCmd)\n\tn2nLinkCmds = append(n2nLinkCmds, NetnsLinkUp(nodeName, nodeinf))\n\tn2nLinkCmds = append(n2nLinkCmds, NetnsLinkUp(peerNode, peerinf))\n\n\treturn n2nLinkCmds\n}\n\n// S2nLink Connect links between nodes and switches\nfunc (inf *Interface) S2nLink(nodeName string) (s2nLinkCmds []string) {\n\n\tnodeinf := inf.Name\n\tpeerBr := inf.Args\n\tpeerBrInf := fmt.Sprintf(\"%s-%s\", peerBr, nodeName)\n\ts2nLinkCmd := fmt.Sprintf(\"ip link add %s netns %s type veth peer name %s\", nodeinf, nodeName, peerBrInf)\n\ts2nLinkCmds = append(s2nLinkCmds, s2nLinkCmd)\n\ts2nLinkCmds = append(s2nLinkCmds, NetnsLinkUp(nodeName, nodeinf))\n\ts2nLinkCmds = append(s2nLinkCmds, HostLinkUp(peerBrInf))\n\tsetBrLinkCmd := fmt.Sprintf(\"ovs-vsctl add-port %s %s\", peerBr, peerBrInf)\n\ts2nLinkCmds = append(s2nLinkCmds, setBrLinkCmd)\n\n\treturn s2nLinkCmds\n}\n\n// V2cLink Connect links between veth and container\nfunc (inf *Interface) V2cLink(nodeName string) (v2cLinkCmds []string) {\n\n\tnodeinf := inf.Name\n\tpeerName := inf.Args\n\tv2cLinkCmd := fmt.Sprintf(\"ip link add %s type veth peer name %s\", nodeinf, peerName)\n\tv2cLinkCmds = append(v2cLinkCmds, v2cLinkCmd)\n\n\tv2cLinkCmds = append(v2cLinkCmds, inf.P2cLink(nodeName)...)\n\tv2cLinkCmds = append(v2cLinkCmds, HostLinkUp(peerName))\n\n\treturn v2cLinkCmds\n}\n\n// P2cLink Connect links between phys-eth and container\nfunc (inf *Interface) P2cLink(nodeName string) (p2cLinkCmds []string) {\n\n\tphysInf := inf.Name\n\tsetNsCmd := fmt.Sprintf(\"ip link set dev %s netns %s\", physInf, nodeName)\n\tp2cLinkCmds = append(p2cLinkCmds, setNsCmd)\n\texecNsCmd := fmt.Sprintf(\"ip netns exec %s ip link set %s up\", nodeName, physInf)\n\tp2cLinkCmds = append(p2cLinkCmds, execNsCmd)\n\tdelNsCmd := fmt.Sprintf(\"ip netns del %s\", nodeName)\n\tp2cLinkCmds = append(p2cLinkCmds, delNsCmd)\n\n\treturn p2cLinkCmds\n}\n\n// Mount_docker_netns Mount docker netns to ip netns\nfunc (node *Node) Mount_docker_netns() (mountDockerNetnsCmds []string) {\n\n\tnetnsDir := \"/var/run/netns\"\n\tmkdirCmd := fmt.Sprintf(\"mkdir -p %s\", netnsDir)\n\tmountDockerNetnsCmds = append(mountDockerNetnsCmds, mkdirCmd)\n\tdockerPid := GetContainerPid(node.Name)\n\tmountDockerNetnsCmds = append(mountDockerNetnsCmds, dockerPid)\n\tmountDockerNetnsCmd := fmt.Sprintf(\"ln -s /proc/$PID/ns/net /var/run/netns/%s\", node.Name)\n\tmountDockerNetnsCmds = append(mountDockerNetnsCmds, mountDockerNetnsCmd)\n\n\treturn mountDockerNetnsCmds\n}\n\n// GetContainerPid func is Output get Docker PID Command\nfunc GetContainerPid(nodename string) (getpidCmd string) {\n\n\tgetpidCmd = fmt.Sprintf(\"PID=`docker inspect %s --format '{{.State.Pid}}'`\", nodename)\n\n\treturn getpidCmd\n}\n\n// DelNsCmds\nfunc (node *Node) DelNsCmd() (delNsCmd string) {\n\n\tdelNsCmd = fmt.Sprintf(\"ip netns del %s\", node.Name)\n\n\treturn delNsCmd\n}\n\n// MountTmpl\nfunc (node *Node) MountTmpl() (mountTmplCmd []string, err error) {\n\tfor _, tmpl := range node.Templates {\n\t\tdest := strings.Split(tmpl.Dst, \"/\")\n\t\tdestfile := node.Name + \"_\" + dest[len(dest)-1]\n\t\tf, err := os.Create(destfile)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer f.Close()\n\n\t\tif len(tmpl.Src) > 0 {\n\t\t\ttpl, err := template.ParseFiles(tmpl.Src)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\terr = tpl.Execute(f, node.Vars)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else if len(tmpl.Content) > 0 {\n\t\t\ttpl, err := template.New(\"\").Parse(tmpl.Content)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\terr = tpl.Execute(f, node.Vars)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\ttmplCmd := fmt.Sprintf(\"docker cp %s %s:%s\", destfile, node.Name, tmpl.Dst)\n\t\tmountTmplCmd = append(mountTmplCmd, tmplCmd)\n\t\tremoveFileCmd := fmt.Sprintf(\"rm -rf %s\", destfile)\n\t\tmountTmplCmd = append(mountTmplCmd, removeFileCmd)\n\t}\n\n\treturn mountTmplCmd, nil\n}\n"
  },
  {
    "path": "internal/pkg/shell/shell_test.go",
    "content": "package shell\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestNodeConfig_ExecConf(t *testing.T) {\n\ttype fields struct {\n\t\tName string\n\t\tCmds []Cmd\n\t}\n\ttype args struct {\n\t\tnodeType string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"docker exec\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"R1\",\n\t\t\t\tCmds: []Cmd{\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"/usr/lib/frr/frr start\",\n\t\t\t\t\t},\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"ip addr add 10.0.0.1/24 dev net0\",\n\t\t\t\t\t},\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"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'\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tnodeType: \"\",\n\t\t\t},\n\t\t\twant: []string{\"docker exec R1 /usr/lib/frr/frr start\", \"docker exec R1 ip addr add 10.0.0.1/24 dev net0\", \"docker exec R1 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'\"},\n\t\t},\n\t\t{\n\t\t\tname: \"ip netns exec\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"H0\",\n\t\t\t\tCmds: []Cmd{\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"ip addr add 10.0.0.1/24 dev net0\",\n\t\t\t\t\t},\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"ip addr add 10.1.0.1/24 dev net1\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tnodeType: \"netns\",\n\t\t\t},\n\t\t\twant: []string{\"ip netns exec H0 ip addr add 10.0.0.1/24 dev net0\", \"ip netns exec H0 ip addr add 10.1.0.1/24 dev net1\"},\n\t\t},\n\t\t{\n\t\t\tname: \"not support node\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"R0\",\n\t\t\t\tCmds: []Cmd{\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"ip addr add 10.0.0.1/24 dev net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tnodeType: \"hoge\",\n\t\t\t},\n\t\t\twant: []string{\"\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tnodeConfig := &NodeConfig{\n\t\t\t\tName: tt.fields.Name,\n\t\t\t\tCmds: tt.fields.Cmds,\n\t\t\t}\n\t\t\tif got := nodeConfig.ExecConf(tt.args.nodeType); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"NodeConfig.ExecConf() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNode_DeleteNode(t *testing.T) {\n\ttype fields struct {\n\t\tName           string\n\t\tType           string\n\t\tNetBase        string\n\t\tImage          string\n\t\tInterfaces     []Interface\n\t\tSysctls        []Sysctl\n\t\tMounts         []string\n\t\tDNS            []string\n\t\tDNSSearches    []string\n\t\tHostNameIgnore bool\n\t\tEntryPoint     string\n\t\tExtraArgs      string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"delete docker\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"R1\",\n\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\tType:  \"docker\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"R2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker rm -f R1 || true\", \"rm -rf /var/run/netns/R1\"},\n\t\t},\n\t\t{\n\t\t\tname: \"delete netns\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"H1\",\n\t\t\t\tType: \"netns\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"H2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"ip netns del H1\", \"rm -rf /var/run/netns/H1\"},\n\t\t},\n\t\t{\n\t\t\tname: \"delete not support nodetype\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"U1\",\n\t\t\t\tType: \"hoge\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"U2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tnode := &Node{\n\t\t\t\tName:           tt.fields.Name,\n\t\t\t\tType:           tt.fields.Type,\n\t\t\t\tNetBase:        tt.fields.NetBase,\n\t\t\t\tImage:          tt.fields.Image,\n\t\t\t\tInterfaces:     tt.fields.Interfaces,\n\t\t\t\tSysctls:        tt.fields.Sysctls,\n\t\t\t\tMounts:         tt.fields.Mounts,\n\t\t\t\tDNS:            tt.fields.DNS,\n\t\t\t\tDNSSearches:    tt.fields.DNSSearches,\n\t\t\t\tHostNameIgnore: tt.fields.HostNameIgnore,\n\t\t\t\tEntryPoint:     tt.fields.EntryPoint,\n\t\t\t\tExtraArgs:      tt.fields.ExtraArgs,\n\t\t\t}\n\t\t\tif got := node.DeleteNode(); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Node.DeleteNode() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSwitch_DeleteSwitch(t *testing.T) {\n\ttype fields struct {\n\t\tName       string\n\t\tInterfaces []Interface\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname: \"delete bridge\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"SW\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net2\",\n\t\t\t\t\t\tType: \"docker\",\n\t\t\t\t\t\tArgs: \"R1\",\n\t\t\t\t\t},\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"docker\",\n\t\t\t\t\t\tArgs: \"R2\",\n\t\t\t\t\t},\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"docker\",\n\t\t\t\t\t\tArgs: \"R3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: \"ovs-vsctl del-br SW\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tbr := &Switch{\n\t\t\t\tName:       tt.fields.Name,\n\t\t\t\tInterfaces: tt.fields.Interfaces,\n\t\t\t}\n\t\t\tif got := br.DeleteSwitch(); got != tt.want {\n\t\t\t\tt.Errorf(\"Switch.DeleteSwitch() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTn_Exec(t *testing.T) {\n\ttype fields struct {\n\t\tPreCmd      []PreCmd\n\t\tPreInit     []PreInit\n\t\tPreConf     []PreConf\n\t\tPostInit    []PostInit\n\t\tPostFini    []PostFini\n\t\tNodes       []Node\n\t\tSwitches    []Switch\n\t\tNodeConfigs []NodeConfig\n\t\tTest        []Test\n\t}\n\ttype args struct {\n\t\tnodeName string\n\t\tCmds     []string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twant   string\n\t}{\n\t\t// TODO: Add test cases.\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\ttnconfig := &Tn{\n\t\t\t\tPreCmd:      tt.fields.PreCmd,\n\t\t\t\tPreInit:     tt.fields.PreInit,\n\t\t\t\tPreConf:     tt.fields.PreConf,\n\t\t\t\tPostInit:    tt.fields.PostInit,\n\t\t\t\tPostFini:    tt.fields.PostFini,\n\t\t\t\tNodes:       tt.fields.Nodes,\n\t\t\t\tSwitches:    tt.fields.Switches,\n\t\t\t\tNodeConfigs: tt.fields.NodeConfigs,\n\t\t\t\tTest:        tt.fields.Test,\n\t\t\t}\n\t\t\tif got := tnconfig.Exec(tt.args.nodeName, tt.args.Cmds); got != tt.want {\n\t\t\t\tt.Errorf(\"Tn.Exec() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGenerateFile(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\twant    string\n\t\twantErr bool\n\t}{\n\t\t// TODO: Add test cases.\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := GenerateFile()\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"GenerateFile() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif got != tt.want {\n\t\t\t\tt.Errorf(\"GenerateFile() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDockerPs(t *testing.T) {\n\ttype args struct {\n\t\tall bool\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"docker ps\",\n\t\t\targs: args{\n\t\t\t\tall: false,\n\t\t\t},\n\t\t\twant: \"docker ps --format 'table {{.ID}}\\\\t{{.Names}}\\\\t{{.Status}}\\\\t{{.Networks}}'\",\n\t\t},\n\t\t{\n\t\t\tname: \"docker ps -a\",\n\t\t\targs: args{\n\t\t\t\tall: true,\n\t\t\t},\n\t\t\twant: \"docker ps --format 'table {{.ID}}\\\\t{{.Names}}\\\\t{{.Status}}\\\\t{{.Networks}}' -a\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := DockerPs(tt.args.all); got != tt.want {\n\t\t\t\tt.Errorf(\"DockerPs() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNetnsPs(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"ip netns list\",\n\t\t\twant: \"ip netns list\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := NetnsPs(); got != tt.want {\n\t\t\t\tt.Errorf(\"NetnsPs() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestPull(t *testing.T) {\n\ttype args struct {\n\t\tnodes []Node\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant []string\n\t}{\n\t\t{\n\t\t\tname: \"docker pull\",\n\t\t\targs: args{\n\t\t\t\tnodes: []Node{\n\t\t\t\t\tNode{\n\t\t\t\t\t\tName:  \"R1\",\n\t\t\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\t\t},\n\t\t\t\t\tNode{\n\t\t\t\t\t\tName:  \"R2\",\n\t\t\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker pull slankdev/frr\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := Pull(tt.args.nodes); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Pull() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestExecCmd(t *testing.T) {\n\ttype args struct {\n\t\tcmds []Cmd\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant []string\n\t}{\n\t\t{\n\t\t\tname: \"Exec Cmd\",\n\t\t\targs: args{\n\t\t\t\tcmds: []Cmd{\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"ovs-vsctl add-port ovs0 C0net0 tag=10\",\n\t\t\t\t\t},\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"ovs-vsctl del-port ovs0 C0net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"ovs-vsctl add-port ovs0 C0net0 tag=10\", \"ovs-vsctl del-port ovs0 C0net0\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := ExecCmd(tt.args.cmds); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"ExecCmd() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNode_CreateNode(t *testing.T) {\n\ttype fields struct {\n\t\tName           string\n\t\tType           string\n\t\tNetBase        string\n\t\tVolumeBase     string\n\t\tImage          string\n\t\tInterfaces     []Interface\n\t\tSysctls        []Sysctl\n\t\tMounts         []string\n\t\tDNS            []string\n\t\tDNSSearches    []string\n\t\tHostNameIgnore bool\n\t\tEntryPoint     string\n\t\tExtraArgs      string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"create docker node net None\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"R1\",\n\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"C1#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net none --name R1 --rm --privileged --hostname R1 -v /tmp/tinet:/tinet slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create docker node net None with sysctls\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"R1\",\n\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"C1#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSysctls: []Sysctl{\n\t\t\t\t\tSysctl{\n\t\t\t\t\t\tSysctl: \"net.ipv4.ip_forward=1\",\n\t\t\t\t\t},\n\t\t\t\t\tSysctl{\n\t\t\t\t\t\tSysctl: \"net.ipv6.conf.all.forwarding=1\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net none --name R1 --rm --privileged --hostname R1 --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv6.conf.all.forwarding=1 -v /tmp/tinet:/tinet slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create docker node net bridge\",\n\t\t\tfields: fields{\n\t\t\t\tName:    \"R1\",\n\t\t\t\tImage:   \"slankdev/frr\",\n\t\t\t\tNetBase: \"bridge\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"C1#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net bridge --name R1 --rm --privileged --hostname R1 -v /tmp/tinet:/tinet slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create netns node\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"C1\",\n\t\t\t\tType:  \"netns\",\n\t\t\t\tImage: \"\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"R1#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"ip netns add C1\", \"ip netns exec C1 ip link set lo up\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create netns node with sysctls\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"C1\",\n\t\t\t\tType:  \"netns\",\n\t\t\t\tImage: \"\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"R1#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSysctls: []Sysctl{\n\t\t\t\t\tSysctl{\n\t\t\t\t\t\tSysctl: \"net.ipv4.ip_forward=1\",\n\t\t\t\t\t},\n\t\t\t\t\tSysctl{\n\t\t\t\t\t\tSysctl: \"net.ipv6.conf.all.forwarding=1\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"ip netns add C1\", \"ip netns exec C1 sysctl -w net.ipv4.ip_forward=1\", \"ip netns exec C1 sysctl -w net.ipv6.conf.all.forwarding=1\", \"ip netns exec C1 ip link set lo up\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create not support node\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"U1\",\n\t\t\t\tType:  \"hoge\",\n\t\t\t\tImage: \"\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"U2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"unknown nodetype hoge\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create node with mounts\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"T1\",\n\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"T2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tMounts: []string{\n\t\t\t\t\t\"`pwd`:/mnt/test\",\n\t\t\t\t\t\"/usr/share/vim:/mnt/vim\",\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net none --name T1 --rm --privileged --hostname T1 -v /tmp/tinet:/tinet -v `pwd`:/mnt/test -v /usr/share/vim:/mnt/vim slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create node with DNS\",\n\t\t\tfields: fields{\n\t\t\t\tName:    \"R1\",\n\t\t\t\tImage:   \"slankdev/frr\",\n\t\t\t\tNetBase: \"bridge\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"C1#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tDNS: []string{\n\t\t\t\t\t\"8.8.8.8\",\n\t\t\t\t\t\"1.1.1.1\",\n\t\t\t\t},\n\t\t\t\tDNSSearches: []string{\n\t\t\t\t\t\"local\",\n\t\t\t\t\t\"corp\",\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net bridge --name R1 --rm --privileged --hostname R1 -v /tmp/tinet:/tinet --dns=8.8.8.8 --dns=1.1.1.1 --dns-search=local --dns-search=corp slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create node with specify tinet volume\",\n\t\t\tfields: fields{\n\t\t\t\tName:       \"T1\",\n\t\t\t\tImage:      \"slankdev/frr\",\n\t\t\t\tVolumeBase: \"/tmp/ak1ra24\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"T2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net none --name T1 --rm --privileged --hostname T1 -v /tmp/ak1ra24:/tinet slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create node with hostname_ignore\",\n\t\t\tfields: fields{\n\t\t\t\tName:       \"T1\",\n\t\t\t\tImage:      \"slankdev/frr\",\n\t\t\t\tVolumeBase: \"/tmp/ak1ra24\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"T2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tHostNameIgnore: true,\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net none --name T1 --rm --privileged -v /tmp/ak1ra24:/tinet slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create node with entrypoint\",\n\t\t\tfields: fields{\n\t\t\t\tName:       \"T1\",\n\t\t\t\tImage:      \"slankdev/frr\",\n\t\t\t\tVolumeBase: \"/tmp/ak1ra24\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"T2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tEntryPoint: \"bash\",\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net none --name T1 --rm --privileged --hostname T1 --entrypoint bash -v /tmp/ak1ra24:/tinet slankdev/frr\"},\n\t\t},\n\t\t{\n\t\t\tname: \"create node with extra args\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"T1\",\n\t\t\t\tImage: \"nginx\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"T2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tExtraArgs: \"-p 8080:80\",\n\t\t\t},\n\t\t\twant: []string{\"docker run -td --net none --name T1 --rm --privileged --hostname T1 -v /tmp/tinet:/tinet -p 8080:80 nginx\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tnode := &Node{\n\t\t\t\tName:           tt.fields.Name,\n\t\t\t\tType:           tt.fields.Type,\n\t\t\t\tNetBase:        tt.fields.NetBase,\n\t\t\t\tVolumeBase:     tt.fields.VolumeBase,\n\t\t\t\tImage:          tt.fields.Image,\n\t\t\t\tInterfaces:     tt.fields.Interfaces,\n\t\t\t\tSysctls:        tt.fields.Sysctls,\n\t\t\t\tMounts:         tt.fields.Mounts,\n\t\t\t\tDNS:            tt.fields.DNS,\n\t\t\t\tDNSSearches:    tt.fields.DNSSearches,\n\t\t\t\tHostNameIgnore: tt.fields.HostNameIgnore,\n\t\t\t\tEntryPoint:     tt.fields.EntryPoint,\n\t\t\t\tExtraArgs:      tt.fields.ExtraArgs,\n\t\t\t}\n\t\t\tif got := node.CreateNode(); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Node.CreateNode() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestHostLinkUp(t *testing.T) {\n\ttype args struct {\n\t\tlinkName string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"netns link up\",\n\t\t\targs: args{\n\t\t\t\tlinkName: \"net0\",\n\t\t\t},\n\t\t\twant: \"ip link set net0 up\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := HostLinkUp(tt.args.linkName); got != tt.want {\n\t\t\t\tt.Errorf(\"HostLinkUp() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNetnsLinkUp(t *testing.T) {\n\ttype args struct {\n\t\tnetnsName string\n\t\tlinkName  string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"netns link up\",\n\t\t\targs: args{\n\t\t\t\tnetnsName: \"R1\",\n\t\t\t\tlinkName:  \"net0\",\n\t\t\t},\n\t\t\twant: \"ip netns exec R1 ip link set net0 up\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := NetnsLinkUp(tt.args.netnsName, tt.args.linkName); got != tt.want {\n\t\t\t\tt.Errorf(\"NetnsLinkUp() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSwitch_CreateSwitch(t *testing.T) {\n\ttype fields struct {\n\t\tName       string\n\t\tInterfaces []Interface\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"create switch shell\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"SW\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"docker\",\n\t\t\t\t\t\tArgs: \"R1\",\n\t\t\t\t\t},\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"docker\",\n\t\t\t\t\t\tArgs: \"R2\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"ovs-vsctl add-br SW\", \"ip link set SW up\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tbridge := &Switch{\n\t\t\t\tName:       tt.fields.Name,\n\t\t\t\tInterfaces: tt.fields.Interfaces,\n\t\t\t}\n\t\t\tif got := bridge.CreateSwitch(); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Switch.CreateSwitch() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestInterface_N2nLink(t *testing.T) {\n\ttype fields struct {\n\t\tName string\n\t\tType string\n\t\tArgs string\n\t\tAddr string\n\t}\n\ttype args struct {\n\t\tnodeName string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"peer between containers\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"net0\",\n\t\t\t\tType: \"direct\",\n\t\t\t\tArgs: \"R2#net0\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tnodeName: \"R1\",\n\t\t\t},\n\t\t\twant: []string{\"ip link add net0 netns R1 type veth peer name net0 netns R2\", \"ip netns exec R1 ip link set net0 up\", \"ip netns exec R2 ip link set net0 up\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinf := &Interface{\n\t\t\t\tName: tt.fields.Name,\n\t\t\t\tType: tt.fields.Type,\n\t\t\t\tArgs: tt.fields.Args,\n\t\t\t\tAddr: tt.fields.Addr,\n\t\t\t}\n\t\t\tif got := inf.N2nLink(tt.args.nodeName); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Interface.N2nLink() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestInterface_S2nLink(t *testing.T) {\n\ttype fields struct {\n\t\tName string\n\t\tType string\n\t\tArgs string\n\t\tAddr string\n\t}\n\ttype args struct {\n\t\tnodeName string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"link connect between switch and container\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"net0\",\n\t\t\t\tType: \"bridge\",\n\t\t\t\tArgs: \"SW\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tnodeName: \"R1\",\n\t\t\t},\n\t\t\twant: []string{\"ip link add net0 netns R1 type veth peer name SW-R1\", \"ip netns exec R1 ip link set net0 up\", \"ip link set SW-R1 up\", \"ovs-vsctl add-port SW SW-R1\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinf := &Interface{\n\t\t\t\tName: tt.fields.Name,\n\t\t\t\tType: tt.fields.Type,\n\t\t\t\tArgs: tt.fields.Args,\n\t\t\t\tAddr: tt.fields.Addr,\n\t\t\t}\n\t\t\tif got := inf.S2nLink(tt.args.nodeName); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Interface.S2nLink() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestInterface_V2cLink(t *testing.T) {\n\ttype fields struct {\n\t\tName string\n\t\tType string\n\t\tArgs string\n\t\tAddr string\n\t}\n\ttype args struct {\n\t\tnodeName string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"link connect between veth and container\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"port-0-6-0\",\n\t\t\t\tType: \"veth\",\n\t\t\t\tArgs: \"pp6\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tnodeName: \"R1\",\n\t\t\t},\n\t\t\twant: []string{\"ip link add port-0-6-0 type veth peer name pp6\", \"ip link set dev port-0-6-0 netns R1\", \"ip netns exec R1 ip link set port-0-6-0 up\", \"ip netns del R1\", \"ip link set pp6 up\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinf := &Interface{\n\t\t\t\tName: tt.fields.Name,\n\t\t\t\tType: tt.fields.Type,\n\t\t\t\tArgs: tt.fields.Args,\n\t\t\t\tAddr: tt.fields.Addr,\n\t\t\t}\n\t\t\tif got := inf.V2cLink(tt.args.nodeName); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Interface.V2cLink() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestInterface_P2cLink(t *testing.T) {\n\ttype fields struct {\n\t\tName string\n\t\tType string\n\t\tArgs string\n\t\tAddr string\n\t}\n\ttype args struct {\n\t\tnodeName string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\targs   args\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"Link connect between phys ethernet and Container\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"ens20f1\",\n\t\t\t\tType: \"phys\",\n\t\t\t\tArgs: \"\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\tnodeName: \"R1\",\n\t\t\t},\n\t\t\twant: []string{\"ip link set dev ens20f1 netns R1\", \"ip netns exec R1 ip link set ens20f1 up\", \"ip netns del R1\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinf := &Interface{\n\t\t\t\tName: tt.fields.Name,\n\t\t\t\tType: tt.fields.Type,\n\t\t\t\tArgs: tt.fields.Args,\n\t\t\t\tAddr: tt.fields.Addr,\n\t\t\t}\n\t\t\tif got := inf.P2cLink(tt.args.nodeName); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Interface.P2cLink() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNode_Mount_docker_netns(t *testing.T) {\n\ttype fields struct {\n\t\tName           string\n\t\tType           string\n\t\tNetBase        string\n\t\tImage          string\n\t\tInterfaces     []Interface\n\t\tSysctls        []Sysctl\n\t\tMounts         []string\n\t\tHostNameIgnore bool\n\t\tEntryPoint     string\n\t\tExtraArgs      string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\twant   []string\n\t}{\n\t\t{\n\t\t\tname: \"docker mount netns\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"R1\",\n\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\tType:  \"docker\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"R2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: []string{\"mkdir -p /var/run/netns\", \"PID=`docker inspect R1 --format '{{.State.Pid}}'`\", \"ln -s /proc/$PID/ns/net /var/run/netns/R1\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tnode := &Node{\n\t\t\t\tName:           tt.fields.Name,\n\t\t\t\tType:           tt.fields.Type,\n\t\t\t\tNetBase:        tt.fields.NetBase,\n\t\t\t\tImage:          tt.fields.Image,\n\t\t\t\tInterfaces:     tt.fields.Interfaces,\n\t\t\t\tSysctls:        tt.fields.Sysctls,\n\t\t\t\tMounts:         tt.fields.Mounts,\n\t\t\t\tHostNameIgnore: tt.fields.HostNameIgnore,\n\t\t\t\tEntryPoint:     tt.fields.EntryPoint,\n\t\t\t\tExtraArgs:      tt.fields.ExtraArgs,\n\t\t\t}\n\t\t\tif got := node.Mount_docker_netns(); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Node.Mount_docker_netns() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetContainerPid(t *testing.T) {\n\ttype args struct {\n\t\tnodename string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"d\",\n\t\t\targs: args{\n\t\t\t\tnodename: \"R1\",\n\t\t\t},\n\t\t\twant: \"PID=`docker inspect R1 --format '{{.State.Pid}}'`\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := GetContainerPid(tt.args.nodename); got != tt.want {\n\t\t\t\tt.Errorf(\"GetContainerPid() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNode_DelNsCmd(t *testing.T) {\n\ttype fields struct {\n\t\tName           string\n\t\tType           string\n\t\tNetBase        string\n\t\tImage          string\n\t\tInterfaces     []Interface\n\t\tSysctls        []Sysctl\n\t\tMounts         []string\n\t\tDNS            []string\n\t\tDNSSearches    []string\n\t\tHostNameIgnore bool\n\t\tEntryPoint     string\n\t\tExtraArgs      string\n\t}\n\ttests := []struct {\n\t\tname   string\n\t\tfields fields\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname: \"node netns del\",\n\t\t\tfields: fields{\n\t\t\t\tName:  \"R1\",\n\t\t\t\tImage: \"slankdev/frr\",\n\t\t\t\tType:  \"docker\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"R2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: \"ip netns del R1\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tnode := &Node{\n\t\t\t\tName:           tt.fields.Name,\n\t\t\t\tType:           tt.fields.Type,\n\t\t\t\tNetBase:        tt.fields.NetBase,\n\t\t\t\tImage:          tt.fields.Image,\n\t\t\t\tInterfaces:     tt.fields.Interfaces,\n\t\t\t\tSysctls:        tt.fields.Sysctls,\n\t\t\t\tMounts:         tt.fields.Mounts,\n\t\t\t\tDNS:            tt.fields.DNS,\n\t\t\t\tDNSSearches:    tt.fields.DNSSearches,\n\t\t\t\tHostNameIgnore: tt.fields.HostNameIgnore,\n\t\t\t\tEntryPoint:     tt.fields.EntryPoint,\n\t\t\t\tExtraArgs:      tt.fields.ExtraArgs,\n\t\t\t}\n\t\t\tif got := node.DelNsCmd(); got != tt.want {\n\t\t\t\tt.Errorf(\"Node.DelNsCmd() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNode_BuildCmd(t *testing.T) {\n\ttype fields struct {\n\t\tName           string\n\t\tType           string\n\t\tNetBase        string\n\t\tVolumeBase     string\n\t\tImage          string\n\t\tBuildFile      string\n\t\tBuildContext   string\n\t\tInterfaces     []Interface\n\t\tSysctls        []Sysctl\n\t\tMounts         []string\n\t\tDNS            []string\n\t\tDNSSearches    []string\n\t\tHostNameIgnore bool\n\t\tEntryPoint     string\n\t\tExtraArgs      string\n\t\tVars           map[string]interface{}\n\t\tTemplates      []Template\n\t}\n\ttests := []struct {\n\t\tname         string\n\t\tfields       fields\n\t\twantBuildCmd string\n\t}{\n\t\t{\n\t\t\tname: \"docker build\",\n\t\t\tfields: fields{\n\t\t\t\tName:         \"R1\",\n\t\t\t\tType:         \"docker\",\n\t\t\t\tImage:        \"ak1ra24/testimage\",\n\t\t\t\tBuildFile:    \"`pwd`/dockerfile/Dockerfile\",\n\t\t\t\tBuildContext: \"\",\n\t\t\t\tInterfaces: []Interface{\n\t\t\t\t\tInterface{\n\t\t\t\t\t\tName: \"net0\",\n\t\t\t\t\t\tType: \"direct\",\n\t\t\t\t\t\tArgs: \"R2#net0\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantBuildCmd: \"docker build -t ak1ra24/testimage -f `pwd`/dockerfile/Dockerfile .\\n\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tnode := &Node{\n\t\t\t\tName:           tt.fields.Name,\n\t\t\t\tType:           tt.fields.Type,\n\t\t\t\tNetBase:        tt.fields.NetBase,\n\t\t\t\tVolumeBase:     tt.fields.VolumeBase,\n\t\t\t\tImage:          tt.fields.Image,\n\t\t\t\tBuildFile:      tt.fields.BuildFile,\n\t\t\t\tBuildContext:   tt.fields.BuildContext,\n\t\t\t\tInterfaces:     tt.fields.Interfaces,\n\t\t\t\tSysctls:        tt.fields.Sysctls,\n\t\t\t\tMounts:         tt.fields.Mounts,\n\t\t\t\tDNS:            tt.fields.DNS,\n\t\t\t\tDNSSearches:    tt.fields.DNSSearches,\n\t\t\t\tHostNameIgnore: tt.fields.HostNameIgnore,\n\t\t\t\tEntryPoint:     tt.fields.EntryPoint,\n\t\t\t\tExtraArgs:      tt.fields.ExtraArgs,\n\t\t\t\tVars:           tt.fields.Vars,\n\t\t\t\tTemplates:      tt.fields.Templates,\n\t\t\t}\n\t\t\tif gotBuildCmd := node.BuildCmd(); gotBuildCmd != tt.wantBuildCmd {\n\t\t\t\tt.Errorf(\"Node.BuildCmd() = %v, want %v\", gotBuildCmd, tt.wantBuildCmd)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTest_TnTestCmdExec(t *testing.T) {\n\ttype fields struct {\n\t\tName string\n\t\tCmds []Cmd\n\t}\n\ttests := []struct {\n\t\tname           string\n\t\tfields         fields\n\t\twantTnTestCmds []string\n\t}{\n\t\t{\n\t\t\tname: \"test name not set\",\n\t\t\tfields: fields{\n\t\t\t\tCmds: []Cmd{\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"echo slankdev\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantTnTestCmds: []string{\"echo slankdev\"},\n\t\t},\n\t\t{\n\t\t\tname: \"test name set\",\n\t\t\tfields: fields{\n\t\t\t\tName: \"p2p\",\n\t\t\t\tCmds: []Cmd{\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"docker exec R1 echo hello\",\n\t\t\t\t\t},\n\t\t\t\t\tCmd{\n\t\t\t\t\t\tCmd: \"docker exec R2 echo world\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantTnTestCmds: []string{\"docker exec R1 echo hello\", \"docker exec R2 echo world\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\ttr := &Test{\n\t\t\t\tName: tt.fields.Name,\n\t\t\t\tCmds: tt.fields.Cmds,\n\t\t\t}\n\t\t\tif gotTnTestCmds := tr.TnTestCmdExec(); !reflect.DeepEqual(gotTnTestCmds, tt.wantTnTestCmds) {\n\t\t\t\tt.Errorf(\"Test.TnTestCmdExec() = %v, want %v\", gotTnTestCmds, tt.wantTnTestCmds)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/pkg/utils/utils.go",
    "content": "// Package utils\npackage utils\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\n// Exists check if the directory exist\nfunc Exists(name string) bool {\n\t_, err := os.Stat(name)\n\treturn !os.IsNotExist(err)\n}\n\n// RemoveDuplicatesString remove duplicate string in slice\nfunc RemoveDuplicatesString(elements []string) []string {\n\tencountered := map[string]bool{}\n\n\t// Create a map of all unique elements.\n\tfor v := range elements {\n\t\tencountered[elements[v]] = true\n\t}\n\n\t// Place all keys from the map into a slice.\n\tresult := []string{}\n\tfor key := range encountered {\n\t\tresult = append(result, key)\n\t}\n\treturn result\n}\n\n// PrintCmd cmd output\nfunc PrintCmd(w io.Writer, cmd string, verbose bool) {\n\tif verbose {\n\t\tfmt.Fprintln(w, cmd)\n\t} else {\n\t\tcmd = cmd + \" > /dev/null\"\n\t\tfmt.Fprintln(w, cmd)\n\t}\n}\n\nfunc PrintCmds(w io.Writer, cmds []string, verbose bool) {\n\tif verbose {\n\t\tfor _, cmd := range cmds {\n\t\t\tfmt.Fprintln(w, cmd)\n\t\t}\n\t} else {\n\t\tfor _, cmd := range cmds {\n\t\t\tcmd = cmd + \" > /dev/null\"\n\t\t\tfmt.Fprintln(w, cmd)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/pkg/utils/utils_test.go",
    "content": "package utils\n\nimport (\n\t\"bytes\"\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestExists(t *testing.T) {\n\ttype args struct {\n\t\tname string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant bool\n\t}{\n\t\t{\n\t\t\tname: \"check if the directory/file exists\",\n\t\t\targs: args{\n\t\t\t\tname: \"main.go\",\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := Exists(tt.args.name); got != tt.want {\n\t\t\t\tt.Errorf(\"Exists() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestRemoveDuplicatesString(t *testing.T) {\n\ttype args struct {\n\t\telements []string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant []string\n\t}{\n\t\t{\n\t\t\tname: \"delete duplicate string slice\",\n\t\t\targs: args{\n\t\t\t\telements: []string{\"test\", \"test\"},\n\t\t\t},\n\t\t\twant: []string{\"test\"},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := RemoveDuplicatesString(tt.args.elements); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"RemoveDuplicatesString() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestPrintCmd(t *testing.T) {\n\ttype args struct {\n\t\tcmd     string\n\t\tverbose bool\n\t}\n\ttests := []struct {\n\t\tname  string\n\t\targs  args\n\t\twantW string\n\t}{\n\t\t{\n\t\t\tname: \"cmd output verbose\",\n\t\t\targs: args{\n\t\t\t\tcmd:     \"test output\",\n\t\t\t\tverbose: true,\n\t\t\t},\n\t\t\twantW: \"test output\\n\",\n\t\t},\n\t\t{\n\t\t\tname: \"cmd output no verbose\",\n\t\t\targs: args{\n\t\t\t\tcmd:     \"test output > /dev/null\",\n\t\t\t\tverbose: true,\n\t\t\t},\n\t\t\twantW: \"test output > /dev/null\\n\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tw := &bytes.Buffer{}\n\t\t\tPrintCmd(w, tt.args.cmd, tt.args.verbose)\n\t\t\tif gotW := w.String(); gotW != tt.wantW {\n\t\t\t\tt.Errorf(\"PrintCmd() = %v, want %v\", gotW, tt.wantW)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestPrintCmds(t *testing.T) {\n\ttype args struct {\n\t\tcmds    []string\n\t\tverbose bool\n\t}\n\ttests := []struct {\n\t\tname  string\n\t\targs  args\n\t\twantW string\n\t}{\n\t\t{\n\t\t\tname: \"cmds output verbose\",\n\t\t\targs: args{\n\t\t\t\tcmds:    []string{\"test output\", \"test2 output\"},\n\t\t\t\tverbose: true,\n\t\t\t},\n\t\t\twantW: \"test output\\ntest2 output\\n\",\n\t\t},\n\t\t{\n\t\t\tname: \"cmd output no verbose\",\n\t\t\targs: args{\n\t\t\t\tcmds:    []string{\"test output > /dev/null\", \"test2 output > /dev/null\"},\n\t\t\t\tverbose: true,\n\t\t\t},\n\t\t\twantW: \"test output > /dev/null\\ntest2 output > /dev/null\\n\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tw := &bytes.Buffer{}\n\t\t\tPrintCmds(w, tt.args.cmds, tt.args.verbose)\n\t\t\tif gotW := w.String(); gotW != tt.wantW {\n\t\t\t\tt.Errorf(\"PrintCmds() = %v, want %v\", gotW, tt.wantW)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/urfave/cli/v2\"\n)\n\nconst (\n\tname        = \"tinet\"\n\tdescription = \"tinet: Tiny Network\"\n)\n\nvar (\n\tVersion = \"0.0.1\"\n)\n\nfunc main() {\n\tif err := newApp().Run(os.Args); err != nil {\n\t\tfmt.Println(err)\n\t\tos.Exit(1)\n\t}\n}\n\nfunc newApp() *cli.App {\n\tapp := cli.NewApp()\n\tapp.Name = name\n\tapp.Version = Version\n\tapp.Usage = description\n\tapp.Authors = []*cli.Author{\n\t\t{\n\t\t\tName:  \"ak1ra24\",\n\t\t\tEmail: \"ak1ra24net@gmail.com\",\n\t\t},\n\t\t{\n\t\t\tName:  \"slankdev\",\n\t\t\tEmail: \"slank.dev@gmail.com\",\n\t\t},\n\t}\n\tapp.Commands = commands\n\n\treturn app\n}\n"
  }
]