Skip to content

Conversation

hxngillani
Copy link

@hxngillani hxngillani commented Feb 26, 2025

Enhancement: Dynamic UPF Routing and NAT Handling

Changes Made:

  • Replaced static aether-ue-nat.service with aether-ue-nat.service.j2 for dynamic NAT configuration..
  • Updated install.yaml to generate the NAT service dynamically based on UPF configuration.
  • Improved 20-aether-core.network to dynamically add routes for additional UPFs.
  • Modified the UPF module to check for existing routes before adding, preventing duplicate route errors.
  • Ensured a consistent and streamlined route management approach between the core network and UPF installation.

Why This Change?

  • The original aether-ue-nat.service was static, meaning new UPFs required manual modifications.
  • Using Jinja2 templating allows the NAT service to automatically adapt to new UPFs.
  • Previously, additional UPFs required route configuration, which is being done in UPF role in install task which near me should be part of router role.
  • The new approach automates UPF routing in router role section
  • Ensures that UPF routes do not fail with RTNETLINK answers: File exists when adding new UPFs.

Testing & Validation:

  • Successfully deployed Aether 5GC with multiple UPFs without issues.
  • Verified dynamic generation of NAT service using Jinja2.
  • Ensured UPF routing was correctly applied without requiring manual intervention.
  • No duplicate route errors occurred when adding multiple UPFs.

Notes for Reviewers:

  • Please verify if moving route handling to the router section aligns with project best practices.
  • Open to feedback on improving the logic for route management.

@hxngillani hxngillani force-pushed the upf-routing-improvements branch from 081a98a to fd8760a Compare February 26, 2025 23:26
@gab-arrobo
Copy link
Contributor

Hi @hxngillani, thanks for your contribution

Hi @llpeterson, @mbilal92, can you please review this PR? Thanks!

Comment on lines 13 to 20
{% 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 %} \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if someone wants to deploy more than 2 additional UPFs? Would it be better to replace these if statements by a for loop?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for review great idea let me do that and test if it works will then amend in PR

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have updated and tested it is working now for multiple UPFs use case.

Screenshot from 2025-02-27 20-43-52

@hxngillani hxngillani force-pushed the upf-routing-improvements branch from fd8760a to cea71ab Compare February 27, 2025 19:40
Comment on lines 62 to 63

# ignore_errors: yes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If ignore_errors is not used, I think it is better to just remove it

Suggested change
# ignore_errors: yes

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gab-arrobo I thought ignore_errors was added for some reason, but it was already there should i remove it ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gab-arrobo i for now i have removed as it is not being used

[Route]
Gateway={{ core.upf.default_upf.ip.core }}
Destination={{ core.upf.default_upf.ue_ip_pool }}

# Additional UPFs - Dynamically Generated Routes
Copy link
Contributor

@mbilal92 mbilal92 Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hxngillani, this approach works well if you know the number of UPFs to deploy upfront. However, if you add more UPFs later, you’d need to rerun the setup. It would be better to make this independent, allowing users to deploy additional UPFs without reconfiguring the system.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i agree my idea was to put routing related configs in route section because when we enable multiple upfs in main.yml i assumed these will be deployed so route will configure but yeah route config while ups is added is also fine.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will amend with previous route configuration :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great, I’d recommend creating a router configuration file as part of the additional UPF role.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbilal92 done please check

@mbilal92
Copy link
Contributor

mbilal92 commented Mar 12, 2025

@hxngillani left a comment. Let's keep support to add additional UPFs apart from the router.

@hxngillani hxngillani force-pushed the upf-routing-improvements branch 3 times, most recently from 470ec9e to fda8928 Compare March 12, 2025 01:53
@@ -10,4 +10,4 @@ Address={{ core.upf.core_subnet }}

