diff --git a/Makefile b/Makefile index fc1d0b0..7f0c999 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,10 @@ PROFILES = --profile debug PROJECT_DIRECTORY = --project-directory $(BUILD_DIR) MAKE = make --no-print-directory +DATE := $(shell date --iso-8601=seconds) -$(BCOMPOSE): templates/compose.yaml.j2 scripts/jinja/customize.py $(BCONFIG) + +$(BCOMPOSE): templates/compose.yaml.j2 templates/images-list.yaml scripts/jinja/customize.py $(BCONFIG) @if [ $(BCONFIG) -ot default-config.yaml ]; then \ echo "Warning: default-config.yaml has been updated recently, consider updating $(BCONFIG)"; \ fi @@ -232,7 +234,7 @@ restart: .PHONY: e e/%: @# enter container - docker exec -it $(@F) bash + docker exec -it $(@F) sh .PHONY: ran ran/%: @@ -350,3 +352,337 @@ plot/latency-switch: @$(MAKE) down @echo "[7/7] Plotting data" @scripts/plots/latency_switch.py $(BUILD_DIR)/volumes/ue1/ping-sr4mec.txt $(BUILD_DIR)/volumes/ue3/ping-ulcl.txt $(BUILD_DIR)/volumes/ue1/plot-latency-switch.pdf + + +.PHONY: thesis/plot/binding +thesis/plot/binding: + @echo "[1/2] [1/7] Configuring testbed with NextMN-SRv6" + @./scripts/config_edit.py $(BCONFIG) --handover=false + @$(MAKE) set/controlplane/free5gc + @$(MAKE) set/dataplane/nextmn-srv6 + @$(MAKE) set/nb-ue/2 # TODO: configure different slices + @$(MAKE) set/nb-edges/2 # XXX: this currently means central DN + 1 edge + @$(MAKE) set/nb-gnb/1 + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/info + @echo "[1/2] [2/7] Starting containers" + @$(MAKE) up + @echo "[1/2] [3/7] Adding latencies" + @# central DN latency + @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # uplink + @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # downlink + @# radio latency + @docker exec ue1-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # uplink UE1 + @docker exec ue2-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # uplink UE2 + @docker exec gnb1-debug bash -c "tc qdisc add dev ran-0 root netem delay 7ms" # downlink gNB1 + @echo "[1/2] [4/7] Checking if instance is reachable" + @sleep 2 + @docker exec ue1-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @docker exec ue2-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @echo "[1/2] [5/7] Setting UE2 on edge 1" + @docker exec ue2-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is still reachable + @$(MAKE) ue/switch-edge/2 + @echo "[1/2] [6/7] [$$(date --rfc-3339=seconds)] Starting ping from ue1 and ue2 (60s + 5s margin)" + @bash -c 'docker exec ue1-debug bash -c "ping -D -w 60 10.4.0.1 -i 0.1 > /volume/ping-binding-slice-s1.txt"' & + @bash -c 'docker exec ue2-debug bash -c "ping -D -w 60 10.4.0.1 -i 0.1 > /volume/ping-binding-slice-s2.txt"' & + @sleep 65 + @echo "[1/2] [6/6] Stopping containers" + @$(MAKE) down + @echo "[2/2] Plotting data" + @mkdir -p $(BUILD_DIR)/thesis-plots/binding/$(DATE)/ + @cp $(BUILD_DIR)/volumes/ue1/ping-binding-slice-s1.txt $(BUILD_DIR)/thesis-plots/binding/$(DATE)/slice-s1.txt + @cp $(BUILD_DIR)/volumes/ue2/ping-binding-slice-s2.txt $(BUILD_DIR)/thesis-plots/binding/$(DATE)/slice-s2.txt + @scripts/thesis/binding.py $(BUILD_DIR)/thesis-plots/binding/$(DATE)/slice-s1.txt $(BUILD_DIR)/thesis-plots/binding/$(DATE)/slice-s2.txt $(BUILD_DIR)/thesis-plots/binding/$(DATE)/01_10_evaluation-plot-binding.pdf + +.PHONY: thesis/plot/migration +thesis/plot/migration: + @echo "[1/7] Configuring testbed with NextMN-SRv6 + NextMN-UPF" + @./scripts/config_edit.py $(BCONFIG) --handover=false + @$(MAKE) set/controlplane/free5gc + @$(MAKE) set/dataplane/nextmn-srv6+nextmn-upf + @$(MAKE) set/nb-ue/1 # 1 UE in each DN + @$(MAKE) set/nb-edges/2 # central DN + 1 edge + @$(MAKE) set/nb-gnb/1 + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/info + @echo "[2/7] Starting containers" + @$(MAKE) up + @echo "[3/7] Adding latencies" + @# central DN latency + @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # uplink + @docker exec upfa1-nmn bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # uplink + @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # downlink + @# radio latency + @docker exec ue1-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # uplink UE1 + @docker exec ue5-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # uplink UE5 + @docker exec gnb1-debug bash -c "tc qdisc add dev ran-0 root netem delay 7ms" # downlink gNB1 + @sleep 2 + @docker exec ue1-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @docker exec ue5-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 30s" + @bash -c 'sleep 30 && $(MAKE) ue/switch-edge/1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Switching UE1 from edge 0 to edge 1"' & + @echo "[5/7] [$$(date --rfc-3339=seconds)] Start ping for 60s + 5s margin" + @bash -c 'docker exec ue5-debug bash -c "ping -D -w 60 10.4.0.1 -i 0.1 > /volume/ping-migration-ulcl.txt"' & + @bash -c 'docker exec ue1-debug bash -c "ping -D -w 60 10.4.0.1 -i 0.1 > /volume/ping-migration-sr4mec.txt"' & + @sleep 65 + @echo "[6/7] Stopping containers" + @$(MAKE) down + @echo "[7/7] Plotting data" + @mkdir -p $(BUILD_DIR)/thesis-plots/migration/$(DATE)/ + @cp $(BUILD_DIR)/volumes/ue5/ping-migration-ulcl.txt $(BUILD_DIR)/thesis-plots/migration/$(DATE)/ulcl.txt + @cp $(BUILD_DIR)/volumes/ue1/ping-migration-sr4mec.txt $(BUILD_DIR)/thesis-plots/migration/$(DATE)/sr4mec.txt + @scripts/thesis/migration.py $(BUILD_DIR)/thesis-plots/migration/$(DATE)/sr4mec.txt $(BUILD_DIR)/thesis-plots/migration/$(DATE)/ulcl.txt $(BUILD_DIR)/thesis-plots/migration/$(DATE)/02_10_evaluation-plot-migration.pdf + +.PHONY: thesis/plot/mobility/ulcl +thesis/plot/mobility/ulcl: + @echo "[1/7] Configuring testbed with NextMN-UPF" + @./scripts/config_edit.py $(BCONFIG) --handover=true + @$(MAKE) set/controlplane/nextmn-lite + @$(MAKE) set/dataplane/nextmn-upf + @$(MAKE) set/nb-ue/1 + @$(MAKE) set/nb-edges/2 + @$(MAKE) set/nb-gnb/3 # gnbl3 is in a different area + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/info + @echo "[2/7] Starting containers" + @$(MAKE) up + @echo "[3/7] Adding latencies" + @# CP latency + @docker exec cp-lite-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # uplink + @docker exec upfi1-nmn-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # downlink + @docker exec upfi2-nmn-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # downlink + @docker exec upfa1-nmn-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # downlink + @docker exec upfa2-nmn-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # downlink + @# Inter-areas latencies + @docker exec inter-areas-debug bash -c "tc qdisc add dev dataplane-0 root netem delay 2ms" + @# upfi1-nmn (edge 1) - upfi2-nmn (edge 2) + @docker exec upfi1-nmn-debug bash -c "ip route replace 10.1.4.144/32 via 10.1.4.146" # from upfi1-nmn to upfi2-nmn via inter-areas + @docker exec upfi2-nmn-debug bash -c "ip route replace 10.1.4.135/32 via 10.1.4.146" # from upfi2-nmn to upfi1-nmn via inter-areas + @# upfi2-nmn (edge 2) - upfa2-nmn (edge 1) + @docker exec upfa2-nmn-debug bash -c "ip route replace 10.1.4.144/32 via 10.1.4.146" # from upfa2-nmn to upfi2-nmn via inter-areas + @docker exec upfi2-nmn-debug bash -c "ip route replace 10.1.4.137/32 via 10.1.4.146" # from upfi2-nmn to upfa2-nmn via inter-areas + @#### + @docker exec uel5-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @docker exec upfi1-nmn-debug bash -c "ping -c 1 10.1.4.144 > /dev/null" + @docker exec upfi2-nmn-debug bash -c "ping -c 1 10.1.4.135 > /dev/null" + @docker exec upfa2-nmn-debug bash -c "ping -c 1 10.1.4.144 > /dev/null" + @docker exec upfi2-nmn-debug bash -c "ping -c 1 10.1.4.137 > /dev/null" + @docker exec uel5-debug bash -c "ping -c 1 fd00:0:0:0:1:8000:0:c > /dev/null" # to gNBl3 + @docker exec gnbl3-debug bash -c "ping -c 1 10.1.4.144 > /dev/null" # to upfi2 + @sleep 2 + @#### + @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" + @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel5 nmn-upf-0 gnbl3 gnbl1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 1 to Area 2"' & + @echo "[5/7] [$$(date --rfc-3339=seconds)] Start ping for 20s + 5s margin" + @# Note: we cannot do less than 0.1 interval, otherwise our UPF is too slow to process + @bash -c 'docker exec uel5-debug bash -c "ping -D -w 20 10.4.0.1 -i 0.1 > /volume/ping-mobility-ulcl.txt"' & + @sleep 25 + @echo "[6/7] Stopping containers" + @$(MAKE) down + @echo "[7/7] Plotting data" + @mkdir -p $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ + @cp $(BUILD_DIR)/volumes/uel5/ping-mobility-ulcl.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ulcl.txt + @scripts/thesis/mobility.py $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ulcl.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/03_10_evaluation-plot-mobility-ulcl.pdf + +.PHONY: thesis/plot/mobility/posteriori/central +thesis/plot/mobility/posteriori/central: + @echo "[1/7] Configuring testbed with NextMN-SRv6" + @./scripts/config_edit.py $(BCONFIG) --handover=true --migration-a-posteriori=true + @$(MAKE) set/controlplane/nextmn-lite + @$(MAKE) set/dataplane/nextmn-srv6 + @$(MAKE) set/nb-ue/2 + @$(MAKE) set/nb-edges/3 + @$(MAKE) set/nb-gnb/3 # gnbl3 is in a different area + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/info + @echo "[2/7] Starting containers" + @$(MAKE) up + @echo "[3/7] Adding latencies" + @# central DN latency + @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # uplink + @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # downlink + @# CP latency + @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink + @docker exec srgw0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec srgw1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r2-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @# Inter-areas latencies + @docker exec inter-areas-debug bash -c "tc qdisc add dev dataplane-0 root netem delay 2ms" + @# srgw0 (edge 1) - srgw1 (edge 2) + @docker exec srgw0-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from srgw0 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:1::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to srgw0 via inter-areas + @# r1 (edge 1) - srgw1 (edge 2) + @docker exec r1-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from r1 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:3::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to r1 via inter-areas + @#### + @docker exec uel1-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @sleep 2 + @#### + @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" + @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel1 sr4mec-0 gnbl3 gnbl1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 1 to Area 2"' & + @echo "[5/7] [$$(date --rfc-3339=seconds)] Start ping for 20s + 5s margin" + @# Note: we cannot do less than 0.1 interval, otherwise our UPF is too slow to process + @bash -c 'docker exec uel1-debug bash -c "ping -D -w 20 10.4.0.1 -i 0.1 > /volume/ping-mobility-posteriori-central.txt"' & + @sleep 25 + @echo "[6/7] Stopping containers" + @$(MAKE) down + @echo "[7/7] Plotting data" + @mkdir -p $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ + @cp $(BUILD_DIR)/volumes/uel1/ping-mobility-posteriori-central.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/posteriori-central.txt + @scripts/thesis/mobility.py $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/posteriori-central.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/03_20_evaluation-plot-mobility-changement-a-posteriori-central.pdf + +.PHONY: thesis/plot/mobility/posteriori/edge +thesis/plot/mobility/posteriori/edge: + @echo "[1/7] Configuring testbed with NextMN-SRv6" + @./scripts/config_edit.py $(BCONFIG) --handover=true --migration-a-posteriori=true + @$(MAKE) set/controlplane/nextmn-lite + @$(MAKE) set/dataplane/nextmn-srv6 + @$(MAKE) set/nb-ue/2 + @$(MAKE) set/nb-edges/3 + @$(MAKE) set/nb-gnb/3 # gnbl3 is in a different area + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/info + @echo "[2/7] Starting containers" + @$(MAKE) up + @echo "[3/7] Adding latencies" + @# central DN latency + @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # uplink + @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # downlink + @# CP latency + @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink + @docker exec srgw0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec srgw1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r2-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @# Inter-areas latencies + @docker exec inter-areas-debug bash -c "tc qdisc add dev dataplane-0 root netem delay 2ms" + @# srgw0 (edge 1) - srgw1 (edge 2) + @docker exec srgw0-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from srgw0 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:1::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to srgw0 via inter-areas + @# r1 (edge 1) - srgw1 (edge 2) + @docker exec r1-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from r1 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:3::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to r1 via inter-areas + @#### + @docker exec uel2-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @sleep 2 + @#### + @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" + @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel2 sr4mec-1 gnbl3 gnbl1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 1 to Area 2"' & + @echo "[5/7] [$$(date --rfc-3339=seconds)] Start ping for 20s + 5s margin" + @# Note: we cannot do less than 0.1 interval, otherwise our UPF is too slow to process + @bash -c 'docker exec uel2-debug bash -c "ping -D -w 20 10.4.0.1 -i 0.1 > /volume/ping-mobility-posteriori-edge.txt"' & + @sleep 25 + @echo "[6/7] Stopping containers" + @$(MAKE) down + @echo "[7/7] Plotting data" + @mkdir -p $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ + @cp $(BUILD_DIR)/volumes/uel2/ping-mobility-posteriori-edge.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/posteriori-edge.txt + @scripts/thesis/mobility.py $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/posteriori-edge.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/03_21_evaluation-plot-mobility-changement-a-posteriori-edge.pdf + +.PHONY: thesis/plot/mobility/immediate/central +thesis/plot/mobility/immediate/central: + @echo "[1/7] Configuring testbed with NextMN-SRv6" + @./scripts/config_edit.py $(BCONFIG) --handover=true --migration-a-posteriori=false + @$(MAKE) set/controlplane/nextmn-lite + @$(MAKE) set/dataplane/nextmn-srv6 + @$(MAKE) set/nb-ue/2 + @$(MAKE) set/nb-edges/3 + @$(MAKE) set/nb-gnb/3 # gnbl3 is in a different area + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/info + @echo "[2/7] Starting containers" + @$(MAKE) up + @echo "[3/7] Adding latencies" + @# central DN latency + @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # uplink + @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # downlink + @# CP latency + @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink + @docker exec srgw0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec srgw1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r2-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @# Inter-areas latencies + @docker exec inter-areas-debug bash -c "tc qdisc add dev dataplane-0 root netem delay 2ms" + @# srgw0 (edge 1) - srgw1 (edge 2) + @docker exec srgw0-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from srgw0 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:1::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to srgw0 via inter-areas + @# r1 (edge 1) - srgw1 (edge 2) + @docker exec r1-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from r1 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:3::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to r1 via inter-areas + @#### + @docker exec uel1-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @sleep 2 + @#### + @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" + @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel1 sr4mec-0 gnbl3 gnbl1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 1 to Area 2"' & + @echo "[5/7] [$$(date --rfc-3339=seconds)] Start ping for 20s + 5s margin" + @# Note: we cannot do less than 0.1 interval, otherwise our UPF is too slow to process + @bash -c 'docker exec uel1-debug bash -c "ping -D -w 20 10.4.0.1 -i 0.1 > /volume/ping-mobility-immediat-central.txt"' & + @sleep 25 + @echo "[6/7] Stopping containers" + @$(MAKE) down + @echo "[7/7] Plotting data" + @mkdir -p $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ + @cp $(BUILD_DIR)/volumes/uel1/ping-mobility-immediat-central.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/immediat-central.txt + @scripts/thesis/mobility.py $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/immediat-central.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/03_30_evaluation-plot-mobility-changement-immediat-central.pdf + +.PHONY: thesis/plot/mobility/immediate/edge +thesis/plot/mobility/immediate/edge: + @echo "[1/7] Configuring testbed with NextMN-SRv6" + @./scripts/config_edit.py $(BCONFIG) --handover=true --migration-a-posteriori=false + @$(MAKE) set/controlplane/nextmn-lite + @$(MAKE) set/dataplane/nextmn-srv6 + @$(MAKE) set/nb-ue/2 + @$(MAKE) set/nb-edges/3 + @$(MAKE) set/nb-gnb/3 # gnbl3 is in a different area + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/info + @echo "[2/7] Starting containers" + @$(MAKE) up + @echo "[3/7] Adding latencies" + @# central DN latency + @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # uplink + @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # downlink + @# CP latency + @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink + @docker exec srgw0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec srgw1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @docker exec r2-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink + @# Inter-areas latencies + @docker exec inter-areas-debug bash -c "tc qdisc add dev dataplane-0 root netem delay 2ms" + @# srgw0 (edge 1) - srgw1 (edge 2) + @docker exec srgw0-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from srgw0 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:1::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to srgw0 via inter-areas + @# r1 (edge 1) - srgw1 (edge 2) + @docker exec r1-debug bash -c "ip route replace fc00:4::/32 via fd00:0:0:0:3:8000:0:7" # from r1 to srgw1 via inter-areas + @docker exec srgw1-debug bash -c "ip route replace fc00:3::/32 via fd00:0:0:0:3:8000:0:7" # from srgw1 to r1 via inter-areas + @#### + @docker exec uel2-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @sleep 2 + @#### + @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" + @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel2 sr4mec-1 gnbl3 gnbl1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 1 to Area 2"' & + @echo "[5/7] [$$(date --rfc-3339=seconds)] Start ping for 20s + 5s margin" + @# Note: we cannot do less than 0.1 interval, otherwise our UPF is too slow to process + @bash -c 'docker exec uel2-debug bash -c "ping -D -w 20 10.4.0.1 -i 0.1 > /volume/ping-mobility-immediat-edge.txt"' & + @sleep 25 + @echo "[6/7] Stopping containers" + @$(MAKE) down + @echo "[7/7] Plotting data" + @mkdir -p $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ + @cp $(BUILD_DIR)/volumes/uel2/ping-mobility-immediat-edge.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/immediat-edge.txt + @scripts/thesis/mobility.py $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/immediat-edge.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/03_31_evaluation-plot-mobility-changement-immediat-edge.pdf + +.PHONY: thesis/plot/mobility +thesis/plot/mobility: + $(MAKE) thesis/plot/mobility/posteriori/central + $(MAKE) thesis/plot/mobility/posteriori/edge + $(MAKE) thesis/plot/mobility/immediate/central + $(MAKE) thesis/plot/mobility/immediate/edge diff --git a/default-config.yaml b/default-config.yaml index f52dd8c..3521c3c 100644 --- a/default-config.yaml +++ b/default-config.yaml @@ -11,6 +11,7 @@ config: version: "stable" # ( stable | dev ) dev_build_path: ../../ueransim/build # relative to the root of the testbed, not to the testbed build directory handover: false + migration_a_posteriori: false dataplane: # ( nextmn-srv6 | free5gc | nextmn-upf) - "nextmn-srv6" controlplane: "free5gc" # ( free5gc | nextmn-lite ) @@ -117,36 +118,9 @@ subnets: ipv4_address: 10.1.3.140 upfa3-nmn: ipv4_address: 10.1.3.155 - gnbl1: - ipv4_address: 10.1.3.141 - ipv6_address: fd00:0:0:0:2:8000:0:7 - gnbl2: - ipv4_address: 10.1.3.142 - ipv6_address: fd00:0:0:0:2:8000:0:8 - gnbl3: - ipv4_address: 10.1.3.150 - ipv6_address: fd00:0:0:0:2:8000:0:10 - uel1: - ipv4_address: 10.1.3.143 - ipv6_address: fd00:0:0:0:2:8000:0:9 cp-lite: ipv4_address: 10.1.3.144 ipv6_address: fd00:0:0:0:2:8000:0:a - uel2: - ipv4_address: 10.1.3.145 - ipv6_address: fd00:0:0:0:2:8000:0:b - uel3: - ipv4_address: 10.1.3.146 - ipv6_address: fd00:0:0:0:2:8000:0:c - uel4: - ipv4_address: 10.1.3.147 - ipv6_address: fd00:0:0:0:2:8000:0:d - uel5: - ipv4_address: 10.1.3.148 - ipv6_address: fd00:0:0:0:2:8000:0:e - uel6: - ipv4_address: 10.1.3.149 - ipv6_address: fd00:0:0:0:2:8000:0:f dataplane: gnb1: ipv4_address: 10.1.4.129 @@ -190,6 +164,9 @@ subnets: ipv4_address: 10.1.4.139 gnbl3: ipv4_address: 10.1.4.140 + inter-areas: + ipv4_address: 10.1.4.146 + ipv6_address: fd00:0:0:0:3:8000:0:7 edge: r0: ipv4_address: 10.1.5.129 @@ -215,47 +192,89 @@ subnets: ipv4_address: 10.1.5.136 upfa3-nmn: ipv4_address: 10.1.5.140 + rest: + srgw0: + ipv6_address: fd00:0:0:0:5:8000:0:2 + srgw1: + ipv6_address: fd00:0:0:0:5:8000:0:3 + r0: + ipv6_address: fd00:0:0:0:5:8000:0:4 + r1: + ipv6_address: fd00:0:0:0:5:8000:0:5 + r2: + ipv6_address: fd00:0:0:0:5:8000:0:6 + srv6-ctrl: + ipv6_address: fd00:0:0:0:5:8000:0:7 + cp-lite: + ipv6_address: fd00:0:0:0:5:8000:0:8 + uel1: + ipv6_address: fd00:0:0:0:5:8000:0:9 + uel2: + ipv6_address: fd00:0:0:0:5:8000:0:a + uel3: + ipv6_address: fd00:0:0:0:5:8000:0:b + uel4: + ipv6_address: fd00:0:0:0:5:8000:0:c + uel5: + ipv6_address: fd00:0:0:0:5:8000:0:d + uel6: + ipv6_address: fd00:0:0:0:5:8000:0:e + gnbl1: + ipv6_address: fd00:0:0:0:5:8000:0:f + gnbl2: + ipv6_address: fd00:0:0:0:5:8000:0:10 + gnbl3: + ipv6_address: fd00:0:0:0:5:8000:0:11 service: s: ipv4_address: 10.4.0.1 nots: ipv4_address: 10.4.0.2 - slice0: + slice-sr4mec: + subnet: + ipv4_prefix: 10.2.0.0/23 + slice-sr4mec-0: subnet: ipv4_prefix: 10.2.0.0/24 - slice0-static: + slice-sr4mec-0-static: subnet: ipv4_prefix: 10.2.0.128/25 - slice1: + slice-sr4mec-1: subnet: ipv4_prefix: 10.2.1.0/24 - slice1-e1: + slice-sr4mec-1-static: subnet: - ipv4_prefix: 10.2.1.0/26 - slice1-e1-static: - subnet: - ipv4_prefix: 10.2.1.64/26 - slice1-e2: - subnet: - ipv4_prefix: 10.2.1.128/26 - slice1-e2-static: - subnet: - ipv4_prefix: 10.2.1.192/26 - slice2: + ipv4_prefix: 10.2.1.128/25 + slice-f5gc-0: subnet: ipv4_prefix: 10.2.2.0/24 - slice2-e1: + slice-f5gc-0-e1: subnet: ipv4_prefix: 10.2.2.0/26 - slice2-e1-static: + slice-f5gc-0-e1-static: subnet: ipv4_prefix: 10.2.2.64/26 - slice2-e2: + slice-f5gc-0-e2: subnet: ipv4_prefix: 10.2.2.128/26 - slice2-e2-static: + slice-f5gc-0-e2-static: subnet: ipv4_prefix: 10.2.2.192/26 + slice-nmn-upf-0: + subnet: + ipv4_prefix: 10.2.3.0/24 + slice-nmn-upf-0-e1: + subnet: + ipv4_prefix: 10.2.3.0/26 + slice-nmn-upf-0-e1-static: + subnet: + ipv4_prefix: 10.2.3.64/26 + slice-nmn-upf-0-e2: + subnet: + ipv4_prefix: 10.2.3.128/26 + slice-nmn-upf-0-e2-static: + subnet: + ipv4_prefix: 10.2.3.192/26 srgw0: subnet: ipv6_prefix: fc00:1::/32 diff --git a/doc b/doc index de57ca8..2762dd1 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit de57ca8dbd48214c32f6cf1c2b6db60077588c0b +Subproject commit 2762dd1a9f35a52f84b183161909f8398319ef61 diff --git a/scripts/config_edit.py b/scripts/config_edit.py index b93cf1a..2ca09d5 100755 --- a/scripts/config_edit.py +++ b/scripts/config_edit.py @@ -31,6 +31,7 @@ def increase_indent(self, flow=False, indentless=False): parser.add_argument('--full-debug') parser.add_argument('--ran') parser.add_argument('--handover') + parser.add_argument('--migration-a-posteriori') args = parser.parse_args() ran = ('stable', 'dev') controlplane = ('free5gc', 'nextmn-lite') @@ -55,6 +56,8 @@ def increase_indent(self, flow=False, indentless=False): raise ConfigException('Invalid value for full debug: must be a boolean') if args.handover and (args.handover.lower() not in ('true', 'false')): raise ConfigException('Invalid value for handover: must be a boolean') + if args.migration_a_posteriori and (args.migration_a_posteriori.lower() not in ('true', 'false')): + raise ConfigException('Invalid value for migration-a-posteriori: must be a boolean') if args.ran and (args.ran not in ran): raise ConfigException(f'Invalid ran config: use one from {ran}') if args.controlplane and (args.controlplane not in controlplane): @@ -82,6 +85,8 @@ def increase_indent(self, flow=False, indentless=False): c['config']['topology']['full_debug'] = args.full_debug.lower() == 'true' if args.handover is not None: c['config']['topology']['ran']['handover'] = args.handover.lower() == 'true' + if args.migration_a_posteriori is not None: + c['config']['topology']['ran']['migration_a_posteriori'] = args.migration_a_posteriori.lower() == 'true' if args.ran: c['config']['topology']['ran']['version'] = args.ran with open(args.buildconfig, 'w', encoding='utf-8') as f2: diff --git a/scripts/handover.py b/scripts/handover.py index ddcbc6a..8cbf077 100755 --- a/scripts/handover.py +++ b/scripts/handover.py @@ -38,14 +38,16 @@ def same_area(gnb1: str, gnb2: str) -> bool: args = parser.parse_args() # TODO: this should not be hardcoded - if args.dnn == "srv6": - UE_ADDR = "10.2.0.1" - elif args.dnn == "free5gc": - UE_ADDR = "10.2.1.1" - elif args.dnn == "nextmn-upf": - UE_ADDR = "10.2.2.1" + if args.dnn == "sr4mec-0": + UE_ADDR = "10.2.0.1" # uel1 + elif args.dnn == "sr4mec-1": + UE_ADDR = "10.2.1.1" # uel2 + elif args.dnn == "f5gc-0": + UE_ADDR = "10.2.2.1" # uel3 + elif args.dnn == "nmn-upf-0": + UE_ADDR = "10.2.3.1" #uel5 else: - raise ValueError("DNN must be in (srv6, free5gc, nextmn-upf)") + raise ValueError("DNN must be in (sr4mec-0, sr4mec-1, f5gc-0, nmn-upf-0)") # TODO: this info should be guessable by the gNB @@ -53,9 +55,9 @@ def same_area(gnb1: str, gnb2: str) -> bool: with open(args.config, 'r', encoding='utf-8') as f: c = yaml.safe_load(f) - gnb_source_uri = f'http://[{c["subnets"]["control"][args.gnb_source]["ipv6_address"]}]:8080' - gnb_target_uri = f'http://[{c["subnets"]["control"][args.gnb_target]["ipv6_address"]}]:8080' - ue_uri = f'http://[{c["subnets"]["control"][args.ue]["ipv6_address"]}]:8080' + gnb_source_uri = f'http://[{c["subnets"]["rest"][args.gnb_source]["ipv6_address"]}]:8080' + gnb_target_uri = f'http://[{c["subnets"]["rest"][args.gnb_target]["ipv6_address"]}]:8080' + ue_uri = f'http://[{c["subnets"]["rest"][args.ue]["ipv6_address"]}]:8080' handover_req = { "ue-ctrl": ue_uri, "gnb-target": gnb_target_uri, diff --git a/scripts/jinja/customize.py b/scripts/jinja/customize.py index 932e383..013ff17 100644 --- a/scripts/jinja/customize.py +++ b/scripts/jinja/customize.py @@ -16,6 +16,10 @@ import jinja2 import yaml +with open('templates/images-list.yaml', 'r', encoding='utf-8') as file_images_list: + images_list = yaml.safe_load(file_images_list) + + class TemplateError(Exception): '''Template error''' @@ -209,16 +213,86 @@ def build_and_template_dir(): 'Error while parsing j2cli options to find the outfile and template file.') ) from exc -@j2_function +@j2_function(output='json') @functools.cache # we don't want to copy more than once -def volume_ro(src: str, dst: str) -> str: +def volume_bind_ro(src: str, dst: str) -> str: '''Create a read only volume''' build, template = build_and_template_dir() build, template = os.path.join(build, src), os.path.join(template, src) print(f'Copying {template} into {build}.') os.makedirs(os.path.dirname(build), exist_ok=True) shutil.copy2(src=template, dst=build) - return f'- ./{src}:{dst}:ro' + ret = { + 'type': 'bind', + 'source': src, + 'target': dst, + 'read_only': True, + } + return json.dumps(ret) + +@j2_function(output='json') +def volume_bind_ran_binary_ro(name: str, _context: _Context) -> str: + '''Mount ueransim build directory''' + ret = { + 'type': 'bind', + 'source': os.path.join('..', + _context.dict['config']['topology']['ran']['dev_build_path'], + name), + 'target': os.path.join('/usr/bin/', name), + 'read_only': True, + } + return json.dumps(ret) + + +@j2_function(output='json') +def mount_volume_named_rw(volume: str, dst: str) -> str: + '''Mount a rw named volume''' + ret = { + 'type': 'volume', + 'source': volume, + 'target': dst, + 'read_only': False, + } + return json.dumps(ret) + +@j2_function(output='json') +def mount_volume_named_postgres_rw(volume: str) -> str: + '''Mount a ro named volume for postgres''' + ret = { + 'type': 'volume', + 'source': volume, + 'target': '/var/run/postgresql/', + 'read_only': False, + } + return json.dumps(ret) + +@j2_function(output='str') +def environment_postgres_socket_path() -> str: + '''Return environment variable for postgres unix socket path''' + return 'POSTGRES_UNIX_SOCKET_PATH: /var/run/postgresql' + + +@j2_function(output='json') +def mount_volume_named_ro(volume: str, dst: str) -> str: + '''Mount a ro named volume''' + ret = { + 'type': 'volume', + 'source': volume, + 'target': dst, + 'read_only': True, + } + return json.dumps(ret) + + +@j2_function(output='json') +def mount_xdg_config(name: str, filename: str) -> str: + '''Mount a config in /etc/xdg''' + ret = { + 'source': name, + 'target': os.path.join('/etc/xdg/', filename), + } + return json.dumps(ret) + @j2_function def secret(name: str) -> str: @@ -413,11 +487,12 @@ def ipv4_subnet(subnet: str, _context: _Context) -> str: '''Get IPv4 subnet''' try: addr = _context.dict['subnets'][subnet]['subnet']['ipv4_prefix'] - except KeyError as exc: + except KeyError: # XXX: remove this backward compatibility fallback after some time try: addr = _context.dict['subnets'][subnet]['subnet']['ipv4_address'] - print('warning: subnets[].subnet.ipv4_address is deprecated and must be replaced by subnets[].subnet.ipv4_prefix') + print('warning: subnets[].subnet.ipv4_address is deprecated', + 'and must be replaced by subnets[].subnet.ipv4_prefix') except KeyError as exc: raise(TemplateError(f'Unknown ipv4 subnet: {subnet}')) from exc return addr @@ -427,11 +502,12 @@ def ipv6_subnet(subnet: str, _context: _Context) -> str: '''Get IPv6 subnet''' try: addr = _context.dict['subnets'][subnet]['subnet']['ipv6_prefix'] - except KeyError as exc: + except KeyError: # XXX: remove this backward compatibility fallback after some time try: addr = _context.dict['subnets'][subnet]['subnet']['ipv6_address'] - print('warning: subnets[].subnet.ipv6_address is deprecated and must be replaced by subnets[].subnet.ipv6_prefix') + print('warning: subnets[].subnet.ipv6_address is deprecated', + 'and must be replaced by subnets[].subnet.ipv6_prefix') except KeyError as exc: raise(TemplateError(f'Unknown ipv6 subnet: {subnet}')) from exc return addr @@ -446,14 +522,14 @@ def ipv6_prefix(name: str, subnet: str, _context: _Context) -> str: return addr @j2_function(output='json') -def container(name: str, image: str, _context: _Context, enable_ipv6: typing.Optional[bool] = False, # pylint: disable=too-many-arguments, disable=too-many-branches, disable=too-many-locals +def container(name: str, service: str, # pylint: disable=too-many-arguments, disable=too-many-branches, disable=too-many-locals + _context: _Context, enable_ipv6: typing.Optional[bool] = False, srv6: typing.Optional[bool] = False, iface_tun: typing.Optional[bool] = False, command: typing.Optional[str|bool] = None, init: typing.Optional[bool] = False, cap_net_admin: typing.Optional[bool] = False, restart: typing.Optional[str] = None, ipv4_forward: typing.Optional[bool] = False, debug: typing.Optional[str] = 'never', debug_volume: typing.Optional[bool] = False, - image_build: typing.Optional[str] = None, ) -> str: '''Add a container''' containers = {} @@ -462,11 +538,13 @@ def container(name: str, image: str, _context: _Context, enable_ipv6: typing.Opt containers[f'{name}-debug'] = { "container_name": f'{name}-debug', "network_mode": f'service:{name}', - "image": 'louisroyer/network-debug', - "build": 'https://github.com/louisroyer-docker/network-debug.git#master:network-debug', "cap_add": ['NET_ADMIN',], "profiles": ['debug',], } + containers[f'{name}-debug']['image'] = images_list['services']['debug']['image'] + if 'build' in images_list['services']['debug']: + containers[f'{name}-debug']['build'] = images_list['services']['debug']['build'] + if debug_volume: containers[f'{name}-debug']['volumes'] = [f'./volumes/{name}:/volume'] build, _ = build_and_template_dir() @@ -489,10 +567,10 @@ def container(name: str, image: str, _context: _Context, enable_ipv6: typing.Opt containers[name] = { "container_name": name, "hostname": name, - "image": image, + "image": images_list['services'][service]['image'], } - if image_build: - containers[name]['build'] = image_build + if 'build' in images_list['services'][service]: + containers[name]["build"] = images_list['services'][service]['build'] if command: containers[name]['command'] = command elif command is None: @@ -522,6 +600,22 @@ def container(name: str, image: str, _context: _Context, enable_ipv6: typing.Opt containers[name]['init'] = True return json.dumps(containers) +@j2_function(output='json') +def depends_on_healthy(*args: str) -> str: + '''Depends on this service (healthy)''' + ret = {} + for i in args: + ret[i] = {'condition': 'service_healthy'} + return json.dumps(ret) + +@j2_function(output='json') +def depends_on_started(*args: str) -> str: + '''Depends on this service (started)''' + ret = {} + for i in args: + ret[i] = {'condition': 'service_started'} + return json.dumps(ret) + @j2_function(output='json') def container_setup(name: str) -> str: '''Add a setup container''' @@ -529,9 +623,16 @@ def container_setup(name: str) -> str: containers[f'{name}-setup'] = { "container_name": f'{name}-setup', "network_mode": f'service:{name}', - "image": 'louisroyer/docker-setup', - "build": 'https://github.com/louisroyer-docker/docker-setup#master:.', + "image": images_list['services']['docker-setup']['image'], + "build": images_list['services']['docker-setup']['build'], "cap_add": ['NET_ADMIN',], "restart": "no", } return json.dumps(containers) + +@j2_function(output="txt") +def migration_a_posteriori(_context: _Context) -> str: + '''Is migration a posteriori set''' + if _context.dict['config']['topology']['ran']['migration_a_posteriori']: + return "true" + return "false" diff --git a/scripts/show_ctrl.py b/scripts/show_ctrl.py index 4655245..1866b02 100755 --- a/scripts/show_ctrl.py +++ b/scripts/show_ctrl.py @@ -19,12 +19,12 @@ with open(args.config, 'r', encoding='utf-8') as f: c = yaml.safe_load(f) # TODO: open all the below without hardcoding list of controllers/routers - controller = f'http://[{c["subnets"]["control"]["srv6-ctrl"]["ipv6_address"]}]:8080' - r0 = f'http://[{c["subnets"]["control"]["r0"]["ipv6_address"]}]:8080' - r1 = f'http://[{c["subnets"]["control"]["r1"]["ipv6_address"]}]:8080' - r2 = f'http://[{c["subnets"]["control"]["r2"]["ipv6_address"]}]:8080' - srgw0 = f'http://[{c["subnets"]["control"]["srgw0"]["ipv6_address"]}]:8080' - srgw1 = f'http://[{c["subnets"]["control"]["srgw1"]["ipv6_address"]}]:8080' + controller = f'http://[{c["subnets"]["rest"]["srv6-ctrl"]["ipv6_address"]}]:8080' + r0 = f'http://[{c["subnets"]["rest"]["r0"]["ipv6_address"]}]:8080' + r1 = f'http://[{c["subnets"]["rest"]["r1"]["ipv6_address"]}]:8080' + r2 = f'http://[{c["subnets"]["rest"]["r2"]["ipv6_address"]}]:8080' + srgw0 = f'http://[{c["subnets"]["rest"]["srgw0"]["ipv6_address"]}]:8080' + srgw1 = f'http://[{c["subnets"]["rest"]["srgw1"]["ipv6_address"]}]:8080' webbrowser.get('firefox').open_new_tab(f'{controller}/routers#controller') webbrowser.get('firefox').open_new_tab(f'{r0}/rules#r0') webbrowser.get('firefox').open_new_tab(f'{r1}/rules#r1') diff --git a/scripts/switch.py b/scripts/switch.py index d8c8ffd..338b77d 100755 --- a/scripts/switch.py +++ b/scripts/switch.py @@ -19,7 +19,7 @@ args = parser.parse_args() with open(args.config, 'r', encoding='utf-8') as f: c = yaml.safe_load(f) - srgw = f'http://[{c["subnets"]["control"]["srgw0"]["ipv6_address"]}]:8080' + srgw = f'http://[{c["subnets"]["rest"]["srgw0"]["ipv6_address"]}]:8080' r = requests.get(f'{srgw}/rules', timeout=1) rules = [None, None] for ruleid, rule in r.json().items(): diff --git a/scripts/thesis/binding.py b/scripts/thesis/binding.py new file mode 100755 index 0000000..250ac04 --- /dev/null +++ b/scripts/thesis/binding.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +'''Create plot for thesis/binding scenario''' +# Copyright Louis Royer and the NextMN contributors. All rights reserved. +# Use of this source code is governed by a MIT-style license that can be +# found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import argparse +import pathlib +import matplotlib.pyplot as plt +import matplotlib as mpl + +def plot(arguments: argparse.Namespace): + '''Write plot''' + res = [] + with open(arguments.slice1, 'r', encoding='utf8') as ping: + res.append({'tsp': [], 'pqt': []}) + for i, line in enumerate(ping): + if 'time=' in line: + res[0]['tsp'].append(float (line.split('[')[1].split('] ')[0])) + res[0]['pqt'].append(float(line.split('time=' )[1].split(' ms' )[0])) + with open(arguments.slice2, 'r', encoding='utf8') as ping: + res.append({'tsp': [], 'pqt': []}) + for i, line in enumerate(ping): + if 'time=' in line: + res[1]['tsp'].append(float (line.split('[')[1].split('] ')[0])) + res[1]['pqt'].append(float(line.split('time=' )[1].split(' ms' )[0])) + first = min(res[0]['tsp'][0], res[1]['tsp'][0]) + for i, timestamp in enumerate(res[0]['tsp']): + res[0]['tsp'][i] = timestamp - first + for i, timestamp in enumerate(res[1]['tsp']): + res[1]['tsp'][i] = timestamp - first + mpl.rcParams["font.size"] = 15 + _, axplt = plt.subplots(figsize=(7,4.2)) + axplt.set_xlim(-1, 61) + axplt.set_xlabel('$t$ (s)') + #axplt.xaxis.set_label_coords(1.13, -0.025) + axplt.set_ylabel('RTT (ms)') + axplt.plot(res[0]['tsp'], res[0]['pqt'], color='tab:blue', + label='$UE_1$') + axplt.plot(res[1]['tsp'], res[1]['pqt'], color='tab:red', + label='$UE_2$') + axplt.autoscale_view() + axplt.legend() + plt.tight_layout() + plt.savefig(arguments.output, bbox_inches='tight') + print(f'plot saved in {arguments.output}') + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + prog='binding', + description='Convert ping result into plot' + ) + parser.set_defaults(func=plot) + parser.add_argument('slice1', type=pathlib.Path, + help='ping result file') + parser.add_argument('slice2', type=pathlib.Path, + help='ping result file') + parser.add_argument('output', type=pathlib.Path, + help='output file') + + args = parser.parse_args() + args.func(args) diff --git a/scripts/thesis/migration.py b/scripts/thesis/migration.py new file mode 100755 index 0000000..02f1964 --- /dev/null +++ b/scripts/thesis/migration.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +'''Create plot for migration scenario''' +# Copyright Louis Royer and the NextMN contributors. All rights reserved. +# Use of this source code is governed by a MIT-style license that can be +# found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import argparse +import pathlib +import matplotlib.pyplot as plt +import matplotlib as mpl + +def plot(arguments: argparse.Namespace): + '''Write plot''' + res = [] + with open(arguments.inputsr4mec, 'r', encoding='utf8') as ping: + res.append({'tsp': [], 'pqt': []}) + for i, line in enumerate(ping): + if 'time=' in line: + res[0]['tsp'].append(float (line.split('[')[1].split('] ')[0])) + res[0]['pqt'].append(float(line.split('time=' )[1].split(' ms' )[0])) + with open(arguments.inputulcl, 'r', encoding='utf8') as ping: + res.append({'tsp': [], 'pqt': []}) + for i, line in enumerate(ping): + if 'time=' in line: + res[1]['tsp'].append(float (line.split('[')[1].split('] ')[0])) + res[1]['pqt'].append(float(line.split('time=' )[1].split(' ms' )[0])) + first = min(res[0]['tsp'][0], res[1]['tsp'][0]) + for i, timestamp in enumerate(res[0]['tsp']): + res[0]['tsp'][i] = timestamp - first + for i, timestamp in enumerate(res[1]['tsp']): + res[1]['tsp'][i] = timestamp - first + mpl.rcParams["font.size"] = 15 + _, axplt = plt.subplots(figsize=(7,4.2)) + axplt.set_xlim(-1, 61) + axplt.set_xlabel('$t$ (s)') + axplt.set_ylabel('RTT (ms)') + axplt.plot(res[1]['tsp'], res[1]['pqt'], color='tab:blue', label='UL-CL') + axplt.plot(res[0]['tsp'], res[0]['pqt'], color='tab:red', label='SR4MEC') + axplt.autoscale_view() + axplt.legend() + plt.tight_layout() + plt.savefig(arguments.output, bbox_inches='tight') + print(f'plot saved in {arguments.output}') + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + prog='migration', + description='Convert ping result into plot' + ) + parser.set_defaults(func=plot) + parser.add_argument('inputsr4mec', type=pathlib.Path, + help='ping result file') + parser.add_argument('inputulcl', type=pathlib.Path, + help='ping result file') + parser.add_argument('output', type=pathlib.Path, + help='output file') + + args = parser.parse_args() + args.func(args) diff --git a/scripts/thesis/mobility.py b/scripts/thesis/mobility.py new file mode 100755 index 0000000..ec46d79 --- /dev/null +++ b/scripts/thesis/mobility.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +'''Create plot for mobility scenario''' +# Copyright Louis Royer and the NextMN contributors. All rights reserved. +# Use of this source code is governed by a MIT-style license that can be +# found in the LICENSE file. +# SPDX-License-Identifier: MIT + +import argparse +import pathlib +import matplotlib.pyplot as plt +import matplotlib as mpl +from matplotlib.ticker import FuncFormatter + +def fmt(value, unused): + '''formatter''' + _ = unused + if str(value).endswith('.0'): + value = str(value)[:-2] + return value + + +def plot(arguments: argparse.Namespace): + '''Write plot''' + res = [] + with open(arguments.input, 'r', encoding='utf8') as ping: + res.append({'tsp': [], 'pqt': []}) + for i, line in enumerate(ping): + if 'time=' in line: + res[0]['tsp'].append(float(line.split('[')[1].split('] ')[0])) + res[0]['pqt'].append(float(line.split('time=')[1].split(' ms')[0])) + first = res[0]['tsp'][0] + for i, timestamp in enumerate(res[0]['tsp']): + res[0]['tsp'][i] = timestamp - first + mpl.rcParams["font.size"] = 15 + _, axplt = plt.subplots(figsize=(7,4.2)) + axplt.set_xlim(-1, 21) + axplt.set_ylim(29, 56) + axplt.set_xlabel('$t$ (s)') + axplt.set_ylabel('RTT (ms)') + axplt.plot(res[0]['tsp'], res[0]['pqt'], color='tab:red') + plt.gca().xaxis.set_major_formatter(FuncFormatter(fmt)) + axplt.autoscale_view() + plt.tight_layout() + plt.savefig(arguments.output, bbox_inches='tight') + print(f'plot saved in {arguments.output}') + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + prog='mobility', + description='Convert ping result into plot' + ) + parser.set_defaults(func=plot) + parser.add_argument('input', type=pathlib.Path, + help='ping result file') + parser.add_argument('output', type=pathlib.Path, + help='output file') + + args = parser.parse_args() + args.func(args) diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index 22cc7e1..b55ced8 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -6,14 +6,13 @@ name: "nextmn-testbed" services: #~ if ("nextmn-srv6" in config["topology"]["dataplane"]) and (config["topology"]["controlplane"] == "free5gc") - {{ container_s(name='ue1', image='docker.io/louisroyer/ueransim-ue', image_build='https://github.com/louisroyer-docker/ueransim.git#master:ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} + {{ container_s(name='ue1', service='ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-ue:/usr/bin/nr-ue:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-ue') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: MSISDN: "0000000001" @@ -30,7 +29,7 @@ services: sd: 000001 SESSIONS: |- - type: "IPv4" - apn: "srv6" + apn: "sr4mec-0" slice: sst: 1 sd: 000001 @@ -38,45 +37,47 @@ services: ran: # automatic allocation by docker compose #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='ue2', image='docker.io/louisroyer/ueransim-ue', image_build='https://github.com/louisroyer-docker/ueransim.git#master:ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} + {{ container_s(name='ue2', service='ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-ue:/usr/bin/nr-ue:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-ue') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: MSISDN: "0000000002" GNBS: |- + #~ if config["topology"]["nb_gnb"] > 2 - "{{ ipv6('gnb2', 'ran') }}" + #~ else + - "{{ ipv6('gnb1', 'ran') }}" + #~ endif CONFIGURED_NSSAI: |- - sst: 1 - sd: 000001 + sd: 000002 DEFAULT_NSSAI: |- - sst: 1 - sd: 000001 + sd: 000002 SESSIONS: |- - type: "IPv4" - apn: "srv6" + apn: "sr4mec-1" slice: sst: 1 - sd: 000001 + sd: 000002 networks: ran: # automatic allocation by docker compose #~ endif #~ endif #~ if ("free5gc" in config["topology"]["dataplane"]) and (config["topology"]["controlplane"] == "free5gc") - {{ container_s(name='ue3', image='docker.io/louisroyer/ueransim-ue', image_build='https://github.com/louisroyer-docker/ueransim.git#master:ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} + {{ container_s(name='ue3', service='ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-ue:/usr/bin/nr-ue:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-ue') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: MSISDN: "0000000003" @@ -87,28 +88,27 @@ services: #~ endif CONFIGURED_NSSAI: |- - sst: 1 - sd: 000002 + sd: 000003 DEFAULT_NSSAI: |- - sst: 1 - sd: 000002 + sd: 000003 SESSIONS: |- - type: "IPv4" - apn: "free5gc" + apn: "f5gc-0" slice: sst: 1 - sd: 000002 + sd: 000003 networks: ran: # automatic allocation by docker compose #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='ue4', image='docker.io/louisroyer/ueransim-ue', image_build='https://github.com/louisroyer-docker/ueransim.git#master:ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} + {{ container_s(name='ue4', service='ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-ue:/usr/bin/nr-ue:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-ue') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: MSISDN: "0000000004" @@ -116,30 +116,29 @@ services: - "{{ ipv6('gnb2', 'ran') }}" CONFIGURED_NSSAI: |- - sst: 1 - sd: 000002 + sd: 000003 DEFAULT_NSSAI: |- - sst: 1 - sd: 000002 + sd: 000003 SESSIONS: |- - type: "IPv4" - apn: "free5gc" + apn: "f5gc-0" slice: sst: 1 - sd: 000002 + sd: 000003 networks: ran: # automatic allocation by docker compose #~ endif #~ endif #~ if ("nextmn-upf" in config["topology"]["dataplane"]) and (config["topology"]["controlplane"] == "free5gc") - {{ container_s(name='ue5', image='docker.io/louisroyer/ueransim-ue', image_build='https://github.com/louisroyer-docker/ueransim.git#master:ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} + {{ container_s(name='ue5', service='ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-ue:/usr/bin/nr-ue:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-ue') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: MSISDN: "0000000005" @@ -150,28 +149,27 @@ services: #~ endif CONFIGURED_NSSAI: |- - sst: 1 - sd: 000003 + sd: 000004 DEFAULT_NSSAI: |- - sst: 1 - sd: 000003 + sd: 000004 SESSIONS: |- - type: "IPv4" - apn: "nextmn-upf" + apn: "nmn-upf-0" slice: sst: 1 - sd: 000003 + sd: 000004 networks: ran: # automatic allocation by docker compose #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='ue6', image='docker.io/louisroyer/ueransim-ue', image_build='https://github.com/louisroyer-docker/ueransim.git#master:ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} + {{ container_s(name='ue6', service='ue', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True, init=True) }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-ue:/usr/bin/nr-ue:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-ue') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: MSISDN: "0000000006" @@ -179,30 +177,29 @@ services: - "{{ ipv6('gnb2', 'ran') }}" CONFIGURED_NSSAI: |- - sst: 1 - sd: 000003 + sd: 000004 DEFAULT_NSSAI: |- - sst: 1 - sd: 000003 + sd: 000004 SESSIONS: |- - type: "IPv4" - apn: "nextmn-upf" + apn: "nmn-upf-0" slice: sst: 1 - sd: 000003 + sd: 000004 networks: ran: # automatic allocation by docker compose #~ endif #~ endif #~ if config["topology"]["controlplane"] == "free5gc" - {{ container_s(name='gnb1', image='docker.io/louisroyer/ueransim-gnb', image_build='https://github.com/louisroyer-docker/ueransim.git#master:gnb', enable_ipv6=True, restart='always', iface_tun=True, cap_net_admin=True, debug='allow') }} + {{ container_s(name='gnb1', service='gnb', enable_ipv6=True, restart='always', iface_tun=True, cap_net_admin=True, debug='allow') }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-gnb:/usr/bin/nr-gnb:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-gnb') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: NCI: "0x000000010" @@ -213,12 +210,14 @@ services: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - sst: 1 sd: 000001 - #~ elif "free5gc" in config["topology"]["dataplane"] - sst: 1 sd: 000002 - #~ elif "nextmn-upf" in config["topology"]["dataplane"] + #~ elif "free5gc" in config["topology"]["dataplane"] - sst: 1 sd: 000003 + #~ elif "nextmn-upf" in config["topology"]["dataplane"] + - sst: 1 + sd: 000004 #~ endif MCC: "001" MNC: "01" @@ -241,14 +240,13 @@ services: ipv4_address: "{{ ipv4('gnb1', 'dataplane') }}" #~ if (config["topology"]["nb_ue"] > 1) or (config["topology"]["ran"]["handover"]) - {{ container_s(name='gnb2', image='docker.io/louisroyer/ueransim-gnb', image_build='https://github.com/louisroyer-docker/ueransim.git#master:gnb', enable_ipv6=True, restart='always', iface_tun=True, cap_net_admin=True, debug='allow') }} + {{ container_s(name='gnb2', service='gnb', enable_ipv6=True, restart='always', iface_tun=True, cap_net_admin=True, debug='allow') }} depends_on: - amf: - condition: service_started + {{ depends_on_started_s('amf') | indent(2) }} #~ if config["topology"]["ran"]["version"] == "dev" volumes: - - ../{{ config.topology.ran.dev_build_path }}/nr-gnb:/usr/bin/nr-gnb:ro - - ../{{ config.topology.ran.dev_build_path }}/nr-cli:/usr/bin/nr-cli:ro + - {{ volume_bind_ran_binary_ro_s('nr-gnb') | indent(3) }} + - {{ volume_bind_ran_binary_ro_s('nr-cli') | indent(3) }} #~ endif environment: NCI: "0x000000020" @@ -259,12 +257,14 @@ services: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - sst: 1 sd: 000001 - #~ elif "free5gc" in config["topology"]["dataplane"] - sst: 1 sd: 000002 - #~ elif "nextmn-upf" in config["topology"]["dataplane"] + #~ elif "free5gc" in config["topology"]["dataplane"] - sst: 1 sd: 000003 + #~ elif "nextmn-upf" in config["topology"]["dataplane"] + - sst: 1 + sd: 000004 #~ endif MCC: "001" MNC: "01" @@ -289,12 +289,9 @@ services: #~ endif #~ if config["topology"]["controlplane"] == "free5gc" - {{ container_s(name='amf', image='docker.io/louisroyer/dev-free5gc-amf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:amf', restart='always') }} + {{ container_s(name='amf', service='amf', restart='always', debug='allow') }} depends_on: - smf: - condition: service_started - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('smf', 'nrf') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -311,26 +308,29 @@ services: AMF_KEY: "{{ openssl_secret_key('amf', 'sbi') }}" SUPPORT_DNN_LIST: |- #~ if "nextmn-srv6" in config["topology"]["dataplane"] - - srv6 + - sr4mec-0 + - sr4mec1 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - - free5gc + - f5gc #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - - nextmn-upf + - nmn-upf #~ endif SNSSAI_LIST: |- #~ if "nextmn-srv6" in config["topology"]["dataplane"] - sst: 1 sd: 000001 + - sst: 1 + sd: 000002 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - sst: 1 - sd: 000002 + sd: 000003 #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - sst: 1 - sd: 000003 + sd: 000004 #~ endif TAC: "000001" secrets: @@ -342,14 +342,13 @@ services: sbi: ipv4_address: "{{ ipv4('amf', 'sbi') }}" - {{ container_s(name='mongodb', image='docker.io/library/mongo', restart='always', command='mongod --port 27017 --bind_ip_all') }} + {{ container_s(name='mongodb', service='mongo', restart='always', command='mongod --port 27017 --bind_ip_all') }} networks: db: - {{ container_s(name='nrf', image='docker.io/louisroyer/dev-free5gc-nrf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:nrf', restart='always') }} + {{ container_s(name='nrf', service='nrf', restart='always') }} depends_on: - mongodb: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('mongodb') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -373,10 +372,9 @@ services: sbi: ipv4_address: "{{ ipv4('nrf', 'sbi') }}" - {{ container_s(name='ausf', image='docker.io/louisroyer/dev-free5gc-ausf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:ausf', restart='always') }} + {{ container_s(name='ausf', service='ausf', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('nrf') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -394,10 +392,9 @@ services: sbi: ipv4_address: "{{ ipv4('ausf', 'sbi') }}" - {{ container_s(name='udm', image='docker.io/louisroyer/dev-free5gc-udm', image_build='https://github.com/louisroyer-docker/free5gc.git#master:udm', restart='always') }} + {{ container_s(name='udm', service='udm', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('nrf') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -416,10 +413,9 @@ services: sbi: ipv4_address: "{{ ipv4('udm', 'sbi') }}" - {{ container_s(name='udr', image='docker.io/louisroyer/dev-free5gc-udr', image_build='https://github.com/louisroyer-docker/free5gc.git#master:udr', restart='always') }} + {{ container_s(name='udr', service='udr', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('nrf') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -440,10 +436,9 @@ services: sbi: ipv4_address: "{{ ipv4('udr', 'sbi') }}" - {{ container_s(name='pcf', image='docker.io/louisroyer/dev-free5gc-pcf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:pcf', restart='always') }} + {{ container_s(name='pcf', service='pcf', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('nrf') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -464,12 +459,9 @@ services: sbi: ipv4_address: "{{ ipv4('pcf', 'sbi') }}" - {{ container_s(name='chf', image='docker.io/louisroyer/dev-free5gc-chf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:chf', restart='always') }} + {{ container_s(name='chf', service='chf', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started - webconsole: - condition: service_started + {{ depends_on_started_s('nrf', 'webconsole') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -492,10 +484,9 @@ services: sbi: ipv4_address: "{{ ipv4('chf', 'sbi') }}" - {{ container_s(name='webconsole', image='docker.io/louisroyer/dev-free5gc-webconsole', image_build='https://github.com/louisroyer-docker/free5gc.git#master:webconsole', restart='always') }} + {{ container_s(name='webconsole', service='webconsole', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('nrf') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -514,17 +505,11 @@ services: sbi: ipv4_address: "{{ ipv4('webconsole', 'sbi') }}" - {{ container_s(name='smf', image='docker.io/louisroyer/dev-free5gc-smf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:smf', restart='always') }} + {{ container_s(name='smf', service='smf', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('nrf') | indent(2) }} #~ if "nextmn-srv6" in config["topology"]["dataplane"] - r0: - condition: service_healthy - r1: - condition: service_healthy - srgw0: - condition: service_healthy + {{ depends_on_healthy_s('r0', 'r1', 'srgw0') | indent(2) }} #~ endif environment: LOG_LEVEL: "{{ log_level() }}" @@ -546,7 +531,15 @@ services: sst: 1 sd: 000001 dnnInfos: - - dnn: srv6 + - dnn: sr4mec-0 + dns: + ipv4: 9.9.9.9 # TODO: replace with local dns + ipv6: 2620:fe::fe + - sNssai: + sst: 1 + sd: 000002 + dnnInfos: + - dnn: sr4mec-1 dns: ipv4: 9.9.9.9 # TODO: replace with local dns ipv6: 2620:fe::fe @@ -554,9 +547,9 @@ services: #~ if "free5gc" in config["topology"]["dataplane"] - sNssai: sst: 1 - sd: 000002 + sd: 000003 dnnInfos: - - dnn: free5gc + - dnn: f5gc-0 dns: ipv4: 9.9.9.9 # TODO: replace with local dns ipv6: 2620:fe::fe @@ -564,9 +557,9 @@ services: #~ if "nextmn-upf" in config["topology"]["dataplane"] - sNssai: sst: 1 - sd: 000003 + sd: 000004 dnnInfos: - - dnn: nextmn-upf + - dnn: nmn-upf-0 dns: ipv4: 9.9.9.9 # TODO: replace with local dns ipv6: 2620:fe::fe @@ -584,17 +577,27 @@ services: sst: 1 sd: 000001 dnnUpfInfoList: - - dnn: srv6 + - dnn: sr4mec-0 + pools: + - cidr: {{ ipv4_subnet('slice-sr4mec-0') }} + staticPools: + - cidr: {{ ipv4_subnet('slice-sr4mec-0-static') }} + - sNssai: + sst: 1 + sd: 000002 + dnnUpfInfoList: + - dnn: sr4mec-1 pools: - - cidr: {{ ipv4_subnet('slice0') }} + - cidr: {{ ipv4_subnet('slice-sr4mec-1') }} staticPools: - - cidr: {{ ipv4_subnet('slice0-static') }} + - cidr: {{ ipv4_subnet('slice-sr4mec-1-static') }} interfaces: - interfaceType: N3 endpoints: - {{ ipv4('srgw0', 'srgw0') }} networkInstances: - - srv6 + - sr4mec-0 + - sr4mec-1 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] UPFI1_F5GC: @@ -604,20 +607,20 @@ services: sNssaiUpfInfos: - sNssai: sst: 1 - sd: 000002 + sd: 000003 dnnUpfInfoList: - - dnn: free5gc + - dnn: f5gc-0 interfaces: - interfaceType: N3 endpoints: - {{ ipv4('upfi1-f5gc', 'dataplane') }} networkInstances: - - free5gc + - f5gc-0 - interfaceType: N9 endpoints: - {{ ipv4('upfi1-f5gc', 'dataplane') }} networkInstances: - - free5gc + - f5gc-0 UPFA1_F5GC: type: UPF nodeID: "{{ ipv4('upfa1-f5gc', 'control') }}" @@ -625,19 +628,19 @@ services: sNssaiUpfInfos: - sNssai: sst: 1 - sd: 000002 + sd: 000003 dnnUpfInfoList: - - dnn: free5gc + - dnn: f5gc-0 pools: - - cidr: {{ ipv4_subnet('slice1-e1') }} + - cidr: {{ ipv4_subnet('slice-f5gc-0-e1') }} staticPools: - - cidr: {{ ipv4_subnet('slice1-e1-static') }} + - cidr: {{ ipv4_subnet('slice-f5gc-0-e1-static') }} interfaces: - interfaceType: N9 endpoints: - {{ ipv4('upfa1-f5gc', 'dataplane') }} networkInstances: - - free5gc + - f5gc-0 #~ if config["topology"]["nb_edges"] > 1 UPFA2_F5GC: type: UPF @@ -646,19 +649,19 @@ services: sNssaiUpfInfos: - sNssai: sst: 1 - sd: 000002 + sd: 000003 dnnUpfInfoList: - - dnn: free5gc + - dnn: f5gc-0 pools: - - cidr: {{ ipv4_subnet('slice1-e2') }} + - cidr: {{ ipv4_subnet('slice-f5gc-0-e2') }} staticPools: - - cidr: {{ ipv4_subnet('slice1-e2-static') }} + - cidr: {{ ipv4_subnet('slice-f5gc-0-e2-static') }} interfaces: - interfaceType: N9 endpoints: - {{ ipv4('upfa2-f5gc', 'dataplane') }} networkInstances: - - free5gc + - f5gc-0 #~ endif #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] @@ -669,20 +672,20 @@ services: sNssaiUpfInfos: - sNssai: sst: 1 - sd: 000003 + sd: 000004 dnnUpfInfoList: - - dnn: nextmn-upf + - dnn: nmn-upf-0 interfaces: - interfaceType: N3 endpoints: - {{ ipv4('upfi1-nmn', 'dataplane') }} networkInstances: - - nextmn-upf + - nmn-upf-0 - interfaceType: N9 endpoints: - {{ ipv4('upfi1-nmn', 'dataplane') }} networkInstances: - - nextmn-upf + - nmn-upf-0 UPFA1_NEXTMNUPF: type: UPF nodeID: "{{ ipv4('upfa1-nmn', 'control') }}" @@ -690,19 +693,19 @@ services: sNssaiUpfInfos: - sNssai: sst: 1 - sd: 000003 + sd: 000004 dnnUpfInfoList: - - dnn: nextmn-upf + - dnn: nmn-upf-0 pools: - - cidr: {{ ipv4_subnet('slice2-e1') }} + - cidr: {{ ipv4_subnet('slice-nmn-upf-0-e1') }} staticPools: - - cidr: {{ ipv4_subnet('slice2-e1-static') }} + - cidr: {{ ipv4_subnet('slice-nmn-upf-0-e1-static') }} interfaces: - interfaceType: N9 endpoints: - {{ ipv4('upfa1-nmn', 'dataplane') }} networkInstances: - - nextmn-upf + - nmn-upf-0 #~ if config["topology"]["nb_edges"] > 1 UPFA2_NEXTMNUPF: type: UPF @@ -711,19 +714,19 @@ services: sNssaiUpfInfos: - sNssai: sst: 1 - sd: 000003 + sd: 000004 dnnUpfInfoList: - - dnn: nextmn-upf + - dnn: nmn-upf-0 pools: - - cidr: {{ ipv4_subnet('slice2-e2') }} + - cidr: {{ ipv4_subnet('slice-nmn-upf-0-e2') }} staticPools: - - cidr: {{ ipv4_subnet('slice2-e2-static') }} + - cidr: {{ ipv4_subnet('slice-nmn-upf-0-e2-static') }} interfaces: - interfaceType: N9 endpoints: - {{ ipv4('upfa2-nmn', 'dataplane') }} networkInstances: - - nextmn-upf + - nmn-upf-0 #~ endif #~ endif ULCL: "true" @@ -822,10 +825,9 @@ services: sbi: ipv4_address: "{{ ipv4('smf', 'sbi') }}" - {{ container_s(name='populate', image='docker.io/louisroyer/dev-free5gc-populate', image_build='https://github.com/louisroyer-docker/free5gc-populate.git#master:dev-free5gc-populate', restart='no') }} + {{ container_s(name='populate', service='dev-free5gc-populate', restart='no') }} depends_on: - mongodb: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('mongodb') | indent(2) }} environment: MONGO_HOST: "mongodb.db" SLICES: |- @@ -833,19 +835,23 @@ services: - sst: 1 sd: 000001 varqi: 9 - dnn: srv6 + dnn: sr4mec-0 + - sst: 1 + sd: 000002 + varqi: 9 + dnn: sr4mec-1 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - sst: 1 - sd: 000002 + sd: 000003 varqi: 9 - dnn: free5gc + dnn: f5gc-0 #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - sst: 1 - sd: 000003 + sd: 000004 varqi: 9 - dnn: nextmn-upf + dnn: nmn-upf-0 #~ endif IMSI: |- #~ if "nextmn-srv6" in config["topology"]["dataplane"] @@ -869,10 +875,9 @@ services: networks: db: - {{ container_s(name='nssf', image='docker.io/louisroyer/dev-free5gc-nssf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:nssf', restart='always') }} + {{ container_s(name='nssf', service='nssf', restart='always') }} depends_on: - nrf: # required to being able to deregister propertly - condition: service_started + {{ depends_on_started_s('nrf') | indent(2) }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -895,14 +900,16 @@ services: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - sst: 1 sd: 000001 + - sst: 1 + sd: 000002 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - sst: 1 - sd: 000002 + sd: 000003 #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - sst: 1 - sd: 000003 + sd: 000004 #~ endif NSI_LIST: |- - snssai: @@ -925,14 +932,16 @@ services: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - sst: 1 sd: 000001 + - sst: 1 + sd: 000002 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - sst: 1 - sd: 000002 + sd: 000003 #~endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - sst: 1 - sd: 000003 + sd: 000004 #~ endif AMF_LIST: |- - nfId: 469de254-2fe5-4ca0-8381-af3f500af77c @@ -946,14 +955,16 @@ services: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - sst: 1 sd: 000001 + - sst: 1 + sd: 000002 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - sst: 1 - sd: 000002 + sd: 000003 #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - sst: 1 - sd: 000003 + sd: 000004 #~ endif TA_LIST: |- @@ -967,14 +978,16 @@ services: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - sst: 1 sd: 000001 + - sst: 1 + sd: 000002 #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - sst: 1 - sd: 000002 + sd: 000003 #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - sst: 1 - sd: 000003 + sd: 000004 #~ endif MAPPING_LIST_FROM_PLMN: |- @@ -990,8 +1003,6 @@ services: homeSnssai: sst: 1 sd: 00001 - #~ endif - #~ if "free5gc" in config["topology"]["dataplane"] - servingSnssai: sst: 1 sd: 00002 @@ -999,13 +1010,21 @@ services: sst: 1 sd: 00002 #~ endif - #~ if "nextmn-upf" in config["topology"]["dataplane"] + #~ if "free5gc" in config["topology"]["dataplane"] - servingSnssai: sst: 1 sd: 00003 homeSnssai: sst: 1 sd: 00003 + #~ endif + #~ if "nextmn-upf" in config["topology"]["dataplane"] + - servingSnssai: + sst: 1 + sd: 00004 + homeSnssai: + sst: 1 + sd: 00004 #~ endif secrets: {{ openssl_secrets_pem_s('nrf', 'sbi') | indent(2) }} @@ -1016,54 +1035,32 @@ services: #~ endif #~ if "nextmn-srv6" in config["topology"]["dataplane"] - {{ container_s(name='r0', image='docker.io/louisroyer/dev-nextmn-srv6', image_build='https://github.com/louisroyer-docker/nextmn.git#master:srv6', restart='always', srv6=True, debug='allow') }} + {{ container_s(name='r0', service='nextmn-srv6', restart='always', srv6=True, debug='allow') }} depends_on: - srv6-ctrl: - condition: service_healthy - r0-db: - condition: service_healthy + {{ depends_on_healthy_s('srv6-ctrl', 'r0-db') | indent(2) }} volumes: - {{ volume_ro('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') }} - - r0_db_volume:/var/run/postgresql/ + - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('r0_db_volume') | indent(3) }} + configs: + - {{ mount_xdg_config_s('r0', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - LOG_LEVEL: "{{ log_level() }}" - NEI_ADDR: "{{ ipv6_subnet('r1') }} {{ ipv6_subnet('srgw0') }} {{ ipv4('s', 'service') }}" - NEI_NH: "{{ ipv6('r1', 'dataplane') }} {{ ipv6('srgw0', 'dataplane') }} {{ ipv4('s0', 'edge') }}" - HOOKS: |- - pre-init-hook: remove-default-routes.sh - post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('r0', 'control') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" - GIN_MODE: "release" - BACKBONE_IP: "{{ ipv6('r0', 'dataplane') }}" - LOCATOR: "{{ ipv6_subnet('r0') }}" - ENDPOINTS: |- - - prefix: "{{ ipv6_prefix('end-dx4', 'r0') }}" - provider: "Linux" - behavior: "End.DX4" - IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice0') }}" - HEADENDS: |- - - name: "downlink (controlled)" - to: "{{ ipv4_subnet('slice0') }}" - provider: "NextMN-ctrl" - behavior: "H.Encaps" - source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r0') }}" + NEI_ADDR: "{{ ipv6_subnet('r1') }} {{ ipv6_subnet('srgw0') }} {{ ipv6_subnet('srgw1') }} {{ ipv4('s', 'service') }}" + NEI_NH: "{{ ipv6('r1', 'dataplane') }} {{ ipv6('srgw0', 'dataplane') }} {{ ipv6('srgw1', 'dataplane') }} {{ ipv4('s0', 'edge') }}" POSTGRES_PASSWORD_FILE: /run/secrets/r0_db_password POSTGRES_HOST: "r0-db.nextmndb" - POSTGRES_UNIX_SOCKET_PATH: "/var/run/postgresql/" + {{ environment_postgres_socket_path() }} secrets: - r0_db_password networks: - control: - ipv6_address: "{{ ipv6('r0', 'control') }}" + rest: + ipv6_address: "{{ ipv6('r0', 'rest') }}" dataplane: ipv6_address: "{{ ipv6('r0', 'dataplane') }}" edge: ipv4_address: "{{ ipv4('r0', 'edge') }}" nextmndb: - {{ container_s(name='r0-db', image='docker.io/library/postgres', restart='always', command=False) }} + {{ container_s(name='r0-db', service='postgres', restart='always', command=False) }} healthcheck: test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"] start_interval: 1s @@ -1076,58 +1073,36 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r0_db_password volumes: - - r0_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw_s('r0_db_volume') | indent(3) }} networks: nextmndb: - {{ container_s(name='r1', image='docker.io/louisroyer/dev-nextmn-srv6', image_build='https://github.com/louisroyer-docker/nextmn.git#master:srv6', restart='always', srv6=True, debug='allow' ) }} + {{ container_s(name='r1', service='nextmn-srv6', restart='always', srv6=True, debug='allow' ) }} depends_on: - srv6-ctrl: - condition: service_healthy - r1-db: - condition: service_healthy + {{ depends_on_healthy_s('srv6-ctrl', 'r1-db') | indent(2) }} volumes: - {{ volume_ro('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') }} - - r1_db_volume:/var/run/postgresql/ + - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('r1_db_volume') | indent(3) }} + configs: + - {{ mount_xdg_config_s('r1', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - LOG_LEVEL: "{{ log_level() }}" - NEI_ADDR: "{{ ipv6_subnet('r0') }} {{ ipv6_subnet('srgw0') }} {{ ipv4('s', 'service') }}" - NEI_NH: "{{ ipv6('r0', 'dataplane') }} {{ ipv6('srgw0', 'dataplane') }} {{ ipv4('s1', 'edge') }}" - HOOKS: |- - pre-init-hook: remove-default-routes.sh - post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('r1', 'control') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" - GIN_MODE: "release" - BACKBONE_IP: "{{ ipv6('r1', 'dataplane') }}" - LOCATOR: "{{ ipv6_subnet('r1') }}" - ENDPOINTS: |- - - prefix: "{{ ipv6_prefix('end-dx4', 'r1') }}" - provider: "Linux" - behavior: "End.DX4" - IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice0') }}" - HEADENDS: |- - - name: "downlink (controlled)" - to: "{{ ipv4_subnet('slice0') }}" - provider: "NextMN-ctrl" - behavior: "H.Encaps" - source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r1') }}" + NEI_ADDR: "{{ ipv6_subnet('r0') }} {{ ipv6_subnet('srgw0') }} {{ ipv6_subnet('srgw1') }} {{ ipv4('s', 'service') }}" + NEI_NH: "{{ ipv6('r0', 'dataplane') }} {{ ipv6('srgw0', 'dataplane') }} {{ ipv6('srgw1', 'dataplane') }} {{ ipv4('s1', 'edge') }}" POSTGRES_PASSWORD_FILE: /run/secrets/r1_db_password POSTGRES_HOST: "r1-db.nextmndb" - POSTGRES_UNIX_SOCKET_PATH: "/var/run/postgresql" + {{ environment_postgres_socket_path() }} secrets: - r1_db_password networks: - control: - ipv6_address: "{{ ipv6('r1', 'control') }}" + rest: + ipv6_address: "{{ ipv6('r1', 'rest') }}" dataplane: ipv6_address: "{{ ipv6('r1', 'dataplane') }}" edge: ipv4_address: "{{ ipv4('r1', 'edge') }}" nextmndb: - {{ container_s(name='r1-db', image='docker.io/library/postgres', restart='always', command=False) }} + {{ container_s(name='r1-db', service='postgres', restart='always', command=False) }} healthcheck: test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"] start_interval: 1s @@ -1140,59 +1115,37 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r1_db_password volumes: - - r1_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw_s('r1_db_volume') | indent(3) }} networks: nextmndb: #~ if config["topology"]["nb_edges"] > 2 - {{ container_s(name='r2', image='docker.io/louisroyer/dev-nextmn-srv6', image_build='https://github.com/louisroyer-docker/nextmn.git#master:srv6', restart='always', srv6=True, debug='allow' ) }} + {{ container_s(name='r2', service='nextmn-srv6', restart='always', srv6=True, debug='allow' ) }} depends_on: - srv6-ctrl: - condition: service_healthy - r2-db: - condition: service_healthy + {{ depends_on_healthy_s('srv6-ctrl', 'r2-db') | indent(2) }} volumes: - {{ volume_ro('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') }} - - r2_db_volume:/var/run/postgresql/ + - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('r2_db_volume') | indent(3) }} + configs: + - {{ mount_xdg_config_s('r2', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - LOG_LEVEL: "{{ log_level() }}" - NEI_ADDR: "{{ ipv6_subnet('srgw1') }} {{ ipv4('s', 'service') }}" - NEI_NH: "{{ ipv6('srgw1', 'dataplane') }} {{ ipv4('s2', 'edge') }}" - HOOKS: |- - pre-init-hook: remove-default-routes.sh - post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('r2', 'control') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" - GIN_MODE: "release" - BACKBONE_IP: "{{ ipv6('r2', 'dataplane') }}" - LOCATOR: "{{ ipv6_subnet('r2') }}" - ENDPOINTS: |- - - prefix: "{{ ipv6_prefix('end-dx4', 'r2') }}" - provider: "Linux" - behavior: "End.DX4" - IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice0') }}" - HEADENDS: |- - - name: "downlink (controlled)" - to: "{{ ipv4_subnet('slice0') }}" - provider: "NextMN-ctrl" - behavior: "H.Encaps" - source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r2') }}" + NEI_ADDR: "{{ ipv6_subnet('srgw0') }} {{ ipv6_subnet('srgw1') }} {{ ipv4('s', 'service') }}" + NEI_NH: "{{ ipv6('srgw0', 'dataplane') }} {{ ipv6('srgw1', 'dataplane') }} {{ ipv4('s2', 'edge') }}" POSTGRES_PASSWORD_FILE: /run/secrets/r2_db_password POSTGRES_HOST: "r2-db.nextmndb" - POSTGRES_UNIX_SOCKET_PATH: "/var/run/postgresql" + {{ environment_postgres_socket_path() }} secrets: - r2_db_password networks: - control: - ipv6_address: "{{ ipv6('r2', 'control') }}" + rest: + ipv6_address: "{{ ipv6('r2', 'rest') }}" dataplane: ipv6_address: "{{ ipv6('r2', 'dataplane') }}" edge: ipv4_address: "{{ ipv4('r2', 'edge') }}" nextmndb: - {{ container_s(name='r2-db', image='docker.io/library/postgres', restart='always', command=False) }} + {{ container_s(name='r2-db', service='postgres', restart='always', command=False) }} healthcheck: test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"] start_interval: 1s @@ -1205,59 +1158,36 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r2_db_password volumes: - - r2_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw_s('r2_db_volume') | indent(3) }} networks: nextmndb: - #~ endif + #~ endif - {{ container_s(name='srgw0', image='docker.io/louisroyer/dev-nextmn-srv6', image_build='https://github.com/louisroyer-docker/nextmn.git#master:srv6', restart='always', srv6=True, debug='allow' ) }} + {{ container_s(name='srgw0', service='nextmn-srv6', restart='always', srv6=True, debug='allow' ) }} depends_on: - srv6-ctrl: - condition: service_healthy - srgw0-db: - condition: service_healthy + {{ depends_on_healthy_s('srv6-ctrl', 'srgw0-db') | indent(2) }} volumes: - {{ volume_ro('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') }} - - srgw0_db_volume:/var/run/postgresql/ + - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('srgw0_db_volume') | indent(3) }} + configs: + - {{ mount_xdg_config_s('srgw0', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - LOG_LEVEL: "{{ log_level() }}" NEI_ADDR: "{{ ipv6_subnet('r0') }} {{ ipv6_subnet('r1') }}" NEI_NH: "{{ ipv6('r0', 'dataplane') }} {{ ipv6('r1', 'dataplane') }}" - HOOKS: |- - pre-init-hook: remove-default-routes.sh - post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('srgw0', 'control') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" - GIN_MODE: "release" - BACKBONE_IP: "{{ ipv6('srgw0', 'dataplane') }}" - LOCATOR: "{{ ipv6_subnet('srgw0') }}" - GTP4_HEADEND_PREFIX: "{{ ipv4('srgw0', 'srgw0') }}/32" - HEADENDS: |- - - name: "srgw0 uplink (controlled)" - to: "{{ ipv4('srgw0', 'srgw0') }}/32" - provider: "NextMN-Ctrl" - behavior: "H.M.GTP4.D" - source-address-prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" - ENDPOINTS: |- - - prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" - provider: "NextMN" - behavior: "End.M.GTP4.E" POSTGRES_PASSWORD_FILE: /run/secrets/srgw0_db_password POSTGRES_HOST: "srgw0-db.nextmndb" - POSTGRES_UNIX_SOCKET_PATH: "/var/run/postgresql/" + {{ environment_postgres_socket_path() }} secrets: - srgw0_db_password networks: - control: - ipv4_address: "{{ ipv4('srgw0', 'control') }}" - ipv6_address: "{{ ipv6('srgw0', 'control') }}" + rest: + ipv6_address: "{{ ipv6('srgw0', 'rest') }}" dataplane: ipv4_address: "{{ ipv4('srgw0', 'dataplane') }}" ipv6_address: "{{ ipv6('srgw0', 'dataplane') }}" nextmndb: - {{ container_s(name='srgw0-db', image='docker.io/library/postgres', restart='always', command=False) }} + {{ container_s(name='srgw0-db', service='postgres', restart='always', command=False) }} healthcheck: test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"] start_interval: 1s @@ -1270,59 +1200,36 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/srgw0_db_password volumes: - - srgw0_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw_s('srgw0_db_volume') | indent(3) }} networks: nextmndb: #~ if config["topology"]["nb_gnb"] > 2 - {{ container_s(name='srgw1', image='docker.io/louisroyer/dev-nextmn-srv6', image_build='https://github.com/louisroyer-docker/nextmn.git#master:srv6', restart='always', srv6=True, debug='allow' ) }} + {{ container_s(name='srgw1', service='nextmn-srv6', restart='always', srv6=True, debug='allow' ) }} depends_on: - srv6-ctrl: - condition: service_healthy - srgw1-db: - condition: service_healthy + {{ depends_on_healthy_s('srv6-ctrl', 'srgw1-db') | indent(2) }} volumes: - {{ volume_ro('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') }} - - srgw1_db_volume:/var/run/postgresql/ + - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('srgw1_db_volume') | indent(3) }} + configs: + - {{ mount_xdg_config_s('srgw1', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - LOG_LEVEL: "{{ log_level() }}" - NEI_ADDR: "{{ ipv6_subnet('r2') }}" - NEI_NH: "{{ ipv6('r2', 'dataplane') }}" - HOOKS: |- - pre-init-hook: remove-default-routes.sh - post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('srgw1', 'control') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" - GIN_MODE: "release" - BACKBONE_IP: "{{ ipv6('srgw1', 'dataplane') }}" - LOCATOR: "{{ ipv6_subnet('srgw1') }}" - GTP4_HEADEND_PREFIX: "{{ ipv4('srgw1', 'srgw1') }}/32" - HEADENDS: |- - - name: "srgw1 uplink (controlled)" - to: "{{ ipv4('srgw1', 'srgw1') }}/32" - provider: "NextMN-Ctrl" - behavior: "H.M.GTP4.D" - source-address-prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" - ENDPOINTS: |- - - prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" - provider: "NextMN" - behavior: "End.M.GTP4.E" + NEI_ADDR: "{{ ipv6_subnet('r0') }} {{ ipv6_subnet('r1') }} {{ ipv6_subnet('r2') }}" + NEI_NH: "{{ ipv6('r0', 'dataplane') }} {{ ipv6('r1', 'dataplane') }} {{ ipv6('r2', 'dataplane') }}" POSTGRES_PASSWORD_FILE: /run/secrets/srgw1_db_password POSTGRES_HOST: "srgw1-db.nextmndb" - POSTGRES_UNIX_SOCKET_PATH: "/var/run/postgresql/" + {{ environment_postgres_socket_path() }} secrets: - srgw1_db_password networks: - control: - ipv4_address: "{{ ipv4('srgw1', 'control') }}" - ipv6_address: "{{ ipv6('srgw1', 'control') }}" + rest: + ipv6_address: "{{ ipv6('srgw1', 'rest') }}" dataplane: ipv4_address: "{{ ipv4('srgw1', 'dataplane') }}" ipv6_address: "{{ ipv6('srgw1', 'dataplane') }}" nextmndb: - {{ container_s(name='srgw1-db', image='docker.io/library/postgres', restart='always', command=False) }} + {{ container_s(name='srgw1-db', service='postgres', restart='always', command=False) }} healthcheck: test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"] start_interval: 1s @@ -1335,115 +1242,17 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/srgw1_db_password volumes: - - srgw1_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw_s('srgw1_db_volume') | indent(3) }} networks: nextmndb: #~ endif - {{ container_s(name='srv6-ctrl', image='docker.io/louisroyer/dev-nextmn-srv6-ctrl', image_build='https://github.com/louisroyer-docker/nextmn.git#master:srv6-ctrl', debug='allow', restart='always') }} - environment: - N4: "{{ ipv4('srv6-ctrl', 'control') }}" - HTTP_ADDRESS: "{{ ipv6('srv6-ctrl', 'control') }}" - HTTP_PORT: "8080" - LOG_LEVEL: "{{ log_level() }}" - GIN_MODE: "release" - DOWNLINK: |- - - control-uri: "http://[{{ ipv6('r0', 'control') }}]:8080" - enabled: true - area: - #~ if config["topology"]["controlplane"] == "free5gc" - - "{{ ipv4('gnb1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnb2', 'dataplane') }}/32" - #~ endif - #~ endif - #~ if config["topology"]["controlplane"] == "nextmn-lite" - - "{{ ipv4('gnbl1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnbl2', 'dataplane') }}/32" - #~ endif - #~ endif - srgw-gtp4: "{{ ipv4('srgw0', 'srgw0') }}" - segments-list: - - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" - #~ if config["topology"]["nb_edges"] > 1 - - control-uri: "http://[{{ ipv6('r1', 'control') }}]:8080" - enabled: true - area: - #~ if config["topology"]["controlplane"] == "free5gc" - - "{{ ipv4('gnb1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnb2', 'dataplane') }}/32" - #~ endif - #~ endif - #~ if config["topology"]["controlplane"] == "nextmn-lite" - - "{{ ipv4('gnbl1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnbl2', 'dataplane') }}/32" - #~ endif - #~ endif - srgw-gtp4: "{{ ipv4('srgw0', 'srgw0') }}" - segments-list: - - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" - #~ endif - #~ if config["topology"]["nb_edges"] > 2 - - control-uri: "http://[{{ ipv6('r2', 'control') }}]:8080" - enabled: true - area: - - "{{ ipv4('gnbl3', 'dataplane') }}/32" - srgw-gtp4: "{{ ipv4('srgw1', 'srgw1') }}" - segments-list: - - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" - #~ endif - UPLINK: |- - - control-uri: "http://[{{ ipv6('srgw0', 'control') }}]:8080" - enabled: true - service: "{{ ipv4('s', 'service') }}" - area: - #~ if config["topology"]["controlplane"] == "free5gc" - - "{{ ipv4('gnb1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnb2', 'dataplane') }}/32" - #~ endif - #~ endif - #~ if config["topology"]["controlplane"] == "nextmn-lite" - - "{{ ipv4('gnbl1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnbl2', 'dataplane') }}/32" - #~ endif - #~ endif - segments-list: - - "{{ ipv6('end-dx4', 'r0') }}" -#~ if config["topology"]["nb_edges"] > 1 - - control-uri: "http://[{{ ipv6('srgw0', 'control') }}]:8080" - enabled: false - service: "{{ ipv4('s', 'service') }}" - area: - #~ if config["topology"]["controlplane"] == "free5gc" - - "{{ ipv4('gnb1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnb2', 'dataplane') }}/32" - #~ endif - #~ endif - #~ if config["topology"]["controlplane"] == "nextmn-lite" - - "{{ ipv4('gnbl1', 'dataplane') }}/32" - #~ if config["topology"]["nb_gnb"] > 1 - - "{{ ipv4('gnbl2', 'dataplane') }}/32" - #~ endif - #~ endif - segments-list: - - "{{ ipv6('end-dx4', 'r1') }}" - #~ if (config["topology"]["nb_gnb"] > 2) and (config["topology"]["nb_edges"] > 2) and (config["topology"]["controlplane"] == "nextmn-lite") - - control-uri: "http://[{{ ipv6('srgw1', 'control') }}]:8080" - enabled: true - service: "{{ ipv4('s', 'service') }}" - area: - - "{{ ipv4('gnbl3', 'dataplane') }}/32" - segments-list: - - "{{ ipv6('end-dx4', 'r2') }}" - #~ endif -#~ endif + {{ container_s(name='srv6-ctrl', service='nextmn-srv6-ctrl', debug='allow', restart='always') }} + configs: + - {{ mount_xdg_config_s('srv6-ctrl', 'nextmn-srv6-ctrl/config.yaml') | indent(3) }} networks: + rest: + ipv6_address: "{{ ipv6('srv6-ctrl', 'rest') }}" control: ipv4_address: "{{ ipv4('srv6-ctrl', 'control') }}" ipv6_address: "{{ ipv6('srv6-ctrl', 'control') }}" @@ -1454,13 +1263,13 @@ services: ONESHOT: "true" ROUTES_INIT: |- #~ if "nextmn-srv6" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice0') }} via {{ ipv4('r0', 'edge') }} + - add {{ ipv4_subnet('slice-sr4mec') }} via {{ ipv4('r0', 'edge') }} #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice1') }} via {{ ipv4('upfa1-f5gc', 'edge') }} + - add {{ ipv4_subnet('slice-f5gc-0') }} via {{ ipv4('upfa1-f5gc', 'edge') }} #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice2') }} via {{ ipv4('upfa1-nmn', 'edge') }} + - add {{ ipv4_subnet('slice-nmn-upf-0') }} via {{ ipv4('upfa1-nmn', 'edge') }} #~ endif PRE_INIT_HOOK: "ip" PRE_INIT_HOOK_0: "addr" @@ -1468,9 +1277,9 @@ services: PRE_INIT_HOOK_2: "{{ ipv4('s', 'service') }}" PRE_INIT_HOOK_3: "dev" PRE_INIT_HOOK_4: "edge-0" - {{ container_s(name='s0', image='docker.io/library/nginx', command=False, debug='always') }} + {{ container_s(name='s0', service='nginx', command=False, debug='always') }} volumes: - {{ volume_ro('nginx/instance.conf.template', '/etc/nginx/templates/instance.conf.template') }} + - {{ volume_bind_ro_s('nginx/instance.conf.template', '/etc/nginx/templates/instance.conf.template') | indent(3) }} environment: NGINX_PORT: "80" NGINX_SERVICE_ID: "{{ ipv4('s', 'service') }}" @@ -1484,13 +1293,13 @@ services: ONESHOT: "true" ROUTES_INIT: |- #~ if "nextmn-srv6" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice0') }} via {{ ipv4('r1', 'edge') }} + - add {{ ipv4_subnet('slice-sr4mec') }} via {{ ipv4('r1', 'edge') }} #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice1') }} via {{ ipv4('upfa2-f5gc', 'edge') }} + - add {{ ipv4_subnet('slice-f5gc-0') }} via {{ ipv4('upfa2-f5gc', 'edge') }} #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice2') }} via {{ ipv4('upfa2-nmn', 'edge') }} + - add {{ ipv4_subnet('slice-nmn-upf-0') }} via {{ ipv4('upfa2-nmn', 'edge') }} #~ endif PRE_INIT_HOOK: "ip" PRE_INIT_HOOK_0: "addr" @@ -1498,9 +1307,9 @@ services: PRE_INIT_HOOK_2: "{{ ipv4('s', 'service') }}" PRE_INIT_HOOK_3: "dev" PRE_INIT_HOOK_4: "edge-0" - {{ container_s(name='s1', image='docker.io/library/nginx', command=False, debug='always') }} + {{ container_s(name='s1', service='nginx', command=False, debug='always') }} volumes: - {{ volume_ro('nginx/instance.conf.template', '/etc/nginx/templates/instance.conf.template') }} + - {{ volume_bind_ro_s('nginx/instance.conf.template', '/etc/nginx/templates/instance.conf.template') | indent(3) }} environment: NGINX_PORT: "80" NGINX_SERVICE_ID: "{{ ipv4('s', 'service') }}" @@ -1515,13 +1324,13 @@ services: ONESHOT: "true" ROUTES_INIT: |- #~ if "nextmn-srv6" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice0') }} via {{ ipv4('r2', 'edge') }} + - add {{ ipv4_subnet('slice-sr4mec') }} via {{ ipv4('r2', 'edge') }} #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice1') }} via {{ ipv4('upfa3-f5gc', 'edge') }} + - add {{ ipv4_subnet('slice-f5gc-0') }} via {{ ipv4('upfa3-f5gc', 'edge') }} #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - - add {{ ipv4_subnet('slice2') }} via {{ ipv4('upfa3-nmn', 'edge') }} + - add {{ ipv4_subnet('slice-nmn-upf-0') }} via {{ ipv4('upfa3-nmn', 'edge') }} #~ endif PRE_INIT_HOOK: "ip" PRE_INIT_HOOK_0: "addr" @@ -1529,9 +1338,9 @@ services: PRE_INIT_HOOK_2: "{{ ipv4('s', 'service') }}" PRE_INIT_HOOK_3: "dev" PRE_INIT_HOOK_4: "edge-0" - {{ container_s(name='s2', image='docker.io/library/nginx', command=False, debug='always') }} + {{ container_s(name='s2', service='nginx', command=False, debug='always') }} volumes: - {{ volume_ro('nginx/instance.conf.template', '/etc/nginx/templates/instance.conf.template') }} + - {{ volume_bind_ro_s('nginx/instance.conf.template', '/etc/nginx/templates/instance.conf.template') | indent(3) }} environment: NGINX_PORT: "80" NGINX_SERVICE_ID: "{{ ipv4('s', 'service') }}" @@ -1542,7 +1351,7 @@ services: #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - {{ container_s(name='upfi1-f5gc', image='docker.io/louisroyer/dev-free5gc-upf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:upf', restart='always', cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfi1-f5gc', service='free5gc-upf', restart='always', cap_net_admin=True, debug='allow') }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -1553,15 +1362,15 @@ services: - addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: free5gc - cidr: {{ ipv4_subnet('slice1') }} + - dnn: f5gc-0 + cidr: {{ ipv4_subnet('slice-f5gc-0') }} networks: control: ipv4_address: "{{ ipv4('upfi1-f5gc', 'control') }}" dataplane: ipv4_address: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" #~ if config["topology"]["nb_gnb"] > 2 - {{ container_s(name='upfi2-f5gc', image='docker.io/louisroyer/dev-free5gc-upf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:upf', restart='always', cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfi2-f5gc', service='free5gc-upf', restart='always', cap_net_admin=True, debug='allow') }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -1572,15 +1381,15 @@ services: - addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: free5gc - cidr: {{ ipv4_subnet('slice1') }} + - dnn: f5gc-0 + cidr: {{ ipv4_subnet('slice-f5gc-0') }} networks: control: ipv4_address: "{{ ipv4('upfi2-f5gc', 'control') }}" dataplane: ipv4_address: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" #~ endif - {{ container_s(name='upfa1-f5gc', image='docker.io/louisroyer/dev-free5gc-upf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:upf', restart='always', cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfa1-f5gc', service='free5gc-upf', restart='always', cap_net_admin=True, debug='allow') }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -1589,8 +1398,8 @@ services: - addr: "{{ ipv4('upfa1-f5gc', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: free5gc - cidr: {{ ipv4_subnet('slice1') }} + - dnn: f5gc-0 + cidr: {{ ipv4_subnet('slice-f5gc-0') }} ROUTES_INIT: |- - add {{ ipv4('s', 'service') }} via {{ ipv4('s0', 'edge') }} networks: @@ -1601,7 +1410,7 @@ services: edge: ipv4_address: "{{ ipv4('upfa1-f5gc', 'edge') }}" #~ if config["topology"]["nb_edges"] > 1 - {{ container_s(name='upfa2-f5gc', image='docker.io/louisroyer/dev-free5gc-upf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:upf', restart='always', cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfa2-f5gc', service='free5gc-upf', restart='always', cap_net_admin=True, debug='allow') }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -1610,8 +1419,8 @@ services: - addr: "{{ ipv4('upfa2-f5gc', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: free5gc - cidr: {{ ipv4_subnet('slice1') }} + - dnn: f5gc-0 + cidr: {{ ipv4_subnet('slice-f5gc-0') }} ROUTES_INIT: |- - add {{ ipv4('s', 'service') }} via {{ ipv4('s1', 'edge') }} networks: @@ -1623,7 +1432,7 @@ services: ipv4_address: "{{ ipv4('upfa2-f5gc', 'edge') }}" #~ endif #~ if config["topology"]["nb_edges"] > 2 - {{ container_s(name='upfa3-f5gc', image='docker.io/louisroyer/dev-free5gc-upf', image_build='https://github.com/louisroyer-docker/free5gc.git#master:upf', restart='always', cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfa3-f5gc', service='free5gc-upf', restart='always', cap_net_admin=True, debug='allow') }} environment: LOG_LEVEL: "{{ log_level() }}" LOG_REPORT_CALLER: "{{ log_report_caller() }}" @@ -1632,8 +1441,8 @@ services: - addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: free5gc - cidr: {{ ipv4_subnet('slice1') }} + - dnn: f5gc-0 + cidr: {{ ipv4_subnet('slice-f5gc-0') }} ROUTES_INIT: |- - add {{ ipv4('s', 'service') }} via {{ ipv4('s2', 'edge') }} networks: @@ -1647,7 +1456,7 @@ services: #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - {{ container_s(name='upfi1-nmn', image='docker.io/louisroyer/dev-nextmn-upf', image_build='https://github.com/louisroyer-docker/nextmn.git#master:upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfi1-nmn', service='nextmn-upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} environment: N4: "{{ ipv4('upfi1-nmn', 'control') }}" IF_LIST: |- @@ -1656,8 +1465,8 @@ services: - addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: nextmn-upf - cidr: {{ ipv4_subnet('slice2') }} + - dnn: nmn-upf-0 + cidr: {{ ipv4_subnet('slice-nmn-upf-0') }} LOG_LEVEL: "{{ log_level() }}" networks: control: @@ -1665,7 +1474,7 @@ services: dataplane: ipv4_address: "{{ ipv4('upfi1-nmn', 'dataplane') }}" #~ if config["topology"]["nb_gnb"] > 2 - {{ container_s(name='upfi2-nmn', image='docker.io/louisroyer/dev-nextmn-upf', image_build='https://github.com/louisroyer-docker/nextmn.git#master:upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfi2-nmn', service='nextmn-upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} environment: N4: "{{ ipv4('upfi2-nmn', 'control') }}" IF_LIST: |- @@ -1674,8 +1483,8 @@ services: - addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: nextmn-upf - cidr: {{ ipv4_subnet('slice2') }} + - dnn: nmn-upf-0 + cidr: {{ ipv4_subnet('slice-nmn-upf-0') }} LOG_LEVEL: "{{ log_level() }}" networks: control: @@ -1683,15 +1492,15 @@ services: dataplane: ipv4_address: "{{ ipv4('upfi2-nmn', 'dataplane') }}" #~ endif - {{ container_s(name='upfa1-nmn', image='docker.io/louisroyer/dev-nextmn-upf', image_build='https://github.com/louisroyer-docker/nextmn.git#master:upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfa1-nmn', service='nextmn-upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} environment: N4: "{{ ipv4('upfa1-nmn', 'control') }}" IF_LIST: |- - addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: nextmn-upf - cidr: {{ ipv4_subnet('slice2') }} + - dnn: nmn-upf-0 + cidr: {{ ipv4_subnet('slice-nmn-upf-0') }} ROUTES_INIT: |- - add {{ ipv4('s', 'service') }} via {{ ipv4('s0', 'edge') }} LOG_LEVEL: "{{ log_level() }}" @@ -1703,15 +1512,15 @@ services: edge: ipv4_address: "{{ ipv4('upfa1-nmn', 'edge') }}" #~ if config["topology"]["nb_edges"] > 1 - {{ container_s(name='upfa2-nmn', image='docker.io/louisroyer/dev-nextmn-upf', image_build='https://github.com/louisroyer-docker/nextmn.git#master:upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfa2-nmn', service='nextmn-upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} environment: N4: "{{ ipv4('upfa2-nmn', 'control') }}" IF_LIST: |- - addr: "{{ ipv4('upfa2-nmn', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: nextmn-upf - cidr: {{ ipv4_subnet('slice2') }} + - dnn: nmn-upf-0 + cidr: {{ ipv4_subnet('slice-nmn-upf-0') }} ROUTES_INIT: |- - add {{ ipv4('s', 'service') }} via {{ ipv4('s1', 'edge') }} LOG_LEVEL: "{{ log_level() }}" @@ -1724,15 +1533,15 @@ services: ipv4_address: "{{ ipv4('upfa2-nmn', 'edge') }}" #~ endif #~ if config["topology"]["nb_edges"] > 2 - {{ container_s(name='upfa3-nmn', image='docker.io/louisroyer/dev-nextmn-upf', image_build='https://github.com/louisroyer-docker/nextmn.git#master:upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} + {{ container_s(name='upfa3-nmn', service='nextmn-upf', restart='always', iface_tun=True, ipv4_forward=True, cap_net_admin=True, debug='allow') }} environment: N4: "{{ ipv4('upfa3-nmn', 'control') }}" IF_LIST: |- - addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" type: N9 DNN_LIST: |- - - dnn: nextmn-upf - cidr: {{ ipv4_subnet('slice2') }} + - dnn: nmn-upf-0 + cidr: {{ ipv4_subnet('slice-nmn-upf-0') }} ROUTES_INIT: |- - add {{ ipv4('s', 'service') }} via {{ ipv4('s2', 'edge') }} LOG_LEVEL: "{{ log_level() }}" @@ -1748,340 +1557,531 @@ services: #~ if config["topology"]["controlplane"] == "nextmn-lite" #~ if "nextmn-srv6" in config["topology"]["dataplane"] - {{ container_s(name='uel1', image='docker.io/louisroyer/dev-nextmn-ue-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} + {{ container_s(name='uel1', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True) }} depends_on: - gnbl1: - condition: service_started + {{ depends_on_healthy_s('gnbl1') | indent(2) }} #~ if config["topology"]["ran"]["handover"] - gnbl2: - condition: service_started + {{ depends_on_healthy_s('gnbl2') | indent(2) }} #~ if config["topology"]["nb_gnb"] > 2 - gnbl3: - condition: service_started + {{ depends_on_healthy_s('gnbl3') | indent(2) }} #~ endif #~ endif - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('uel1', 'control') }}" - HTTP_PORT: "8080" - RAN: |- - bind-addr: "[{{ ipv6('uel1', 'ran') }}]:1234" - gnbs: - - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - #~ if config["topology"]["ran"]["handover"] - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - #~ if config["topology"]["nb_gnb"] > 2 - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" - #~ endif - #~ endif - pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - dnn: "srv6" - LOG_LEVEL: "{{ log_level() }}" + configs: + - {{ mount_xdg_config_s('uel1', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel1', 'ran') }}" ipv6_address: "{{ ipv6('uel1', 'ran') }}" - control: - ipv4_address: "{{ ipv4('uel1', 'control') }}" - ipv6_address: "{{ ipv6('uel1', 'control') }}" + rest: + ipv6_address: "{{ ipv6('uel1', 'rest') }}" #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='uel2', image='docker.io/louisroyer/dev-nextmn-ue-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} + {{ container_s(name='uel2', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True) }} depends_on: - gnbl2: - condition: service_started - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('uel2', 'control') }}" - HTTP_PORT: "8080" - RAN: |- - bind-addr: "[{{ ipv6('uel2', 'ran') }}]:1234" - gnbs: - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - dnn: "srv6" - LOG_LEVEL: "{{ log_level() }}" + {{ depends_on_healthy_s('gnbl1') | indent(2) }} + #~ if config["topology"]["ran"]["handover"] + {{ depends_on_healthy_s('gnbl2') | indent(2) }} + #~ if config["topology"]["nb_gnb"] > 2 + {{ depends_on_healthy_s('gnbl3') | indent(2) }} + #~ endif + #~ endif + configs: + - {{ mount_xdg_config_s('uel2', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel2', 'ran') }}" ipv6_address: "{{ ipv6('uel2', 'ran') }}" - control: - ipv4_address: "{{ ipv4('uel2', 'control') }}" - ipv6_address: "{{ ipv6('uel2', 'control') }}" + rest: + ipv6_address: "{{ ipv6('uel2', 'rest') }}" #~ endif #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - {{ container_s(name='uel3', image='docker.io/louisroyer/dev-nextmn-ue-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} + {{ container_s(name='uel3', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} depends_on: - gnbl1: - condition: service_started + {{ depends_on_healthy_s('gnbl1') | indent(2) }} #~ if config["topology"]["ran"]["handover"] - gnbl2: - condition: service_started + {{ depends_on_healthy_s('gnbl2') | indent(2) }} #~ if config["topology"]["nb_gnb"] > 2 - gnbl3: - condition: service_started + {{ depends_on_healthy_s('gnbl3') | indent(2) }} #~ endif #~ endif - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('uel3', 'control') }}" - HTTP_PORT: "8080" - RAN: |- - bind-addr: "[{{ ipv6('uel3', 'ran') }}]:1234" - gnbs: - - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - #~ if config["topology"]["ran"]["handover"] - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - #~ if config["topology"]["nb_gnb"] > 2 - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" - #~ endif - #~ endif - pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - dnn: "free5gc" - LOG_LEVEL: "{{ log_level() }}" + configs: + - {{ mount_xdg_config_s('uel3', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel3', 'ran') }}" ipv6_address: "{{ ipv6('uel3', 'ran') }}" - control: - ipv4_address: "{{ ipv4('uel3', 'control') }}" - ipv6_address: "{{ ipv6('uel3', 'control') }}" + rest: + ipv6_address: "{{ ipv6('uel3', 'rest') }}" #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='uel4', image='docker.io/louisroyer/dev-nextmn-ue-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} + {{ container_s(name='uel4', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} depends_on: - gnbl2: - condition: service_started - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('uel4', 'control') }}" - HTTP_PORT: "8080" - RAN: |- - bind-addr: "[{{ ipv6('uel4', 'ran') }}]:1234" - gnbs: - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - dnn: "free5gc" - LOG_LEVEL: "{{ log_level() }}" + {{ depends_on_healthy_s('gnbl2') | indent(2) }} + configs: + - {{ mount_xdg_config_s('uel4', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel4', 'ran') }}" ipv6_address: "{{ ipv6('uel4', 'ran') }}" - control: - ipv4_address: "{{ ipv4('uel4', 'control') }}" - ipv6_address: "{{ ipv6('uel4', 'control') }}" + rest: + ipv6_address: "{{ ipv6('uel4', 'rest') }}" #~ endif #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - {{ container_s(name='uel5', image='docker.io/louisroyer/dev-nextmn-ue-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} + {{ container_s(name='uel5', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=True, iface_tun=True, cap_net_admin=True) }} depends_on: - gnbl1: - condition: service_started + {{ depends_on_healthy_s('gnbl1') | indent(2) }} #~ if config["topology"]["ran"]["handover"] - gnbl2: - condition: service_started + {{ depends_on_healthy_s('gnbl2') | indent(2) }} #~ if config["topology"]["nb_gnb"] > 2 - gnbl3: - condition: service_started + {{ depends_on_healthy_s('gnbl3') | indent(2) }} #~ endif #~ endif - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('uel5', 'control') }}" - HTTP_PORT: "8080" - RAN: |- - bind-addr: "[{{ ipv6('uel5', 'ran') }}]:1234" - gnbs: - - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - #~ if config["topology"]["ran"]["handover"] - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - #~ if config["topology"]["nb_gnb"] > 2 - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" - #~ endif - #~ endif - pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - dnn: "nextmn-upf" - LOG_LEVEL: "{{ log_level() }}" + configs: + - {{ mount_xdg_config_s('uel5', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel5', 'ran') }}" ipv6_address: "{{ ipv6('uel5', 'ran') }}" - control: - ipv4_address: "{{ ipv4('uel5', 'control') }}" - ipv6_address: "{{ ipv6('uel5', 'control') }}" + rest: + ipv6_address: "{{ ipv6('uel5', 'rest') }}" #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='uel6', image='docker.io/louisroyer/dev-nextmn-ue-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} + {{ container_s(name='uel6', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} depends_on: - gnbl2: - condition: service_started - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('uel6', 'control') }}" - HTTP_PORT: "8080" - RAN: |- - bind-addr: "[{{ ipv6('uel6', 'ran') }}]:1234" - gnbs: - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - dnn: "nextmn-upf" - LOG_LEVEL: "{{ log_level() }}" + {{ depends_on_healthy_s('gnbl2') | indent(2) }} + configs: + - {{ mount_xdg_config_s('uel6', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel6', 'ran') }}" ipv6_address: "{{ ipv6('uel6', 'ran') }}" - control: - ipv4_address: "{{ ipv4('uel6', 'control') }}" - ipv6_address: "{{ ipv6('uel6', 'control') }}" + rest: + ipv6_address: "{{ ipv6('uel6', 'rest') }}" #~ endif #~ endif - {{ container_s(name='gnbl1', image='docker.io/louisroyer/dev-nextmn-gnb-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:gnb-lite', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='gnbl1', service='nextmn-gnb-lite', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} depends_on: - cp-lite: - condition: service_started - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('gnbl1', 'control') }}" - HTTP_PORT: "8080" - CP: "http://[{{ ipv6('cp-lite', 'control') }}]:8080" - N3: "{{ ipv4('gnbl1', 'dataplane') }}" - RAN: |- - bind-addr: "[{{ ipv6('gnbl1', 'ran') }}]:1234" - LOG_LEVEL: "{{ log_level() }}" - ROUTES_INIT: |- - - add {{ ipv4('srgw0', 'srgw0') }} via {{ ipv4('srgw0', 'dataplane') }} + {{ depends_on_healthy_s('cp-lite') | indent(2) }} + configs: + - {{ mount_xdg_config_s('gnbl1', 'nextmn-gnb-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('gnbl1', 'ran') }}" ipv6_address: "{{ ipv6('gnbl1', 'ran') }}" - control: - ipv4_address: "{{ ipv4('gnbl1', 'control') }}" - ipv6_address: "{{ ipv6('gnbl1', 'control') }}" + rest: + ipv6_address: "{{ ipv6('gnbl1', 'rest') }}" dataplane: ipv4_address: "{{ ipv4('gnbl1', 'dataplane') }}" - {{ container_s(name='gnbl2', image='docker.io/louisroyer/dev-nextmn-gnb-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:gnb-lite', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='gnbl2', service='nextmn-gnb-lite', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} depends_on: - cp-lite: - condition: service_started - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('gnbl2', 'control') }}" - HTTP_PORT: "8080" - CP: "http://[{{ ipv6('cp-lite', 'control') }}]:8080" - N3: "{{ ipv4('gnbl2', 'dataplane') }}" - RAN: |- - bind-addr: "[{{ ipv6('gnbl2', 'ran') }}]:1234" - LOG_LEVEL: "{{ log_level() }}" - ROUTES_INIT: |- - - add {{ ipv4('srgw0', 'srgw0') }} via {{ ipv4('srgw0', 'dataplane') }} + {{ depends_on_healthy_s('cp-lite') | indent(2) }} + configs: + - {{ mount_xdg_config_s('gnbl2', 'nextmn-gnb-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('gnbl2', 'ran') }}" ipv6_address: "{{ ipv6('gnbl2', 'ran') }}" - control: - ipv4_address: "{{ ipv4('gnbl2', 'control') }}" - ipv6_address: "{{ ipv6('gnbl2', 'control') }}" + rest: + ipv6_address: "{{ ipv6('gnbl2', 'rest') }}" dataplane: ipv4_address: "{{ ipv4('gnbl2', 'dataplane') }}" #~ if config["topology"]["nb_gnb"] > 2 - {{ container_s(name='gnbl3', image='docker.io/louisroyer/dev-nextmn-gnb-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:gnb-lite', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='gnbl3', service='nextmn-gnb-lite', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} depends_on: - cp-lite: - condition: service_started - environment: - GIN_MODE: "release" - HTTP_ADDRESS: "{{ ipv6('gnbl3', 'control') }}" - HTTP_PORT: "8080" - CP: "http://[{{ ipv6('cp-lite', 'control') }}]:8080" - N3: "{{ ipv4('gnbl3', 'dataplane') }}" - RAN: |- - bind-addr: "[{{ ipv6('gnbl3', 'ran') }}]:1234" - LOG_LEVEL: "{{ log_level() }}" - ROUTES_INIT: |- - - add {{ ipv4('srgw1', 'srgw1') }} via {{ ipv4('srgw1', 'dataplane') }} + {{ depends_on_healthy_s('cp-lite') | indent(2) }} + configs: + - {{ mount_xdg_config_s('gnbl3', 'nextmn-gnb-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('gnbl3', 'ran') }}" ipv6_address: "{{ ipv6('gnbl3', 'ran') }}" - control: - ipv4_address: "{{ ipv4('gnbl3', 'control') }}" - ipv6_address: "{{ ipv6('gnbl3', 'control') }}" + rest: + ipv6_address: "{{ ipv6('gnbl3', 'rest') }}" dataplane: ipv4_address: "{{ ipv4('gnbl3', 'dataplane') }}" #~ endif - {{ container_s(name='cp-lite', image='docker.io/louisroyer/dev-nextmn-cp-lite', image_build='https://github.com/louisroyer-docker/nextmn.git#master:cp-lite', enable_ipv6=True, debug='allow', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='cp-lite', service='nextmn-cp-lite', enable_ipv6=True, debug='allow', debug_volume=False, cap_net_admin=True) }} depends_on: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6-ctrl: - condition: service_started - srgw0: - condition: service_started - #~ if config["topology"]["nb_gnb"] > 2 - srgw1: - condition: service_started - #~ endif - r0: - condition: service_started - r1: - condition: service_started + {{ depends_on_healthy_s('srv6-ctrl', 'srgw0', 'r0', 'r1') | indent(2) }} #~ if config["topology"]["nb_gnb"] > 2 - r2: - condition: service_started + {{ depends_on_healthy_s('srgw1', 'r2') | indent(2) }} #~ endif #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - upfi1-f5gc: - condition: service_started + {{ depends_on_started_s('upfi1-f5gc', 'upfa1-f5gc', 'upfa2-f5gc') | indent(2) }} #~ if config["topology"]["nb_gnb"] > 2 - upfi2-f5gc: - condition: service_started + {{ depends_on_started_s('upfi2-f5gc', 'upfa3-f5gc') | indent(2) }} + #~ endif + #~ endif + #~ if "nextmn-upf" in config["topology"]["dataplane"] + {{ depends_on_started_s('upfi1-nmn', 'upfa1-nmn') | indent(2) }} + #~ if config["topology"]["nb_edges"] > 1 + {{ depends_on_started_s('upfa2-nmn') | indent(2) }} + #~ endif + #~ if config["topology"]["nb_edges"] > 2 + {{ depends_on_started_s('upfa3-nmn') | indent(2) }} #~ endif - upfa1-f5gc: - condition: service_started - upfa2-f5gc: - condition: service_started #~ if config["topology"]["nb_gnb"] > 2 - upfa3-f5gc: - condition: service_started + {{ depends_on_started_s('upfi2-nmn') | indent(2) }} #~ endif + #~ endif + configs: + - {{ mount_xdg_config_s('cp-lite', 'nextmn-cp-lite/config.yaml') | indent(3) }} + networks: + control: + ipv4_address: "{{ ipv4('cp-lite', 'control') }}" + ipv6_address: "{{ ipv6('cp-lite', 'control') }}" + rest: + ipv6_address: "{{ ipv6('cp-lite', 'rest') }}" + +#~ endif + {{ container_s(name='inter-areas', service='docker-setup', enable_ipv6=True, srv6=True, debug='allow', debug_volume=False, cap_net_admin=True) }} + environment: + ROUTES_INIT: |- + - add {{ ipv6_subnet('r1') }} via {{ ipv6('r1', 'dataplane') }} + - add {{ ipv6_subnet('r2') }} via {{ ipv6('r2', 'dataplane') }} + - add {{ ipv6_subnet('srgw0') }} via {{ ipv6('srgw0', 'dataplane') }} + - add {{ ipv6_subnet('srgw1') }} via {{ ipv6('srgw1', 'dataplane') }} + PRE_INIT_HOOK: "iptables" + PRE_INIT_HOOK_0: "-A" + PRE_INIT_HOOK_1: "OUTPUT" + PRE_INIT_HOOK_2: "-p" + PRE_INIT_HOOK_3: "icmp" + PRE_INIT_HOOK_4: "--icmp-type" + PRE_INIT_HOOK_5: "redirect" + PRE_INIT_HOOK_6: "-j" + PRE_INIT_HOOK_7: "DROP" + networks: + dataplane: + ipv4_address: "{{ ipv4('inter-areas', 'dataplane') }}" + ipv6_address: "{{ ipv6('inter-areas', 'dataplane') }}" + +#~ if (config["topology"]["controlplane"] == "free5gc") or ("nextmn-srv6" in config["topology"]["dataplane"]) +secrets: +#~ endif +#~ if config["topology"]["controlplane"] == "free5gc" + {{ openssl_root_s() }} + {{ openssl_s('amf', 'sbi') }} + {{ openssl_s('ausf', 'sbi') }} + {{ openssl_s('chf', 'sbi') }} + {{ openssl_s('nrf', 'sbi') }} + {{ openssl_s('nssf', 'sbi') }} + {{ openssl_s('pcf', 'sbi') }} + {{ openssl_s('smf', 'sbi') }} + {{ openssl_s('udm', 'sbi') }} + {{ openssl_s('udr', 'sbi') }} +#~ endif +#~ if "nextmn-srv6" in config["topology"]["dataplane"] + r0_db_password: + file: "{{ secret('r0_db_password.txt') }}" + r1_db_password: + file: "{{ secret('r1_db_password.txt') }}" + #~ if config["topology"]["nb_edges"] > 2 + r2_db_password: + file: "{{ secret('r2_db_password.txt') }}" + #~ endif + srgw0_db_password: + file: "{{ secret('srgw0_db_password.txt') }}" + #~ if config["topology"]["nb_gnb"] > 2 + srgw1_db_password: + file: "{{ secret('srgw1_db_password.txt') }}" + #~ endif +#~ endif +#~ if "nextmn-srv6" in config["topology"]["dataplane"] +volumes: + r0_db_volume: + r1_db_volume: + #~ if config["topology"]["nb_edges"] > 2 + r2_db_volume: + #~ endif + srgw0_db_volume: + #~ if config["topology"]["nb_gnb"] > 2 + srgw1_db_volume: + #~ endif +#~ endif + +#~ if config["topology"]["controlplane"] == "nextmn-lite" or "nextmn-srv6" in config["topology"]["dataplane"] +configs: + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + uel1: + content: | + control: + uri: "http://[{{ ipv6('uel1', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('uel1', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel1', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" + gnbs: + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + #~ if config["topology"]["ran"]["handover"] + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + #~ if config["topology"]["nb_gnb"] > 2 + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" + #~ endif + #~ endif + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + dnn: "sr4mec-0" + logger: + level: "{{ log_level() }}" + #~ if config["topology"]["nb_ue"] > 1 + uel2: + content: | + control: + uri: "http://[{{ ipv6('uel2', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('uel2', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel2', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" + gnbs: + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + #~ if config["topology"]["ran"]["handover"] + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + #~ if config["topology"]["nb_gnb"] > 2 + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" + #~ endif + #~ endif + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + dnn: "sr4mec-1" + logger: + level: "{{ log_level() }}" + #~ endif + #~ endif + #~ if "free5gc" in config["topology"]["dataplane"] + uel3: + content: | + control: + uri: "http://[{{ ipv6('uel3', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('uel3', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel3', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" + gnbs: + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + #~ if config["topology"]["ran"]["handover"] + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + #~ if config["topology"]["nb_gnb"] > 2 + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" + #~ endif + #~ endif + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + dnn: "f5gc-0" + logger: + level: "{{ log_level() }}" + #~ if config["topology"]["nb_ue"] > 1 + uel4: + content: | + control: + uri: "http://[{{ ipv6('uel4', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('uel4', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel4', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" + gnbs: + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + dnn: "f5gc-0" + logger: + level: "{{ log_level() }}" + #~ endif #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - upfi1-nmn: - condition: service_started - #~ if config["topology"]["nb_gnb"] > 2 - upfi2-nmn: - condition: service_started + uel5: + content: | + control: + uri: "http://[{{ ipv6('uel5', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('uel5', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel5', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" + gnbs: + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + #~ if config["topology"]["ran"]["handover"] + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + #~ if config["topology"]["nb_gnb"] > 2 + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" + #~ endif #~ endif - upfa1-nmn: - condition: service_started - upfa2-nmn: - condition: service_started - #~ if config["topology"]["nb_gnb"] > 2 - upfa3-nmn: - condition: service_started + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + dnn: "nmn-upf-0" + logger: + level: "{{ log_level() }}" + #~ if config["topology"]["nb_ue"] > 1 + uel6: + content: | + control: + uri: "http://[{{ ipv6('uel6', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('uel6', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel6', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" + gnbs: + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + dnn: "nmn-upf-0" + logger: + level: "{{ log_level() }}" #~ endif #~ endif - environment: - GIN_MODE: "release" - N4: "{{ ipv4('cp-lite', 'control') }}" - HTTP_ADDRESS: "{{ ipv6('cp-lite', 'control') }}" - HTTP_PORT: "8080" - SLICES: |- + gnbl1: + content: | + control: + uri: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('gnbl1', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('gnbl1', 'ran') }}]:1234" + one-way-delays: + control: "7ms" + data: "7ms" + cp: + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" + one-way-delay: "9ms" + gtp: "{{ ipv4('gnbl1', 'dataplane') }}" + logger: + level: {{ log_level() }} + docker-setup: + routes: + - prefix: "{{ ipv4('srgw0', 'srgw0') }}/32" + gateway: "{{ ipv4('srgw0', 'dataplane') }}" + gnbl2: + content: | + control: + uri: "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('gnbl2', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('gnbl2', 'ran') }}]:1234" + one-way-delays: + control: "7ms" + data: "7ms" + cp: + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" + one-way-delay: "9ms" + gtp: "{{ ipv4('gnbl2', 'dataplane') }}" + logger: + level: {{ log_level() }} + docker-setup: + routes: + - prefix: "{{ ipv4('srgw0', 'srgw0') }}/32" + gateway: "{{ ipv4('srgw0', 'dataplane') }}" + + #~ if config["topology"]["nb_gnb"] > 2 + gnbl3: + content: | + control: + uri: "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('gnbl3', 'rest') }}]:8080" + ran: + bind-addr: "[{{ ipv6('gnbl3', 'ran') }}]:1234" + one-way-delays: + control: "7ms" + data: "7ms" + cp: + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" + one-way-delay: "9ms" + gtp: "{{ ipv4('gnbl3', 'dataplane') }}" + logger: + level: {{ log_level() }} + docker-setup: + routes: + - prefix: "{{ ipv4('srgw1', 'srgw1') }}/32" + gateway: "{{ ipv4('srgw1', 'dataplane') }}" + #~ endif + cp-lite: + content: | + control: + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('cp-lite', 'rest') }}]:8080" + pfcp: "{{ ipv4('cp-lite', 'control') }}" + emulation: + handover-notify: "200ms" + #~ if config["topology"]["ran"]["handover"] and "nextmn-srv6" in config["topology"]["dataplane"] + n4-sr4mec: + enabled: true + control: + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('cp-lite', 'rest') }}]:8080" + slices: + sr4mec-0: # initial link: central network + migration-a-posteriori: {{ migration_a_posteriori() }} + migration-delay: "3s" + service: "{{ ipv4('s', 'service') }}" + ps-establishment: + srgw: "http://[{{ ipv6('srgw0', 'rest') }}]:8080" + srgw-gtp4: "{{ ipv4('srgw0', 'srgw0') }}" + anchor: "http://[{{ ipv6('r0', 'rest') }}]:8080" + uplink-segments: + - "{{ ipv6('end-dx4', 'r0') }}" + downlink-segments: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" + handover-migration: + srgw: "http://[{{ ipv6('srgw1', 'rest') }}]:8080" + srgw-gtp4: "{{ ipv4('srgw1', 'srgw1') }}" + anchor: "http://[{{ ipv6('r2', 'rest') }}]:8080" + uplink-segments: + - "{{ ipv6('end-dx4', 'r2') }}" + downlink-segments: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" + sr4mec-1: # initial link: edge 1 + migration-a-posteriori: {{ migration_a_posteriori() }} + migration-delay: "3s" + service: "{{ ipv4('s', 'service') }}" + ps-establishment: + srgw: "http://[{{ ipv6('srgw0', 'rest') }}]:8080" + srgw-gtp4: "{{ ipv4('srgw0', 'srgw0') }}" + anchor: "http://[{{ ipv6('r1', 'rest') }}]:8080" + uplink-segments: + - "{{ ipv6('end-dx4', 'r1') }}" + downlink-segments: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" + handover-migration: + srgw: "http://[{{ ipv6('srgw1', 'rest') }}]:8080" + srgw-gtp4: "{{ ipv4('srgw1', 'srgw1') }}" + anchor: "http://[{{ ipv6('r2', 'rest') }}]:8080" + uplink-segments: + - "{{ ipv6('end-dx4', 'r2') }}" + downlink-segments: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" + #~ endif + slices: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: - pool: "{{ ipv4_subnet('slice0') }}" + sr4mec-0: + pool: "{{ ipv4_subnet('slice-sr4mec-0') }}" + upfs: + - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('srgw0', 'srgw0') }}" + #~ if config["topology"]["nb_gnb"] > 2 + - type: "N3" + addr: "{{ ipv4('srgw1', 'srgw1') }}" + #~ endif + sr4mec-1: + pool: "{{ ipv4_subnet('slice-sr4mec-1') }}" upfs: - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" interfaces: @@ -2093,8 +2093,8 @@ services: #~ endif #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - free5gc: - pool: "{{ ipv4_subnet('slice1') }}" + f5gc-0: + pool: "{{ ipv4_subnet('slice-f5gc-0') }}" upfs: - node-id: "{{ ipv4('upfi1-f5gc', 'control') }}" interfaces: @@ -2122,8 +2122,8 @@ services: #~ endif #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - nextmn-upf: - pool: "{{ ipv4_subnet('slice2') }}" + nmn-upf-0: + pool: "{{ ipv4_subnet('slice-nmn-upf-0') }}" upfs: - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" interfaces: @@ -2143,6 +2143,12 @@ services: - type: "N9" addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" #~ endif + #~ if config["topology"]["nb_edges"] > 1 + - node-id: "{{ ipv4('upfa2-nmn', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa2-nmn', 'dataplane') }}" + #~ endif #~ if config["topology"]["nb_edges"] > 2 - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" interfaces: @@ -2150,108 +2156,303 @@ services: addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" #~ endif #~ endif - AREAS: |- + areas: # RAN areas area1: gnbs: - - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" #~ if config["topology"]["nb_gnb"] > 1 - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" #~ endif paths: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: + sr4mec-0: + - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" + interface-addr: "{{ ipv4('srgw0', 'srgw0') }}" + sr4mec-1: - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" interface-addr: "{{ ipv4('srgw0', 'srgw0') }}" #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - free5gc: + f5gc-0: - node-id: "{{ ipv4('upfi1-f5gc', 'control') }}" interface-addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" - node-id: "{{ ipv4('upfa1-f5gc', 'control') }}" interface-addr: "{{ ipv4('upfa1-f5gc', 'dataplane') }}" #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - nextmn-upf: + nmn-upf-0: - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" interface-addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" + #~ if config["topology"]["ran"]["handover"] + - node-id: "{{ ipv4('upfa2-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfa2-nmn', 'dataplane') }}" + #~ else - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" interface-addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" + #~ endif #~ endif - #~ if (config["topology"]["nb_gnb"] > 2) and (config["topology"]["nb_edges"] > 2) + #~ if (config["topology"]["nb_gnb"] > 2) area2: gnbs: - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" paths: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: + sr4mec-0: + - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" + interface-addr: "{{ ipv4('srgw1', 'srgw1') }}" + sr4mec-1: - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" interface-addr: "{{ ipv4('srgw1', 'srgw1') }}" #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - free5gc: + f5gc-0: - node-id: "{{ ipv4('upfi2-f5gc', 'control') }}" interface-addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" - - node-id: "{{ ipv4('upfa3-f5gc', 'control') }}" - interface-addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" + - node-id: "{{ ipv4('upfa2-f5gc', 'control') }}" + interface-addr: "{{ ipv4('upfa2-f5gc', 'dataplane') }}" #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - nextmn-upf: + nmn-upf-0: - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" interface-addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" - - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" - interface-addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" + #~ if config["topology"]["ran"]["handover"] + - node-id: "{{ ipv4('upfa2-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfa2-nmn', 'dataplane') }}" + #~ else + - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" + #~ endif #~ endif #~ endif - LOG_LEVEL: "{{ log_level() }}" - networks: + logger: + level: "{{ log_level() }}" + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + srv6-ctrl: + content: | + pfcp-address: "{{ ipv4('srv6-ctrl', 'control') }}" control: - ipv4_address: "{{ ipv4('cp-lite', 'control') }}" - ipv6_address: "{{ ipv6('cp-lite', 'control') }}" - -#~ endif - -#~ if (config["topology"]["controlplane"] == "free5gc") or ("nextmn-srv6" in config["topology"]["dataplane"]) -secrets: -#~ endif -#~ if config["topology"]["controlplane"] == "free5gc" - {{ openssl_root_s() }} - {{ openssl_s('amf', 'sbi') }} - {{ openssl_s('ausf', 'sbi') }} - {{ openssl_s('chf', 'sbi') }} - {{ openssl_s('nrf', 'sbi') }} - {{ openssl_s('nssf', 'sbi') }} - {{ openssl_s('pcf', 'sbi') }} - {{ openssl_s('smf', 'sbi') }} - {{ openssl_s('udm', 'sbi') }} - {{ openssl_s('udr', 'sbi') }} -#~ endif -#~ if "nextmn-srv6" in config["topology"]["dataplane"] - r0_db_password: - file: "{{ secret('r0_db_password.txt') }}" - r1_db_password: - file: "{{ secret('r1_db_password.txt') }}" - #~ if config["topology"]["nb_edges"] > 2 - r2_db_password: - file: "{{ secret('r2_db_password.txt') }}" - #~ endif - srgw0_db_password: - file: "{{ secret('srgw0_db_password.txt') }}" - #~ if config["topology"]["nb_gnb"] > 2 - srgw1_db_password: - file: "{{ secret('srgw1_db_password.txt') }}" - #~ endif -#~ endif - -#~ if "nextmn-srv6" in config["topology"]["dataplane"] -volumes: - r0_db_volume: - r1_db_volume: - #~ if config["topology"]["nb_edges"] > 2 - r2_db_volume: + uri: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" + logger: + level: "{{ log_level() }}" + uplink: + - control-uri: "http://[{{ ipv6('srgw0', 'rest') }}]:8080" + enabled: true + service: "{{ ipv4('s', 'service') }}" + area: + #~ if config["topology"]["controlplane"] == "free5gc" + - "{{ ipv4('gnb1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnb2', 'dataplane') }}/32" + #~ endif + #~ endif + #~ if config["topology"]["controlplane"] == "nextmn-lite" + - "{{ ipv4('gnbl1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnbl2', 'dataplane') }}/32" + #~ endif + #~ endif + segments-list: + - "{{ ipv6('end-dx4', 'r0') }}" + #~ if config["topology"]["nb_edges"] > 1 + - control-uri: "http://[{{ ipv6('srgw0', 'rest') }}]:8080" + enabled: false + service: "{{ ipv4('s', 'service') }}" + area: + #~ if config["topology"]["controlplane"] == "free5gc" + - "{{ ipv4('gnb1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnb2', 'dataplane') }}/32" + #~ endif + #~ endif + #~ if config["topology"]["controlplane"] == "nextmn-lite" + - "{{ ipv4('gnbl1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnbl2', 'dataplane') }}/32" + #~ endif + #~ endif + segments-list: + - "{{ ipv6('end-dx4', 'r1') }}" + #~ if (config["topology"]["nb_gnb"] > 2) and (config["topology"]["nb_edges"] > 2) and (config["topology"]["controlplane"] == "nextmn-lite") + - control-uri: "http://[{{ ipv6('srgw1', 'rest') }}]:8080" + enabled: true + service: "{{ ipv4('s', 'service') }}" + area: + - "{{ ipv4('gnbl3', 'dataplane') }}/32" + segments-list: + - "{{ ipv6('end-dx4', 'r2') }}" + #~ endif + #~ endif + downlink: + - control-uri: "http://[{{ ipv6('r0', 'rest') }}]:8080" + enabled: true + area: + #~ if config["topology"]["controlplane"] == "free5gc" + - "{{ ipv4('gnb1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnb2', 'dataplane') }}/32" + #~ endif + #~ endif + #~ if config["topology"]["controlplane"] == "nextmn-lite" + - "{{ ipv4('gnbl1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnbl2', 'dataplane') }}/32" + #~ endif + #~ endif + srgw-gtp4: "{{ ipv4('srgw0', 'srgw0') }}" + segments-list: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" + #~ if config["topology"]["nb_edges"] > 1 + - control-uri: "http://[{{ ipv6('r1', 'rest') }}]:8080" + enabled: true + area: + #~ if config["topology"]["controlplane"] == "free5gc" + - "{{ ipv4('gnb1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnb2', 'dataplane') }}/32" + #~ endif + #~ endif + #~ if config["topology"]["controlplane"] == "nextmn-lite" + - "{{ ipv4('gnbl1', 'dataplane') }}/32" + #~ if config["topology"]["nb_gnb"] > 1 + - "{{ ipv4('gnbl2', 'dataplane') }}/32" + #~ endif + #~ endif + srgw-gtp4: "{{ ipv4('srgw0', 'srgw0') }}" + segments-list: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" + #~ endif + #~ if config["topology"]["nb_edges"] > 2 + - control-uri: "http://[{{ ipv6('r2', 'rest') }}]:8080" + enabled: true + area: + - "{{ ipv4('gnbl3', 'dataplane') }}/32" + srgw-gtp4: "{{ ipv4('srgw1', 'srgw1') }}" + segments-list: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" + #~ endif #~ endif - srgw0_db_volume: - #~ if config["topology"]["nb_gnb"] > 2 - srgw1_db_volume: + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + srgw0: + content: | + hooks: + pre-init-hook: remove-default-routes.sh + post-init-hook: routes-to-nei.sh + control: + uri: "http://[{{ ipv6('srgw0', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('srgw0', 'rest') }}]:8080" + controller-uri: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" + backbone-ip: "{{ ipv6('srgw0', 'dataplane') }}" + gtp4-headend-prefix: "{{ ipv4('srgw0', 'srgw0') }}/32" + headends: + - name: "srgw0 uplink (controlled)" + to: "{{ ipv4('srgw0', 'srgw0') }}/32" + provider: "NextMN-Ctrl" + behavior: "H.M.GTP4.D" + source-address-prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" + locator: "{{ ipv6_subnet('srgw0') }}" + endpoints: + - prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" + provider: "NextMN" + behavior: "End.M.GTP4.E" + logger: + level: "{{ log_level() }}" + srgw1: + content: | + hooks: + pre-init-hook: remove-default-routes.sh + post-init-hook: routes-to-nei.sh + control: + uri: "http://[{{ ipv6('srgw1', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('srgw1', 'rest') }}]:8080" + controller-uri: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" + backbone-ip: "{{ ipv6('srgw1', 'dataplane') }}" + gtp4-headend-prefix: "{{ ipv4('srgw1', 'srgw1') }}/32" + headends: + - name: "srgw1 uplink (controlled)" + to: "{{ ipv4('srgw1', 'srgw1') }}/32" + provider: "NextMN-Ctrl" + behavior: "H.M.GTP4.D" + source-address-prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" + locator: "{{ ipv6_subnet('srgw1') }}" + endpoints: + - prefix: "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" + provider: "NextMN" + behavior: "End.M.GTP4.E" + logger: + level: "{{ log_level() }}" + r0: + content: | + hooks: + pre-init-hook: remove-default-routes.sh + post-init-hook: routes-to-nei.sh + control: + uri: "http://[{{ ipv6('r0', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('r0', 'rest') }}]:8080" + controller-uri: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" + locator: "{{ ipv6_subnet('r0') }}" + backbone-ip: "{{ ipv6('r0', 'dataplane') }}" + ipv4-headend-prefix: "{{ ipv4_subnet('slice-sr4mec') }}" + headends: + - name: "downlink (controlled)" + to: "{{ ipv4_subnet('slice-sr4mec') }}" + provider: "NextMN-ctrl" + behavior: "H.Encaps" + source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r0') }}" + endpoints: + - prefix: "{{ ipv6_prefix('end-dx4', 'r0') }}" + provider: "Linux" + behavior: "End.DX4" + logger: + level: "{{ log_level() }}" + r1: + content: | + hooks: + pre-init-hook: remove-default-routes.sh + post-init-hook: routes-to-nei.sh + control: + uri: "http://[{{ ipv6('r1', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('r1', 'rest') }}]:8080" + controller-uri: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" + locator: "{{ ipv6_subnet('r1') }}" + backbone-ip: "{{ ipv6('r1', 'dataplane') }}" + ipv4-headend-prefix: "{{ ipv4_subnet('slice-sr4mec') }}" + headends: + - name: "downlink (controlled)" + to: "{{ ipv4_subnet('slice-sr4mec') }}" + provider: "NextMN-ctrl" + behavior: "H.Encaps" + source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r1') }}" + endpoints: + - prefix: "{{ ipv6_prefix('end-dx4', 'r1') }}" + provider: "Linux" + behavior: "End.DX4" + logger: + level: "{{ log_level() }}" + r2: + content: | + hooks: + pre-init-hook: remove-default-routes.sh + post-init-hook: routes-to-nei.sh + control: + uri: "http://[{{ ipv6('r2', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('r2', 'rest') }}]:8080" + controller-uri: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" + locator: "{{ ipv6_subnet('r2') }}" + backbone-ip: "{{ ipv6('r2', 'dataplane') }}" + ipv4-headend-prefix: "{{ ipv4_subnet('slice-sr4mec') }}" + headends: + - name: "downlink (controlled)" + to: "{{ ipv4_subnet('slice-sr4mec') }}" + provider: "NextMN-ctrl" + behavior: "H.Encaps" + source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r2') }}" + endpoints: + - prefix: "{{ ipv6_prefix('end-dx4', 'r2') }}" + provider: "Linux" + behavior: "End.DX4" + logger: + level: "{{ log_level() }}" #~ endif #~ endif @@ -2361,3 +2562,21 @@ networks: - subnet: fd00:0:0:0:4::/80 ip_range: fd00:0:0:0:4::/81 gateway: fd00::4:8000:0:1 +#~ if "nextmn-srv6" in config["topology"]["dataplane"] or config["topology"]["controlplane"] == "nextmn-lite" + rest: + name: rest + enable_ipv6: true + driver: bridge + driver_opts: + com.docker.network.container_iface_prefix: rest- + com.docker.network.bridge.name: rest + ipam: + driver: default + config: + - subnet: 10.1.7.0/24 + ip_range: 10.1.7.0/25 + gateway: 10.1.7.254 + - subnet: fd00:0:0:0:5::/80 + ip_range: fd00:0:0:0:5::/81 + gateway: fd00::5:8000:0:1 +#~ endif diff --git a/templates/images-list.yaml b/templates/images-list.yaml index cfea202..003c0c8 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -38,20 +38,40 @@ services: image: docker.io/louisroyer/dev-nextmn-upf build: https://github.com/louisroyer-docker/nextmn.git#master:upf nextmn-srv6: - image: docker.io/louisroyer/dev-nextmn-srv6 - build: https://github.com/louisroyer-docker/nextmn.git#master:srv6 + image: ghcr.io/nextmn/srv6:fix + build: + context: https://github.com/nextmn/srv6.git#cf584fe0b510b5901b14f686b9fd685c541abfaf + args: + SOURCE_DATE_EPOCH: 0 + BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-srv6-ctrl: - image: docker.io/louisroyer/dev-nextmn-srv6-ctrl - build: https://github.com/louisroyer-docker/nextmn.git#master:srv6-ctrl + image: ghcr.io/nextmn/srv6-ctrl:delay + build: + context: https://github.com/nextmn/srv6-ctrl.git#ad4171e43bdefaed14a893db90826e686870a1f8 + args: + SOURCE_DATE_EPOCH: 0 + BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-ue-lite: - image: docker.io/louisroyer/dev-nextmn-ue-lite - build: https://github.com/louisroyer-docker/nextmn.git#master:ue-lite + image: ghcr.io/nextmn/ue-lite:delay + build: + context: https://github.com/nextmn/ue-lite.git#e9a33156fbe936e58c2fb4902454ad18bba82951 + args: + SOURCE_DATE_EPOCH: 0 + BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-gnb-lite: - image: docker.io/louisroyer/dev-nextmn-gnb-lite - build: https://github.com/louisroyer-docker/nextmn.git#master:gnb-lite + image: ghcr.io/nextmn/gnb-lite:delay + build: + context: https://github.com/nextmn/gnb-lite.git#383258ef553ef8ee1020372be3137c7884fe970e + args: + SOURCE_DATE_EPOCH: 0 + BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-cp-lite: - image: docker.io/louisroyer/dev-nextmn-cp-lite - build: https://github.com/louisroyer-docker/nextmn.git#master:cp-lite + image: ghcr.io/nextmn/cp-lite:delay + build: + context: https://github.com/nextmn/cp-lite.git#edc814c9cfe66b17a5c756a0441129028254d6fc + args: + SOURCE_DATE_EPOCH: 0 + BUILDKIT_CONTEXT_KEEP_GIT_DIR: true amf: image: docker.io/louisroyer/dev-free5gc-amf build: https://github.com/louisroyer-docker/free5gc.git#master:amf diff --git a/templates/nextmn/routes-to-nei.sh b/templates/nextmn/routes-to-nei.sh index 0eb6e46..4506d6e 100755 --- a/templates/nextmn/routes-to-nei.sh +++ b/templates/nextmn/routes-to-nei.sh @@ -1,22 +1,19 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # Copyright Louis Royer and the NextMN contributors. All rights reserved. # Use of this source code is governed by a MIT-style license that can be # found in the LICENSE file. # SPDX-License-Identifier: MIT set -e -IFS=$' ' -read -r -a NEI_NH_ARR <<< "${NEI_NH}" - -read -r -a NEI_ADDR_ARR <<< "${NEI_ADDR}" - -if [ ${#NEI_NH_ARR[@]} -ne ${#NEI_ADDR_ARR[@]} ]; then - exit 1 -fi - -i=0 -while [ $i -le $((${#NEI_NH_ARR[@]} - 1)) ]; do - ip route replace "${NEI_ADDR_ARR[$i]}" via "${NEI_NH_ARR[$i]}" - i=$((i+1)) +while + IFS=' ' read -r current_addr NEI_ADDR <