Modify TUN interface handling to also handle TAP

Modify all functions to also handle TAP (where applicable). The actual
TAP interface code is not used in this commit, it will be used later.

To make the interface creation stand out, make "Interface XXX
successfully configured" a LOG_A.
This commit is contained in:
Robert Schmidt
2025-10-20 11:05:20 +02:00
parent 1e5c28279e
commit cadd031c81
3 changed files with 62 additions and 21 deletions

View File

@@ -27,7 +27,6 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/ipv6.h>
#include <linux/if_tun.h>
#include <linux/netlink.h>
#include "tuntap_if.h"
@@ -38,7 +37,7 @@
int nas_sock_fd[MAX_MOBILES_PER_ENB * 2]; // Allocated for both LTE UE and NR UE.
int nas_sock_mbms_fd;
int tun_alloc(const char *dev)
int tuntap_alloc(int flag, const char *dev)
{
struct ifreq ifr;
int fd, err;
@@ -54,7 +53,8 @@ int tun_alloc(const char *dev)
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
DevAssert(flag == IFF_TUN || flag == IFF_TAP);
ifr.ifr_flags = flag | IFF_NO_PI;
strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name) - 1);
if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) {
close(fd);
@@ -76,7 +76,7 @@ int tun_alloc(const char *dev)
int tun_init_mbms(char *ifname)
{
nas_sock_mbms_fd = tun_alloc(ifname);
nas_sock_mbms_fd = tuntap_alloc(IFF_TUN, ifname);
if (nas_sock_mbms_fd == -1) {
LOG_E(UTIL, "Error opening mbms socket %s (%d:%s)\n", ifname, errno, strerror(errno));
@@ -96,7 +96,7 @@ int tun_init_mbms(char *ifname)
int tun_init(const char *ifname, int instance_id)
{
nas_sock_fd[instance_id] = tun_alloc(ifname);
nas_sock_fd[instance_id] = tuntap_alloc(IFF_TUN, ifname);
if (nas_sock_fd[instance_id] == -1) {
LOG_E(UTIL, "Error opening socket %s (%d:%s)\n", ifname, errno, strerror(errno));
@@ -238,7 +238,7 @@ bool tun_config(const char* ifname, const char *ipv4, const char *ipv6)
success = set_if_flags(sock_fd, ifname, (IFF_UP | IFF_NOARP | IFF_POINTOPOINT) & ~IFF_MULTICAST);
if (success)
LOG_I(OIP, "Interface %s successfully configured, IPv4 %s, IPv6 %s\n", ifname, ipv4, ipv6);
LOG_A(OIP, "TUN Interface %s successfully configured, IPv4 %s, IPv6 %s\n", ifname, ipv4, ipv6);
else
LOG_E(OIP, "Interface %s couldn't be configured (IPv4 %s, IPv6 %s)\n", ifname, ipv4, ipv6);
@@ -246,6 +246,25 @@ bool tun_config(const char* ifname, const char *ipv4, const char *ipv6)
return success;
}
bool tap_config(const char* ifname)
{
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0) {
LOG_E(UTIL, "Failed creating socket for interface management: %d, %s\n", errno, strerror(errno));
return false;
}
bool success = set_if_flags(sock_fd, ifname, IFF_UP);
if (success)
LOG_A(OIP, "TAP interface %s successfully configured\n", ifname);
else
LOG_E(OIP, "Tap interface %s couldn't be configured\n", ifname);
close(sock_fd);
return success;
}
void setup_ue_ipv4_route(const char* ifname, int instance_id, const char *ipv4)
{
int table_id = instance_id - 1 + 10000;
@@ -274,14 +293,16 @@ int tun_generate_ifname(char *ifname, const char *ifprefix, int instance_id)
return snprintf(ifname, IFNAMSIZ, "%s%d", ifprefix, instance_id + 1);
}
int tun_generate_ue_ifname(char *ifname, int instance_id, int pdu_session_id)
int tuntap_generate_ue_ifname(char *ifname, int flag, int instance_id, int pdu_session_id)
{
DevAssert(flag == IFF_TUN || flag == IFF_TAP);
char pdu_session_string[10];
snprintf(pdu_session_string, sizeof(pdu_session_string), "p%d", pdu_session_id);
return snprintf(ifname, IFNAMSIZ, "%s%d%s", "oaitun_ue", instance_id + 1, pdu_session_id == -1 ? "" : pdu_session_string);
const char *basename = flag == IFF_TUN ? "oaitun_ue" : "oaitap_ue";
return snprintf(ifname, IFNAMSIZ, "%s%d%s", basename, instance_id + 1, pdu_session_id == -1 ? "" : pdu_session_string);
}
void tun_destroy(const char *dev)
void tuntap_destroy(const char *dev)
{
// Use a new socket for ioctl operations
int fd = socket(AF_INET, SOCK_DGRAM, 0);

View File

@@ -24,6 +24,7 @@
#include <stdbool.h>
#include <net/if.h>
#include <linux/if_tun.h>
/*!
* \brief This function generates the name of the interface based on the prefix and
@@ -34,7 +35,17 @@
* \param[in] instance_id unique instance number
*/
int tun_generate_ifname(char *ifname, const char *ifprefix, int instance_id);
int tun_generate_ue_ifname(char *ifname, int instance_id, int pdu_session_id);
/*!
* \brief This function generates the name of the interface based on the prefix and
* the instance id for a UE.
*
* \param[in,out] ifname name of the interface
* \param[in] flag IFF_TUN (for TUN device) or IFF_TAP (for TAP device)
* \param[in] ifprefix prefix of the interface
* \param[in] instance_id unique instance number
*/
int tuntap_generate_ue_ifname(char *ifname, int flag, int instance_id, int pdu_session_id);
/*!
* \brief This function initializes the TUN interface
@@ -50,9 +61,8 @@ int tun_init(const char *ifname, int instance_id);
int tun_init_mbms(char *ifname);
/*!
* \brief This function initializes the nasmesh interface using the basic values,
* basic address, network mask and broadcast address, as the default configured
* ones
* \brief Initializes the TUN interface with an IPv4 or IPv6 address and
* activates the interface.
* \param[in] ifname name of the interface
* \param[in] ipv4 IPv4 address of this interface as a string
* \param[in] ipv6 IPv6 address of this interface as a string
@@ -62,6 +72,15 @@ int tun_init_mbms(char *ifname);
*/
bool tun_config(const char* ifname, const char *ipv4, const char *ipv6);
/*!
* \brief Initializes and activates the TAP interface.
* \param[in] ifname name of the interface
* \return true on success, otherwise false
* \note
* @ingroup _nas
*/
bool tap_config(const char* ifname);
/*!
* \brief Setup a IPv4 rule in table (interface_id - 1 + 10000) and route to
* force packets coming into interface back through it, and workaround
@@ -75,16 +94,17 @@ bool tun_config(const char* ifname, const char *ipv4, const char *ipv6);
void setup_ue_ipv4_route(const char* ifname, int instance_id, const char *ipv4);
/*!
* \brief This function allocates a TUN interface
* \brief This function allocates a TUN or TAP interface
* \param[in] flag IFF_TUN (for TUN device) or IFF_TAP (for TAP device)
* \param[in] dev name of the interface
* \return file descriptor of the allocated interface
*/
int tun_alloc(const char *dev);
int tuntap_alloc(int flag, const char *dev);
/*!
* \brief This function destroys the TUN interface
* \brief This function destroys the TUN or TAP interface
* \param[in] dev name of the interface
*/
void tun_destroy(const char *dev);
void tuntap_destroy(const char *dev);
#endif /*TUN_IF_H_*/

View File

@@ -165,7 +165,7 @@ void start_sdap_tun_gnb_first_ue_default_pdu_session(ue_id_t ue_id, int pdu_sess
char *ifprefix = get_softmodem_params()->nsa ? "oaitun_gnb" : "oaitun_enb";
char ifname[IFNAMSIZ];
tun_generate_ifname(ifname, ifprefix, ue_id - 1);
entity->pdusession_sock = tun_alloc(ifname);
entity->pdusession_sock = tuntap_alloc(IFF_TUN, ifname);
entity->pdusession_if_name = strdup(ifname);
tun_config(ifname, "10.0.1.1", NULL);
threadCreate(&entity->pdusession_thread, sdap_tun_read_thread, entity, "gnb_tun_read_thread", -1, OAI_PRIORITY_RT_LOW);
@@ -189,8 +189,8 @@ void create_ue_ip_if(const char *ipv4, const char *ipv6, int ue_id, int pdu_sess
{
int default_pdu = get_softmodem_params()->default_pdu_session_id;
char ifname[IFNAMSIZ];
tun_generate_ue_ifname(ifname, ue_id, pdu_session_id != default_pdu ? pdu_session_id : -1);
const int sock = tun_alloc(ifname);
tuntap_generate_ue_ifname(ifname, IFF_TUN, ue_id, pdu_session_id != default_pdu ? pdu_session_id : -1);
const int sock = tuntap_alloc(IFF_TUN, ifname);
tun_config(ifname, ipv4, ipv6);
if (ipv4) {
setup_ue_ipv4_route(ifname, ue_id, ipv4);
@@ -212,7 +212,7 @@ void remove_ip_if(nr_sdap_entity_t *entity)
int ret = pthread_join(entity->pdusession_thread, NULL);
AssertFatal(ret == 0, "pthread_join() failed, errno: %d, %s\n", errno, strerror(errno));
// Bring down the IP interface
tun_destroy(entity->pdusession_if_name);
tuntap_destroy(entity->pdusession_if_name);
free(entity->pdusession_if_name);
entity->pdusession_if_name = NULL;
}