From 10099d692125361dda4a49b13050cff9d21e64cb Mon Sep 17 00:00:00 2001 From: hxngillani Date: Wed, 26 Feb 2025 23:51:26 +0100 Subject: [PATCH 1/2] Enhancement: Improved UPF routing and NAT handling - Replaced static aether-ue-nat.service with dynamic aether-ue-nat.service.j2 - Updated install.yaml to use Jinja2 templating for NAT service - Improved 20-aether-core.network to dynamically add routes for additional UPFs - Modified add UPF module to check for existing routes before adding - Ensured consistent route management between core network and UPF installation Signed-off-by: hxngillani --- roles/router/tasks/install.yml | 15 ++++-------- .../templates/systemd/20-aether-core.network | 10 ++++++++ .../templates/systemd/aether-ue-nat.service | 9 ------- .../systemd/aether-ue-nat.service.j2 | 24 +++++++++++++++++++ roles/upf/tasks/install.yml | 2 ++ 5 files changed, 41 insertions(+), 19 deletions(-) delete mode 100644 roles/router/templates/systemd/aether-ue-nat.service create mode 100644 roles/router/templates/systemd/aether-ue-nat.service.j2 diff --git a/roles/router/tasks/install.yml b/roles/router/tasks/install.yml index e6f7f5c..1993494 100644 --- a/roles/router/tasks/install.yml +++ b/roles/router/tasks/install.yml @@ -1,5 +1,3 @@ ---- - # TODO: running on master node for now (fix to run on multiple nodes) - set_fact: @@ -70,11 +68,6 @@ when: inventory_hostname in groups['master_nodes'] become: true -- name: Disable GRO flag on the {{ core.data_iface }} interface - shell: ethtool -K {{ core.data_iface }} gro off - when: inventory_hostname in groups['master_nodes'] - become: true - - name: find {{ core.data_iface }}'s netplan network directory shell: basename $(find /*/systemd/network -maxdepth 1 -not -type d -name '*{{ core.data_iface }}.network' -print) register: result @@ -95,10 +88,12 @@ when: inventory_hostname in groups['master_nodes'] become: true -- name: copy aether-ue-nat.service to {{ systemd_system_dir }}/aether-ue-nat.service +# Use Jinja template for `aether-ue-nat.service` +- name: Generate aether-ue-nat.service dynamically template: - src: roles/router/templates/systemd/aether-ue-nat.service + src: roles/router/templates/systemd/aether-ue-nat.service.j2 dest: "{{ systemd_system_dir }}/aether-ue-nat.service" + mode: "0644" when: inventory_hostname in groups['master_nodes'] become: true @@ -122,7 +117,7 @@ when: inventory_hostname in groups['master_nodes'] become: true -- name: restart systemd-networkd +- name: Restart systemd-networkd systemd: name: systemd-networkd state: restarted diff --git a/roles/router/templates/systemd/20-aether-core.network b/roles/router/templates/systemd/20-aether-core.network index 43499f8..d88debf 100644 --- a/roles/router/templates/systemd/20-aether-core.network +++ b/roles/router/templates/systemd/20-aether-core.network @@ -8,6 +8,16 @@ Name=core IPForward=yes Address={{ core.upf.core_subnet }} +# Default UPF Route [Route] Gateway={{ core.upf.default_upf.ip.core }} Destination={{ core.upf.default_upf.ue_ip_pool }} + +# Additional UPFs - Dynamically Generated Routes +{% if core.upf.additional_upfs is defined and core.upf.additional_upfs %} +{% for upf in core.upf.additional_upfs.values() %} +[Route] +Gateway={{ upf.ip.core }} +Destination={{ upf.ue_ip_pool }} +{% endfor %} +{% endif %} diff --git a/roles/router/templates/systemd/aether-ue-nat.service b/roles/router/templates/systemd/aether-ue-nat.service deleted file mode 100644 index 50e8473..0000000 --- a/roles/router/templates/systemd/aether-ue-nat.service +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2022-present Open Networking Foundation -# SPDX-License-Identifier: Apache-2.0 - -[Service] -Type=oneshot -ExecStart=/bin/bash -c "sudo iptables -t nat -C POSTROUTING -s {{ core.upf.default_upf.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || sudo iptables -t nat -A POSTROUTING -s {{ core.upf.default_upf.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE" - -[Install] -WantedBy=sys-subsystem-net-devices-core.device diff --git a/roles/router/templates/systemd/aether-ue-nat.service.j2 b/roles/router/templates/systemd/aether-ue-nat.service.j2 new file mode 100644 index 0000000..235b680 --- /dev/null +++ b/roles/router/templates/systemd/aether-ue-nat.service.j2 @@ -0,0 +1,24 @@ +# Copyright 2022-present Open Networking Foundation +# SPDX-License-Identifier: Apache-2.0 + +[Unit] +Description=Aether UE NAT Setup +After=network.target + +[Service] +Type=oneshot +ExecStart=/bin/bash -c "\ + sudo iptables -t nat -C POSTROUTING -s {{ core.upf.default_upf.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || \ + sudo iptables -t nat -A POSTROUTING -s {{ core.upf.default_upf.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE; \ + {% if '1' in core.upf.additional_upfs %} \ + sudo iptables -t nat -C POSTROUTING -s {{ core.upf.additional_upfs['1'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || \ + sudo iptables -t nat -A POSTROUTING -s {{ core.upf.additional_upfs['1'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE; \ + {% endif %} \ + {% if '2' in core.upf.additional_upfs %} \ + sudo iptables -t nat -C POSTROUTING -s {{ core.upf.additional_upfs['2'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || \ + sudo iptables -t nat -A POSTROUTING -s {{ core.upf.additional_upfs['2'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE; \ + {% endif %} \ +" + +[Install] +WantedBy=multi-user.target diff --git a/roles/upf/tasks/install.yml b/roles/upf/tasks/install.yml index 95b16df..6559444 100644 --- a/roles/upf/tasks/install.yml +++ b/roles/upf/tasks/install.yml @@ -54,8 +54,10 @@ - name: configure route for upf traffic on gnbsim node shell: | + ip route show | grep -q "{{ item.value.ue_ip_pool }} via {{ item.value.ip.core }}" || \ ip route add {{ item.value.ue_ip_pool }} via {{ item.value.ip.core }} when: inventory_hostname in groups['master_nodes'] with_dict: "{{ core.upf.additional_upfs}}" become: true + # ignore_errors: yes From 8985a13cc90144c838a25eb064750ebe4ac90cf3 Mon Sep 17 00:00:00 2001 From: hxngillani Date: Thu, 27 Feb 2025 00:24:00 +0100 Subject: [PATCH 2/2] UE NAT setup to support dynamic UPF scaling Signed-off-by: hxngillani --- roles/router/tasks/install.yml | 5 +++++ .../templates/systemd/20-aether-core.network | 10 ---------- .../templates/systemd/aether-ue-nat.service.j2 | 14 +++++--------- roles/upf/tasks/install.yml | 2 -- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/roles/router/tasks/install.yml b/roles/router/tasks/install.yml index 1993494..3d6cc63 100644 --- a/roles/router/tasks/install.yml +++ b/roles/router/tasks/install.yml @@ -68,6 +68,11 @@ when: inventory_hostname in groups['master_nodes'] become: true +- name: Disable GRO flag on the {{ core.data_iface }} interface + shell: ethtool -K {{ core.data_iface }} gro off + when: inventory_hostname in groups['master_nodes'] + become: true + - name: find {{ core.data_iface }}'s netplan network directory shell: basename $(find /*/systemd/network -maxdepth 1 -not -type d -name '*{{ core.data_iface }}.network' -print) register: result diff --git a/roles/router/templates/systemd/20-aether-core.network b/roles/router/templates/systemd/20-aether-core.network index d88debf..43499f8 100644 --- a/roles/router/templates/systemd/20-aether-core.network +++ b/roles/router/templates/systemd/20-aether-core.network @@ -8,16 +8,6 @@ Name=core IPForward=yes Address={{ core.upf.core_subnet }} -# Default UPF Route [Route] Gateway={{ core.upf.default_upf.ip.core }} Destination={{ core.upf.default_upf.ue_ip_pool }} - -# Additional UPFs - Dynamically Generated Routes -{% if core.upf.additional_upfs is defined and core.upf.additional_upfs %} -{% for upf in core.upf.additional_upfs.values() %} -[Route] -Gateway={{ upf.ip.core }} -Destination={{ upf.ue_ip_pool }} -{% endfor %} -{% endif %} diff --git a/roles/router/templates/systemd/aether-ue-nat.service.j2 b/roles/router/templates/systemd/aether-ue-nat.service.j2 index 235b680..9b3945d 100644 --- a/roles/router/templates/systemd/aether-ue-nat.service.j2 +++ b/roles/router/templates/systemd/aether-ue-nat.service.j2 @@ -10,15 +10,11 @@ Type=oneshot ExecStart=/bin/bash -c "\ sudo iptables -t nat -C POSTROUTING -s {{ core.upf.default_upf.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || \ sudo iptables -t nat -A POSTROUTING -s {{ core.upf.default_upf.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE; \ - {% if '1' in core.upf.additional_upfs %} \ - sudo iptables -t nat -C POSTROUTING -s {{ core.upf.additional_upfs['1'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || \ - sudo iptables -t nat -A POSTROUTING -s {{ core.upf.additional_upfs['1'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE; \ - {% endif %} \ - {% if '2' in core.upf.additional_upfs %} \ - sudo iptables -t nat -C POSTROUTING -s {{ core.upf.additional_upfs['2'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || \ - sudo iptables -t nat -A POSTROUTING -s {{ core.upf.additional_upfs['2'].ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE; \ - {% endif %} \ + {% for upf_key, upf_data in core.upf.additional_upfs.items() %} \ + sudo iptables -t nat -C POSTROUTING -s {{ upf_data.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || \ + sudo iptables -t nat -A POSTROUTING -s {{ upf_data.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE; \ + {% endfor %} \ " [Install] -WantedBy=multi-user.target +WantedBy=sys-subsystem-net-devices-core.device diff --git a/roles/upf/tasks/install.yml b/roles/upf/tasks/install.yml index 6559444..bf4d41e 100644 --- a/roles/upf/tasks/install.yml +++ b/roles/upf/tasks/install.yml @@ -59,5 +59,3 @@ when: inventory_hostname in groups['master_nodes'] with_dict: "{{ core.upf.additional_upfs}}" become: true - - # ignore_errors: yes