Handle interface reset at session end

This commit is contained in:
Suvendhu Hansa 2022-06-14 09:34:17 +00:00 committed by Vivek Kumar Dutta
parent e18acd99d7
commit 94e27976a8
3 changed files with 101 additions and 5 deletions

88
cwmp.c
View file

@ -16,6 +16,7 @@
#include <syslog.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <regex.h>
#include "common.h"
#include "ssl_utils.h"
@ -53,6 +54,79 @@ static pthread_t periodic_check_notify;
static pthread_t heart_beat_session_thread;
bool g_firewall_restart = false;
static struct ubus_context *ctx = NULL;
struct list_head intf_reset_list;
static void cwmp_invoke_intf_reset(char *path)
{
if (path == NULL)
return;
CWMP_LOG(INFO, "Reset interface: %s", path);
struct blob_buf b = { 0 };
memset(&b, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
bb_add_string(&b, "path", path);
bb_add_string(&b, "action", "Reset()");
icwmp_ubus_invoke(USP_OBJECT_NAME, "operate", b.head, NULL, NULL);
blob_buf_free(&b);
return;
}
static bool interface_reset_req(char *param_name, char *value)
{
if (param_name == NULL || value == NULL)
return false;
char reg_exp[60] = {0};
snprintf(reg_exp, sizeof(reg_exp), "^(%s|%s)[0-9]+.Reset$", DM_IP_INTERFACE_PATH, DM_PPP_INTERFACE_PATH);
regex_t reegex;
int ret = regcomp(&reegex, reg_exp, REG_EXTENDED);
if (ret != 0)
return false;
ret = regexec(&reegex, param_name, 0, NULL, 0);
if (ret != 0)
return false;
if (strcmp(value, "1") != 0 && strcmp(value, "true") != 0)
return false;
return true;
}
void set_interface_reset_request(char *param_name, char *value)
{
if (param_name == NULL || value == NULL)
return;
if (interface_reset_req(param_name, value) == false) {
return;
}
// Store the interface path to handle after session end
int len = 0;
char *pos = strrchr(param_name, '.');
if (pos == NULL)
return;
len = pos - param_name + 2;
if (len <= 0)
return;
intf_reset_node *node = (intf_reset_node *)malloc(sizeof(intf_reset_node));
if (node == NULL) {
CWMP_LOG(ERROR, "Out of memory");
return;
}
memset(node, 0, sizeof(intf_reset_node));
snprintf(node->path, len, "%s", param_name);
INIT_LIST_HEAD(&node->list);
list_add_tail(&node->list, &intf_reset_list);
}
int cwmp_get_retry_interval(struct cwmp *cwmp, bool heart_beat)
{
@ -338,6 +412,18 @@ int run_session_end_func(void)
cwmp_factory_reset();
exit(EXIT_SUCCESS);
}
// check if any interface reset request exists then take action
intf_reset_node *iter = NULL, *node = NULL;
list_for_each_entry_safe(iter, node, &intf_reset_list, list) {
CWMP_LOG(INFO, "Executing interface reset: end session request");
cwmp_invoke_intf_reset(iter->path);
list_del(&iter->list);
free(iter);
}
INIT_LIST_HEAD(&intf_reset_list);
cwmp_uci_exit();
icwmp_cleanmem();
end_session_flag = 0;
@ -783,6 +869,8 @@ static int cwmp_init(int argc, char **argv, struct cwmp *cwmp)
init_list_param_notify();
cwmp_uci_exit();
get_nonce_key();
memset(&intf_reset_list, 0, sizeof(struct list_head));
INIT_LIST_HEAD(&intf_reset_list);
return CWMP_OK;
}

View file

@ -57,10 +57,11 @@
#define DEFAULT_AMD_VERSION 5
#define DEFAULT_INSTANCE_MODE 0
#define DEFAULT_SESSION_TIMEOUT 60
#define DEFAULT_ACSURL "http://192.168.1.1:8080/openacs/acs"
#define MAX_NBRE_SERVICES 256
#define FIREWALL_CWMP "/etc/firewall.cwmp"
#define CWMP_VARSTATE_UCI_PACKAGE "/var/state/cwmp"
#define DM_PPP_INTERFACE_PATH "Device.PPP.Interface."
#define DM_IP_INTERFACE_PATH "Device.IP.Interface."
extern char *commandKey;
extern bool thread_end;
@ -484,6 +485,11 @@ typedef struct opfault {
char *fault_string;
} opfault;
typedef struct intf_reset_node {
char path[1024];
struct list_head list;
} intf_reset_node;
extern struct cwmp cwmp_main;
extern long int flashsize;
extern struct FAULT_CPE FAULT_CPE_ARRAY[];
@ -536,5 +542,6 @@ time_t convert_datetime_to_timestamp(char *value);
int cwmp_get_retry_interval(struct cwmp *cwmp, bool heart_beat);
int cwmp_schedule_rpc(struct cwmp *cwmp, struct session *session);
int run_session_end_func(void);
void set_interface_reset_request(char *param_name, char *value);
#endif

View file

@ -509,11 +509,11 @@ static void load_inform_xml_schema(mxml_node_t **tree, struct cwmp *cwmp, struct
*tree = xml;
}
int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *session, struct rpc *this)
int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *session, struct rpc *this __attribute__((unused)))
{
mxml_node_t *tree;
if (session == NULL || this == NULL)
if (session == NULL)
return -1;
load_inform_xml_schema(&tree, cwmp, session);
@ -1348,9 +1348,10 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc
goto fault;
struct cwmp_dm_parameter *param_value;
// cppcheck-suppress unknownMacro
list_for_each_entry (param_value, &list_set_param_value, list)
list_for_each_entry (param_value, &list_set_param_value, list) {
set_interface_reset_request(param_value->name, param_value->value);
set_diagnostic_parameter_structure_value(param_value->name, param_value->value);
}
cwmp_free_all_dm_parameter_list(&list_set_param_value);