Commit ae5702d0 authored by Robert Schmidt's avatar Robert Schmidt

nas_config(): change API to handle both IPv4 and IPv6

Implement handling of IPv4 and IPv6 (on the same interface) in
nas_config().
parent ffcf53fc
...@@ -2300,22 +2300,22 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask, int id) { ...@@ -2300,22 +2300,22 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask, int id) {
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? MAX_MOBILES_PER_ENB : 1; int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? MAX_MOBILES_PER_ENB : 1;
netlink_init_tun("oaitun_ue", num_if, id); netlink_init_tun("oaitun_ue", num_if, id);
if (IS_SOFTMODEM_NOS1) if (IS_SOFTMODEM_NOS1)
nas_config(1, "10.0.1.2", "oaitun_ue"); nas_config(1, "10.0.1.2", NULL, "oaitun_ue");
netlink_init_mbms_tun("oaitun_uem", id + 1); netlink_init_mbms_tun("oaitun_uem", id + 1);
nas_config(1, "10.0.2.2", "oaitun_uem"); nas_config(1, "10.0.2.2", NULL, "oaitun_uem");
LOG_I(PDCP, "UE pdcp will use tun interface\n"); LOG_I(PDCP, "UE pdcp will use tun interface\n");
} else if (ENB_NAS_USE_TUN) { } else if (ENB_NAS_USE_TUN) {
netlink_init_tun("oaitun_enb", 1, 0); netlink_init_tun("oaitun_enb", 1, 0);
nas_config(1, "10.0.1.1", "oaitun_enb"); nas_config(1, "10.0.1.1", NULL, "oaitun_enb");
if (pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT) { if (pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT) {
netlink_init_mbms_tun("oaitun_enm", 1); netlink_init_mbms_tun("oaitun_enm", 1);
nas_config(1, "10.0.2.1", "oaitun_enm"); nas_config(1, "10.0.2.1", NULL, "oaitun_enm");
LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n"); LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
} }
LOG_I(PDCP, "ENB pdcp will use tun interface\n"); LOG_I(PDCP, "ENB pdcp will use tun interface\n");
} else if (pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT) { } else if (pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT) {
netlink_init_mbms_tun("oaitun_enm", 0); netlink_init_mbms_tun("oaitun_enm", 0);
nas_config(1, "10.0.2.1", "oaitun_enm"); nas_config(1, "10.0.2.1", NULL, "oaitun_enm");
LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n"); LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
} }
......
...@@ -618,7 +618,7 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) ...@@ -618,7 +618,7 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
netlink_init_tun(ifprefix, num_if, id); netlink_init_tun(ifprefix, num_if, id);
if (IS_SOFTMODEM_NOS1) { if (IS_SOFTMODEM_NOS1) {
const char *ip = !get_softmodem_params()->nsa ? "10.0.1.2" : "10.0.1.3"; const char *ip = !get_softmodem_params()->nsa ? "10.0.1.2" : "10.0.1.3";
nas_config(1, ip, ifprefix); nas_config(1, ip, NULL, ifprefix);
set_qfi_pduid(7, 10); set_qfi_pduid(7, 10);
} }
LOG_I(PDCP, "UE pdcp will use tun interface\n"); LOG_I(PDCP, "UE pdcp will use tun interface\n");
...@@ -626,7 +626,7 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) ...@@ -626,7 +626,7 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
} else if (ENB_NAS_USE_TUN) { } else if (ENB_NAS_USE_TUN) {
char *ifprefix = get_softmodem_params()->nsa ? "oaitun_gnb" : "oaitun_enb"; char *ifprefix = get_softmodem_params()->nsa ? "oaitun_gnb" : "oaitun_enb";
netlink_init_tun(ifprefix, 1, id); netlink_init_tun(ifprefix, 1, id);
nas_config(1, "10.0.1.1", ifprefix); nas_config(1, "10.0.1.1", NULL, ifprefix);
LOG_I(PDCP, "ENB pdcp will use tun interface\n"); LOG_I(PDCP, "ENB pdcp will use tun interface\n");
start_pdcp_tun_enb(); start_pdcp_tun_enb();
} }
......
...@@ -771,7 +771,7 @@ rrc_ue_establish_drb( ...@@ -771,7 +771,7 @@ rrc_ue_establish_drb(
"10.0.%d.%d", "10.0.%d.%d",
UE_NAS_USE_TUN ? 1 : (ip_addr_offset3 + ue_mod_idP + 1), UE_NAS_USE_TUN ? 1 : (ip_addr_offset3 + ue_mod_idP + 1),
ip_addr_offset4 + ue_mod_idP + 1); ip_addr_offset4 + ue_mod_idP + 1);
oip_ifup = nas_config(ip_addr_offset3 + ue_mod_idP + 1, ip, "oaitun_oip"); oip_ifup = nas_config(ip_addr_offset3 + ue_mod_idP + 1, ip, NULL, "oaitun_oip");
if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n",
......
...@@ -5257,7 +5257,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ...@@ -5257,7 +5257,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
ctxt_pP->module_id); ctxt_pP->module_id);
char ip[20]; char ip[20];
snprintf(ip, sizeof(ip), "10.0.%d.%d", ctxt_pP->module_id + 1, ctxt_pP->module_id + 1); snprintf(ip, sizeof(ip), "10.0.%d.%d", ctxt_pP->module_id + 1, ctxt_pP->module_id + 1);
oip_ifup = nas_config(ctxt_pP->module_id, ip, "oaitun_oai"); oip_ifup = nas_config(ctxt_pP->module_id, ip, NULL, "oaitun_oai");
if (oip_ifup == 0) { // interface is up --> send a config the DRB if (oip_ifup == 0) { // interface is up --> send a config the DRB
module_id_t ue_module_id; module_id_t ue_module_id;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/ipv6.h>
#include "nas_config.h" #include "nas_config.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
...@@ -40,17 +41,42 @@ ...@@ -40,17 +41,42 @@
* (set flags) * (set flags)
* \return true on success, false otherwise * \return true on success, false otherwise
*/ */
static bool setInterfaceParameter(int sock_fd, const char *ifn, const char *if_addr, int operation) static bool setInterfaceParameter(int sock_fd, const char *ifn, int af, const char *if_addr, int operation)
{ {
DevAssert(af == AF_INET || af == AF_INET6);
struct ifreq ifr = {0}; struct ifreq ifr = {0};
strncpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name));
struct in6_ifreq ifr6 = {0};
void *ioctl_opt = NULL;
if (af == AF_INET) {
struct sockaddr_in addr = {.sin_family = AF_INET};
int ret = inet_pton(af, if_addr, &addr.sin_addr);
if (ret != 1) {
LOG_E(OIP, "inet_pton(): cannot convert %s to IPv4 network address\n", if_addr);
return false;
}
memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in));
ioctl_opt = &ifr;
} else {
struct sockaddr_in6 addr6 = {.sin6_family = AF_INET6};
int ret = inet_pton(af, if_addr, &addr6.sin6_addr);
if (ret != 1) {
LOG_E(OIP, "inet_pton(): cannot convert %s to IPv6 network address\n", if_addr);
return false;
}
memcpy(&ifr6.ifr6_addr, &addr6.sin6_addr, sizeof(struct in6_addr));
// we need to get the if index to put it into ifr6
if (ioctl(sock_fd, SIOGIFINDEX, &ifr) < 0) {
LOG_E(OIP, "ioctl() failed: errno %d, %s\n", errno, strerror(errno));
return false;
}
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
ifr6.ifr6_prefixlen = 64;
ioctl_opt = &ifr6;
}
struct sockaddr_in addr = {.sin_family = AF_INET}; bool success = ioctl(sock_fd, operation, ioctl_opt) == 0;
inet_aton(if_addr, &addr.sin_addr);
//inet_pton(AF_INET6 or AF_INET)
memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in));
bool success = ioctl(sock_fd,operation,&ifr) == 0;
if (!success) if (!success)
LOG_E(OIP, "Setting operation %d for %s: ioctl call failed: %d, %s\n", operation, ifn, errno, strerror(errno)); LOG_E(OIP, "Setting operation %d for %s: ioctl call failed: %d, %s\n", operation, ifn, errno, strerror(errno));
return success; return success;
...@@ -80,11 +106,13 @@ static bool change_interface_state(int sock_fd, const char *ifn, if_action_t if_ ...@@ -80,11 +106,13 @@ static bool change_interface_state(int sock_fd, const char *ifn, if_action_t if_
} }
// non blocking full configuration of the interface (address, and the two lest octets of the address) // non blocking full configuration of the interface (address, and the two lest octets of the address)
bool nas_config(int interface_id, const char *ip, const char *ifpref) bool nas_config(int interface_id, const char *ipv4, const char *ipv6, const char *ifpref)
{ {
char interfaceName[IFNAMSIZ]; char interfaceName[IFNAMSIZ];
snprintf(interfaceName, sizeof(interfaceName), "%s%d", ifpref, interface_id); snprintf(interfaceName, sizeof(interfaceName), "%s%d", ifpref, interface_id);
AssertFatal(ipv4 != NULL || ipv6 != NULL, "need to have IP address, but none given\n");
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0) { if (sock_fd < 0) {
LOG_E(UTIL, "Failed creating socket for interface management: %d, %s\n", errno, strerror(errno)); LOG_E(UTIL, "Failed creating socket for interface management: %d, %s\n", errno, strerror(errno));
...@@ -92,18 +120,33 @@ bool nas_config(int interface_id, const char *ip, const char *ifpref) ...@@ -92,18 +120,33 @@ bool nas_config(int interface_id, const char *ip, const char *ifpref)
} }
change_interface_state(sock_fd, interfaceName, INTERFACE_DOWN); change_interface_state(sock_fd, interfaceName, INTERFACE_DOWN);
bool success = setInterfaceParameter(sock_fd, interfaceName, ip, SIOCSIFADDR); bool success = true;
// set the machine network mask if (ipv4 != NULL)
if (success) success = setInterfaceParameter(sock_fd, interfaceName, AF_INET, ipv4, SIOCSIFADDR);
success = setInterfaceParameter(sock_fd, interfaceName, "255.255.255.0", SIOCSIFNETMASK); // set the machine network mask for IPv4
if (success && ipv4 != NULL)
success = setInterfaceParameter(sock_fd, interfaceName, AF_INET, "255.255.255.0", SIOCSIFNETMASK);
if (ipv6 != NULL) {
// for setting the IPv6 address, we need an IPv6 socket. For setting IPv4,
// we need an IPv4 socket. So do all operations using IPv4 socket, except
// for setting the IPv6
int sock_fd = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock_fd < 0) {
LOG_E(UTIL, "Failed creating socket for interface management: %d, %s\n", errno, strerror(errno));
success = false;
}
success = success && setInterfaceParameter(sock_fd, interfaceName, AF_INET6, ipv6, SIOCSIFADDR);
close(sock_fd);
}
if (success) if (success)
success = change_interface_state(sock_fd, interfaceName, INTERFACE_UP); success = change_interface_state(sock_fd, interfaceName, INTERFACE_UP);
if (success) if (success)
LOG_I(OIP, "Interface %s successfully configured, ip address %s\n", interfaceName, ip); LOG_I(OIP, "Interface %s successfully configured, IPv4 %s, IPv6 %s\n", interfaceName, ipv4, ipv6);
else else
LOG_E(OIP, "Interface %s couldn't be configured (ip address %s)\n", interfaceName, ip); LOG_E(OIP, "Interface %s couldn't be configured (IPv4 %s, IPv6 %s)\n", interfaceName, ipv4, ipv6);
close(sock_fd); close(sock_fd);
return success; return success;
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#define NAS_CONFIG_H_ #define NAS_CONFIG_H_
#include <stdbool.h> #include <stdbool.h>
#include <netinet/in.h>
/*! \fn int nas_config(char*, int, int) /*! \fn int nas_config(char*, int, int)
* \brief This function initializes the nasmesh interface using the basic values, * \brief This function initializes the nasmesh interface using the basic values,
...@@ -31,14 +30,15 @@ ...@@ -31,14 +30,15 @@
* ones * ones
* \param[in] interface_id number of this interface, prepended after interface * \param[in] interface_id number of this interface, prepended after interface
* name * name
* \param[in] ip IPv4 address of this interface as a string * \param[in] ipv4 IPv4 address of this interface as a string
* \param[in] ipv6 IPv6 address of this interface as a string
* \param[in] ifprefix interface name prefix to which an interface number will * \param[in] ifprefix interface name prefix to which an interface number will
* be appended * be appended
* \return true on success, otherwise false * \return true on success, otherwise false
* \note * \note
* @ingroup _nas * @ingroup _nas
*/ */
bool nas_config(int interface_id, const char *ip, const char *ifprefix); bool nas_config(int interface_id, const char *ipv4, const char *ipv6, const char *ifprefix);
/*! /*!
* \brief Setup a IPv4 rule in table (interface_id - 1 + 10000) and route to * \brief Setup a IPv4 rule in table (interface_id - 1 + 10000) and route to
......
...@@ -118,7 +118,7 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ ...@@ -118,7 +118,7 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_
addr->pdu_addr_oct2, addr->pdu_addr_oct2,
addr->pdu_addr_oct3, addr->pdu_addr_oct3,
addr->pdu_addr_oct4); addr->pdu_addr_oct4);
nas_config(1, ip, "oaitun_ue"); nas_config(1, ip, NULL, "oaitun_ue");
setup_ue_ipv4_route(1, ip, "oaitun_ue"); setup_ue_ipv4_route(1, ip, "oaitun_ue");
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received UE IP: %s\n", ip); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received UE IP: %s\n", ip);
} else { } else {
......
...@@ -845,7 +845,7 @@ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buff ...@@ -845,7 +845,7 @@ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buff
char ip[20]; char ip[20];
sprintf(ip, "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3)); sprintf(ip, "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3));
LOG_A(NAS, "Received PDU Session Establishment Accept\n"); LOG_A(NAS, "Received PDU Session Establishment Accept\n");
nas_config(1, ip, "oaitun_ue"); nas_config(1, ip, NULL, "oaitun_ue");
setup_ue_ipv4_route(1, ip, "oaitun_ue"); setup_ue_ipv4_route(1, ip, "oaitun_ue");
} else { } else {
LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type); LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type);
...@@ -1432,7 +1432,7 @@ void *nas_nrue(void *args_p) ...@@ -1432,7 +1432,7 @@ void *nas_nrue(void *args_p)
char ip[20]; char ip[20];
snprintf(ip, sizeof(ip), "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3)); snprintf(ip, sizeof(ip), "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3));
LOG_I(NAS, "Received PDU Session Establishment Accept, UE IP: %s\n", ip); LOG_I(NAS, "Received PDU Session Establishment Accept, UE IP: %s\n", ip);
nas_config(1, ip, "oaitun_ue"); nas_config(1, ip, NULL, "oaitun_ue");
setup_ue_ipv4_route(1, ip, "oaitun_ue"); setup_ue_ipv4_route(1, ip, "oaitun_ue");
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment