Merge remote-tracking branch 'origin/add-ci-ue-rrc-idle-test' into integration_2025_w22 (!3277)
Add CI test to force RRC IDLE and new connection setup with 5G-S-TMSI This MR is a follow up to !2725 (merged).. The primary goal is to introduce a CI test that enforces the following behavior: - Forces the UE to enter RRC_IDLE state. - Validates the UE's re-connection procedure using the 5G-S-TMSI as the UE identity.
This commit is contained in:
@@ -25,6 +25,8 @@ extern "C" {
|
||||
#include "common/config/config_userapi.h"
|
||||
void *config_allocate_new(configmodule_interface_t *cfg, int sz, bool autoFree);
|
||||
void config_check_valptr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int elt_sz, int nb_elt);
|
||||
#include "../config_userapi.h"
|
||||
#include "../config_common.h"
|
||||
}
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
@@ -98,6 +100,9 @@ void SetDefault(configmodule_interface_t *cfg, paramdef_t *param)
|
||||
param->uptr = (uint32_t *)param->defintarrayval;
|
||||
}
|
||||
break;
|
||||
case TYPE_IPV4ADDR:
|
||||
config_setdefault_ipv4addr(cfg, param, param->defstrval);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Unhandled type %d", param->type);
|
||||
}
|
||||
@@ -186,6 +191,16 @@ void SetNonDefault(configmodule_interface_t *cfg, const YAML::Node &node, paramd
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_IPV4ADDR: {
|
||||
std::string ipv4addr = node[optname].as<std::string>();
|
||||
char* ipv4addr_ptr = strdup(ipv4addr.c_str());
|
||||
int rst = config_assign_ipv4addr(cfg, param, ipv4addr_ptr);
|
||||
free(ipv4addr_ptr);
|
||||
if (rst < 0) {
|
||||
fprintf(stderr,"[LIBCONFIG] %s not valid for %s \n", ipv4addr.c_str(), optname.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
AssertFatal(false, "Unhandled type %d", param->type);
|
||||
}
|
||||
|
||||
@@ -10,3 +10,4 @@ configure_file(test_string.yaml test_string.yaml COPYONLY)
|
||||
configure_file(test_list_of_mappings.yml test_list_of_mappings.yml COPYONLY)
|
||||
configure_file(test_int_array.yaml test_int_array.yaml COPYONLY)
|
||||
configure_file(test_read_mapping_as_list.yaml test_read_mapping_as_list.yaml COPYONLY)
|
||||
configure_file(test_ipv4.yaml test_ipv4.yaml COPYONLY)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
test:
|
||||
ipv4_1: 0.0.0.0
|
||||
ipv4_2: 192.168.0.1
|
||||
#ipv4_3: check default
|
||||
@@ -391,6 +391,36 @@ TEST(yaml_config, test_read_mapping_as_list) {
|
||||
end_configmodule(cfg);
|
||||
}
|
||||
|
||||
TEST(yaml_config, test_read_ipv4) {
|
||||
configmodule_interface_t *cfg = static_cast<configmodule_interface_t*>(calloc(1, sizeof(*cfg)));
|
||||
cfg->cfgP[0] = strdup("test_ipv4.yaml");
|
||||
EXPECT_EQ(config_yaml_init(cfg), 0);
|
||||
|
||||
paramdef_t p = {};
|
||||
p.type = TYPE_IPV4ADDR;
|
||||
strncpy(p.optname, "ipv4_1", sizeof(p.optname) - 1);
|
||||
uint32_t addr = 0;
|
||||
p.uptr = &addr;
|
||||
p.defstrval = nullptr;
|
||||
char prefix[] = "test";
|
||||
config_yaml_get(cfg, &p, 1, prefix);
|
||||
printf("%x\n", addr);
|
||||
|
||||
strncpy(p.optname, "ipv4_2", sizeof(p.optname) - 1);
|
||||
config_yaml_get(cfg, &p, 1, prefix);
|
||||
printf("%x\n", addr);
|
||||
|
||||
p.defstrval = strdup("10.0.0.1");
|
||||
strncpy(p.optname, "ipv4_3", sizeof(p.optname) - 1);
|
||||
config_yaml_get(cfg, &p, 1, prefix);
|
||||
printf("%x\n", addr);
|
||||
|
||||
config_yaml_end(cfg);
|
||||
free(cfg->cfgP[0]);
|
||||
end_configmodule(cfg);
|
||||
free(p.defstrval);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
logInit();
|
||||
|
||||
@@ -102,12 +102,21 @@ int force_crnti_ra(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int force_deregistration(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DEREGISTRATION_REQ);
|
||||
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
|
||||
itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Telnet shell command definitions */
|
||||
static telnetshell_cmddef_t cicmds[] = {
|
||||
{"sync_state", "[UE_ID(int,opt)]", get_sync_state},
|
||||
{"force_rlf", "", force_rlf},
|
||||
{"force_RRC_IDLE", "", force_RRC_IDLE},
|
||||
{"force_crnti_ra", "", force_crnti_ra},
|
||||
{"deregistration", "", force_deregistration},
|
||||
{"", "", NULL},
|
||||
};
|
||||
|
||||
|
||||
+19
-8
@@ -168,10 +168,14 @@ static bool change_interface_state(int sock_fd, const char *ifn, if_action_t if_
|
||||
|
||||
struct ifreq ifr = {0};
|
||||
strncpy(ifr.ifr_name, ifn, sizeof(ifr.ifr_name));
|
||||
|
||||
/* get flags of this interface: see netdevice(7) */
|
||||
bool success = ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t)&ifr) == 0;
|
||||
if (!success)
|
||||
goto fail_interface_state;
|
||||
if (!success && if_action == INTERFACE_DOWN && errno == ENODEV) {
|
||||
LOG_W(OIP, "trying to remove non-existant device %s\n", ifn);
|
||||
return true;
|
||||
}
|
||||
LOG_D(OIP, "Got flags for %s: 0x%x (action: %s)\n", ifn, ifr.ifr_flags, action);
|
||||
|
||||
if (if_action == INTERFACE_UP) {
|
||||
ifr.ifr_flags |= IFF_UP | IFF_NOARP | IFF_POINTOPOINT;
|
||||
@@ -183,6 +187,8 @@ static bool change_interface_state(int sock_fd, const char *ifn, if_action_t if_
|
||||
success = ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t)&ifr) == 0;
|
||||
if (!success)
|
||||
goto fail_interface_state;
|
||||
LOG_D(OIP, "Interface %s successfully set %s\n", ifn, action);
|
||||
|
||||
return true;
|
||||
|
||||
fail_interface_state:
|
||||
@@ -201,10 +207,6 @@ bool tun_config(const char* ifname, const char *ipv4, const char *ipv6)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!change_interface_state(sock_fd, ifname, INTERFACE_DOWN)) {
|
||||
close(sock_fd);
|
||||
return false;
|
||||
}
|
||||
bool success = true;
|
||||
if (ipv4 != NULL)
|
||||
success = setInterfaceParameter(sock_fd, ifname, AF_INET, ipv4, SIOCSIFADDR);
|
||||
@@ -272,8 +274,17 @@ int tun_generate_ue_ifname(char *ifname, int instance_id, int pdu_session_id)
|
||||
return snprintf(ifname, IFNAMSIZ, "%s%d%s", "oaitun_ue", instance_id + 1, pdu_session_id == -1 ? "" : pdu_session_string);
|
||||
}
|
||||
|
||||
void tun_destroy(const char *dev, int fd) {
|
||||
if (change_interface_state(fd, dev, INTERFACE_DOWN) == 0) {
|
||||
void tun_destroy(const char *dev)
|
||||
{
|
||||
// Use a new socket for ioctl operations
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
LOG_E(UTIL, "Failed to create socket for interface teardown: %d, %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = change_interface_state(fd, dev, INTERFACE_DOWN);
|
||||
if (success) {
|
||||
LOG_I(UTIL, "Interface %s is now down.\n", dev);
|
||||
} else {
|
||||
LOG_E(UTIL, "Could not bring interface %s down.\n", dev);
|
||||
|
||||
@@ -84,8 +84,7 @@ int tun_alloc(const char *dev);
|
||||
/*!
|
||||
* \brief This function destroys the TUN interface
|
||||
* \param[in] dev name of the interface
|
||||
* \param[in] fd file descriptor of the allocated interface
|
||||
*/
|
||||
void tun_destroy(const char *dev, int fd);
|
||||
void tun_destroy(const char *dev);
|
||||
|
||||
#endif /*TUN_IF_H_*/
|
||||
|
||||
Reference in New Issue
Block a user