uci option to use ifname in curl option

This commit is contained in:
Vivek Kumar Dutta 2024-08-08 15:58:11 +05:30
parent 3d7ce039bd
commit 450d362cbf
11 changed files with 78 additions and 519 deletions

View file

@ -518,15 +518,16 @@ static int set_management_server_periodic_inform_time(char *refparam, struct dmc
static void get_management_ip_port(char **listen_addr)
{
char *ip = NULL, *port = NULL, *interface = NULL, *ip_version = NULL;
char *l3_device = NULL;
dmuci_get_option_value_string("cwmp", "cpe", "default_wan_interface", &interface);
dmuci_get_option_value_string("cwmp", "cpe", "interface", &l3_device);
dmuci_get_option_value_string("cwmp", "cpe", "port", &port);
dmuci_get_option_value_string_varstate("icwmp", "acs", "ip_version", &ip_version);
if (!DM_STRLEN(interface))
return;
if (DM_STRLEN(l3_device) == 0 && DM_STRLEN(interface) != 0)
l3_device = get_l3_device(interface);
char *l3_device = get_l3_device(interface);
if (!DM_STRLEN(l3_device))
return;

File diff suppressed because one or more lines are too long

View file

@ -194,6 +194,20 @@
"default": "wan",
"description": "Configure the default wan interface that will be used for IPv4/IPv6 connection."
},
{
"name": "interface",
"type": "string",
"required": "no",
"default": "",
"description": "Use this option to define l3 device ifname directly, if this option is used default_wan_interface shall be ignored"
},
{
"name": "use_curl_ifname",
"type": "boolean",
"required": "no",
"default": "false",
"description": "If this option is set, then cwmp shall use l3 device ifname as CURLOPT_INTERFACE"
},
{
"name": "log_to_console",
"type": "string",

View file

@ -931,7 +931,7 @@ static void ubus_network_interface_callback(struct ubus_request *req __attribute
snprintf(cwmp_main->net.interface, sizeof(cwmp_main->net.interface), "%s", l3_device);
CWMP_LOG(DEBUG, "CWMP IFACE - interface: %s && device: %s", cwmp_main->conf.default_wan_iface, cwmp_main->net.interface);
CWMP_LOG(DEBUG, "CWMP IFACE - interface: %s && l3_name: %s", cwmp_main->conf.default_wan_iface, cwmp_main->net.interface);
}
static bool is_ipv6_addr_available(const char *device)

View file

@ -109,6 +109,7 @@ struct connection {
char interface[BUF_SIZE_16];
long ip_resolve;
bool ipv6_status;
bool use_curl_ifname;
};
typedef struct config {
@ -638,7 +639,7 @@ bool file_exists(const char *path);
void cwmp_reboot(char *command_key);
void cwmp_factory_reset();
void get_firewall_zone_name_by_wan_iface(char *if_wan, char **zone_name);
int download_file(const char *file_path, const char *url, const char *username, const char *password);
int download_file(const char *file_path, const char *url, const char *username, const char *password, const char *interface);
unsigned int get_file_size(char *file_name);
int cwmp_check_image();
int cwmp_apply_firmware();

View file

@ -75,7 +75,7 @@ int icwmp_check_http_connection(void)
curl_easy_setopt(c, CURLOPT_IPRESOLVE, resolve);
curl_easy_setopt(c, CURLOPT_TIMEOUT, 2);
if (CWMP_STRLEN(cwmp_main->net.interface))
if (cwmp_main->net.use_curl_ifname && CWMP_STRLEN(cwmp_main->net.interface))
curl_easy_setopt(c, CURLOPT_INTERFACE, cwmp_main->net.interface);
ret = curl_easy_perform(c);

View file

@ -35,7 +35,7 @@ int count_download_queue = 0;
/*
* Download File
*/
int download_file(const char *file_path, const char *url, const char *username, const char *password)
int download_file(const char *file_path, const char *url, const char *username, const char *password, const char *interface)
{
if (url == NULL) {
CWMP_LOG(ERROR, "download %s: no url specified", __FUNCTION__);
@ -59,6 +59,11 @@ int download_file(const char *file_path, const char *url, const char *username,
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 10000L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, 1L);
// Use l3 interface name
if (CWMP_STRLEN(interface))
curl_easy_setopt(curl, CURLOPT_INTERFACE, interface);
if (file_path == NULL)
file_path = "/tmp/download_file";
FILE *fp = fopen(file_path, "wb");
@ -90,10 +95,10 @@ char *download_file_task_function(char *task)
blob_buf_free(&bbuf);
return NULL;
}
const struct blobmsg_policy p[5] = { { "task", BLOBMSG_TYPE_STRING }, { "file_path", BLOBMSG_TYPE_STRING }, { "url", BLOBMSG_TYPE_STRING }, { "username", BLOBMSG_TYPE_STRING }, { "password", BLOBMSG_TYPE_STRING } };
const struct blobmsg_policy p[6] = { { "task", BLOBMSG_TYPE_STRING }, { "file_path", BLOBMSG_TYPE_STRING }, { "url", BLOBMSG_TYPE_STRING }, { "username", BLOBMSG_TYPE_STRING }, { "password", BLOBMSG_TYPE_STRING }, {"interface", BLOBMSG_TYPE_STRING} };
struct blob_attr *tb[5] = { NULL, NULL, NULL, NULL, NULL};
blobmsg_parse(p, 5, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
struct blob_attr *tb[6] = { NULL, NULL, NULL, NULL, NULL};
blobmsg_parse(p, 6, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
char *task_name = blobmsg_get_string(tb[0]);
if (CWMP_STRCMP(task_name, "download") != 0)
return NULL;
@ -101,8 +106,9 @@ char *download_file_task_function(char *task)
char *url = blobmsg_get_string(tb[2]);
char *username = blobmsg_get_string(tb[3]);
char *password = blobmsg_get_string(tb[4]);
char *interface = blobmsg_get_string(tb[5]);
int http_code = download_file(file_path, url, username, password);
int http_code = download_file(file_path, url, username, password, interface);
char *http_ret = (char *)malloc(4 * sizeof(char));
snprintf(http_ret, 4, "%d", http_code);
http_ret[3] = 0;
@ -129,6 +135,10 @@ int download_file_in_subprocess(const char *file_path, const char *url, const ch
blobmsg_add_string(&bbuf, "url", url ? url : "");
blobmsg_add_string(&bbuf, "username", username ? username : "");
blobmsg_add_string(&bbuf, "password", password ? password : "");
if (cwmp_main->net.use_curl_ifname && CWMP_STRLEN(cwmp_main->net.interface))
blobmsg_add_string(&bbuf, "interface", cwmp_main->net.interface);
char *download_task = blobmsg_format_json(bbuf.head, true);
blob_buf_free(&bbuf);

View file

@ -133,7 +133,7 @@ static void http_set_connection_options()
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, cwmp_main->net.ip_resolve);
if (CWMP_STRLEN(cwmp_main->net.interface))
if (cwmp_main->net.use_curl_ifname && CWMP_STRLEN(cwmp_main->net.interface))
curl_easy_setopt(curl, CURLOPT_INTERFACE, cwmp_main->net.interface);
}

View file

@ -238,8 +238,10 @@ static void config_get_cpe_elements(struct uci_section *s)
UCI_CPE_FORCE_IPV4,
UCI_CPE_KEEP_SETTINGS,
UCI_CPE_DEFAULT_WAN_IFACE,
UCI_CPE_INTERFACE,
UCI_CPE_CLOCK_SYNC_TIMEOUT,
UCI_CPE_ENABLE,
UCI_CPE_USE_CURL_IFNAME,
__MAX_NUM_UCI_CPE_ATTRS,
};
@ -262,8 +264,10 @@ static void config_get_cpe_elements(struct uci_section *s)
[UCI_CPE_FORCE_IPV4] = { .name = "force_ipv4", .type = UCI_TYPE_STRING },
[UCI_CPE_KEEP_SETTINGS] = { .name = "fw_upgrade_keep_settings", .type = UCI_TYPE_STRING },
[UCI_CPE_DEFAULT_WAN_IFACE] = { .name = "default_wan_interface", .type = UCI_TYPE_STRING },
[UCI_CPE_INTERFACE] = { .name = "interface", .type = UCI_TYPE_STRING },
[UCI_CPE_CLOCK_SYNC_TIMEOUT] = { .name = "clock_sync_timeout", .type = UCI_TYPE_STRING },
[UCI_CPE_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING }
[UCI_CPE_ENABLE] = { .name = "enable", .type = UCI_TYPE_STRING },
[UCI_CPE_USE_CURL_IFNAME] = { .name = "use_curl_ifname", .type = UCI_TYPE_STRING }
};
struct uci_option *cpe_tb[__MAX_NUM_UCI_CPE_ATTRS];
@ -373,15 +377,23 @@ static void config_get_cpe_elements(struct uci_section *s)
cwmp_main->conf.fw_upgrade_keep_settings = cpe_tb[UCI_CPE_KEEP_SETTINGS] ? str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_KEEP_SETTINGS])) : true;
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe keep settings enable: %d", cwmp_main->conf.fw_upgrade_keep_settings);
char *value = get_value_from_uci_option(cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]);
char *value = get_value_from_uci_option(cpe_tb[UCI_CPE_INTERFACE]);
if ((CWMP_STRLEN(cwmp_main->net.interface) == 0) && (CWMP_STRLEN(value) != 0)) {
snprintf(cwmp_main->net.interface, sizeof(cwmp_main->net.interface), "%s", value);
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe INTERFACE resolved[%s], defined [%s]", cwmp_main->net.interface, value);
value = get_value_from_uci_option(cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]);
char *wan_intf = CWMP_STRLEN(value) ? value : "wan";
if (strcmp(cwmp_main->conf.default_wan_iface, wan_intf) != 0) {
snprintf(cwmp_main->conf.default_wan_iface, sizeof(cwmp_main->conf.default_wan_iface), "%s", wan_intf);
memset(cwmp_main->net.interface, 0, sizeof(cwmp_main->net.interface));
}
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe default_wan_interface: %s", cwmp_main->conf.default_wan_iface);
cwmp_main->net.use_curl_ifname = str_to_bool(get_value_from_uci_option(cpe_tb[UCI_CPE_USE_CURL_IFNAME]));
CWMP_LOG(DEBUG, "CWMP CONFIG - cpe use ifname in curl: %d", cwmp_main->net.use_curl_ifname);
cwmp_main->conf.clock_sync_timeout = DEFAULT_SYNC_TIMEOUT;
char *sync_time = get_value_from_uci_option(cpe_tb[UCI_CPE_CLOCK_SYNC_TIMEOUT]);
if (CWMP_STRLEN(sync_time) != 0) {

View file

@ -67,7 +67,7 @@ static int lookup_vlf_name(int instance, char **value)
/*
* Upload file
*/
static long upload_file(const char *file_path, const char *url, const char *username, const char *password)
static long upload_file(const char *file_path, const char *url, const char *username, const char *password, const char *interface)
{
long res_code = 0;
CURL *curl;
@ -123,6 +123,10 @@ static long upload_file(const char *file_path, const char *url, const char *user
curl_easy_setopt(curl, CURLOPT_READDATA, fd_upload);
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
// Use l3 interface name
if (CWMP_STRLEN(interface))
curl_easy_setopt(curl, CURLOPT_INTERFACE, interface);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
CWMP_LOG(ERROR, "## curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
@ -153,10 +157,10 @@ char *upload_file_task_function(char *task)
blob_buf_free(&bbuf);
return NULL;
}
const struct blobmsg_policy p[5] = { { "task", BLOBMSG_TYPE_STRING }, { "file_path", BLOBMSG_TYPE_STRING }, { "url", BLOBMSG_TYPE_STRING }, { "username", BLOBMSG_TYPE_STRING }, { "password", BLOBMSG_TYPE_STRING } };
const struct blobmsg_policy p[6] = { { "task", BLOBMSG_TYPE_STRING }, { "file_path", BLOBMSG_TYPE_STRING }, { "url", BLOBMSG_TYPE_STRING }, { "username", BLOBMSG_TYPE_STRING }, { "password", BLOBMSG_TYPE_STRING }, {"interface", BLOBMSG_TYPE_STRING}};
struct blob_attr *tb[5] = { NULL, NULL, NULL, NULL, NULL};
blobmsg_parse(p, 5, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
struct blob_attr *tb[6] = { NULL, NULL, NULL, NULL, NULL};
blobmsg_parse(p, 6, tb, blobmsg_data(bbuf.head), blobmsg_len(bbuf.head));
char *task_name = blobmsg_get_string(tb[0]);
if (CWMP_STRCMP(task_name, "upload") != 0)
return NULL;
@ -164,8 +168,9 @@ char *upload_file_task_function(char *task)
char *url = blobmsg_get_string(tb[2]);
char *username = blobmsg_get_string(tb[3]);
char *password = blobmsg_get_string(tb[4]);
char *interface = blobmsg_get_string(tb[5]);
long http_code = upload_file(file_path, url, username, password);
long http_code = upload_file(file_path, url, username, password, interface);
char *http_ret = (char *)malloc(16 * sizeof(char));
if (http_ret == NULL)
return NULL;
@ -191,6 +196,10 @@ int upload_file_in_subprocess(const char *file_path, const char *url, const char
blobmsg_add_string(&bbuf, "url", url);
blobmsg_add_string(&bbuf, "username", username);
blobmsg_add_string(&bbuf, "password", password);
if (cwmp_main->net.use_curl_ifname && CWMP_STRLEN(cwmp_main->net.interface))
blobmsg_add_string(&bbuf, "interface", cwmp_main->net.interface);
char *upload_task = blobmsg_format_json(bbuf.head, true);
blob_buf_free(&bbuf);

View file

@ -46,6 +46,12 @@ static void free_download(struct download *p)
icwmp_free(p);
}
static int download_unit_test_init(void **state)
{
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
return 0;
}
static int download_unit_tests_clean(void **state)
{
icwmp_cleanmem();
@ -53,6 +59,7 @@ static int download_unit_tests_clean(void **state)
free_transfer_complete(transfer_complete_test);
remove(ICWMP_DOWNLOAD_FILE);
remove(FIRMWARE_UPGRADE_IMAGE);
FREE(cwmp_main);
return 0;
}
@ -62,7 +69,7 @@ static void cwmp_download_file_unit_test(void **state)
/*
* Valid URL
*/
int http_code = download_file(ICWMP_DOWNLOAD_FILE, "http://127.0.0.1/firmware_v1.0.bin", NULL, NULL);
int http_code = download_file(ICWMP_DOWNLOAD_FILE, "http://127.0.0.1/firmware_v1.0.bin", NULL, NULL, NULL);
assert_int_equal(http_code, 200);
assert_int_equal(access( ICWMP_DOWNLOAD_FILE, F_OK ), 0);
remove(ICWMP_DOWNLOAD_FILE);
@ -70,7 +77,7 @@ static void cwmp_download_file_unit_test(void **state)
/*
* Not Valid URL
*/
http_code = download_file(ICWMP_DOWNLOAD_FILE, "http://127.0.0.1/firmware.bin", NULL, NULL);
http_code = download_file(ICWMP_DOWNLOAD_FILE, "http://127.0.0.1/firmware.bin", NULL, NULL, NULL);
assert_int_equal(http_code, 404);
assert_int_equal(access( ICWMP_DOWNLOAD_FILE, F_OK ), 0);
remove(ICWMP_DOWNLOAD_FILE);
@ -188,5 +195,5 @@ int icwmp_download_unit_test(void)
cmocka_unit_test(cwmp_launch_download_unit_test)
};
return cmocka_run_group_tests(tests, NULL, download_unit_tests_clean);
return cmocka_run_group_tests(tests, download_unit_test_init, download_unit_tests_clean);
}