Docker コンテナ間で P4 をデバッグできれば色々デバッグが捗るのでできるようにする(今回は mininet は使わない)。
今回使う P4 プログラムは https://github.com/p4lang/tutorials/tree/master/exercises/basic 。
(Optional) iptables, masq, forward を無効化する
ハマらないために、 `/etc/docker/daemon.json` で設定しても良い。
{ "ip-forward": true, "ip-masq": true, "iptables":true }
お互いに通信できないコンテナを作る
Docker network を別々にすれば(`simple_switch` がなければ)お互いに通信できない。
$ docker network create network1 --subnet=172.18.100.0/24 $ docker network create network2 --subnet=172.18.200.0/24
コンテナをたてる
IP とネットワークを指定する。
$ docker run --rm -it --ip=172.18.100.2 --network=network1 --name=container1 busybox sh $ docker run --rm -it --ip=172.18.200.2 --network=network2 --name=container2 busybox sh
simple_switch をたてる
コンテナの veth にアタッチする。Bridge interface でも良い。
$ sudo simple_switch build/basic.json -i 1@veth65e0b28 -i 2@veth79593d4 --log-console
仮想スイッチにエントリを入れる
MAC アドレスは Docker コンテナ側から見た MAC アドレスであることに注意。
$ simple_switch_CLI Obtaining JSON from switch… Done Control utility for runtime P4 table manipulation RuntimeCmd: table_add MyIngress.ipv4_lpm MyIngress.ipv4_forward 172.18.200.2/32 => 02:42:d1:d2:6b:16 2 Adding entry to lpm match table MyIngress.ipv4_lpm match key: LPM-ac:12:c8:02/32 action: MyIngress.ipv4_forward runtime data: 02:42:d1:d2:6b:16 00:02 Entry has been added with handle 0 RuntimeCmd: table_add MyIngress.ipv4_lpm MyIngress.ipv4_forward 172.18.100.2/32 => 02:42:d3:9d:be:4f 1 Adding entry to lpm match table MyIngress.ipv4_lpm match key: LPM-ac:12:64:02/32 action: MyIngress.ipv4_forward runtime data: 02:42:d3:9d:be:4f 00:01 Entry has been added with handle 12
これで ping が相互に届き、返事もできるようになる。
なお、MAC アドレスを(外から見たものにする等して)間違えていた場合、宛先インターフェースまでは届くものの返事はしない。