diff --git a/bbf_plugin/datamodel.c b/bbf_plugin/datamodel.c index 9219753..b96e20e 100644 --- a/bbf_plugin/datamodel.c +++ b/bbf_plugin/datamodel.c @@ -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; diff --git a/docs/api/uci/cwmp.md b/docs/api/uci/cwmp.md index 737d881..3e24d77 100644 --- a/docs/api/uci/cwmp.md +++ b/docs/api/uci/cwmp.md @@ -1,496 +1 @@ -# UCI schema - - - - -
cwmp
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
section
description
multi
options
acs
Configure the ACS parameters, used by icwmp
false
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
name
type
required
default
description
url
string
yes
URL of ACS server
userid
string
no
Username for ACS server connection
passwd
string
no
Password for ACS server connection
periodic_inform_enable
boolean
no
1
-
If set to 1, the CPE must periodically open session with ACS by sending Inform message to the ACS.
-
periodic_inform_interval
uinteger
no
86400
The duration in seconds of the interval for which the CPE must attempt to connect with the ACS and call the Inform method.
periodic_inform_time
uinteger
no
An absolute time reference to determine when the CPE will initiate the periodic Inform method calls.
dhcp_discovery
string
no
-
if set to enable, the CPE will get the url of ACS from DHCP server Option 43.
-
compression
boolean
no
-
if set to 1, the CPE must use the HTTP Compression when communicating with the ACS.
-
retry_min_wait_interval
uinteger
no
5
The minimum wait interval for session retry (in seconds)
retry_interval_multiplier
uinteger
no
2000
The retry interval multiplier for session retry session as described in the standard.
ssl_capath
string
no
The path of ssl certificates for TR-069 sessions.
insecure_enable
boolean
no
-
if set to 1, the CPE skips validation of the ACS certificates.
-
http_disable_100continue
boolean
no
-
if set to 1, disables the http 100 continue behaviour.
-
dhcp_url
string
no
-
the url of ACS server received from the DHCP server via Option 43. This parameter is automatically updated by daemon, When 'dhcp_discovery' option is enabled.
-
ip_version
string
no
ip_version of ConnectionRequestURL
get_rpc_methods
boolean
no
1
Enable/Disable optional GetRPCMethods to ACS
-
cpe
CWMP client configuration
false
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
name
type
required
default
description
enable
boolean
no
1
if set to 1, the cwmp client will be enabled.
manufacturer
string
no
Overwrite DeviceId parameter
manufacturer_oui
string
no
Overwrite DeviceId parameter
product_class
string
no
Overwrite DeviceId parameter
serial_number
string
no
Overwrite DeviceId parameter
software_version
string
no
Overwrite DeviceId parameter
model_name
string
no
Overwrite DeviceId parameter
description
string
no
Overwrite DeviceId parameter
default_lan_interface
string
no
lan
Configure the default lan interface of the device.
default_wan_interface
string
yes
wan
Configure the default wan interface that will be used for IPv4/IPv6 connection.
log_to_console
string
no
-
If set to 1, the log messages will be shown in the console/stdout.
-
log_to_file
string
no
-
If set to 1, the log messages will be saved in the log file.
-
log_severity
string
no
-
- Specifies the log type to use, by default INFO. The possible types are -
    -
  • EMERG
  • -
  • ALERT
  • -
  • CRITIC
  • -
  • ERROR
  • -
  • WARNING
  • -
  • NOTICE
  • -
  • INFO
  • -
  • DEBUG
  • -
- . -
-
log_file_name
string
no
/var/log/icwmpd.log
-
Specifies the path of the log file, by default '/var/log/icwmpd.log'.
-
log_max_size
uinteger
no
102400
-
Size of the log file. The default value is 102400.
-
userid
string
no
The username of the device used in a connection request from ACS to CPE.
passwd
string
no
The password of the device when sending a connection request from ACS to CPE.
port
uinteger
no
7547
The port used for connection request.
path
string
no
/
CPE Connection request URI path
provisioning_code
string
no
-
- Specifies the primary service provider and other provisioning information, which may be used by the ACS to determine service provider-specific customization and provisioning parameters. -
-
amd_version
uinteger
no
5
Configure the amendment version to use.
instance_mode
string
no
InstanceNumber
-
Configure the instance mode to use. Supported instance modes are : InstanceNumber and InstanceNumber
-
session_timeout
uinteger
no
60
-
Represents the number of seconds that should be used by the ACS as the amount of time to wait before timing out a CWMP session due to the CPE not responding.
-
notification
boolean
no
-
If set to 1, it enables the notification feature.
-
exec_download
boolean
no
-
If set to 1, Specifies if Download method is executed.
-
log_to_syslog
boolean
no
-
If set to 1, the cwmp log will be appended to busybox syslog.
-
periodic_notify_enable
boolean
no
1
-
If set to 1, icwmp will be able to detect parameter value change at any time.
-
periodic_notify_interval
integer
no
10
Interval in sec to check for value change notifications
custom_notify_json
string
no
Define absolute path of the JSON containing parameters on which notification get enabled as per the definition. See readme for examples.
incoming_rule
string
no
This configure firewall rules. Allowed values . IP_Only means only acs ip as source ip used for firewall input rule, Port_Only means only destination port will be used and IP_Port or empty value meaning both ip and port will be used for firewall input rule.
force_ipv4
boolean
no
-
If set to 1, it forces the connectivity over v4 IP address.
-
fw_upgrade_keep_settings
boolean
no
1
-
If set to 1, icwmp will keep the uci setting while doing firmware upgrade using Download RPC with '1 Firmware Upgrade Image'.
-
clock_sync_timeout
integer
no
128
-
The maximum time in seconds, icwmp should wait for the system clock to be synchronized with the time source before sending the initial inform message. Valid range is 0-180 seconds.
-
-
lwn
Lightweight notification configuration
false
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
name
type
required
default
description
enable
boolean
no
0
-
if set to 1, the Lightweight Notifications will be enabled.
-
hostname
host
no
ACS url
The hostname or address to be used when sending the UDP Lightweight Notifications.
port
port
no
7547
The port number to be used when sending UDP Lightweight Notifications.
-
- - - +
cwmp
section
description
multi
options
acs
Configure the ACS parameters, used by icwmp
false
name
type
required
default
description
url
string
yes
URL of ACS server
userid
string
no
Username for ACS server connection
passwd
string
no
Password for ACS server connection
periodic_inform_enable
boolean
no
1
If set to **1**, the CPE must periodically open session with ACS by sending Inform message to the ACS.
periodic_inform_interval
uinteger
no
86400
The duration in seconds of the interval for which the CPE must attempt to connect with the ACS and call the Inform method.
periodic_inform_time
uinteger
no
An absolute time reference to determine when the CPE will initiate the periodic Inform method calls.
dhcp_discovery
string
no
if set to **enable**, the CPE will get the url of ACS from DHCP server Option 43.
compression
boolean
no
if set to **1**, the CPE must use the HTTP Compression when communicating with the ACS.
retry_min_wait_interval
uinteger
no
5
The minimum wait interval for session retry (in seconds)
retry_interval_multiplier
uinteger
no
2000
The retry interval multiplier for session retry session as described in the standard.
ssl_capath
string
no
The path of ssl certificates for TR-069 sessions.
insecure_enable
boolean
no
if set to **1**, the CPE skips validation of the ACS certificates.
http_disable_100continue
boolean
no
if set to **1**, disables the http 100 continue behaviour.
dhcp_url
string
no
the **url** of ACS server received from the DHCP server via Option 43. This parameter is automatically updated by daemon, When **'dhcp_discovery'** option is enabled.
ip_version
string
no
IP version of ConnectionRequestURL
get_rpc_methods
boolean
no
1
Enable/Disable optional GetRPCMethods to ACS
cpe
CWMP client configuration
false
name
type
required
default
description
enable
boolean
no
1
if set to **1**, the cwmp client will be enabled.
manufacturer
string
no
Overwrite DeviceId parameter
manufacturer_oui
string
no
Overwrite DeviceId parameter
product_class
string
no
Overwrite DeviceId parameter
serial_number
string
no
Overwrite DeviceId parameter
software_version
string
no
Overwrite DeviceId parameter
model_name
string
no
Overwrite DeviceId parameter
description
string
no
Overwrite DeviceId parameter
default_lan_interface
string
no
lan
Configure the default lan interface of the device.
default_wan_interface
string
yes
wan
Configure the default wan interface that will be used for IPv4/IPv6 connection.
interface
string
no
Use this option to define l3 device ifname directly, if this option is used default_wan_interface shall be ignored
use_curl_ifname
boolean
no
false
If this option is set, then cwmp shall use l3 device ifname as CURLOPT_INTERFACE
log_to_console
string
no
If set to **1**, the log messages will be shown in the console/stdout.
log_to_file
string
no
If set to **1**, the log messages will be saved in the log file.
log_severity
string
no
Specifies the log type to use, by default **'INFO'**. The possible types are **'EMERG', 'ALERT', 'CRITIC' ,'ERROR', 'WARNING', 'NOTICE', 'INFO' and 'DEBUG'**.
log_file_name
string
no
/var/log/icwmpd.log
Specifies the path of the log file, by default **'/var/log/icwmpd.log'**.
log_max_size
uinteger
no
102400
Size of the log file. The default value is **102400**.
userid
string
no
The username of the device used in a connection request from ACS to CPE.
passwd
string
no
The password of the device when sending a connection request from ACS to CPE.
port
uinteger
no
7547
The port used for connection request.
path
string
no
/
CPE Connection request URI path
provisioning_code
string
no
Specifies the primary service provider and other provisioning information, which may be used by the ACS to determine service provider-specific customization and provisioning parameters.
amd_version
uinteger
no
5
Configure the amendment version to use.
instance_mode
string
no
InstanceNumber
Configure the instance mode to use. Supported instance modes are : <B>InstanceNumber</B> and <B>InstanceNumber</B>.
session_timeout
uinteger
no
60
Represents the number of seconds that should be used by the ACS as the amount of time to wait before timing out a CWMP session due to the CPE not responding.
notification
boolean
no
If set to **1**, it enables the notification feature.
exec_download
boolean
no
If set to **1**, Specifies if Download method is executed.
log_to_syslog
boolean
no
If set to **1**, the cwmp log will be appended to busybox syslog.
periodic_notify_enable
boolean
no
1
If set to **1**, icwmp will be able to detect parameter value change at any time.
periodic_notify_interval
integer
no
10
Interval in sec to check for value change notifications
custom_notify_json
string
no
Define absolute path of the JSON containing parameters on which notification get enabled as per the definition. See readme for examples.
incoming_rule
string
no
This configure firewall rules. Allowed values <IP_Only/Port_Only/IP_Port>. IP_Only means only acs ip as source ip used for firewall input rule, Port_Only means only destination port will be used and IP_Port or empty value meaning both ip and port will be used for firewall input rule.
force_ipv4
boolean
no
If set to 1, it forces the connectivity over v4 IP address.
fw_upgrade_keep_settings
boolean
no
1
If set to **1**, icwmp will keep the uci setting while doing firmware upgrade using Download RPC with '1 Firmware Upgrade Image'.
lwn
Lightweight notification configuration
false
name
type
required
default
description
enable
boolean
no
0
if set to **1**, the Lightweight Notifications will be enabled.
hostname
host
no
ACS url
The hostname or address to be used when sending the UDP Lightweight Notifications.
port
port
no
7547
The port number to be used when sending UDP Lightweight Notifications.
\ No newline at end of file diff --git a/schemas/uci/cwmp.json b/schemas/uci/cwmp.json index d1d7455..2a4c8d9 100644 --- a/schemas/uci/cwmp.json +++ b/schemas/uci/cwmp.json @@ -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", diff --git a/src/common.c b/src/common.c index bb8da7d..07eb7a9 100755 --- a/src/common.c +++ b/src/common.c @@ -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) diff --git a/src/common.h b/src/common.h index 0e57efb..981e4b1 100644 --- a/src/common.h +++ b/src/common.h @@ -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(); diff --git a/src/cwmp_http.c b/src/cwmp_http.c index ccaff0d..52c91b6 100644 --- a/src/cwmp_http.c +++ b/src/cwmp_http.c @@ -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); diff --git a/src/download.c b/src/download.c index 99d0b89..f1ba015 100644 --- a/src/download.c +++ b/src/download.c @@ -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); diff --git a/src/http.c b/src/http.c index aefccdd..bece0ee 100644 --- a/src/http.c +++ b/src/http.c @@ -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); } diff --git a/src/uci_utils.c b/src/uci_utils.c index 33e7e03..513d726 100644 --- a/src/uci_utils.c +++ b/src/uci_utils.c @@ -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) { diff --git a/src/upload.c b/src/upload.c index 7672c5a..905641c 100644 --- a/src/upload.c +++ b/src/upload.c @@ -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); diff --git a/test/cmocka/icwmp_download_unit_test.c b/test/cmocka/icwmp_download_unit_test.c index 3401012..634f146 100644 --- a/test/cmocka/icwmp_download_unit_test.c +++ b/test/cmocka/icwmp_download_unit_test.c @@ -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); }