== Running OsmoUPF The OsmoUPF executable (`osmo-upf`) offers the following command-line arguments: === SYNOPSIS *osmo-upf* [-h|-V] [-D] [-c 'CONFIGFILE'] === OPTIONS *-h, --help*:: Print a short help message about the supported options *-V, --version*:: Print the compile-time version number of the OsmoHNBGW program *-D, --daemonize*:: Fork the process as a daemon into background. *-c, --config-file 'CONFIGFILE'*:: Specify the file and path name of the configuration file to be used. If none is specified, use `osmo-upf.cfg` in the current working directory. === Multiple instances Running multiple instances of `osmo-upf` on the same computer is possible if all interfaces (VTY, CTRL, PFCP) are separated using the appropriate configuration options. The IP based interfaces are binding to local host by default. In order to separate the processes, the user has to bind those services to different ports, or different specific IP addresses. The VTY and the Control interface can be bound to IP addresses from the loopback address range, for example: ---- line vty bind 127.0.0.2 ctrl bind 127.0.0.2 ---- The PFCP port is specified to be fixed as port 8805. Hence, each osmo-upf process needs to run on a distinct local interface: ---- pfcp local-addr 10.9.0.2 ---- For GTP encapsulation/decapsulation and GTP tunnel relaying, osmo-upf depends on the IP addresses configured at the Linux kernel GTP module, and the IP addresses negotiated within PFCP by the control plane function. If multiple `osmo-upf` processes are running on the same Linux kernel, each `osmo-upf` needs to be configured with a distinct netfilter table name, so that naming of individual tunnel rulesets does not collide: ---- tunmap table-name osmo-upf-2 ---- === Configure PFCP Server The following example configures OsmoUPF to listen for PFCP association requests from Control Plane Function entities on local interface 10.9.8.7, port 8805: ---- pfcp local-addr 10.9.8.7 ---- 3GPP TS 29.244 4.2.2 specifies that PFCP Request messages shall be sent to UDP port 8805, i.e. the PFCP port is fixed as 8805 and currently not configurable in osmo-upf. Setting a 'local-addr' is required: the PFCP protocol features a Node ID, which uniquely identifies PFCP peers across different interfaces. According to the PFCP specification, the Node ID can be a fully-qualified domain name (FQDN) or an IP address. Currently, osmo-upf has no support for using an FQDN as Node ID, and so far uses the 'local-addr' as local Node ID -- hence the 'local-addr' must not be "0.0.0.0", which is an unfortunate consequence. This is likely to improve in the future, see https://osmocom.org/issues/5682 . === Linux Kernel Features OsmoUPF uses two distinct Linux kernel features: * The GTP module is used for `tunend`: GTP encapsulation/decapsulation from/to "the internet". * The netfilter framework and nftables are used for `tunmap`: GTP tunnel proxying, also known as tunnel forwarding or tunnel mapping. .Linux kernel feature usage [graphviz] ---- include::upf_gtp_roles.dot[] ---- GTP kernel module configuration in the `tunend` section can be omitted for sites that serve only as GTP forwarding proxy, without encapsulation/decapsulation of GTP payloads -- except to provide GTP Echo service, see <>. Netfilter configuration in the `tunmap` section can be omitted for sites only serving as GTP tunnel endpoint. [[gtp_module]] === Configure Linux Kernel GTP Module for `tunend` The Linux kernel GTP module is used for the `tunend` use case, i.e. GTP encapsulation/decapsulation from/to "the internet". To use the GTP kernel module, OsmoUPF requires a GTP device, which is a dedicated network device provided by the Linux kernel, serving as GTP tunnel endpoint. It is typically named like "apn0". `osmo-upf` can either create a GTP device on startup, or use a pre-existing GTP device. To en/decapsulate GTP, the APN device needs to be assigned an IP address range that matches the UE IP addresses that are configured in GTP-C / PFCP. The following configuration placed in `osmo-upf.cfg` creates a GTP device called `apn23` on startup of osmo-upf, which is destroyed on program exit. It listens for GTP on local IP address `1.2.3.4`: ---- tunend dev create apn23 1.2.3.4 ---- TODO:: `osmo-upf` is not yet able to configure this network device's IP address range, MTU etc. The following configuration placed in `osmo-upf.cfg` uses a pre-existing device called `apn42`: ---- tunend dev use apn42 2.3.4.5 ---- GTP kernel devices can be managed manually using the `gtp-link` program available from the 'libgtpnl' project: ---- # gtp-link add apn42 (keep this process running) # ip addr add dev apn42 192.168.42.1/24 $ osmo-upf -c osmo-upf.cfg ---- It is possible to configure multiple GTP devices in `osmo-upf.cfg`. Depending on the Network Instance name, osmo-upf creates tunnel endpoints on the GTP device with a matching IP address: - The Network Instance IE in the PDR on the Access side determines the local IP address to use, see <>. - This local IP address in turn determines the GTP device to use. It is possible for a GTP device to listen on ANY -- just omit the IP address in the `dev` config. In this case, all Network Instance names will be served by this GTP device. When using ANY, there should be exactly one GTP dev configured. [[nftables]] === Configure Linux netfilter for `tunmap` The Linux kernel netfilter module is used for GTP tunnel proxying, also known as tunnel forwarding or tunnel mapping. When using the netfilter module, you may set up `osmo-upf.cfg` for: - GTP Echo (required) - nft table name (optional) [[gtp_echo]] ==== GTP Echo You need to ensure that OsmoUPF responds to GTP Echo requests. - A GTP device configured for `tunend` implicitly includes a GTP Echo service. - For `tunmap`, no GTP Echo mechanism is implemented. So, when your use case is `tunmap` only, you should still add a GTP device as for `tunend`, only to provide the GTP Echo service. Here are some options to do so: If you have no GTP devices configured in `osmo-upf.cfg` yet, you can add a single GTP device without a specific IP address, in order to respond to GTP-U Echo requests on all interfaces to anyone that is asking: ---- tunend dev create gtp-echo ---- Note that `gtp-echo` is just an arbitrary GTP device name, choose any string that makes a valid network device name and is still available, as in the `dev` argument in the `ip addr show dev` command on Linux. This will bind osmo-upf on 0.0.0.0:2152 to respond to GTP Echo requests. If you would like to limit GTP Echo responses to specific network interfaces, you need to add a separate GTP device per local IP address: ---- tunend dev create gtp-echo1 192.168.0.23 dev create gtp-echo2 10.9.8.17 ---- This will bind osmo-upf only on 192.168.0.23:2152 and 10.9.8.17:2152 to respond to GTP Echo requests. For creating and manipulating a GTP device in more versatile ways, see <>. ==== nft Table Name For `tunmap`, `osmo-upf` creates a new nft table, under which it submits rule sets for GTP tunnel proxying. This table name defaults to `osmo-upf`. A custom table name can be configured in `osmo-upf.cfg` like this: ---- tunmap table-name my-table-name ---- When running more than one osmo-upf process on a system, pick distinct table names to avoid name collisions in the nftables rulesets. === IP Forwarding In order to allow forwarding GTP payloads, the Linux operating system must be configured to allow IP forwarding. Note that there are many distribution-specific ways to configure this, and there might be higher-level firewall rule management software available like `ufw`. You should configure firewall rules matching your distribution and setup. To allow IP forwarding from and to all interfaces globally in a reboot-safe way, you may put a line like this in /etc/sysctl.conf: ---- net.ipv4.ip_forward=1 ---- To do the same in an ad-hoc way that is not reboot safe but takes effect immediately: ---- sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" ---- It is also possible to instruct the firewall to allow IP forwarding for specific network devices only. For example, on a Debian based system, place an nft ruleset like this in `/etc/nftables.conf`: ---- define gtp_netdevs = { eth0, eth23 }; table inet filter { chain forward { type filter hook forward priority filter; policy drop; iifname $gtp_netdevs oifname $gtp_netdevs udp dport 2152 accept } } ---- This ruleset allows IP forwarding, but limited to the GTP-U port 2152, and to two specific network devices eth0 and eth23.