diff --git a/common/utils/tuntap_if.c b/common/utils/tuntap_if.c index 4056f2aba3..b4722d69f1 100644 --- a/common/utils/tuntap_if.c +++ b/common/utils/tuntap_if.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #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); diff --git a/common/utils/tuntap_if.h b/common/utils/tuntap_if.h index 8e1463624f..152cc5064f 100644 --- a/common/utils/tuntap_if.h +++ b/common/utils/tuntap_if.h @@ -24,6 +24,7 @@ #include #include +#include /*! * \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_*/ diff --git a/openair2/SDAP/nr_sdap/nr_sdap.c b/openair2/SDAP/nr_sdap/nr_sdap.c index 1ab78be406..fbbe40fcfd 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap.c +++ b/openair2/SDAP/nr_sdap/nr_sdap.c @@ -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; }