[Route]
Gateway={{ core.upf.default_upf.ip.core }}
Destination={{ core.upf.default_upf.ue_ip_pool }}
Destination={{ core.upf.default_upf.ue_ip_pool }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add an empty line to the files that you modified and have the red symbol

@hxngillani hxngillani force-pushed the upf-routing-improvements branch 3 times, most recently from c537d64 to d73e970 Compare March 12, 2025 13:36
@gab-arrobo
Copy link
Contributor

@mbilal92, any update on the review for this PR? Thanks!

@mbilal92
Copy link
Contributor

mbilal92 commented Mar 24, 2025

@gab-arrobo, looks good to me.
@hxngillani, could you please write down how you tested it?

@hxngillani
Copy link
Author

@mbilal92 for testing i used below commands to make sure that UE NAT service is UP and running and MASQUERADE rules show expected subnets and also i used UERANSIM to connected UE with additional upf and i able to access internet successfully.

hassan@Aether:~/aether-onramp$ cat /etc/systemd/system/aether-ue-nat.service 
# 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 172.250.0.0/16 -o enp0s9 -j MASQUERADE || \
    sudo iptables -t nat -A POSTROUTING -s 172.250.0.0/16 -o enp0s9 -j MASQUERADE; \
     \
    sudo iptables -t nat -C POSTROUTING -s 172.248.0.0/16 -o enp0s9 -j MASQUERADE || \
    sudo iptables -t nat -A POSTROUTING -s 172.248.0.0/16 -o enp0s9 -j MASQUERADE; \
     \
"

[Install]
WantedBy=sys-subsystem-net-devices-core.devicehassan@Aether:~/aether-onramp$ 
hassan@Aether:~/aether-onramp$ systemctl status aether-ue-nat.service
○ aether-ue-nat.service - Aether UE NAT Setup
     Loaded: loaded (/etc/systemd/system/aether-ue-nat.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Mon 2025-03-24 14:02:35 UTC; 14min ago
    Process: 46315 ExecStart=/bin/bash -c      sudo iptables -t nat -C POSTROUTING -s 172.250.0.0/16 >
   Main PID: 46315 (code=exited, status=0/SUCCESS)
        CPU: 17ms

Mar 24 14:02:35 Aether sudo[46316]:     root : PWD=/ ; USER=root ; COMMAND=/usr/sbin/iptables -t nat >
Mar 24 14:02:35 Aether sudo[46316]: pam_unix(sudo:session): session opened for user root(uid=0) by (u>
Mar 24 14:02:35 Aether bash[46317]: MASQUERADE  all opt -- in * out enp0s9  172.250.0.0/16  -> 0.0.0.>
Mar 24 14:02:35 Aether sudo[46316]: pam_unix(sudo:session): session closed for user root
Mar 24 14:02:35 Aether sudo[46318]:     root : PWD=/ ; USER=root ; COMMAND=/usr/sbin/iptables -t nat >
Mar 24 14:02:35 Aether sudo[46318]: pam_unix(sudo:session): session opened for user root(uid=0) by (u>
Mar 24 14:02:35 Aether bash[46319]: MASQUERADE  all opt -- in * out enp0s9  172.248.0.0/16  -> 0.0.0.>
Mar 24 14:02:35 Aether sudo[46318]: pam_unix(sudo:session): session closed for user root
Mar 24 14:02:35 Aether systemd[1]: aether-ue-nat.service: Deactivated successfully.
Mar 24 14:02:35 Aether systemd[1]: Finished Aether UE NAT Setup.

hassan@Aether:~/aether-onramp$ sudo iptables -t nat -L -n -v | grep MASQUERADE
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      enp0s9  172.250.0.0/16       0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      enp0s9  172.248.0.0/16       0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            mark match 0x2000/0x2000
  440 26846 MASQUERADE  all  --  *      *       10.42.0.0/16        !224.0.0.0/4          /* flanneld masq */ random-fully
    0     0 MASQUERADE  all  --  *      *      !10.42.0.0/16         10.42.0.0/16         /* flanneld masq */ random-fully
    0     0 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service traffic requiring SNAT */ random-fully
    0     0 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:flqWnvo8yq4ULQLa */ match-set cali40masq-ipam-pools src ! match-set cali40all-ipam-pools dst random-fully
hassan@Aether:~/aether-onramp$ 

@jrmcclurg
Copy link
Contributor

jrmcclurg commented Apr 14, 2025

Hi all, I ran into this issue (improperly configured NAT for additional UPFs) and found the following simple fix:

Add the following at the end of deps/5gc/roles/upf/tasks/install.yml:

- name: configure NAT for upf traffic
  shell: |
    sudo iptables -t nat -C POSTROUTING -s {{ item.value.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE || sudo iptables -t nat -A POSTROUTING -s {{ item.value.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE
  when: inventory_hostname in groups['master_nodes']
  with_dict: "{{ core.upf.additional_upfs}}"
  become: true
  # ignore_errors: yes

Then, any time a new UPF is added, simply do make 5gc-upf-install.

I'm a bit worried that this PR would require a make 5gc-install followed by make 5gc-upf-install when adding a new UPF.

@gab-arrobo
Copy link
Contributor

Hi all, I ran into this issue (improperly configured NAT for additional UPFs) and found the following simple fix:

Add the following at the end of deps/5gc/roles/upf/tasks/install.yml:

- name: configure NAT for upf traffic
  shell: |
    sudo iptables -t nat -C POSTROUTING -s {{ item.value.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE
    sudo iptables -t nat -A POSTROUTING -s {{ item.value.ue_ip_pool }} -o {{ core.data_iface }} -j MASQUERADE
  when: inventory_hostname in groups['master_nodes']
  with_dict: "{{ core.upf.additional_upfs}}"
  become: true
  # ignore_errors: yes

Then, any time a new UPF is added, simply do make 5gc-upf-install.

I'm a bit worried that this PR would require a make 5gc-install followed by make 5gc-upf-install when adding a new UPF.

Hi @hxngillani, what are your thoughts about Jed's comment?

Hi @jrmcclurg, feel free to open a PR with your solution.

@jrmcclurg
Copy link
Contributor

Thanks @gab-arrobo. @hxngillani please let me know if my approach above works in your setup. I haven't done extensive testing with it, so I may be missing something. If it works for you, I can make it into a PR.

@gab-arrobo
Copy link
Contributor

@hxngillani, please rebase your PR. Thanks!

- 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 <[email protected]>
@hxngillani hxngillani force-pushed the upf-routing-improvements branch from d73e970 to 8985a13 Compare April 16, 2025 06:05
@hxngillani
Copy link
Author

Thanks @gab-arrobo. @hxngillani please let me know if my approach above works in your setup. I haven't done extensive testing with it, so I may be missing something. If it works for you, I can make it into a PR.

@jrmcclurg Thank you for the solution. can you please try to reboot your system and check if routes that you are configuring in install are persistent?

@jrmcclurg
Copy link
Contributor

jrmcclurg commented Apr 17, 2025

@hxngillani I can confirm that the NAT routes installed by my fix are not persistent after a restart. However, I have also found that many other routes are also not persistent (e.g., those installed by the many iptables commands executed when performing make 5gc-install, make gnbsim-install, etc.).

So I think your PR is targeting an important issue (persistence of routes), but it only addresses it in the context of UPF-related routes. Much more work would be needed to fully address that issue. More importantly, I am concerned about the need to do make 5gc-install every time a new UPF is added/reconfigured -- that is very slow on my machine. I think the functionality you're proposing would be better in make 5gc-upf-install.

@jrmcclurg
Copy link
Contributor

Hi all, I have added my fix as a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants