Commit e33c7d26 authored by Sakthivel Velumani's avatar Sakthivel Velumani

Modify nas_config to handle ipv6

parent d7852ff4
......@@ -2307,17 +2307,23 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask, int id) {
if (PDCP_USE_NETLINK) {
nas_getparams();
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
if(UE_NAS_USE_TUN) {
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1;
init_tun("ue",num_if, id);
if (IS_SOFTMODEM_NOS1)
nas_config(1, 1, 2, "ue", NULL);
if (IS_SOFTMODEM_NOS1) {
addr[0] = 1;
addr[1] = 2;
nas_config(false, 1, addr, "ue");
}
netlink_init_mbms_tun("uem", id);
nas_config_mbms(1, 2, 2, "uem");
LOG_I(PDCP, "UE pdcp will use tun interface\n");
} else if(ENB_NAS_USE_TUN) {
init_tun("enb", 1, 0);
nas_config(1, 1, 1, "enb", NULL);
addr[0] = 1;
addr[1] = 1;
nas_config(false, 1, addr, "enb");
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
netlink_init_mbms_tun("enm", 0);
nas_config_mbms(1, 2, 1, "enm");
......
......@@ -766,11 +766,13 @@ rrc_ue_establish_drb(
ip_addr_offset4 = 1;
LOG_I(OIP,"[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
oip_ifup = nas_config(ip_addr_offset3 + ue_mod_idP + 1, // interface_id
UE_NAS_USE_TUN ? 1 : (ip_addr_offset3 + ue_mod_idP + 1), // third_octet
ip_addr_offset4 + ue_mod_idP + 1, // fourth_octet
"oip", // interface suffix (when using kernel module)
NULL);
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
addr[0] = UE_NAS_USE_TUN ? 1 : (ip_addr_offset3 + ue_mod_idP + 1);
addr[1] = ip_addr_offset4 + ue_mod_idP + 1;
oip_ifup = nas_config(false,
ip_addr_offset3 + ue_mod_idP + 1, // interface_id
addr,
"oip"); // interface suffix (when using kernel module);
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",
......
......@@ -5257,11 +5257,13 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n",
ctxt_pP->module_id,
ctxt_pP->module_id);
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
addr[0] = ctxt_pP->module_id + 1; // third octet
addr[1] = ctxt_pP->module_id + 1; // fourth octet
oip_ifup = nas_config(ctxt_pP->module_id, // interface index
ctxt_pP->module_id + 1, // third octet
ctxt_pP->module_id + 1, // fourth octet
"oai",
NULL);
false,
addr,
"oai");
if (oip_ifup == 0) { // interface is up --> send a config the DRB
module_id_t ue_module_id;
......
......@@ -52,9 +52,11 @@
//default values according to the examples,
char *baseNetAddress ;
char *baseNetAddressIPv6;
char *netMask ;
char *broadcastAddr ;
#define NASHLP_NETPREFIX "<NAS network prefix, two first bytes of network addresses>\n"
#define NASHLP_NETPREFIX_IPV6 "<NAS IPv6 network prefix, eight first bytes of network addresses>\n"
#define NASHLP_NETMASK "<NAS network mask>\n"
#define NASHLP_BROADCASTADDR "<NAS network broadcast address>\n"
void nas_getparams(void) {
......@@ -66,9 +68,10 @@ void nas_getparams(void) {
/* configuration parameters for netlink, includes network parameters when running in noS1 mode */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
{"NetworkPrefix", NASHLP_NETPREFIX, 0, .strptr=&baseNetAddress, .defstrval="10.0", TYPE_STRING, 0 },
{"NetworkMask", NASHLP_NETMASK, 0, .strptr=&netMask, .defstrval="255.255.255.0", TYPE_STRING, 0 },
{"BroadcastAddr", NASHLP_BROADCASTADDR, 0, .strptr=&broadcastAddr, .defstrval="10.0.255.255", TYPE_STRING, 0 },
{"NetworkPrefix", NASHLP_NETPREFIX, 0, .strptr=&baseNetAddress, .defstrval="10.0", TYPE_STRING, 0 },
{"NetworkPrefixIPv6", NASHLP_NETPREFIX_IPV6, 0, .strptr=&baseNetAddressIPv6, .defstrval="FE80:0000:0000:0000", TYPE_STRING, 0 },
{"NetworkMask", NASHLP_NETMASK, 0, .strptr=&netMask, .defstrval="255.255.255.0", TYPE_STRING, 0 },
{"BroadcastAddr", NASHLP_BROADCASTADDR, 0, .strptr=&broadcastAddr, .defstrval="10.0.255.255", TYPE_STRING, 0 },
};
// clang-format on
config_get(config_get_if(), nasoptions, sizeofArray(nasoptions), "nas.noS1");
......@@ -148,7 +151,8 @@ int set_gateway(char *interfaceName, char *gateway) {
// sets a genneric interface parameter
// (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS)
int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation) {
int setInterfaceParameter(const char *interfaceName, const char *settingAddress, int operation)
{
int sock_fd;
struct ifreq ifr;
struct sockaddr_in addr;
......@@ -163,8 +167,8 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati
strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)-1);
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
inet_aton(settingAddress,&addr.sin_addr);
memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in));
inet_pton(AF_INET, settingAddress, &addr.sin_addr);
memcpy(&ifr.ifr_ifru.ifru_addr, &addr, sizeof(addr));
if(ioctl(sock_fd,operation,&ifr) < 0) {
close(sock_fd);
......@@ -177,14 +181,53 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati
return 0;
}
struct in6_ifreq {
struct in6_addr addr;
uint32_t prefixlen;
unsigned int ifindex;
};
int setInterfaceParameterIPv6(const char *interfaceName, const char *settingAddress, int operation)
{
int sock_fd;
struct ifreq ifr;
struct in6_ifreq ifr6;
if ((sock_fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
LOG_E(OIP, "Setting operation %d, for %s, address, %s : socket failed\n", operation, interfaceName, settingAddress);
return 1;
}
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name) - 1);
if (ioctl(sock_fd, SIOGIFINDEX, &ifr) < 0) {
close(sock_fd);
LOG_E(OIP, "Setting interface name failed %s\n", interfaceName);
}
memset(&ifr6.addr, 0, sizeof(ifr6.addr));
inet_pton(AF_INET6, settingAddress, &ifr6.addr);
ifr6.ifindex = ifr.ifr_ifindex;
ifr6.prefixlen = 64;
if (ioctl(sock_fd, operation, &ifr6) < 0) {
close(sock_fd);
LOG_E(OIP, "Setting operation %d, for %s, address, %s : ioctl call failed\n", operation, interfaceName, settingAddress);
return 2;
}
close(sock_fd);
return 0;
}
// sets a genneric interface parameter
// (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS)
int bringInterfaceUpOrDown(const char *interfaceName, bool up)
int bringInterfaceUpOrDown(const char *interfaceName, bool ipv6, bool up)
{
int sock_fd;
struct ifreq ifr;
int family = ipv6 ? AF_INET6 : AF_INET;
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
if ((sock_fd = socket(family, SOCK_DGRAM, 0)) < 0) {
LOG_E(OIP,"Bringing interface UP, for %s, failed creating socket\n", interfaceName);
return 1;
}
......@@ -215,9 +258,10 @@ int bringInterfaceUpOrDown(const char *interfaceName, bool up)
close( sock_fd );
return 0;
}
// non blocking full configuration of the interface (address, net mask, and broadcast mask)
int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) {
bringInterfaceUpOrDown(interfaceName, false);
bringInterfaceUpOrDown(interfaceName, false, false);
// sets the machine address
int returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
......@@ -232,7 +276,7 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br
// if(!returnValue)
// returnValue=set_gateway(interfaceName, broadcastAddress);
if(!returnValue)
returnValue = bringInterfaceUpOrDown(interfaceName, true);
returnValue = bringInterfaceUpOrDown(interfaceName, false, true);
return returnValue;
}
......@@ -270,7 +314,7 @@ int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifn
sprintf(broadcastAddress, "%s.%d.255",baseNetAddress, thirdOctet);
sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname,
UE_NAS_USE_TUN?ifname/*"ue"*/: (ENB_NAS_USE_TUN?ifname/*"enb"*/:""),interface_id);
bringInterfaceUpOrDown(interfaceName, false);
bringInterfaceUpOrDown(interfaceName, false, false);
// sets the machine address
returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
......@@ -283,7 +327,7 @@ int nas_config_mbms(int interface_id, int thirdOctet, int fourthOctet, char *ifn
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
if(!returnValue)
bringInterfaceUpOrDown(interfaceName, true);
bringInterfaceUpOrDown(interfaceName, false, true);
if(!returnValue)
LOG_I(OIP,"Interface %s successfully configured, ip address %s, mask %s broadcast address %s\n",
......@@ -308,7 +352,7 @@ int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char *
sprintf(broadcastAddress, "%s.%d.255","10.0", thirdOctet);
sprintf(interfaceName, "%s%s%d", "oaitun_",ifname,interface_id);
bringInterfaceUpOrDown(interfaceName, false);
bringInterfaceUpOrDown(interfaceName, false, false);
// sets the machine address
returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
......@@ -323,7 +367,7 @@ int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char *
printf("returnValue %d\n",returnValue);
if(!returnValue)
bringInterfaceUpOrDown(interfaceName, true);
bringInterfaceUpOrDown(interfaceName, false, true);
printf("returnValue %d\n",returnValue);
if(!returnValue)
......@@ -350,29 +394,34 @@ void nas_config_interface_name(int if_id, const char *ifname, const char *ifname
}
// non blocking full configuration of the interface (address, and the two lest octets of the address)
int nas_config(int interface_id, int thirdOctet, int fourthOctet, const char *ifname, const char *ifname_suffix)
int nas_config(bool ipv6, int interface_id, const uint8_t addr[IPV4V6_ADDR_LEN], const char *interfaceName)
{
char ipAddress[20];
char ipAddress[30];
char broadcastAddress[20];
char interfaceName[20];
int returnValue;
sprintf(ipAddress, "%s.%d.%d", baseNetAddress,thirdOctet,fourthOctet);
sprintf(broadcastAddress, "%s.%d.255",baseNetAddress, thirdOctet);
nas_config_interface_name(interface_id, ifname, ifname_suffix, interfaceName, sizeof(interfaceName));
bringInterfaceUpOrDown(interfaceName, false);
const uint16_t *paddr = (const uint16_t *)addr;
if (ipv6) {
sprintf(ipAddress, "%s:%04x:%04x:%04x:%04x", baseNetAddressIPv6, paddr[0], paddr[1], paddr[2], paddr[3]);
} else {
sprintf(ipAddress, "%s.%d.%d", baseNetAddress, addr[0], addr[1]);
}
sprintf(broadcastAddress, "%s.%d.255", baseNetAddress, addr[0]);
bringInterfaceUpOrDown(interfaceName, ipv6, false);
int (*p_setInterfaceParameter)(const char *, const char *, int);
p_setInterfaceParameter = ipv6 ? setInterfaceParameterIPv6 : setInterfaceParameter;
// sets the machine address
returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
returnValue = p_setInterfaceParameter(interfaceName, ipAddress, SIOCSIFADDR);
// sets the machine network mask
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, netMask,SIOCSIFNETMASK);
if (!returnValue && !ipv6)
returnValue = p_setInterfaceParameter(interfaceName, netMask, SIOCSIFNETMASK);
// sets the machine broadcast address
if(!returnValue)
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
if (!returnValue && !ipv6)
returnValue = p_setInterfaceParameter(interfaceName, broadcastAddress, SIOCSIFBRDADDR);
if(!returnValue)
returnValue = bringInterfaceUpOrDown(interfaceName, true);
returnValue = bringInterfaceUpOrDown(interfaceName, ipv6, true);
if(!returnValue)
LOG_I(OIP,"Interface %s successfully configured, ip address %s, mask %s broadcast address %s\n",
......
......@@ -31,6 +31,7 @@
#include <netinet/in.h>
#include <stdbool.h>
#include <nr_nas_msg_sim.h>
/*! \fn void void nas_getparams(void)(void)
* \brief This function get parameters used to configure network interface when running in noS1 mode
......@@ -62,7 +63,7 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br
* \note
* @ingroup _nas
*/
int nas_config(int interface_id, int thirdOctet, int fourthOctet, const char *ifname, const char *ifname_suffix);
int nas_config(bool ipv6, int interface_id, const uint8_t addr[IPV4V6_ADDR_LEN], const char *ifname);
/*! \fn int nas_config_mbms(char*, int, int)
* \brief This function initializes the nasmesh interface using the basic values,
......@@ -101,7 +102,7 @@ int nas_config_mbms_s1(int interface_id, int thirdOctet, int fourthOctet, char *
* \note
* @ingroup _nas
*/
int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation);
int setInterfaceParameter(const char *interfaceName, const char *settingAddress, int operation);
/*! \fn int set_gateway(char*, char*)
* \brief This function sets the interface gateway
......@@ -161,7 +162,7 @@ void setBroadcastAddress(char *baseAddr);
*/
char *getBroadcastAddress(void);
int bringInterfaceUpOrDown(const char *interfaceName, bool up);
int bringInterfaceUpOrDown(const char *interfaceName, bool ipv6, bool up);
int rb_validate_config_ipv4(int cx, int inst, int rb);
int rb_conf_ipv4(int action, int cx, int inst, int rb, int dscp, in_addr_t saddr_ipv4, in_addr_t daddr_ipv4);
......
......@@ -87,7 +87,10 @@ void start_sdap_tun_gnb(int id)
char ifname[20];
nas_config_interface_name(id + 1, "oaitun_", NULL, ifname, sizeof(ifname));
arg->sock_fd = init_single_tun(ifname);
nas_config(id + 1, 1, 1, ifname, NULL);
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
addr[0] = 1;
addr[1] = 1;
nas_config(false, id + 1, addr, ifname);
{
// default ue id & pdu session id in nos1 mode
nr_sdap_entity_t *entity = nr_sdap_get_entity(1, get_softmodem_params()->default_pdu_session_id);
......
......@@ -627,7 +627,7 @@ void remove_ue_ip_if(nr_sdap_entity_t *entity)
(entity->pdusession_id != get_softmodem_params()->default_pdu_session_id) ? ifnameSuffix : NULL,
ifnameFull,
sizeof(ifnameFull));
if (bringInterfaceUpOrDown(ifnameFull, false) == 0) {
if (bringInterfaceUpOrDown(ifnameFull, false, false) == 0) {
// Close the socket associated with the interface
close(entity->pdusession_sock);
LOG_I(SDAP, "Interface %s is now down.\n", ifnameFull);
......
......@@ -112,7 +112,10 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_
psea_msg.pdu_addr_ie.pdu_addr_oct4 = *curPtr++;
nas_getparams();
sprintf(baseNetAddress, "%d.%d", psea_msg.pdu_addr_ie.pdu_addr_oct1, psea_msg.pdu_addr_ie.pdu_addr_oct2);
nr_ue_create_ip_if("", 1, psea_msg.pdu_id, psea_msg.pdu_addr_ie.pdu_addr_oct3, psea_msg.pdu_addr_ie.pdu_addr_oct4);
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
addr[0] = psea_msg.pdu_addr_ie.pdu_addr_oct3;
addr[1] = psea_msg.pdu_addr_ie.pdu_addr_oct4;
nr_ue_create_ip_if("", 1, psea_msg.pdu_id, false, addr);
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received UE IP: %d.%d.%d.%d\n",
psea_msg.pdu_addr_ie.pdu_addr_oct1,
psea_msg.pdu_addr_ie.pdu_addr_oct2,
......
......@@ -720,7 +720,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
}
}
void nr_ue_create_ip_if(char *ifname, int ue_id, int pdu_session_id, int third_octet, int fourth_octet)
void nr_ue_create_ip_if(const char *ifname, int ue_id, int pdu_session_id, bool ipv6, const uint8_t addr[IPV4V6_ADDR_LEN])
{
char ifname_full[20];
char ifname_suffix[10];
......@@ -736,7 +736,7 @@ void nr_ue_create_ip_if(char *ifname, int ue_id, int pdu_session_id, int third_o
return;
}
const int sock = init_single_tun(ifname_full);
nas_config(ue_id, third_octet, fourth_octet, ifname, (pdu_session_id != default_pdu) ? ifname_suffix : NULL);
nas_config(ipv6, ue_id, addr, ifname_full);
start_sdap_tun_ue(ue_id - 1, pdu_session_id, sock); // interface name suffix is ue_id+1
}
......@@ -744,11 +744,12 @@ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buff
uint8_t msg_type = *(pdu_buffer + 16);
if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40));
int third_octet = *(pdu_buffer + 41);
int fourth_octet = *(pdu_buffer + 42);
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
addr[0] = *(pdu_buffer + 41);
addr[1] = *(pdu_buffer + 42);
int pdu_session_id = *(pdu_buffer + 14);
LOG_A(NAS, "Received PDU Session Establishment Accept\n");
nr_ue_create_ip_if("oaitun_", 1, pdu_session_id, third_octet, fourth_octet);
nr_ue_create_ip_if("oaitun_", 1, pdu_session_id, false, addr);
} else {
LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type);
}
......@@ -1268,15 +1269,16 @@ void *nas_nrue(void *args_p)
if ((*(payload_container + offset + 1) == 0x05) && (*(payload_container + offset + 2) == 0x01)) { // IPV4
nas_getparams();
sprintf(baseNetAddress, "%d.%d", *(payload_container + offset + 3), *(payload_container + offset + 4));
int third_octet = *(payload_container + offset + 5);
int fourth_octet = *(payload_container + offset + 6);
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
addr[0] = *(payload_container + offset + 5);
addr[1] = *(payload_container + offset + 6);
LOG_I(NAS,
"Received PDU Session Establishment Accept, UE IP: %d.%d.%d.%d\n",
*(payload_container + offset + 3),
*(payload_container + offset + 4),
*(payload_container + offset + 5),
*(payload_container + offset + 6));
nr_ue_create_ip_if("oaitun_", 1, pdu_session_id, third_octet, fourth_octet);
nr_ue_create_ip_if("oaitun_", 1, pdu_session_id, false, addr);
break;
}
}
......@@ -1299,10 +1301,11 @@ void *nas_nrue(void *args_p)
const int ue_id = instance;
const int pdu_session_id = softmodem_nas_info.default_pdu_session_id;
const int qfi = 7;
const int third_octet = 1;
const int fourth_octet = !softmodem_nas_info.nsa ? 2 : 3;
uint8_t addr[IPV4V6_ADDR_LEN] = {0};
addr[0] = 1;
addr[1] = !softmodem_nas_info.nsa ? 2 : 3;
nas_getparams();
nr_ue_create_ip_if("oaitun_", ue_id + 1, pdu_session_id, third_octet, fourth_octet);
nr_ue_create_ip_if("oaitun_", ue_id + 1, pdu_session_id, false, addr);
set_qfi(qfi, pdu_session_id, ue_id);
break;
}
......
......@@ -74,6 +74,7 @@
#define SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH 7
#define PAYLOAD_CONTAINER_LENGTH_MIN 3
#define PAYLOAD_CONTAINER_LENGTH_MAX 65537
#define IPV4V6_ADDR_LEN 8
typedef struct {
int default_pdu_session_id;
......@@ -192,7 +193,7 @@ nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas);
void *nas_nrue_task(void *args_p);
void *nas_nrue(void *args_p);
void nr_ue_create_ip_if(char *ifname, int ue_id, int pdu_session_id, int third_octet, int fourth_octet);
void nr_ue_create_ip_if(const char *ifname, int ue_id, int pdu_session_id, bool ipv6, const uint8_t addr[IPV4V6_ADDR_LEN]);
#endif /* __NR_NAS_MSG_SIM_H__*/
......
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