From e8d28f493470c9169111d82badc60963f872f0fe Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Thu, 2 Apr 2026 16:11:34 +0200 Subject: [PATCH 01/22] Update nextmn-lite to use delay --- scripts/jinja/customize.py | 18 ++- templates/compose.yaml.j2 | 241 ++++++++++++++++++++++--------------- templates/images-list.yaml | 8 +- 3 files changed, 164 insertions(+), 103 deletions(-) diff --git a/scripts/jinja/customize.py b/scripts/jinja/customize.py index 932e383..212610a 100644 --- a/scripts/jinja/customize.py +++ b/scripts/jinja/customize.py @@ -413,11 +413,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 +428,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 @@ -492,7 +494,13 @@ def container(name: str, image: str, _context: _Context, enable_ipv6: typing.Opt "image": image, } if image_build: - containers[name]['build'] = image_build + containers[name]['build'] = { + "context": image_build, + "args": { + "SOURCE_DATE_EPOCH": 0, + "BUILDKIT_CONTEXT_KEEP_GIT_DIR": True, + } + } if command: containers[name]['command'] = command elif command is None: diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index 22cc7e1..37b533f 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1748,7 +1748,7 @@ 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', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} depends_on: gnbl1: condition: service_started @@ -1760,24 +1760,9 @@ services: condition: service_started #~ 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: + - source: "uel1" + target: "/etc/xdg/nextmn-ue-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('uel1', 'ran') }}" @@ -1787,22 +1772,13 @@ services: ipv6_address: "{{ ipv6('uel1', 'control') }}" #~ 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', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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('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() }}" + configs: + - source: "uel2" + target: "/etc/xdg/nextmn-ue-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('uel2', 'ran') }}" @@ -1813,7 +1789,7 @@ services: #~ 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', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} depends_on: gnbl1: condition: service_started @@ -1825,24 +1801,9 @@ services: condition: service_started #~ 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: + - source: "uel3" + target: "/etc/xdg/nextmn-ue-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('uel3', 'ran') }}" @@ -1852,22 +1813,13 @@ services: ipv6_address: "{{ ipv6('uel3', 'control') }}" #~ 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', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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() }}" + configs: + - source: "uel4" + target: "/etc/xdg/nextmn-ue-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('uel4', 'ran') }}" @@ -1878,7 +1830,7 @@ services: #~ 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', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} depends_on: gnbl1: condition: service_started @@ -1890,24 +1842,9 @@ services: condition: service_started #~ 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: + - source: "uel5" + target: "/etc/xdg/nextmn-ue-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('uel5', 'ran') }}" @@ -1917,22 +1854,13 @@ services: ipv6_address: "{{ ipv6('uel5', 'control') }}" #~ 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', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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() }}" + configs: + - source: "uel6" + target: "/etc/xdg/nextmn-ue-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('uel6', 'ran') }}" @@ -2255,6 +2183,127 @@ volumes: #~ endif #~ endif +configs: +#~ if config["topology"]["controlplane"] == "nextmn-lite" + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + uel1: + content: | + control: + uri: "http://[{{ ipv6('uel1', 'control') }}]:8080" + bind-addr: "[{{ ipv6('uel1', 'control') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel1', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" + 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" + logger: + level: "{{ log_level() }}" + #~ if config["topology"]["nb_ue"] > 1 + uel2: + content: | + control: + uri: "http://[{{ ipv6('uel2', 'control') }}]:8080" + bind-addr: "[{{ ipv6('uel2', 'control') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel2', 'ran') }}]:1234" + gnbs: + - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + dnn: "srv6" + logger: + level: "{{ log_level() }}" + #~ endif + #~ endif + #~ if "free5gc" in config["topology"]["dataplane"] + uel3: + content: | + control: + uri: "http://[{{ ipv6('uel3', 'control') }}]:8080" + bind-addr: "[{{ ipv6('uel3', 'control') }}]: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" + logger: + level: "{{ log_level() }}" + #~ if config["topology"]["nb_ue"] > 1 + uel4: + content: | + control: + uri: "http://[{{ ipv6('uel4', 'control') }}]:8080" + bind-addr: "[{{ ipv6('uel4', 'control') }}]:8080" + ran: + bind-addr: "[{{ ipv6('uel4', 'ran') }}]:1234" + gnbs: + - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + pdu-sessions: + - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + dnn: "free5gc" + logger: + level: "{{ log_level() }}" + #~ endif + #~ endif + #~ if "nextmn-upf" in config["topology"]["dataplane"] + uel5: + content: | + control: + uri: "http://[{{ ipv6('uel5', 'control') }}]:8080" + bind-addr: "[{{ ipv6('uel5', 'control') }}]: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" + logger: + level: "{{ log_level() }}" + #~ if config["topology"]["nb_ue"] > 1 + uel6: + content: | + control: + uri: "http://[{{ ipv6('uel6', 'control') }}]:8080" + bind-addr: "[{{ ipv6('uel6', 'control') }}]: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" + logger: + level: "{{ log_level() }}" + #~ endif + #~ endif +#~ endif + networks: ran: name: ran diff --git a/templates/images-list.yaml b/templates/images-list.yaml index cfea202..33beadd 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -44,8 +44,12 @@ services: image: docker.io/louisroyer/dev-nextmn-srv6-ctrl build: https://github.com/louisroyer-docker/nextmn.git#master:srv6-ctrl 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#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0 + 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 From 9eb6b00c2932862172b78737b07b26213bd467d4 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Wed, 8 Apr 2026 20:09:01 +0200 Subject: [PATCH 02/22] Update gnb-lite and cp-lite --- templates/compose.yaml.j2 | 396 +++++++++++++++++++++---------------- templates/images-list.yaml | 16 +- 2 files changed, 239 insertions(+), 173 deletions(-) diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index 37b533f..2fe999c 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1871,21 +1871,13 @@ services: #~ 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', image='ghcr.io/nextmn/gnb-lite', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', 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') }} + configs: + - source: "gnbl1" + target: "/etc/xdg/nextmn-gnb-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('gnbl1', 'ran') }}" @@ -1896,21 +1888,13 @@ services: 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', image='ghcr.io/nextmn/gnb-lite', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', 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') }} + configs: + - source: "gnbl2" + target: "/etc/xdg/nextmn-gnb-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('gnbl2', 'ran') }}" @@ -1922,21 +1906,13 @@ services: 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', image='ghcr.io/nextmn/gnb-lite', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', 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') }} + configs: + - source: "gnbl3" + target: "/etc/xdg/nextmn-gnb-lite/config.yaml" networks: ran: ipv4_address: "{{ ipv4('gnbl3', 'ran') }}" @@ -1948,7 +1924,7 @@ services: 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', image='ghcr.io/nextmn/cp-lite', image_build='https://github.com/nextmn/cp-lite.git#0f2e28bc343f4784363c53911fe82912b703580d', enable_ipv6=True, debug='allow', debug_volume=False, cap_net_admin=True) }} depends_on: #~ if "nextmn-srv6" in config["topology"]["dataplane"] srv6-ctrl: @@ -1983,7 +1959,6 @@ services: upfa3-f5gc: condition: service_started #~ endif - #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] upfi1-nmn: @@ -2001,136 +1976,9 @@ services: condition: service_started #~ endif #~ endif - environment: - GIN_MODE: "release" - N4: "{{ ipv4('cp-lite', 'control') }}" - HTTP_ADDRESS: "{{ ipv6('cp-lite', 'control') }}" - HTTP_PORT: "8080" - SLICES: |- - #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: - pool: "{{ ipv4_subnet('slice0') }}" - 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 - #~ endif - #~ if "free5gc" in config["topology"]["dataplane"] - free5gc: - pool: "{{ ipv4_subnet('slice1') }}" - upfs: - - node-id: "{{ ipv4('upfi1-f5gc', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" - - node-id: "{{ ipv4('upfa1-f5gc', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa1-f5gc', 'dataplane') }}" - #~ if config["topology"]["nb_gnb"] > 2 - - node-id: "{{ ipv4('upfi2-f5gc', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" - #~ endif - #~ if config["topology"]["nb_edges"] > 2 - - node-id: "{{ ipv4('upfa3-f5gc', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" - #~ endif - #~ endif - #~ if "nextmn-upf" in config["topology"]["dataplane"] - nextmn-upf: - pool: "{{ ipv4_subnet('slice2') }}" - upfs: - - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" - - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" - #~ if config["topology"]["nb_gnb"] > 2 - - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" - #~ endif - #~ if config["topology"]["nb_edges"] > 2 - - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" - #~ endif - #~ endif - AREAS: |- - area1: - gnbs: - - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - #~ if config["topology"]["nb_gnb"] > 1 - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - #~ endif - paths: - #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: - - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" - interface-addr: "{{ ipv4('srgw0', 'srgw0') }}" - #~ endif - #~ if "free5gc" in config["topology"]["dataplane"] - free5gc: - - 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: - - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" - interface-addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" - - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" - interface-addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" - #~ endif - #~ if (config["topology"]["nb_gnb"] > 2) and (config["topology"]["nb_edges"] > 2) - area2: - gnbs: - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" - paths: - #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: - - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" - interface-addr: "{{ ipv4('srgw1', 'srgw1') }}" - #~ endif - #~ if "free5gc" in config["topology"]["dataplane"] - free5gc: - - node-id: "{{ ipv4('upfi2-f5gc', 'control') }}" - interface-addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" - - node-id: "{{ ipv4('upfa3-f5gc', 'control') }}" - interface-addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" - #~ endif - #~ if "nextmn-upf" in config["topology"]["dataplane"] - nextmn-upf: - - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" - interface-addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" - - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" - interface-addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" - #~ endif - #~ endif - LOG_LEVEL: "{{ log_level() }}" + configs: + - source: "cp-lite" + target: "/etc/xdg/nextmn-cp-lite/config.yaml" networks: control: ipv4_address: "{{ ipv4('cp-lite', 'control') }}" @@ -2183,8 +2031,8 @@ volumes: #~ endif #~ endif -configs: #~ if config["topology"]["controlplane"] == "nextmn-lite" +configs: #~ if "nextmn-srv6" in config["topology"]["dataplane"] uel1: content: | @@ -2217,6 +2065,9 @@ configs: bind-addr: "[{{ ipv6('uel2', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('uel2', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" gnbs: - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" pdu-sessions: @@ -2234,6 +2085,9 @@ configs: bind-addr: "[{{ ipv6('uel3', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('uel3', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" gnbs: - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" #~ if config["topology"]["ran"]["handover"] @@ -2255,6 +2109,9 @@ configs: bind-addr: "[{{ ipv6('uel4', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('uel4', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" gnbs: - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" pdu-sessions: @@ -2272,6 +2129,9 @@ configs: bind-addr: "[{{ ipv6('uel5', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('uel5', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" gnbs: - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" #~ if config["topology"]["ran"]["handover"] @@ -2293,6 +2153,9 @@ configs: bind-addr: "[{{ ipv6('uel6', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('uel6', 'ran') }}]:1234" + one-way-delays: + control: "23ms" + data: "23ms" gnbs: - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" pdu-sessions: @@ -2302,6 +2165,201 @@ configs: level: "{{ log_level() }}" #~ endif #~ endif + gnbl1: + content: | + control: + uri: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" + bind-addr: "[{{ ipv6('gnbl1', 'control') }}]:8080" + ran: + bind-addr: "[{{ ipv6('gnbl1', 'ran') }}]:1234" + one-way-delays: + control: "7ms" + data: "7ms" + cp: + uri: "http://[{{ ipv6('cp-lite', 'control') }}]: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', 'control') }}]:8080" + bind-addr: "[{{ ipv6('gnbl2', 'control') }}]:8080" + ran: + bind-addr: "[{{ ipv6('gnbl2', 'ran') }}]:1234" + one-way-delays: + control: "7ms" + data: "7ms" + cp: + uri: "http://[{{ ipv6('cp-lite', 'control') }}]: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', 'control') }}]:8080" + bind-addr: "[{{ ipv6('gnbl3', 'control') }}]:8080" + ran: + bind-addr: "[{{ ipv6('gnbl3', 'ran') }}]:1234" + one-way-delays: + control: "7ms" + data: "7ms" + cp: + uri: "http://[{{ ipv6('cp-lite', 'control') }}]: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', 'control') }}]:8080" + bind-addr: "[{{ ipv6('cp-lite', 'control') }}]:8080" + pfcp: "{{ ipv4('cp-lite', 'control') }}" + slices: + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + srv6: + pool: "{{ ipv4_subnet('slice0') }}" + 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 + #~ endif + #~ if "free5gc" in config["topology"]["dataplane"] + free5gc: + pool: "{{ ipv4_subnet('slice1') }}" + upfs: + - node-id: "{{ ipv4('upfi1-f5gc', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" + - node-id: "{{ ipv4('upfa1-f5gc', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa1-f5gc', 'dataplane') }}" + #~ if config["topology"]["nb_gnb"] > 2 + - node-id: "{{ ipv4('upfi2-f5gc', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" + #~ endif + #~ if config["topology"]["nb_edges"] > 2 + - node-id: "{{ ipv4('upfa3-f5gc', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" + #~ endif + #~ endif + #~ if "nextmn-upf" in config["topology"]["dataplane"] + nextmn-upf: + pool: "{{ ipv4_subnet('slice2') }}" + upfs: + - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" + - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" + #~ if config["topology"]["nb_gnb"] > 2 + - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" + #~ endif + #~ if config["topology"]["nb_edges"] > 2 + - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" + #~ endif + #~ endif + areas: # RAN areas + area1: + gnbs: + - "http://[{{ ipv6('gnbl1', 'control') }}]:8080" + #~ if config["topology"]["nb_gnb"] > 1 + - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + #~ endif + paths: + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + srv6: + - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" + interface-addr: "{{ ipv4('srgw0', 'srgw0') }}" + #~ endif + #~ if "free5gc" in config["topology"]["dataplane"] + free5gc: + - 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: + - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" + - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" + #~ endif + #~ if (config["topology"]["nb_gnb"] > 2) and (config["topology"]["nb_edges"] > 2) + area2: + gnbs: + - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" + paths: + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + srv6: + - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" + interface-addr: "{{ ipv4('srgw1', 'srgw1') }}" + #~ endif + #~ if "free5gc" in config["topology"]["dataplane"] + free5gc: + - node-id: "{{ ipv4('upfi2-f5gc', 'control') }}" + interface-addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" + - node-id: "{{ ipv4('upfa3-f5gc', 'control') }}" + interface-addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" + #~ endif + #~ if "nextmn-upf" in config["topology"]["dataplane"] + nextmn-upf: + - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" + - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" + #~ endif + #~ endif + logger: + level: "{{ log_level() }}" #~ endif networks: diff --git a/templates/images-list.yaml b/templates/images-list.yaml index 33beadd..22c68c0 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -51,11 +51,19 @@ services: 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 + build: + context: https://github.com/nextmn/gnb-lite.git#1198cc0cb45d932acd982d78a9ee3a165f70b35 + 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 + build: + context: https://github.com/nextmn/cp-lite.git#0f2e28bc343f4784363c53911fe82912b703580d + 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 From 38a85bd7756bb300d764db6a8aa447c17a0ffd03 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 10 Apr 2026 22:19:42 +0200 Subject: [PATCH 03/22] Multiple slices for SR4MEC --- Makefile | 46 ++- default-config.yaml | 60 +++- doc | 2 +- scripts/show_ctrl.py | 12 +- scripts/thesis/binding.py | 58 +++ templates/compose.yaml.j2 | 701 +++++++++++++++++++++---------------- templates/images-list.yaml | 12 +- 7 files changed, 550 insertions(+), 341 deletions(-) create mode 100755 scripts/thesis/binding.py diff --git a/Makefile b/Makefile index fc1d0b0..ccddde9 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,8 @@ 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) @if [ $(BCONFIG) -ot default-config.yaml ]; then \ @@ -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,45 @@ 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/6] Configuring testbed with NextMN-SRv6" + @$(MAKE) set/controlplane/free5gc + @$(MAKE) set/dataplane/nextmn-srv6 + @$(MAKE) set/nb-ue/2 # TODO: configure different slices + @$(MAKE) set/nb-edges/1 + @$(MAKE) set/nb-gnb/1 + @$(MAKE) set/full-debug/false + @$(MAKE) set/log-level/info + @echo "[1/2] [2/6] Starting containers" + @$(MAKE) up + @echo "[1/2] [3/6] Adding latencies" + @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # central DN uplink + @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # central DN downlink + @docker exec ue1-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # radio uplink UE1 + @docker exec ue2-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # radio uplink UE2 + @docker exec gnb1-debug bash -c "tc qdisc add dev ran-0 root netem delay 7ms" # radio downlink gNB1 + @docker exec gnb1-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # gNB1 control plane latency + @docker exec amf-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # amf control plane latency + @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency + @docker exec r0-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency + @docker exec r1-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency + @docker exec srgw0-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency + @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] [4/6] Setting UE2 on edge 1" + @$(MAKE) ue/switch-edge/2 + @echo "[1/2] [5/6] [$$(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).txt $(BUILD_DIR)/thesis-plots/binding/$(DATE)/01_10_evalutation-plot-binding.pdf diff --git a/default-config.yaml b/default-config.yaml index f52dd8c..1499b2e 100644 --- a/default-config.yaml +++ b/default-config.yaml @@ -215,47 +215,69 @@ 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 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: - subnet: - ipv4_prefix: 10.2.1.0/26 - slice1-e1-static: + slice-sr4mec-1-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..6be243d 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit de57ca8dbd48214c32f6cf1c2b6db60077588c0b +Subproject commit 6be243d17539c32f29bf1a725e37093950c5ccbf 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/thesis/binding.py b/scripts/thesis/binding.py new file mode 100755 index 0000000..ea74e04 --- /dev/null +++ b/scripts/thesis/binding.py @@ -0,0 +1,58 @@ +#!/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 + +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 + _, axplt = plt.subplots() + axplt.set_xlabel('t (s)') + axplt.set_ylabel('RTT (ms)') + axplt.plot(res[1]['tsp'], res[1]['pqt'], color='tab:red', + label='$UE_2$') + axplt.plot(res[0]['tsp'], res[0]['pqt'], color='tab:blue', + label='$UE_1$') + axplt.autoscale_view() + axplt.legend() + plt.savefig(arguments.output) + 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/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index 2fe999c..bf06b00 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -30,7 +30,7 @@ services: sd: 000001 SESSIONS: |- - type: "IPv4" - apn: "srv6" + apn: "sr4mec-0" slice: sst: 1 sd: 000001 @@ -53,16 +53,16 @@ services: - "{{ ipv6('gnb2', 'ran') }}" 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 @@ -87,16 +87,16 @@ 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 @@ -116,16 +116,16 @@ 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 @@ -150,16 +150,16 @@ 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 @@ -179,16 +179,16 @@ 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 @@ -213,12 +213,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" @@ -259,12 +261,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" @@ -323,14 +327,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 TAC: "000001" secrets: @@ -546,7 +552,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 +568,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 +578,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 +598,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 +628,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 +649,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 +670,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 +693,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 +714,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 +735,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" @@ -833,19 +857,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"] @@ -895,14 +923,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 +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 AMF_LIST: |- - nfId: 469de254-2fe5-4ca0-8381-af3f500af77c @@ -946,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 TA_LIST: |- @@ -967,14 +1001,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 +1026,6 @@ services: homeSnssai: sst: 1 sd: 00001 - #~ endif - #~ if "free5gc" in config["topology"]["dataplane"] - servingSnssai: sst: 1 sd: 00002 @@ -999,13 +1033,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) }} @@ -1032,9 +1074,9 @@ services: HOOKS: |- pre-init-hook: remove-default-routes.sh post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('r0', 'control') }}" + HTTP_ADDRESS: "{{ ipv6('r0', 'rest') }}" HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" + CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" GIN_MODE: "release" BACKBONE_IP: "{{ ipv6('r0', 'dataplane') }}" LOCATOR: "{{ ipv6_subnet('r0') }}" @@ -1042,10 +1084,10 @@ services: - prefix: "{{ ipv6_prefix('end-dx4', 'r0') }}" provider: "Linux" behavior: "End.DX4" - IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice0') }}" + IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice-sr4mec') }}" HEADENDS: |- - name: "downlink (controlled)" - to: "{{ ipv4_subnet('slice0') }}" + to: "{{ ipv4_subnet('slice-sr4mec') }}" provider: "NextMN-ctrl" behavior: "H.Encaps" source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r0') }}" @@ -1055,8 +1097,8 @@ services: secrets: - r0_db_password networks: - control: - ipv6_address: "{{ ipv6('r0', 'control') }}" + rest: + ipv6_address: "{{ ipv6('r0', 'rest') }}" dataplane: ipv6_address: "{{ ipv6('r0', 'dataplane') }}" edge: @@ -1096,9 +1138,9 @@ services: HOOKS: |- pre-init-hook: remove-default-routes.sh post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('r1', 'control') }}" + HTTP_ADDRESS: "{{ ipv6('r1', 'rest') }}" HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" + CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" GIN_MODE: "release" BACKBONE_IP: "{{ ipv6('r1', 'dataplane') }}" LOCATOR: "{{ ipv6_subnet('r1') }}" @@ -1106,10 +1148,10 @@ services: - prefix: "{{ ipv6_prefix('end-dx4', 'r1') }}" provider: "Linux" behavior: "End.DX4" - IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice0') }}" + IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice-sr4mec') }}" HEADENDS: |- - name: "downlink (controlled)" - to: "{{ ipv4_subnet('slice0') }}" + to: "{{ ipv4_subnet('slice-sr4mec') }}" provider: "NextMN-ctrl" behavior: "H.Encaps" source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r1') }}" @@ -1119,8 +1161,8 @@ services: secrets: - r1_db_password networks: - control: - ipv6_address: "{{ ipv6('r1', 'control') }}" + rest: + ipv6_address: "{{ ipv6('r1', 'rest') }}" dataplane: ipv6_address: "{{ ipv6('r1', 'dataplane') }}" edge: @@ -1161,9 +1203,9 @@ services: HOOKS: |- pre-init-hook: remove-default-routes.sh post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('r2', 'control') }}" + HTTP_ADDRESS: "{{ ipv6('r2', 'rest') }}" HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" + CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" GIN_MODE: "release" BACKBONE_IP: "{{ ipv6('r2', 'dataplane') }}" LOCATOR: "{{ ipv6_subnet('r2') }}" @@ -1171,10 +1213,10 @@ services: - prefix: "{{ ipv6_prefix('end-dx4', 'r2') }}" provider: "Linux" behavior: "End.DX4" - IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice0') }}" + IPV4_HEADEND_PREFIX: "{{ ipv4_subnet('slice-sr4mec') }}" HEADENDS: |- - name: "downlink (controlled)" - to: "{{ ipv4_subnet('slice0') }}" + to: "{{ ipv4_subnet('slice-sr4mec') }}" provider: "NextMN-ctrl" behavior: "H.Encaps" source-address-prefix: "{{ ipv6_prefix('end-dx4', 'r2') }}" @@ -1226,9 +1268,9 @@ services: HOOKS: |- pre-init-hook: remove-default-routes.sh post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('srgw0', 'control') }}" + HTTP_ADDRESS: "{{ ipv6('srgw0', 'rest') }}" HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" + CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" GIN_MODE: "release" BACKBONE_IP: "{{ ipv6('srgw0', 'dataplane') }}" LOCATOR: "{{ ipv6_subnet('srgw0') }}" @@ -1249,9 +1291,8 @@ services: 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') }}" @@ -1291,9 +1332,9 @@ services: HOOKS: |- pre-init-hook: remove-default-routes.sh post-init-hook: routes-to-nei.sh - HTTP_ADDRESS: "{{ ipv6('srgw1', 'control') }}" + HTTP_ADDRESS: "{{ ipv6('srgw1', 'rest') }}" HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'control') }}]:8080" + CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]:8080" GIN_MODE: "release" BACKBONE_IP: "{{ ipv6('srgw1', 'dataplane') }}" LOCATOR: "{{ ipv6_subnet('srgw1') }}" @@ -1314,9 +1355,8 @@ services: 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') }}" @@ -1340,110 +1380,13 @@ services: 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', image='ghcr.io/nextmn/srv6-ctrl:delay', image_build='https://github.com/nextmn/srv6-ctrl.git#7ae0b833c8fb77194c24a2715c0c9a7d5fd8a379', debug='allow', restart='always') }} + configs: + - source: "srv6-ctrl" + target: "/etc/xdg/nextmn-srv6-ctrl/config.yaml" networks: + rest: + ipv6_address: "{{ ipv6('srv6-ctrl', 'rest') }}" control: ipv4_address: "{{ ipv4('srv6-ctrl', 'control') }}" ipv6_address: "{{ ipv6('srv6-ctrl', 'control') }}" @@ -1454,13 +1397,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" @@ -1484,13 +1427,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" @@ -1515,13 +1458,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" @@ -1553,8 +1496,8 @@ 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') }}" @@ -1572,8 +1515,8 @@ 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') }}" @@ -1589,8 +1532,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: @@ -1610,8 +1553,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: @@ -1632,8 +1575,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: @@ -1656,8 +1599,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: @@ -1674,8 +1617,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: @@ -1690,8 +1633,8 @@ services: - 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() }}" @@ -1710,8 +1653,8 @@ services: - 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() }}" @@ -1731,8 +1674,8 @@ services: - 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() }}" @@ -1871,7 +1814,7 @@ services: #~ endif #~ endif - {{ container_s(name='gnbl1', image='ghcr.io/nextmn/gnb-lite', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='gnbl1', image='ghcr.io/nextmn/gnb-lite:delay', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} depends_on: cp-lite: condition: service_started @@ -1888,7 +1831,7 @@ services: dataplane: ipv4_address: "{{ ipv4('gnbl1', 'dataplane') }}" - {{ container_s(name='gnbl2', image='ghcr.io/nextmn/gnb-lite', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='gnbl2', image='ghcr.io/nextmn/gnb-lite:delay', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} depends_on: cp-lite: condition: service_started @@ -1906,7 +1849,7 @@ services: ipv4_address: "{{ ipv4('gnbl2', 'dataplane') }}" #~ if config["topology"]["nb_gnb"] > 2 - {{ container_s(name='gnbl3', image='ghcr.io/nextmn/gnb-lite', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='gnbl3', image='ghcr.io/nextmn/gnb-lite:delay', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', enable_ipv6=True, debug='always', debug_volume=False, cap_net_admin=True) }} depends_on: cp-lite: condition: service_started @@ -1924,7 +1867,7 @@ services: ipv4_address: "{{ ipv4('gnbl3', 'dataplane') }}" #~ endif - {{ container_s(name='cp-lite', image='ghcr.io/nextmn/cp-lite', image_build='https://github.com/nextmn/cp-lite.git#0f2e28bc343f4784363c53911fe82912b703580d', enable_ipv6=True, debug='allow', debug_volume=False, cap_net_admin=True) }} + {{ container_s(name='cp-lite', image='ghcr.io/nextmn/cp-lite:delay', image_build='https://github.com/nextmn/cp-lite.git#0f2e28bc343f4784363c53911fe82912b703580d', enable_ipv6=True, debug='allow', debug_volume=False, cap_net_admin=True) }} depends_on: #~ if "nextmn-srv6" in config["topology"]["dataplane"] srv6-ctrl: @@ -2031,7 +1974,7 @@ volumes: #~ endif #~ endif -#~ if config["topology"]["controlplane"] == "nextmn-lite" +#~ if config["topology"]["controlplane"] == "nextmn-lite" or "nextmn-srv6" in config["topology"]["dataplane"] configs: #~ if "nextmn-srv6" in config["topology"]["dataplane"] uel1: @@ -2054,7 +1997,7 @@ configs: #~ endif pdu-sessions: - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - dnn: "srv6" + dnn: "sr4mec-0" logger: level: "{{ log_level() }}" #~ if config["topology"]["nb_ue"] > 1 @@ -2072,7 +2015,7 @@ configs: - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" pdu-sessions: - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - dnn: "srv6" + dnn: "sr4mec-1" logger: level: "{{ log_level() }}" #~ endif @@ -2098,7 +2041,7 @@ configs: #~ endif pdu-sessions: - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - dnn: "free5gc" + dnn: "f5gc-0" logger: level: "{{ log_level() }}" #~ if config["topology"]["nb_ue"] > 1 @@ -2116,7 +2059,7 @@ configs: - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" pdu-sessions: - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - dnn: "free5gc" + dnn: "f5gc-0" logger: level: "{{ log_level() }}" #~ endif @@ -2142,7 +2085,7 @@ configs: #~ endif pdu-sessions: - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - dnn: "nextmn-upf" + dnn: "nmn-upf-0" logger: level: "{{ log_level() }}" #~ if config["topology"]["nb_ue"] > 1 @@ -2160,7 +2103,7 @@ configs: - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" pdu-sessions: - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - dnn: "nextmn-upf" + dnn: "nmn-upf-0" logger: level: "{{ log_level() }}" #~ endif @@ -2236,74 +2179,85 @@ configs: pfcp: "{{ ipv4('cp-lite', 'control') }}" slices: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: - pool: "{{ ipv4_subnet('slice0') }}" - upfs: - - node-id: "{{ ipv4('srv6-ctrl', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('srgw0', 'srgw0') }}" + 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: + - type: "N3" + addr: "{{ ipv4('srgw0', 'srgw0') }}" #~ if config["topology"]["nb_gnb"] > 2 - - type: "N3" - addr: "{{ ipv4('srgw1', 'srgw1') }}" + - type: "N3" + addr: "{{ ipv4('srgw1', 'srgw1') }}" #~ endif #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - free5gc: - pool: "{{ ipv4_subnet('slice1') }}" - upfs: - - node-id: "{{ ipv4('upfi1-f5gc', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" - - node-id: "{{ ipv4('upfa1-f5gc', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa1-f5gc', 'dataplane') }}" + f5gc-0: + pool: "{{ ipv4_subnet('slice-f5gc-0') }}" + upfs: + - node-id: "{{ ipv4('upfi1-f5gc', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi1-f5gc', 'dataplane') }}" + - node-id: "{{ ipv4('upfa1-f5gc', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa1-f5gc', 'dataplane') }}" #~ if config["topology"]["nb_gnb"] > 2 - - node-id: "{{ ipv4('upfi2-f5gc', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" + - node-id: "{{ ipv4('upfi2-f5gc', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi2-f5gc', 'dataplane') }}" #~ endif #~ if config["topology"]["nb_edges"] > 2 - - node-id: "{{ ipv4('upfa3-f5gc', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" + - node-id: "{{ ipv4('upfa3-f5gc', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa3-f5gc', 'dataplane') }}" #~ endif #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - nextmn-upf: - pool: "{{ ipv4_subnet('slice2') }}" - upfs: - - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" - - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" + nmn-upf-0: + pool: "{{ ipv4_subnet('slice-nmn-upf-0') }}" + upfs: + - node-id: "{{ ipv4('upfi1-nmn', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi1-nmn', 'dataplane') }}" + - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" #~ if config["topology"]["nb_gnb"] > 2 - - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" - interfaces: - - type: "N3" - addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" - - type: "N9" - addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" + - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" + interfaces: + - type: "N3" + addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" + - type: "N9" + addr: "{{ ipv4('upfi2-nmn', 'dataplane') }}" #~ endif #~ if config["topology"]["nb_edges"] > 2 - - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" - interfaces: - - type: "N9" - addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" + - node-id: "{{ ipv4('upfa3-nmn', 'control') }}" + interfaces: + - type: "N9" + addr: "{{ ipv4('upfa3-nmn', 'dataplane') }}" #~ endif #~ endif areas: # RAN areas @@ -2315,19 +2269,22 @@ configs: #~ 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') }}" - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" @@ -2339,19 +2296,19 @@ configs: - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" paths: #~ if "nextmn-srv6" in config["topology"]["dataplane"] - srv6: + sr4mec-0: - 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') }}" #~ 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') }}" @@ -2360,6 +2317,112 @@ configs: #~ endif logger: level: "{{ log_level() }}" + #~ if "nextmn-srv6" in config["topology"]["dataplane"] + srv6-ctrl: + content: | + pfcp-address: "{{ ipv4('srv6-ctrl', 'control') }}" + control: + 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 #~ endif networks: @@ -2468,3 +2531,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"] + 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 22c68c0..6ec57a8 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -41,8 +41,12 @@ services: image: docker.io/louisroyer/dev-nextmn-srv6 build: https://github.com/louisroyer-docker/nextmn.git#master:srv6 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#7ae0b833c8fb77194c24a2715c0c9a7d5fd8a379 + args: + SOURCE_DATE_EPOCH: 0 + BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-ue-lite: image: ghcr.io/nextmn/ue-lite:delay build: @@ -51,14 +55,14 @@ services: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-gnb-lite: - image: ghcr.io/nextmn/gnb-lite + image: ghcr.io/nextmn/gnb-lite:delay build: context: https://github.com/nextmn/gnb-lite.git#1198cc0cb45d932acd982d78a9ee3a165f70b35 args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-cp-lite: - image: ghcr.io/nextmn/cp-lite + image: ghcr.io/nextmn/cp-lite:delay build: context: https://github.com/nextmn/cp-lite.git#0f2e28bc343f4784363c53911fe82912b703580d args: From 66cafd97fe6392eb2a51a5d87502f87c9c236378 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Thu, 16 Apr 2026 17:29:08 +0200 Subject: [PATCH 04/22] Update config and image in template; update jinja script --- Makefile | 2 +- scripts/jinja/customize.py | 122 +++++-- templates/compose.yaml.j2 | 638 ++++++++++++++++--------------------- templates/images-list.yaml | 10 +- 4 files changed, 394 insertions(+), 378 deletions(-) diff --git a/Makefile b/Makefile index ccddde9..104c7ed 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ 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 diff --git a/scripts/jinja/customize.py b/scripts/jinja/customize.py index 212610a..d817dab 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: @@ -448,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 = {} @@ -464,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() @@ -491,16 +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'] = { - "context": image_build, - "args": { - "SOURCE_DATE_EPOCH": 0, - "BUILDKIT_CONTEXT_KEEP_GIT_DIR": True, - } - } + 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: @@ -530,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''' @@ -537,8 +623,8 @@ 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", } diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index bf06b00..c5d9c8c 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" @@ -38,14 +37,13 @@ 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" @@ -69,14 +67,13 @@ services: #~ 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" @@ -101,14 +98,13 @@ services: 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" @@ -132,14 +128,13 @@ services: #~ 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" @@ -164,14 +159,13 @@ services: 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" @@ -195,14 +189,13 @@ services: #~ 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" @@ -243,14 +236,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" @@ -293,12 +285,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') }} 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() }}" @@ -348,14 +337,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() }}" @@ -379,10 +367,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() }}" @@ -400,10 +387,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() }}" @@ -422,10 +408,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() }}" @@ -446,10 +431,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() }}" @@ -470,12 +454,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() }}" @@ -498,10 +479,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() }}" @@ -520,17 +500,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() }}" @@ -846,10 +820,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: |- @@ -897,10 +870,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() }}" @@ -1058,42 +1030,20 @@ 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('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', 'rest') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]: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('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') }}" 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: @@ -1105,7 +1055,7 @@ services: 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 @@ -1118,46 +1068,24 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r0_db_password volumes: - - r0_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw('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('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', 'rest') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]: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('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') }}" 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: @@ -1169,7 +1097,7 @@ services: 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 @@ -1182,47 +1110,25 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r1_db_password volumes: - - r1_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw('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('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', 'rest') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]: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('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') }}" 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: @@ -1234,7 +1140,7 @@ services: 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 @@ -1247,47 +1153,25 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r2_db_password volumes: - - r2_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw('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('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', 'rest') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]: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: @@ -1298,7 +1182,7 @@ services: 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 @@ -1311,47 +1195,25 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/srgw0_db_password volumes: - - srgw0_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw('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('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', 'rest') }}" - HTTP_PORT: "8080" - CONTROLLER_URI: "http://[{{ ipv6('srv6-ctrl', 'rest') }}]: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" 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: @@ -1362,7 +1224,7 @@ services: 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 @@ -1375,15 +1237,14 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/srgw1_db_password volumes: - - srgw1_db_volume:/var/run/postgresql/ + - {{ mount_volume_named_postgres_rw('srgw1_db_volume') | indent(3) }} networks: nextmndb: #~ endif - {{ container_s(name='srv6-ctrl', image='ghcr.io/nextmn/srv6-ctrl:delay', image_build='https://github.com/nextmn/srv6-ctrl.git#7ae0b833c8fb77194c24a2715c0c9a7d5fd8a379', debug='allow', restart='always') }} + {{ container_s(name='srv6-ctrl', service='nextmn-srv6-ctrl', debug='allow', restart='always') }} configs: - - source: "srv6-ctrl" - target: "/etc/xdg/nextmn-srv6-ctrl/config.yaml" + - {{ mount_xdg_config_s('srv6-ctrl', 'nextmn-srv6-ctrl/config.yaml') | indent(3) }} networks: rest: ipv6_address: "{{ ipv6('srv6-ctrl', 'rest') }}" @@ -1411,9 +1272,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') }}" @@ -1441,9 +1302,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') }}" @@ -1474,7 +1335,7 @@ services: PRE_INIT_HOOK_4: "edge-0" {{ container_s(name='s2', image='docker.io/library/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') }}" @@ -1485,7 +1346,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() }}" @@ -1504,7 +1365,7 @@ services: 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() }}" @@ -1523,7 +1384,7 @@ services: 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() }}" @@ -1544,7 +1405,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() }}" @@ -1566,7 +1427,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() }}" @@ -1590,7 +1451,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: |- @@ -1608,7 +1469,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: |- @@ -1626,7 +1487,7 @@ 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: |- @@ -1646,7 +1507,7 @@ 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: |- @@ -1667,7 +1528,7 @@ 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: |- @@ -1691,21 +1552,17 @@ services: #~ if config["topology"]["controlplane"] == "nextmn-lite" #~ if "nextmn-srv6" in config["topology"]["dataplane"] - {{ container_s(name='uel1', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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=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 configs: - - source: "uel1" - target: "/etc/xdg/nextmn-ue-lite/config.yaml" + - {{ mount_xdg_config_s('uel1', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel1', 'ran') }}" @@ -1715,13 +1572,11 @@ services: ipv6_address: "{{ ipv6('uel1', 'control') }}" #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='uel2', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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=False, iface_tun=True, cap_net_admin=True) }} depends_on: - gnbl2: - condition: service_started + {{ depends_on_healthy_s('gnbl2') | indent(2) }} configs: - - source: "uel2" - target: "/etc/xdg/nextmn-ue-lite/config.yaml" + - {{ mount_xdg_config_s('uel2', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel2', 'ran') }}" @@ -1732,21 +1587,17 @@ services: #~ endif #~ endif #~ if "free5gc" in config["topology"]["dataplane"] - {{ container_s(name='uel3', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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 configs: - - source: "uel3" - target: "/etc/xdg/nextmn-ue-lite/config.yaml" + - {{ mount_xdg_config_s('uel3', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel3', 'ran') }}" @@ -1756,13 +1607,11 @@ services: ipv6_address: "{{ ipv6('uel3', 'control') }}" #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='uel4', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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 + {{ depends_on_healthy_s('gnbl2') | indent(2) }} configs: - - source: "uel4" - target: "/etc/xdg/nextmn-ue-lite/config.yaml" + - {{ mount_xdg_config_s('uel4', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel4', 'ran') }}" @@ -1773,21 +1622,17 @@ services: #~ endif #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - {{ container_s(name='uel5', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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=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 configs: - - source: "uel5" - target: "/etc/xdg/nextmn-ue-lite/config.yaml" + - {{ mount_xdg_config_s('uel5', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel5', 'ran') }}" @@ -1797,13 +1642,11 @@ services: ipv6_address: "{{ ipv6('uel5', 'control') }}" #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='uel6', image='ghcr.io/nextmn/ue-lite:delay', image_build='https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0', 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 + {{ depends_on_healthy_s('gnbl2') | indent(2) }} configs: - - source: "uel6" - target: "/etc/xdg/nextmn-ue-lite/config.yaml" + - {{ mount_xdg_config_s('uel6', 'nextmn-ue-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('uel6', 'ran') }}" @@ -1814,13 +1657,11 @@ services: #~ endif #~ endif - {{ container_s(name='gnbl1', image='ghcr.io/nextmn/gnb-lite:delay', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', 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 + {{ depends_on_healthy_s('cp-lite') | indent(2) }} configs: - - source: "gnbl1" - target: "/etc/xdg/nextmn-gnb-lite/config.yaml" + - {{ mount_xdg_config_s('gnbl1', 'nextmn-gnb-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('gnbl1', 'ran') }}" @@ -1831,13 +1672,11 @@ services: dataplane: ipv4_address: "{{ ipv4('gnbl1', 'dataplane') }}" - {{ container_s(name='gnbl2', image='ghcr.io/nextmn/gnb-lite:delay', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', 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 + {{ depends_on_healthy_s('cp-lite') | indent(2) }} configs: - - source: "gnbl2" - target: "/etc/xdg/nextmn-gnb-lite/config.yaml" + - {{ mount_xdg_config_s('gnbl2', 'nextmn-gnb-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('gnbl2', 'ran') }}" @@ -1849,13 +1688,11 @@ services: ipv4_address: "{{ ipv4('gnbl2', 'dataplane') }}" #~ if config["topology"]["nb_gnb"] > 2 - {{ container_s(name='gnbl3', image='ghcr.io/nextmn/gnb-lite:delay', image_build='https://github.com/nextmn/gnb-lite.git#47b8c69f015bdc0b4b8f289d6100e45d4cbeae81', 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 + {{ depends_on_healthy_s('cp-lite') | indent(2) }} configs: - - source: "gnbl3" - target: "/etc/xdg/nextmn-gnb-lite/config.yaml" + - {{ mount_xdg_config_s('gnbl3', 'nextmn-gnb-lite/config.yaml') | indent(3) }} networks: ran: ipv4_address: "{{ ipv4('gnbl3', 'ran') }}" @@ -1867,61 +1704,28 @@ services: ipv4_address: "{{ ipv4('gnbl3', 'dataplane') }}" #~ endif - {{ container_s(name='cp-lite', image='ghcr.io/nextmn/cp-lite:delay', image_build='https://github.com/nextmn/cp-lite.git#0f2e28bc343f4784363c53911fe82912b703580d', 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 - #~ 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-f5gc', 'upfa3-f5gc') | indent(2) }} #~ 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 - #~ endif - upfa1-nmn: - condition: service_started - upfa2-nmn: - condition: service_started + {{ depends_on_started_s('upfi1-nmn', 'upfa1-nmn', 'upfa2-nmn') | indent(2) }} #~ if config["topology"]["nb_gnb"] > 2 - upfa3-nmn: - condition: service_started + {{ depends_on_started_s('upfi2-nmn', 'upfa3-nmn') | indent(2) }} #~ endif #~ endif configs: - - source: "cp-lite" - target: "/etc/xdg/nextmn-cp-lite/config.yaml" + - {{ mount_xdg_config_s('cp-lite', 'nextmn-cp-lite/config.yaml') | indent(3) }} networks: control: ipv4_address: "{{ ipv4('cp-lite', 'control') }}" @@ -2423,6 +2227,128 @@ configs: - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw1') }}" #~ endif #~ endif + #~ 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 networks: diff --git a/templates/images-list.yaml b/templates/images-list.yaml index 6ec57a8..ccfa403 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -38,8 +38,12 @@ 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#abaf9755d95271f4dade608dbb61bf655a27895b + args: + SOURCE_DATE_EPOCH: 0 + BUILDKIT_CONTEXT_KEEP_GIT_DIR: true nextmn-srv6-ctrl: image: ghcr.io/nextmn/srv6-ctrl:delay build: @@ -50,7 +54,7 @@ services: nextmn-ue-lite: image: ghcr.io/nextmn/ue-lite:delay build: - context: https://github.com/nextmn/ue-lite.git#583ce2b9adb31d82078ddd66cbc7c0dcb92ca7f0 + context: https://github.com/nextmn/ue-lite.git#e9a33156fbe936e58c2fb4902454ad18bba82951 args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From de917e7cfe76e64c22aeb22d363c7d0f65dace1b Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Thu, 16 Apr 2026 18:32:02 +0200 Subject: [PATCH 05/22] Update script from bash to posix sh --- templates/compose.yaml.j2 | 20 ++++++++++---------- templates/images-list.yaml | 2 +- templates/nextmn/routes-to-nei.sh | 25 +++++++++++-------------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index c5d9c8c..0653e77 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1035,7 +1035,7 @@ services: {{ depends_on_healthy_s('srv6-ctrl', 'r0-db') | indent(2) }} volumes: - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} - - {{ mount_volume_named_postgres_rw('r0_db_volume') | 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: @@ -1068,7 +1068,7 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r0_db_password volumes: - - {{ mount_volume_named_postgres_rw('r0_db_volume') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('r0_db_volume') | indent(3) }} networks: nextmndb: @@ -1077,7 +1077,7 @@ services: {{ depends_on_healthy_s('srv6-ctrl', 'r1-db') | indent(2) }} volumes: - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} - - {{ mount_volume_named_postgres_rw('r1_db_volume') | 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: @@ -1110,7 +1110,7 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r1_db_password volumes: - - {{ mount_volume_named_postgres_rw('r1_db_volume') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('r1_db_volume') | indent(3) }} networks: nextmndb: @@ -1120,7 +1120,7 @@ services: {{ depends_on_healthy_s('srv6-ctrl', 'r2-db') | indent(2) }} volumes: - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} - - {{ mount_volume_named_postgres_rw('r2_db_volume') | 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: @@ -1153,7 +1153,7 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/r2_db_password volumes: - - {{ mount_volume_named_postgres_rw('r2_db_volume') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('r2_db_volume') | indent(3) }} networks: nextmndb: #~ endif @@ -1163,7 +1163,7 @@ services: {{ depends_on_healthy_s('srv6-ctrl', 'srgw0-db') | indent(2) }} volumes: - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} - - {{ mount_volume_named_postgres_rw('srgw0_db_volume') | 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: @@ -1195,7 +1195,7 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/srgw0_db_password volumes: - - {{ mount_volume_named_postgres_rw('srgw0_db_volume') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('srgw0_db_volume') | indent(3) }} networks: nextmndb: @@ -1205,7 +1205,7 @@ services: {{ depends_on_healthy_s('srv6-ctrl', 'srgw1-db') | indent(2) }} volumes: - {{ volume_bind_ro_s('nextmn/routes-to-nei.sh', '/usr/local/bin/routes-to-nei.sh') | indent(3) }} - - {{ mount_volume_named_postgres_rw('srgw1_db_volume') | 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: @@ -1237,7 +1237,7 @@ services: environment: POSTGRES_PASSWORD_FILE: /run/secrets/srgw1_db_password volumes: - - {{ mount_volume_named_postgres_rw('srgw1_db_volume') | indent(3) }} + - {{ mount_volume_named_postgres_rw_s('srgw1_db_volume') | indent(3) }} networks: nextmndb: #~ endif diff --git a/templates/images-list.yaml b/templates/images-list.yaml index ccfa403..78a944f 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -40,7 +40,7 @@ services: nextmn-srv6: image: ghcr.io/nextmn/srv6:fix build: - context: https://github.com/nextmn/srv6.git#abaf9755d95271f4dade608dbb61bf655a27895b + context: https://github.com/nextmn/srv6.git#cf584fe0b510b5901b14f686b9fd685c541abfaf args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true 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 < Date: Fri, 17 Apr 2026 11:14:29 +0200 Subject: [PATCH 06/22] Update scripts with new addresses --- scripts/handover.py | 16 +++++++++------- scripts/switch.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/scripts/handover.py b/scripts/handover.py index ddcbc6a..1a32a0e 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 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(): From 143bfee67369606b97c809a416c966661f02d7a3 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 17 Apr 2026 12:00:15 +0200 Subject: [PATCH 07/22] Fix yaml indent --- templates/compose.yaml.j2 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index 0653e77..c8de352 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1919,9 +1919,9 @@ configs: bind-addr: "[{{ ipv6('gnbl1', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('gnbl1', 'ran') }}]:1234" - one-way-delays: - control: "7ms" - data: "7ms" + one-way-delays: + control: "7ms" + data: "7ms" cp: uri: "http://[{{ ipv6('cp-lite', 'control') }}]:8080" one-way-delay: "9ms" @@ -1939,9 +1939,9 @@ configs: bind-addr: "[{{ ipv6('gnbl2', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('gnbl2', 'ran') }}]:1234" - one-way-delays: - control: "7ms" - data: "7ms" + one-way-delays: + control: "7ms" + data: "7ms" cp: uri: "http://[{{ ipv6('cp-lite', 'control') }}]:8080" one-way-delay: "9ms" @@ -1961,9 +1961,9 @@ configs: bind-addr: "[{{ ipv6('gnbl3', 'control') }}]:8080" ran: bind-addr: "[{{ ipv6('gnbl3', 'ran') }}]:1234" - one-way-delays: - control: "7ms" - data: "7ms" + one-way-delays: + control: "7ms" + data: "7ms" cp: uri: "http://[{{ ipv6('cp-lite', 'control') }}]:8080" one-way-delay: "9ms" From b68ff76d07de2bc126ec5d6a5c934650acd6069e Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Mon, 20 Apr 2026 11:30:26 +0200 Subject: [PATCH 08/22] Update scenario --- Makefile | 40 +++++++++++++++++++++----------------- doc | 2 +- templates/compose.yaml.j2 | 13 +++++++++---- templates/images-list.yaml | 2 +- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 104c7ed..83ce9ee 100644 --- a/Makefile +++ b/Makefile @@ -356,34 +356,38 @@ plot/latency-switch: .PHONY: thesis/plot/binding thesis/plot/binding: - @echo "[1/2] [1/6] Configuring testbed with NextMN-SRv6" + @echo "[1/2] [1/7] Configuring testbed with NextMN-SRv6" @$(MAKE) set/controlplane/free5gc @$(MAKE) set/dataplane/nextmn-srv6 @$(MAKE) set/nb-ue/2 # TODO: configure different slices @$(MAKE) set/nb-edges/1 @$(MAKE) set/nb-gnb/1 - @$(MAKE) set/full-debug/false - @$(MAKE) set/log-level/info - @echo "[1/2] [2/6] Starting containers" + @$(MAKE) set/full-debug/true + @$(MAKE) set/log-level/debug + @echo "[1/2] [2/7] Starting containers" @$(MAKE) up - @echo "[1/2] [3/6] Adding latencies" - @docker exec r0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # central DN uplink - @docker exec s0-debug bash -c "tc qdisc add dev edge-0 root netem delay 9ms" # central DN downlink - @docker exec ue1-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # radio uplink UE1 - @docker exec ue2-debug bash -c "tc qdisc add dev ran-0 root netem delay 23ms" # radio uplink UE2 - @docker exec gnb1-debug bash -c "tc qdisc add dev ran-0 root netem delay 7ms" # radio downlink gNB1 - @docker exec gnb1-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # gNB1 control plane latency - @docker exec amf-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # amf control plane latency - @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency - @docker exec r0-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency - @docker exec r1-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency - @docker exec srgw0-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # srv6-ctrl control plane latency + @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 + @# control plane latency + @docker exec gnb1-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # uplink ran + @docker exec amf-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # downlink ran + @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink SR + @docker exec r0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink R0 + @docker exec r1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink R1 + @docker exec srgw0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink SRGW0 + @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] [4/6] Setting UE2 on edge 1" + @echo "[1/2] [5/7] Setting UE2 on edge 1" @$(MAKE) ue/switch-edge/2 - @echo "[1/2] [5/6] [$$(date --rfc-3339=seconds)] Starting ping from ue1 and ue2 (60s + 5s margin)" + @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 diff --git a/doc b/doc index 6be243d..d2ff190 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit 6be243d17539c32f29bf1a725e37093950c5ccbf +Subproject commit d2ff190ce45ab2a62f06f2759f1f0df46a05a845 diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index c8de352..13893da 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -48,7 +48,11 @@ services: environment: MSISDN: "0000000002" GNBS: |- + #~ if config["topology"]["nb_gnb"] > 2 - "{{ ipv6('gnb2', 'ran') }}" + #~ else + - "{{ ipv6('gnb1', 'ran') }}" + #~ endif CONFIGURED_NSSAI: |- - sst: 1 sd: 000002 @@ -285,7 +289,7 @@ services: #~ endif #~ if config["topology"]["controlplane"] == "free5gc" - {{ container_s(name='amf', service='amf', restart='always') }} + {{ container_s(name='amf', service='amf', restart='always', debug='allow') }} depends_on: {{ depends_on_started_s('smf', 'nrf') | indent(2) }} environment: @@ -304,13 +308,14 @@ 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"] diff --git a/templates/images-list.yaml b/templates/images-list.yaml index 78a944f..a5717f2 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -47,7 +47,7 @@ services: nextmn-srv6-ctrl: image: ghcr.io/nextmn/srv6-ctrl:delay build: - context: https://github.com/nextmn/srv6-ctrl.git#7ae0b833c8fb77194c24a2715c0c9a7d5fd8a379 + context: https://github.com/nextmn/srv6-ctrl.git#ad4171e43bdefaed14a893db90826e686870a1f8 args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From ca86cce48275816838d0627de056649627f10d68 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Mon, 20 Apr 2026 18:55:24 +0200 Subject: [PATCH 09/22] Add scenario --- Makefile | 102 ++++++++++++++++++-- default-config.yaml | 50 +++++----- doc | 2 +- scripts/handover.py | 6 +- scripts/thesis/binding.py | 4 +- scripts/thesis/migration.py | 56 +++++++++++ scripts/thesis/mobility.py | 45 +++++++++ templates/compose.yaml.j2 | 183 ++++++++++++++++++++---------------- templates/images-list.yaml | 2 +- 9 files changed, 324 insertions(+), 126 deletions(-) create mode 100755 scripts/thesis/migration.py create mode 100755 scripts/thesis/mobility.py diff --git a/Makefile b/Makefile index 83ce9ee..aa91d16 100644 --- a/Makefile +++ b/Makefile @@ -360,10 +360,10 @@ thesis/plot/binding: @$(MAKE) set/controlplane/free5gc @$(MAKE) set/dataplane/nextmn-srv6 @$(MAKE) set/nb-ue/2 # TODO: configure different slices - @$(MAKE) set/nb-edges/1 + @$(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/debug + @$(MAKE) set/log-level/info @echo "[1/2] [2/7] Starting containers" @$(MAKE) up @echo "[1/2] [3/7] Adding latencies" @@ -374,18 +374,12 @@ thesis/plot/binding: @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 - @# control plane latency - @docker exec gnb1-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # uplink ran - @docker exec amf-debug bash -c "tc qdisc add dev control-0 root netem delay 9ms" # downlink ran - @docker exec srv6-ctrl-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # downlink SR - @docker exec r0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink R0 - @docker exec r1-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink R1 - @docker exec srgw0-debug bash -c "tc qdisc add dev rest-0 root netem delay 9ms" # uplink SRGW0 @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"' & @@ -397,4 +391,92 @@ thesis/plot/binding: @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).txt $(BUILD_DIR)/thesis-plots/binding/$(DATE)/01_10_evalutation-plot-binding.pdf + @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_evalutation-plot-binding.pdf + +.PHONY: thesis/plot/migration +thesis/plot/migration: + @echo "[1/7] Configuring testbed with NextMN-SRv6 + NextMN-UPF" + @$(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 UE1 + @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_evalutation-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" + @# central DN latency + @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 + @# 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" + @docker exec upfi1-nmn-debug bash -c "ip route replace 10.1.4.144/32 via 10.1.4.146" # to upfi2-nmn via inter-areas + @docker exec upfa2-nmn-debug bash -c "ip route replace 10.1.4.144/32 via 10.1.4.146" # 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" # to upfi1-nmn via inter-areas + @docker exec upfi2-nmn-debug bash -c "ip route replace 10.1.4.134/32 via 10.1.4.146" # to upfa2-nmn via inter-areas + @#### Do a first pair of handovers just to test everything is okay + @sleep 2 + @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 (test)"' & + @docker exec uel5-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @sleep 2 + @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel5 nmn-upf-0 gnbl1 gnbl3 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 2 to Area 1 (test)"' & + @docker exec uel5-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 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_evalutation-plot-mobility-ulcl.pdf diff --git a/default-config.yaml b/default-config.yaml index 1499b2e..69acf31 100644 --- a/default-config.yaml +++ b/default-config.yaml @@ -117,36 +117,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 +163,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 @@ -228,6 +204,26 @@ subnets: 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 diff --git a/doc b/doc index d2ff190..2762dd1 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit d2ff190ce45ab2a62f06f2759f1f0df46a05a845 +Subproject commit 2762dd1a9f35a52f84b183161909f8398319ef61 diff --git a/scripts/handover.py b/scripts/handover.py index 1a32a0e..8cbf077 100755 --- a/scripts/handover.py +++ b/scripts/handover.py @@ -55,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/thesis/binding.py b/scripts/thesis/binding.py index ea74e04..2c0f2c3 100755 --- a/scripts/thesis/binding.py +++ b/scripts/thesis/binding.py @@ -32,10 +32,10 @@ def plot(arguments: argparse.Namespace): _, axplt = plt.subplots() axplt.set_xlabel('t (s)') axplt.set_ylabel('RTT (ms)') - axplt.plot(res[1]['tsp'], res[1]['pqt'], color='tab:red', - label='$UE_2$') 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.savefig(arguments.output) diff --git a/scripts/thesis/migration.py b/scripts/thesis/migration.py new file mode 100755 index 0000000..a0340ee --- /dev/null +++ b/scripts/thesis/migration.py @@ -0,0 +1,56 @@ +#!/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 + +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 + _, axplt = plt.subplots() + 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.savefig(arguments.output) + 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..6428347 --- /dev/null +++ b/scripts/thesis/mobility.py @@ -0,0 +1,45 @@ +#!/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 + +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 + _, axplt = plt.subplots() + axplt.set_xlabel('t(s)') + axplt.set_ylabel('RTT (ms)') + axplt.plot(res[0]['tsp'], res[0]['pqt'], color='tab:red') + axplt.autoscale_view() + axplt.legend(handles=[]) + plt.savefig(arguments.output) + 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 13893da..a1b4a39 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1338,7 +1338,7 @@ 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_bind_ro_s('nginx/instance.conf.template', '/etc/nginx/templates/instance.conf.template') | indent(3) }} environment: @@ -1557,7 +1557,7 @@ services: #~ if config["topology"]["controlplane"] == "nextmn-lite" #~ if "nextmn-srv6" in config["topology"]["dataplane"] - {{ container_s(name='uel1', service='nextmn-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: {{ depends_on_healthy_s('gnbl1') | indent(2) }} #~ if config["topology"]["ran"]["handover"] @@ -1572,9 +1572,8 @@ services: 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', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} @@ -1586,9 +1585,8 @@ services: 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"] @@ -1607,9 +1605,8 @@ services: 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', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} @@ -1621,13 +1618,12 @@ services: 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', service='nextmn-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: {{ depends_on_healthy_s('gnbl1') | indent(2) }} #~ if config["topology"]["ran"]["handover"] @@ -1642,9 +1638,8 @@ services: 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', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} @@ -1656,9 +1651,8 @@ services: 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 @@ -1671,9 +1665,8 @@ services: 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') }}" @@ -1686,9 +1679,8 @@ services: 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') }}" @@ -1702,9 +1694,8 @@ services: 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 @@ -1724,9 +1715,15 @@ services: #~ endif #~ endif #~ if "nextmn-upf" in config["topology"]["dataplane"] - {{ depends_on_started_s('upfi1-nmn', 'upfa1-nmn', 'upfa2-nmn') | indent(2) }} + {{ 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 #~ if config["topology"]["nb_gnb"] > 2 - {{ depends_on_started_s('upfi2-nmn', 'upfa3-nmn') | indent(2) }} + {{ depends_on_started_s('upfi2-nmn') | indent(2) }} #~ endif #~ endif configs: @@ -1735,8 +1732,30 @@ services: 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, 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: @@ -1789,23 +1808,23 @@ configs: uel1: content: | control: - uri: "http://[{{ ipv6('uel1', 'control') }}]:8080" - bind-addr: "[{{ ipv6('uel1', 'control') }}]:8080" + 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', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" #~ if config["topology"]["ran"]["handover"] - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" #~ if config["topology"]["nb_gnb"] > 2 - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" #~ endif #~ endif pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" dnn: "sr4mec-0" logger: level: "{{ log_level() }}" @@ -1813,17 +1832,17 @@ configs: uel2: content: | control: - uri: "http://[{{ ipv6('uel2', 'control') }}]:8080" - bind-addr: "[{{ ipv6('uel2', 'control') }}]:8080" + 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('gnbl2', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + - gnb: "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" dnn: "sr4mec-1" logger: level: "{{ log_level() }}" @@ -1833,23 +1852,23 @@ configs: uel3: content: | control: - uri: "http://[{{ ipv6('uel3', 'control') }}]:8080" - bind-addr: "[{{ ipv6('uel3', 'control') }}]:8080" + 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', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" #~ if config["topology"]["ran"]["handover"] - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" #~ if config["topology"]["nb_gnb"] > 2 - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" #~ endif #~ endif pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" dnn: "f5gc-0" logger: level: "{{ log_level() }}" @@ -1857,17 +1876,17 @@ configs: uel4: content: | control: - uri: "http://[{{ ipv6('uel4', 'control') }}]:8080" - bind-addr: "[{{ ipv6('uel4', 'control') }}]:8080" + 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', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + - gnb: "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" dnn: "f5gc-0" logger: level: "{{ log_level() }}" @@ -1877,23 +1896,23 @@ configs: uel5: content: | control: - uri: "http://[{{ ipv6('uel5', 'control') }}]:8080" - bind-addr: "[{{ ipv6('uel5', 'control') }}]:8080" + 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', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" #~ if config["topology"]["ran"]["handover"] - - "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" #~ if config["topology"]["nb_gnb"] > 2 - - "http://[{{ ipv6('gnbl3', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl3', 'rest') }}]:8080" #~ endif #~ endif pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" dnn: "nmn-upf-0" logger: level: "{{ log_level() }}" @@ -1901,17 +1920,17 @@ configs: uel6: content: | control: - uri: "http://[{{ ipv6('uel6', 'control') }}]:8080" - bind-addr: "[{{ ipv6('uel6', 'control') }}]:8080" + 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', 'control') }}]:8080" + - "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" pdu-sessions: - - gnb: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" + - gnb: "http://[{{ ipv6('gnbl2', 'rest') }}]:8080" dnn: "nmn-upf-0" logger: level: "{{ log_level() }}" @@ -1920,15 +1939,15 @@ configs: gnbl1: content: | control: - uri: "http://[{{ ipv6('gnbl1', 'control') }}]:8080" - bind-addr: "[{{ ipv6('gnbl1', 'control') }}]:8080" + 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', 'control') }}]:8080" + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" one-way-delay: "9ms" gtp: "{{ ipv4('gnbl1', 'dataplane') }}" logger: @@ -1940,15 +1959,15 @@ configs: gnbl2: content: | control: - uri: "http://[{{ ipv6('gnbl2', 'control') }}]:8080" - bind-addr: "[{{ ipv6('gnbl2', 'control') }}]:8080" + 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', 'control') }}]:8080" + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" one-way-delay: "9ms" gtp: "{{ ipv4('gnbl2', 'dataplane') }}" logger: @@ -1962,15 +1981,15 @@ configs: gnbl3: content: | control: - uri: "http://[{{ ipv6('gnbl3', 'control') }}]:8080" - bind-addr: "[{{ ipv6('gnbl3', 'control') }}]:8080" + 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', 'control') }}]:8080" + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" one-way-delay: "9ms" gtp: "{{ ipv4('gnbl3', 'dataplane') }}" logger: @@ -1983,8 +2002,8 @@ configs: cp-lite: content: | control: - uri: "http://[{{ ipv6('cp-lite', 'control') }}]:8080" - bind-addr: "[{{ ipv6('cp-lite', 'control') }}]:8080" + uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" + bind-addr: "[{{ ipv6('cp-lite', 'rest') }}]:8080" pfcp: "{{ ipv4('cp-lite', 'control') }}" slices: #~ if "nextmn-srv6" in config["topology"]["dataplane"] @@ -2072,9 +2091,9 @@ configs: 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"] @@ -2099,10 +2118,10 @@ configs: - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" interface-addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" #~ 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"] sr4mec-0: @@ -2113,15 +2132,15 @@ configs: 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"] 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') }}" + - node-id: "{{ ipv4('upfa1-nmn', 'control') }}" + interface-addr: "{{ ipv4('upfa1-nmn', 'dataplane') }}" #~ endif #~ endif logger: @@ -2462,7 +2481,7 @@ 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"] +#~ if "nextmn-srv6" in config["topology"]["dataplane"] or config["topology"]["controlplane"] == "nextmn-lite" rest: name: rest enable_ipv6: true diff --git a/templates/images-list.yaml b/templates/images-list.yaml index a5717f2..a19c9b7 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -68,7 +68,7 @@ services: nextmn-cp-lite: image: ghcr.io/nextmn/cp-lite:delay build: - context: https://github.com/nextmn/cp-lite.git#0f2e28bc343f4784363c53911fe82912b703580d + context: https://github.com/nextmn/cp-lite.git#6c692d8bb77dc07585654f5af9dab9abd948a26f args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From 347f58f23aa0fb28a3ca50713717e156482d9a1b Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Mon, 20 Apr 2026 19:49:02 +0200 Subject: [PATCH 10/22] Update gnb --- templates/images-list.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/images-list.yaml b/templates/images-list.yaml index a19c9b7..d74a49d 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -61,7 +61,7 @@ services: nextmn-gnb-lite: image: ghcr.io/nextmn/gnb-lite:delay build: - context: https://github.com/nextmn/gnb-lite.git#1198cc0cb45d932acd982d78a9ee3a165f70b35 + context: https://github.com/nextmn/gnb-lite.git#383258ef553ef8ee1020372be3137c7884fe970e args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From 70729af3a68125d250a8f34b3cbf35c87b0d91b1 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Tue, 21 Apr 2026 11:55:00 +0200 Subject: [PATCH 11/22] Fix scenario mobility/ulcl --- Makefile | 12 +++++------- templates/compose.yaml.j2 | 18 ++++++++++++++++++ templates/images-list.yaml | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index aa91d16..5a8fc15 100644 --- a/Makefile +++ b/Makefile @@ -412,7 +412,7 @@ thesis/plot/migration: @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 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 @@ -446,8 +446,6 @@ thesis/plot/mobility/ulcl: @$(MAKE) up @echo "[3/7] Adding latencies" @# central DN latency - @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 @# 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 @@ -462,11 +460,11 @@ thesis/plot/mobility/ulcl: @docker exec upfi2-nmn-debug bash -c "ip route replace 10.1.4.134/32 via 10.1.4.146" # to upfa2-nmn via inter-areas @#### Do a first pair of handovers just to test everything is okay @sleep 2 - @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 (test)"' & - @docker exec uel5-debug bash -c "ping -c 1 10.4.0.1 > /dev/null" # check instance is reachable + @bash -c 'docker exec uel5-debug bash -c "ping -D -w 5 10.4.0.1 -i 0.1 > /dev/null"' & + @bash -c '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 (test)"' & + @sleep 2 + @bash -c 'scripts/handover.py $(BCONFIG) uel5 nmn-upf-0 gnbl1 gnbl3 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 2 to Area 1 (test)"' & @sleep 2 - @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel5 nmn-upf-0 gnbl1 gnbl3 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 2 to Area 1 (test)"' & - @docker exec uel5-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 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"' & diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index a1b4a39..6a92d73 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -2005,6 +2005,8 @@ configs: uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" bind-addr: "[{{ ipv6('cp-lite', 'rest') }}]:8080" pfcp: "{{ ipv4('cp-lite', 'control') }}" + emulation: + handover-notify: "200ms" slices: #~ if "nextmn-srv6" in config["topology"]["dataplane"] sr4mec-0: @@ -2081,6 +2083,12 @@ configs: - 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: @@ -2115,8 +2123,13 @@ configs: 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) area2: @@ -2139,8 +2152,13 @@ configs: nmn-upf-0: - node-id: "{{ ipv4('upfi2-nmn', 'control') }}" interface-addr: "{{ ipv4('upfi2-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 logger: diff --git a/templates/images-list.yaml b/templates/images-list.yaml index d74a49d..263e75a 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -68,7 +68,7 @@ services: nextmn-cp-lite: image: ghcr.io/nextmn/cp-lite:delay build: - context: https://github.com/nextmn/cp-lite.git#6c692d8bb77dc07585654f5af9dab9abd948a26f + context: https://github.com/nextmn/cp-lite.git#9b2e3cc0231628e316a029e28c50af7d8dcb968a args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From 0d4cfad133b8e8390aa25a5aadb0a25b01c6e2ef Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Wed, 22 Apr 2026 09:54:53 +0200 Subject: [PATCH 12/22] Fix mobility/ulcl --- Makefile | 66 ++++++++++++++++++++++++++++++++------ scripts/thesis/mobility.py | 1 - templates/images-list.yaml | 2 +- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 5a8fc15..ca8bf10 100644 --- a/Makefile +++ b/Makefile @@ -454,16 +454,16 @@ thesis/plot/mobility/ulcl: @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" - @docker exec upfi1-nmn-debug bash -c "ip route replace 10.1.4.144/32 via 10.1.4.146" # to upfi2-nmn via inter-areas - @docker exec upfa2-nmn-debug bash -c "ip route replace 10.1.4.144/32 via 10.1.4.146" # 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" # to upfi1-nmn via inter-areas - @docker exec upfi2-nmn-debug bash -c "ip route replace 10.1.4.134/32 via 10.1.4.146" # to upfa2-nmn via inter-areas - @#### Do a first pair of handovers just to test everything is okay - @sleep 2 - @bash -c 'docker exec uel5-debug bash -c "ping -D -w 5 10.4.0.1 -i 0.1 > /dev/null"' & - @bash -c '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 (test)"' & - @sleep 2 - @bash -c 'scripts/handover.py $(BCONFIG) uel5 nmn-upf-0 gnbl1 gnbl3 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 2 to Area 1 (test)"' & + @# 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.134/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" @sleep 2 @#### @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" @@ -478,3 +478,49 @@ thesis/plot/mobility/ulcl: @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_evalutation-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 + @$(MAKE) set/controlplane/nextmn-lite + @$(MAKE) set/dataplane/nextmn-srv6 + @$(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" + @# central DN latency + @# 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 TODO via 10.1.4.146" # from srgw0 to srgw1 via inter-areas + #@docker exec srgw1-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw1 to srgw0 via inter-areas + @# srgw0 (edge 1) - r2 (edge 2) + #@docker exec srgw0-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw0 to r2 via inter-areas + #@docker exec r2-debug bash -c "ip route replace TODO via 10.1.4.146" # from r2 to srgw0 via inter-areas + @# srgw1 (edge 2) - r1 (edge 1) + #@docker exec srgw1-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw1 to r1 via inter-areas + #@docker exec r1-debug bash -c "ip route replace TODO via 10.1.4.146" # from r1 to srgw1 via inter-areas + @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/uel5/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_evalutation-plot-mobility-changement-a-posteriori-central.pdf diff --git a/scripts/thesis/mobility.py b/scripts/thesis/mobility.py index 6428347..133043e 100755 --- a/scripts/thesis/mobility.py +++ b/scripts/thesis/mobility.py @@ -26,7 +26,6 @@ def plot(arguments: argparse.Namespace): axplt.set_ylabel('RTT (ms)') axplt.plot(res[0]['tsp'], res[0]['pqt'], color='tab:red') axplt.autoscale_view() - axplt.legend(handles=[]) plt.savefig(arguments.output) print(f'plot saved in {arguments.output}') diff --git a/templates/images-list.yaml b/templates/images-list.yaml index 263e75a..e2cb67b 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -68,7 +68,7 @@ services: nextmn-cp-lite: image: ghcr.io/nextmn/cp-lite:delay build: - context: https://github.com/nextmn/cp-lite.git#9b2e3cc0231628e316a029e28c50af7d8dcb968a + context: https://github.com/nextmn/cp-lite.git#6b3c43198d62b01fe64a31f0754785241854594d args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From e5354f9009c7f7373d06a6a5b61faa295745bcf3 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Wed, 22 Apr 2026 11:35:32 +0200 Subject: [PATCH 13/22] fixup --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ca8bf10..904482e 100644 --- a/Makefile +++ b/Makefile @@ -459,11 +459,15 @@ thesis/plot/mobility/ulcl: @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.134/32 via 10.1.4.146" # from upfi2-nmn to upfa2-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" From d22061f0feac7319ffbc81ef4b62910518c94f67 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Wed, 22 Apr 2026 14:15:52 +0200 Subject: [PATCH 14/22] Update pyplots --- Makefile | 10 ++++++---- scripts/thesis/binding.py | 9 +++++++-- scripts/thesis/migration.py | 8 ++++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 904482e..aa39df0 100644 --- a/Makefile +++ b/Makefile @@ -356,6 +356,7 @@ plot/latency-switch: .PHONY: thesis/plot/binding thesis/plot/binding: + @echo "Warning: this scenario is currently broken" @echo "[1/2] [1/7] Configuring testbed with NextMN-SRv6" @$(MAKE) set/controlplane/free5gc @$(MAKE) set/dataplane/nextmn-srv6 @@ -391,7 +392,7 @@ thesis/plot/binding: @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_evalutation-plot-binding.pdf + @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: @@ -429,7 +430,7 @@ thesis/plot/migration: @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_evalutation-plot-migration.pdf + @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: @@ -481,10 +482,11 @@ thesis/plot/mobility/ulcl: @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_evalutation-plot-mobility-ulcl.pdf + @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 "Warning: this scenario is currently broken" @echo "[1/7] Configuring testbed with NextMN-SRv6" @./scripts/config_edit.py $(BCONFIG) --handover=true @$(MAKE) set/controlplane/nextmn-lite @@ -527,4 +529,4 @@ thesis/plot/mobility/posteriori/central: @echo "[7/7] Plotting data" @mkdir -p $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ @cp $(BUILD_DIR)/volumes/uel5/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_evalutation-plot-mobility-changement-a-posteriori-central.pdf + @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 diff --git a/scripts/thesis/binding.py b/scripts/thesis/binding.py index 2c0f2c3..e7a6abb 100755 --- a/scripts/thesis/binding.py +++ b/scripts/thesis/binding.py @@ -8,6 +8,7 @@ import argparse import pathlib import matplotlib.pyplot as plt +import matplotlib as mpl def plot(arguments: argparse.Namespace): '''Write plot''' @@ -29,8 +30,11 @@ def plot(arguments: argparse.Namespace): res[0]['tsp'][i] = timestamp - first for i, timestamp in enumerate(res[1]['tsp']): res[1]['tsp'][i] = timestamp - first - _, axplt = plt.subplots() + 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$') @@ -38,7 +42,8 @@ def plot(arguments: argparse.Namespace): label='$UE_2$') axplt.autoscale_view() axplt.legend() - plt.savefig(arguments.output) + plt.tight_layout() + plt.savefig(arguments.output, bbox_inches='tight') print(f'plot saved in {arguments.output}') if __name__ == '__main__': diff --git a/scripts/thesis/migration.py b/scripts/thesis/migration.py index a0340ee..830020e 100755 --- a/scripts/thesis/migration.py +++ b/scripts/thesis/migration.py @@ -8,6 +8,7 @@ import argparse import pathlib import matplotlib.pyplot as plt +import matplotlib as mpl def plot(arguments: argparse.Namespace): '''Write plot''' @@ -29,14 +30,17 @@ def plot(arguments: argparse.Namespace): res[0]['tsp'][i] = timestamp - first for i, timestamp in enumerate(res[1]['tsp']): res[1]['tsp'][i] = timestamp - first - _, axplt = plt.subplots() + 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.savefig(arguments.output) + plt.tight_layout() + plt.savefig(arguments.output, bbox_inches='tight') print(f'plot saved in {arguments.output}') if __name__ == '__main__': From c9d525443568f18faf6cac4414c78f60d9fa0538 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Wed, 22 Apr 2026 20:19:14 +0200 Subject: [PATCH 15/22] Update scripts + fix binding --- Makefile | 7 +++++-- default-config.yaml | 1 + scripts/config_edit.py | 5 +++++ scripts/jinja/customize.py | 7 +++++++ scripts/thesis/mobility.py | 18 ++++++++++++++++-- templates/compose.yaml.j2 | 31 +++++++++++++++++++++++++++++++ 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index aa39df0..8249748 100644 --- a/Makefile +++ b/Makefile @@ -356,8 +356,8 @@ plot/latency-switch: .PHONY: thesis/plot/binding thesis/plot/binding: - @echo "Warning: this scenario is currently broken" @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 @@ -397,6 +397,7 @@ thesis/plot/binding: .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 @@ -488,7 +489,7 @@ thesis/plot/mobility/ulcl: thesis/plot/mobility/posteriori/central: @echo "Warning: this scenario is currently broken" @echo "[1/7] Configuring testbed with NextMN-SRv6" - @./scripts/config_edit.py $(BCONFIG) --handover=true + @./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/1 @@ -500,6 +501,7 @@ thesis/plot/mobility/posteriori/central: @$(MAKE) up @echo "[3/7] Adding latencies" @# central DN latency + @# TODO @# 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 @@ -510,6 +512,7 @@ thesis/plot/mobility/posteriori/central: @# 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) + @# TODO: inter-areas for sr4mec is in ipv6 #@docker exec srgw0-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw0 to srgw1 via inter-areas #@docker exec srgw1-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw1 to srgw0 via inter-areas @# srgw0 (edge 1) - r2 (edge 2) diff --git a/default-config.yaml b/default-config.yaml index 69acf31..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 ) 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/jinja/customize.py b/scripts/jinja/customize.py index d817dab..013ff17 100644 --- a/scripts/jinja/customize.py +++ b/scripts/jinja/customize.py @@ -629,3 +629,10 @@ def container_setup(name: str) -> str: "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/thesis/mobility.py b/scripts/thesis/mobility.py index 133043e..69ddd4f 100755 --- a/scripts/thesis/mobility.py +++ b/scripts/thesis/mobility.py @@ -8,6 +8,16 @@ 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''' @@ -21,12 +31,16 @@ def plot(arguments: argparse.Namespace): first = res[0]['tsp'][0] for i, timestamp in enumerate(res[0]['tsp']): res[0]['tsp'][i] = timestamp - first - _, axplt = plt.subplots() + mpl.rcParams["font.size"] = 15 + _, axplt = plt.subplots(figsize=(7,4.2)) + axplt.set_xlim(-1, 21) 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.savefig(arguments.output) + plt.tight_layout() + plt.savefig(arguments.output, bbox_inches='tight') print(f'plot saved in {arguments.output}') if __name__ == '__main__': diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index 6a92d73..69c008b 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -2007,6 +2007,34 @@ configs: 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: + 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: + uplink-segments: + downlink-segments: + handover-migration: + srgw: + srgw-gtp4: + anchor: + uplink-segments: + downlink-segments: + sr4mec-1: + migration-a-posteriori: {{ migration_a_posteriori() }} + migration-delay: "3s" + service: "{{ ipv4('s', 'service') }}" + #~ endif slices: #~ if "nextmn-srv6" in config["topology"]["dataplane"] sr4mec-0: @@ -2140,6 +2168,9 @@ configs: 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"] f5gc-0: From d03d357fc5360b608d58cc2721f9459fe2e55cf1 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Thu, 23 Apr 2026 20:36:15 +0200 Subject: [PATCH 16/22] Update template --- templates/compose.yaml.j2 | 50 +++++++++++++++++++++++++++++++------- templates/images-list.yaml | 3 ++- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index 69c008b..ce91e71 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1137,8 +1137,8 @@ services: secrets: - r2_db_password networks: - control: - ipv6_address: "{{ ipv6('r2', 'control') }}" + rest: + ipv6_address: "{{ ipv6('r2', 'rest') }}" dataplane: ipv6_address: "{{ ipv6('r2', 'dataplane') }}" edge: @@ -1578,7 +1578,13 @@ services: #~ if config["topology"]["nb_ue"] > 1 {{ container_s(name='uel2', service='nextmn-ue-lite', enable_ipv6=True, debug='always', debug_volume=False, iface_tun=True, cap_net_admin=True) }} depends_on: + {{ 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: @@ -1840,9 +1846,15 @@ configs: 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('gnbl2', 'rest') }}]:8080" + - gnb: "http://[{{ ipv6('gnbl1', 'rest') }}]:8080" dnn: "sr4mec-1" logger: level: "{{ log_level() }}" @@ -2014,26 +2026,46 @@ configs: uri: "http://[{{ ipv6('cp-lite', 'rest') }}]:8080" bind-addr: "[{{ ipv6('cp-lite', 'rest') }}]:8080" slices: - sr4mec-0: + 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: + anchor: "http://[{{ ipv6('r0', 'rest') }}]:8080" uplink-segments: + - "{{ ipv6('end-dx4', 'r0') }}" downlink-segments: + - "{{ ipv6_prefix('end-m-gtp4-e', 'srgw0') }}" handover-migration: - srgw: - srgw-gtp4: - anchor: + 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: - sr4mec-1: + - "{{ 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"] diff --git a/templates/images-list.yaml b/templates/images-list.yaml index e2cb67b..a757ee1 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -68,7 +68,8 @@ services: nextmn-cp-lite: image: ghcr.io/nextmn/cp-lite:delay build: - context: https://github.com/nextmn/cp-lite.git#6b3c43198d62b01fe64a31f0754785241854594d + #context: https://github.com/nextmn/cp-lite.git#6b3c43198d62b01fe64a31f0754785241854594d # version before n4 emulation + context: https://github.com/nextmn/cp-lite.git#ed65b235402c702d46e9cce83a344d664ba6361d args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From d713cb64c5df0b497a844e6a7f96460af747121b Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 24 Apr 2026 14:51:50 +0200 Subject: [PATCH 17/22] Update scenarios --- Makefile | 178 +++++++++++++++++++++++++++++++++---- templates/compose.yaml.j2 | 18 ++-- templates/images-list.yaml | 3 +- 3 files changed, 172 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 8249748..876ea38 100644 --- a/Makefile +++ b/Makefile @@ -447,7 +447,6 @@ thesis/plot/mobility/ulcl: @echo "[2/7] Starting containers" @$(MAKE) up @echo "[3/7] Adding latencies" - @# central DN latency @# 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 @@ -487,13 +486,12 @@ thesis/plot/mobility/ulcl: .PHONY: thesis/plot/mobility/posteriori/central thesis/plot/mobility/posteriori/central: - @echo "Warning: this scenario is currently broken" @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/1 - @$(MAKE) set/nb-edges/2 + @$(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 @@ -501,7 +499,8 @@ thesis/plot/mobility/posteriori/central: @$(MAKE) up @echo "[3/7] Adding latencies" @# central DN latency - @# TODO + @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 @@ -510,17 +509,17 @@ thesis/plot/mobility/posteriori/central: @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" + @docker exec inter-areas-debug bash -c "tc qdisc add dev dataplane-0 root netem delay 2ms" @# srgw0 (edge 1) - srgw1 (edge 2) - @# TODO: inter-areas for sr4mec is in ipv6 - #@docker exec srgw0-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw0 to srgw1 via inter-areas - #@docker exec srgw1-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw1 to srgw0 via inter-areas - @# srgw0 (edge 1) - r2 (edge 2) - #@docker exec srgw0-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw0 to r2 via inter-areas - #@docker exec r2-debug bash -c "ip route replace TODO via 10.1.4.146" # from r2 to srgw0 via inter-areas - @# srgw1 (edge 2) - r1 (edge 1) - #@docker exec srgw1-debug bash -c "ip route replace TODO via 10.1.4.146" # from srgw1 to r1 via inter-areas - #@docker exec r1-debug bash -c "ip route replace TODO via 10.1.4.146" # from r1 to srgw1 via inter-areas + @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)(edge 2)(edge 2)(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" @@ -531,5 +530,152 @@ thesis/plot/mobility/posteriori/central: @$(MAKE) down @echo "[7/7] Plotting data" @mkdir -p $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/ - @cp $(BUILD_DIR)/volumes/uel5/ping-mobility-posteriori-central.txt $(BUILD_DIR)/thesis-plots/mobility/$(DATE)/posteriori-central.txt + @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)(edge 2)(edge 2)(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-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 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)(edge 2)(edge 2)(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)(edge 2)(edge 2)(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-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 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 diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index ce91e71..c02da8e 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1044,8 +1044,8 @@ services: configs: - {{ mount_xdg_config_s('r0', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - NEI_ADDR: "{{ ipv6_subnet('r1') }} {{ ipv6_subnet('srgw0') }} {{ ipv4('s', 'service') }}" - NEI_NH: "{{ ipv6('r1', 'dataplane') }} {{ ipv6('srgw0', 'dataplane') }} {{ ipv4('s0', 'edge') }}" + 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" {{ environment_postgres_socket_path() }} @@ -1086,8 +1086,8 @@ services: configs: - {{ mount_xdg_config_s('r1', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - NEI_ADDR: "{{ ipv6_subnet('r0') }} {{ ipv6_subnet('srgw0') }} {{ ipv4('s', 'service') }}" - NEI_NH: "{{ ipv6('r0', 'dataplane') }} {{ ipv6('srgw0', 'dataplane') }} {{ ipv4('s1', 'edge') }}" + 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" {{ environment_postgres_socket_path() }} @@ -1129,8 +1129,8 @@ services: configs: - {{ mount_xdg_config_s('r2', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - NEI_ADDR: "{{ ipv6_subnet('srgw1') }} {{ ipv4('s', 'service') }}" - NEI_NH: "{{ ipv6('srgw1', 'dataplane') }} {{ ipv4('s2', 'edge') }}" + 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" {{ environment_postgres_socket_path() }} @@ -1214,8 +1214,8 @@ services: configs: - {{ mount_xdg_config_s('srgw1', 'nextmn-srv6/config.yaml') | indent(3) }} environment: - NEI_ADDR: "{{ ipv6_subnet('r2') }}" - NEI_NH: "{{ ipv6('r2', 'dataplane') }}" + 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" {{ environment_postgres_socket_path() }} @@ -1576,7 +1576,7 @@ services: ipv6_address: "{{ ipv6('uel1', 'rest') }}" #~ if config["topology"]["nb_ue"] > 1 - {{ container_s(name='uel2', service='nextmn-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: {{ depends_on_healthy_s('gnbl1') | indent(2) }} #~ if config["topology"]["ran"]["handover"] diff --git a/templates/images-list.yaml b/templates/images-list.yaml index a757ee1..003c0c8 100644 --- a/templates/images-list.yaml +++ b/templates/images-list.yaml @@ -68,8 +68,7 @@ services: nextmn-cp-lite: image: ghcr.io/nextmn/cp-lite:delay build: - #context: https://github.com/nextmn/cp-lite.git#6b3c43198d62b01fe64a31f0754785241854594d # version before n4 emulation - context: https://github.com/nextmn/cp-lite.git#ed65b235402c702d46e9cce83a344d664ba6361d + context: https://github.com/nextmn/cp-lite.git#edc814c9cfe66b17a5c756a0441129028254d6fc args: SOURCE_DATE_EPOCH: 0 BUILDKIT_CONTEXT_KEEP_GIT_DIR: true From 02884aa7ed53fa2dba9dc5ae7f3af2cb5badfa64 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 24 Apr 2026 15:03:14 +0200 Subject: [PATCH 18/22] Fixup --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 876ea38..648355b 100644 --- a/Makefile +++ b/Makefile @@ -570,7 +570,7 @@ thesis/plot/mobility/posteriori/edge: @sleep 2 @#### @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" - @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel2 sr4mec-0 gnbl3 gnbl1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 1 to Area 2"' & + @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"' & @@ -668,7 +668,7 @@ thesis/plot/mobility/immediate/edge: @sleep 2 @#### @echo "[4/7] [$$(date --rfc-3339=seconds)] Scheduling instance switch in 10s" - @bash -c 'sleep 10 && scripts/handover.py $(BCONFIG) uel2 sr4mec-0 gnbl3 gnbl1 && echo "[5.5/7] [$$(date --rfc-3339=seconds)] Mobility from Area 1 to Area 2"' & + @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"' & From c4040ad0c7e255161b047b42a39ae568f2d93d30 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 24 Apr 2026 15:54:11 +0200 Subject: [PATCH 19/22] Enable ipv6 forwarding in inter-areas --- Makefile | 8 ++++---- templates/compose.yaml.j2 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 648355b..acc20d1 100644 --- a/Makefile +++ b/Makefile @@ -513,7 +513,7 @@ thesis/plot/mobility/posteriori/central: @# 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)(edge 2)(edge 2)(edge 2) + @# 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 @#### @@ -562,7 +562,7 @@ thesis/plot/mobility/posteriori/edge: @# 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)(edge 2)(edge 2)(edge 2) + @# 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 @#### @@ -611,7 +611,7 @@ thesis/plot/mobility/immediate/central: @# 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)(edge 2)(edge 2)(edge 2) + @# 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 @#### @@ -660,7 +660,7 @@ thesis/plot/mobility/immediate/edge: @# 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)(edge 2)(edge 2)(edge 2) + @# 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 @#### diff --git a/templates/compose.yaml.j2 b/templates/compose.yaml.j2 index c02da8e..b55ced8 100644 --- a/templates/compose.yaml.j2 +++ b/templates/compose.yaml.j2 @@ -1742,7 +1742,7 @@ services: ipv6_address: "{{ ipv6('cp-lite', 'rest') }}" #~ endif - {{ container_s(name='inter-areas', service='docker-setup', enable_ipv6=True, debug='allow', debug_volume=False, cap_net_admin=True) }} + {{ 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') }} From 578f8e547719581d1fec81bb4bde945e9230d21a Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 24 Apr 2026 15:57:24 +0200 Subject: [PATCH 20/22] Add target thesis/plot/mobility --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index acc20d1..e319c34 100644 --- a/Makefile +++ b/Makefile @@ -679,3 +679,10 @@ thesis/plot/mobility/immediate/edge: @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/posteriori/edge From 4c10dbd65650ff5fd9c684c74b1381e095f01c9b Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 24 Apr 2026 16:20:25 +0200 Subject: [PATCH 21/22] fixup --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e319c34..7f0c999 100644 --- a/Makefile +++ b/Makefile @@ -685,4 +685,4 @@ 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/posteriori/edge + $(MAKE) thesis/plot/mobility/immediate/edge From f42eb277d520d7790249e9c3028c04be9a83e96a Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 24 Apr 2026 22:12:05 +0200 Subject: [PATCH 22/22] Update scripts thesis --- scripts/thesis/binding.py | 2 +- scripts/thesis/migration.py | 2 +- scripts/thesis/mobility.py | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/thesis/binding.py b/scripts/thesis/binding.py index e7a6abb..250ac04 100755 --- a/scripts/thesis/binding.py +++ b/scripts/thesis/binding.py @@ -33,7 +33,7 @@ def plot(arguments: argparse.Namespace): mpl.rcParams["font.size"] = 15 _, axplt = plt.subplots(figsize=(7,4.2)) axplt.set_xlim(-1, 61) - axplt.set_xlabel('t (s)') + 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', diff --git a/scripts/thesis/migration.py b/scripts/thesis/migration.py index 830020e..02f1964 100755 --- a/scripts/thesis/migration.py +++ b/scripts/thesis/migration.py @@ -33,7 +33,7 @@ def plot(arguments: argparse.Namespace): mpl.rcParams["font.size"] = 15 _, axplt = plt.subplots(figsize=(7,4.2)) axplt.set_xlim(-1, 61) - axplt.set_xlabel('t(s)') + 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') diff --git a/scripts/thesis/mobility.py b/scripts/thesis/mobility.py index 69ddd4f..ec46d79 100755 --- a/scripts/thesis/mobility.py +++ b/scripts/thesis/mobility.py @@ -34,7 +34,8 @@ def plot(arguments: argparse.Namespace): mpl.rcParams["font.size"] = 15 _, axplt = plt.subplots(figsize=(7,4.2)) axplt.set_xlim(-1, 21) - axplt.set_xlabel('t(s)') + 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))