[26-06-02 09:43:59] START switch_namespace_snat scenario: cases/switch_namespace_snat.sh header : verify namespace snat source rewriting and non-snat isolation topology: ac1 -> sw2 example [vrf-snat] -- UDP output --> sw1 VIP 10.242.2.11; acb -> sw2 network b (no VRF) ----------------x same VIP topology: # Topology: topology: # - Diagram: topology: # ac1 -> sw2 example [vrf-snat] -- UDP output --> sw1 VIP 10.242.2.11 topology: # acb -> sw2 network b (no VRF) ----------------x same VIP topology: # SNAT changes source from ac1 address to sw2 overlay address topology: # - Docker mgmt network: 172.241.0.0/24 topology: # sw1=172.241.0.241, sw2=172.241.0.242. topology: # - OpenLAN service network "example": 192.64.0.0/24 topology: # sw1=192.64.0.1, sw2=192.64.0.2. topology: # - sw2 service network L3 device is enslaved to VRF "vrf-snat"; sw1 is not. topology: # - Non-namespace network "b": 192.66.0.0/24 topology: # sw2=192.66.0.1. topology: # - Access clients: topology: # ac1=192.64.0.11, connected to sw2 and forwarding 10.242.2.11/32. topology: # acb=192.66.0.11, connected to sw2 network b and forwarding 10.242.2.11/32. topology: # - sw1 VIP: topology: # lo=10.242.2.11/32, HTTP service listens on 10.242.2.11:8081. topology: # - Forwarding link: topology: # sw2 -> sw1 over UDP output. topology: # Validation: topology: # when SNAT is disabled, the VIP HTTP service sees ac1 address 192.64.0.11. topology: # when SNAT is enabled, the VIP HTTP service sees sw2 overlay address 192.64.0.2. topology: # network b is not in the namespace, so acb cannot access the VIP HTTP service topology: # even when example SNAT is enabled. Started switch pause container: tests-sw-namespace-snat1-pause Started switch frr container: tests-sw-namespace-snat1-frr Started switch ipsec container: tests-sw-namespace-snat1-ipsec Started switch container: tests-sw-namespace-snat1 [26-06-02 09:44:00][ASSERT#0001][expect] at cases/switch_namespace_snat.sh:73 fn=setup_sw1 retry=30 cmd="docker logs -f tests-sw-namespace-snat1" expect="Http.Start" 2026/06/02 09:44:01 INFO|root|UdpServer.Listen: udp://0.0.0.0:10002 2026/06/02 09:44:01 INFO|root|Wait: ... 2026/06/02 09:44:01 INFO|root|TcpServer.Listen: tcp://0.0.0.0:10002 2026/06/02 09:44:01 INFO|root|Http.Start 0.0.0.0:10000 [26-06-02 09:44:01][ASSERT#0001][OK] cost=1.033s [26-06-02 09:44:01][ASSERT#0002][cmd] at cases/switch_namespace_snat.sh:75 fn=setup_sw1 cmd="docker exec tests-sw-namespace-snat1 openlan network --name example add --address 192.64.0.1/24" [26-06-02 09:44:01][ASSERT#0002][OK] cost=0.241s [26-06-02 09:44:01][ASSERT#0003][cmd] at cases/switch_namespace_snat.sh:76 fn=setup_sw1 cmd="docker exec tests-sw-namespace-snat1 openlan router address add --device lo --address 10.242.2.11/32" [26-06-02 09:44:01][ASSERT#0003][OK] cost=0.057s [26-06-02 09:44:01][ASSERT#0004][cmd] at cases/switch_namespace_snat.sh:77 fn=setup_sw1 cmd="docker exec tests-sw-namespace-snat1 openlan user add --name t1@example --password 123456" # total 1 username password role lease t1@example 123456 guest 2027-06-02T09 [26-06-02 09:44:02][ASSERT#0004][OK] cost=0.064s Started switch pause container: tests-sw-namespace-snat2-pause Started switch frr container: tests-sw-namespace-snat2-frr Started switch ipsec container: tests-sw-namespace-snat2-ipsec Started switch container: tests-sw-namespace-snat2 [26-06-02 09:44:02][ASSERT#0005][expect] at cases/switch_namespace_snat.sh:86 fn=setup_sw2 retry=30 cmd="docker logs -f tests-sw-namespace-snat2" expect="Http.Start" 2026/06/02 09:44:03 INFO|root|Wait: ... 2026/06/02 09:44:03 INFO|root|UdpServer.Listen: udp://0.0.0.0:10002 2026/06/02 09:44:03 INFO|root|TcpServer.Listen: tcp://0.0.0.0:10002 2026/06/02 09:44:03 INFO|root|Http.Start 0.0.0.0:10000 [26-06-02 09:44:03][ASSERT#0005][OK] cost=1.029s [26-06-02 09:44:03][ASSERT#0006][cmd] at cases/switch_namespace_snat.sh:88 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 openlan network --name example add --address 192.64.0.2/24 --namespace vrf-snat" [26-06-02 09:44:04][ASSERT#0006][OK] cost=0.264s [26-06-02 09:44:04][ASSERT#0007][match] at cases/switch_namespace_snat.sh:89 fn=setup_sw2 retry=1 cmd="docker exec tests-sw-namespace-snat2 openlan network --name example" expect="namespace: vrf-snat" address: 192.64.0.2/24 name: br-example name: example namespace: vrf-snat snat: enable subnet: netmask: 255.255.255.0 [26-06-02 09:44:04][ASSERT#0007][OK] cost=0.069s [26-06-02 09:44:04][ASSERT#0008][cmd] at cases/switch_namespace_snat.sh:90 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 ip link show vrf-snat" 9: vrf-snat: mtu 65575 qdisc noqueue state UP mode DEFAULT group default link/ether ba:c2:eb:d6:05:4c brd ff:ff:ff:ff:ff:ff [26-06-02 09:44:04][ASSERT#0008][OK] cost=0.061s [26-06-02 09:44:04][ASSERT#0009][match] at cases/switch_namespace_snat.sh:91 fn=setup_sw2 retry=5 cmd="docker exec tests-sw-namespace-snat2 ip link show hi-example" expect="master vrf-snat" 8: hi-example@bi-example: mtu 1500 qdisc noqueue master vrf-snat state UP mode DEFAULT group default link/ether fa:91:21:0a:c6:61 brd ff:ff:ff:ff:ff:ff [26-06-02 09:44:04][ASSERT#0009][OK] cost=0.072s [26-06-02 09:44:04][ASSERT#0010][cmd] at cases/switch_namespace_snat.sh:92 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 openlan network --name b add --address 192.66.0.1/24" [26-06-02 09:44:04][ASSERT#0010][OK] cost=0.235s [26-06-02 09:44:04][ASSERT#0011][cmd] at cases/switch_namespace_snat.sh:93 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 openlan network --name example snat disable" [26-06-02 09:44:04][ASSERT#0011][OK] cost=0.086s [26-06-02 09:44:04][ASSERT#0012][cmd] at cases/switch_namespace_snat.sh:94 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 openlan network --name example route add --prefix 10.242.2.11/32 --nexthop 192.64.0.1" [26-06-02 09:44:04][ASSERT#0012][OK] cost=0.074s [26-06-02 09:44:04][ASSERT#0013][cmd] at cases/switch_namespace_snat.sh:95 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 openlan user add --name ac1@example --password 123456" # total 1 username password role lease ac1@example 123456 guest 2027-06-02T09 [26-06-02 09:44:04][ASSERT#0013][OK] cost=0.059s [26-06-02 09:44:04][ASSERT#0014][cmd] at cases/switch_namespace_snat.sh:96 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 openlan user add --name acb@b --password 123456" # total 1 username password role lease acb@b 123456 guest 2027-06-02T09 [26-06-02 09:44:04][ASSERT#0014][OK] cost=0.065s [26-06-02 09:44:04][ASSERT#0015][cmd] at cases/switch_namespace_snat.sh:97 fn=setup_sw2 cmd="docker exec tests-sw-namespace-snat2 openlan network --name example output add --remote 172.241.0.241 --protocol udp --secret t1:123456 --crypt aes-128:ea64d5b0c96c" [26-06-02 09:44:04][ASSERT#0015][OK] cost=0.077s Started access container: tests-sw-namespace-snat.ac1 [26-06-02 09:44:05][ASSERT#0016][expect] at cases/switch_namespace_snat.sh:118 fn=setup_ac1 retry=30 cmd="docker logs -f tests-sw-namespace-snat.ac1" expect="onLogin: success" 2026/06/02 09:44:05 INFO|172.241.0.242:10002|example|Worker.OnSuccess 2026/06/02 09:44:05 INFO|172.241.0.242:10002|example|Access.AddAddr: 192.64.0.11/24 via 2026/06/02 09:44:05 INFO|172.241.0.242:10002|example|Access.AddRoute: 10.242.2.11/32 via 192.64.0.2 2026/06/02 09:44:05 INFO|udp:172.241.0.242:10002|example|SocketWorker.onLogin: success 2026/06/02 09:44:05 INFO|172.241.0.242:10002|example|Worker.OnIpAddr: name:example gateway:192.64.0.2 address:192.64.0.11 netmask:255.255.255.0 routes:[] 2026/06/02 09:44:05 WARN|172.241.0.242:10002|example|Access.AddAddr.SetLinkIp: file exists 2026/06/02 09:44:05 INFO|172.241.0.242:10002|example|Access.AddAddr: 192.64.0.11/24 via 192.64.0.2 [26-06-02 09:44:06][ASSERT#0016][OK] cost=1.030s Started access container: tests-sw-namespace-snat.acb [26-06-02 09:44:06][ASSERT#0017][expect] at cases/switch_namespace_snat.sh:139 fn=setup_acb retry=30 cmd="docker logs -f tests-sw-namespace-snat.acb" expect="onLogin: success" 2026/06/02 09:44:06 INFO|172.241.0.242:10002|b|Worker.OnSuccess 2026/06/02 09:44:06 INFO|172.241.0.242:10002|b|Access.AddAddr: 192.66.0.11/24 via 2026/06/02 09:44:06 INFO|172.241.0.242:10002|b|Access.AddRoute: 10.242.2.11/32 via 192.66.0.1 2026/06/02 09:44:06 INFO|udp:172.241.0.242:10002|b|SocketWorker.onLogin: success 2026/06/02 09:44:06 INFO|172.241.0.242:10002|b|Worker.OnIpAddr: name:b gateway:192.66.0.1 address:192.66.0.11 netmask:255.255.255.0 routes:[] 2026/06/02 09:44:06 WARN|172.241.0.242:10002|b|Access.AddAddr.SetLinkIp: file exists 2026/06/02 09:44:06 INFO|172.241.0.242:10002|b|Access.AddAddr: 192.66.0.11/24 via 192.66.0.1 [26-06-02 09:44:07][ASSERT#0017][OK] cost=1.033s [26-06-02 09:44:07][ASSERT#0018][cmd] at cases/switch_namespace_snat.sh:143 fn=setup_vip_http cmd="docker exec tests-sw-namespace-snat1 sh -c cat > /tmp/namespace-snat-http.sh <<'EOF' #!/bin/sh printf 'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nsrc=%s\n' "$SOCAT_PEERADDR" EOF chmod +x /tmp/namespace-snat-http.sh nohup socat TCP-LISTEN:8081,bind=10.242.2.11,reuseaddr,fork EXEC:/tmp/namespace-snat-http.sh >/tmp/namespace-snat-http.log 2>&1 &" [26-06-02 09:44:07][ASSERT#0018][OK] cost=0.063s [26-06-02 09:44:07][ASSERT#0019][match] at cases/switch_namespace_snat.sh:178 fn=test_namespace_snat retry=15 cmd="docker exec tests-sw-namespace-snat2 openlan network --name example output ls" expect="state: authenticated" protocol: udp remote: 172.241.0.241 secret: t1:123456 state: authenticated [26-06-02 09:44:07][ASSERT#0019][OK] cost=0.065s [26-06-02 09:44:07][ASSERT#0020][cmd] at cases/switch_namespace_snat.sh:180 fn=test_namespace_snat cmd="docker exec tests-sw-namespace-snat2 openlan network --name example snat disable" [26-06-02 09:44:07][ASSERT#0020][OK] cost=0.069s [26-06-02 09:44:07][ASSERT#0021][match] at cases/switch_namespace_snat.sh:164 fn=assert_ping_target retry=20 cmd="docker exec tests-sw-namespace-snat.ac1 ping -c 3 10.242.2.11" expect="bytes from" PING 10.242.2.11 (10.242.2.11) 56(84) bytes of data. 64 bytes from 10.242.2.11: icmp_seq=1 ttl=64 time=2042 ms 64 bytes from 10.242.2.11: icmp_seq=2 ttl=64 time=1030 ms 64 bytes from 10.242.2.11: icmp_seq=3 ttl=64 time=6.40 ms --- 10.242.2.11 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2036ms [26-06-02 09:44:09][ASSERT#0021][OK] cost=2.100s [26-06-02 09:44:09][ASSERT#0022][match] at cases/switch_namespace_snat.sh:154 fn=assert_http_source retry=20 cmd="docker exec tests-sw-namespace-snat.ac1 wget -qO- -T 3 -t 1 http://10.242.2.11:8081" expect="src=192.64.0.11" src=192.64.0.11 [26-06-02 09:44:09][ASSERT#0022][OK] cost=0.066s [26-06-02 09:44:09][ASSERT#0023][cmd] at cases/switch_namespace_snat.sh:184 fn=test_namespace_snat cmd="docker exec tests-sw-namespace-snat2 openlan network --name example snat enable --scope enable" [26-06-02 09:44:09][ASSERT#0023][OK] cost=0.073s [26-06-02 09:44:09][ASSERT#0024][match] at cases/switch_namespace_snat.sh:164 fn=assert_ping_target retry=20 cmd="docker exec tests-sw-namespace-snat.ac1 ping -c 3 10.242.2.11" expect="bytes from" PING 10.242.2.11 (10.242.2.11) 56(84) bytes of data. 64 bytes from 10.242.2.11: icmp_seq=1 ttl=63 time=1.23 ms 64 bytes from 10.242.2.11: icmp_seq=2 ttl=63 time=2.67 ms 64 bytes from 10.242.2.11: icmp_seq=3 ttl=63 time=2.50 ms --- 10.242.2.11 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2004ms [26-06-02 09:44:12][ASSERT#0024][OK] cost=2.068s [26-06-02 09:44:12][ASSERT#0025][match] at cases/switch_namespace_snat.sh:154 fn=assert_http_source retry=20 cmd="docker exec tests-sw-namespace-snat.ac1 wget -qO- -T 3 -t 1 http://10.242.2.11:8081" expect="src=192.64.0.2" src=192.64.0.2 [26-06-02 09:44:12][ASSERT#0025][OK] cost=0.062s [26-06-02 09:44:12][ASSERT#0026][unmatch] at cases/switch_namespace_snat.sh:169 fn=assert_ping_target_fail retry=3 cmd="docker exec tests-sw-namespace-snat.acb ping -c 3 10.242.2.11" unexpected="bytes from" Last output: PING 10.242.2.11 (10.242.2.11) 56(84) bytes of data. --- 10.242.2.11 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2056ms [26-06-02 09:44:51][ASSERT#0026][OK] cost=39.361s [26-06-02 09:44:51][ASSERT#0027][unmatch] at cases/switch_namespace_snat.sh:159 fn=assert_http_unreachable retry=3 cmd="docker exec tests-sw-namespace-snat.acb wget -qO- -T 3 -t 1 http://10.242.2.11:8081" unexpected="src=" Last output: [26-06-02 09:45:03][ASSERT#0027][OK] cost=12.215s [26-06-02 09:45:03][ASSERT#0028][cmd] at cases/switch_namespace_snat.sh:192 fn=test_reload_persistence cmd="docker exec tests-sw-namespace-snat1 openlan reload --save" Save configuraion ... success # reloading pid:42 .... PID 42 CMD: /usr/bin/openlan-switch -conf:dir /etc/openlan/switch -log:level 20 # max wait 60s... # during 1s, new pid:550 ... PID 550 CMD: /usr/bin/openlan-switch -conf:dir /etc/openlan/switch -log:level 20 [26-06-02 09:45:04][ASSERT#0028][OK] cost=1.087s [26-06-02 09:45:04][ASSERT#0029][cmd] at cases/switch_namespace_snat.sh:193 fn=test_reload_persistence cmd="docker exec tests-sw-namespace-snat2 openlan reload --save" Save configuraion ... success # reloading pid:42 .... PID 42 CMD: /usr/bin/openlan-switch -conf:dir /etc/openlan/switch -log:level 20 # max wait 60s... # during 1s, new pid:797 ... PID 797 CMD: /usr/bin/openlan-switch -conf:dir /etc/openlan/switch -log:level 20 [26-06-02 09:45:05][ASSERT#0029][OK] cost=1.067s [26-06-02 09:45:05][ASSERT#0030][match] at cases/switch_namespace_snat.sh:195 fn=test_reload_persistence retry=10 cmd="docker exec tests-sw-namespace-snat2 openlan network --name example" expect="namespace: vrf-snat" address: 192.64.0.2/24 name: br-example name: example namespace: vrf-snat outputs: - crypt: aes-128:ea64d5b0c96c link: udp:172.241.0.241:t1 [26-06-02 09:45:05][ASSERT#0030][OK] cost=0.072s [26-06-02 09:45:05][ASSERT#0031][match] at cases/switch_namespace_snat.sh:196 fn=test_reload_persistence retry=10 cmd="docker exec tests-sw-namespace-snat2 ip link show hi-example" expect="master vrf-snat" 8: hi-example@bi-example: mtu 1500 qdisc noqueue master vrf-snat state UP mode DEFAULT group default link/ether fa:91:21:0a:c6:61 brd ff:ff:ff:ff:ff:ff [26-06-02 09:45:06][ASSERT#0031][OK] cost=0.054s [26-06-02 09:45:06][ASSERT#0032][match] at cases/switch_namespace_snat.sh:164 fn=assert_ping_target retry=20 cmd="docker exec tests-sw-namespace-snat.ac1 ping -c 3 10.242.2.11" expect="bytes from" PING 10.242.2.11 (10.242.2.11) 56(84) bytes of data. 64 bytes from 10.242.2.11: icmp_seq=1 ttl=63 time=2.04 ms 64 bytes from 10.242.2.11: icmp_seq=2 ttl=63 time=2.48 ms 64 bytes from 10.242.2.11: icmp_seq=3 ttl=63 time=2.28 ms --- 10.242.2.11 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms [26-06-02 09:45:21][ASSERT#0032][OK] cost=15.176s [26-06-02 09:45:21][ASSERT#0033][match] at cases/switch_namespace_snat.sh:154 fn=assert_http_source retry=20 cmd="docker exec tests-sw-namespace-snat.ac1 wget -qO- -T 3 -t 1 http://10.242.2.11:8081" expect="src=192.64.0.2" src=192.64.0.2 [26-06-02 09:45:21][ASSERT#0033][OK] cost=0.082s [26-06-02 09:45:21][ASSERT#0034][unmatch] at cases/switch_namespace_snat.sh:169 fn=assert_ping_target_fail retry=3 cmd="docker exec tests-sw-namespace-snat.acb ping -c 3 10.242.2.11" unexpected="bytes from" Last output: PING 10.242.2.11 (10.242.2.11) 56(84) bytes of data. --- 10.242.2.11 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2042ms [26-06-02 09:46:00][ASSERT#0034][OK] cost=39.378s [26-06-02 09:46:00][ASSERT#0035][unmatch] at cases/switch_namespace_snat.sh:159 fn=assert_http_unreachable retry=3 cmd="docker exec tests-sw-namespace-snat.acb wget -qO- -T 3 -t 1 http://10.242.2.11:8081" unexpected="src=" Last output: [26-06-02 09:46:12][ASSERT#0035][OK] cost=12.208s [26-06-02 09:46:13] END switch_namespace_snat status=PASS cost=133.892s