mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2026-03-07 18:07:13 +01:00
tr181: ip: Fixes and cleanups
- use sysfs instread of ubus and ifconfig command execution for Inteface stats. This reduces uneccessary memory and cpu overhead and speeds up the query time for IP.Interface queries by a multiple. - move redundant code to static functions - fix rx/tx multicast/broadcast stats can never be obtained from ifconfig - fix invalid stats for unknownprotopackets. - fix stats not correclty reported when counters exceed 32bit int values. Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
This commit is contained in:
parent
8708940709
commit
219d9b4984
4 changed files with 105 additions and 143 deletions
|
|
@ -197,6 +197,23 @@ static inline int init_ipv6prefix_args(struct ipv6prefix_args *args, struct uci_
|
|||
/*************************************************************
|
||||
* COMMON Functions
|
||||
**************************************************************/
|
||||
static int get_ip_iface_sysfs(const struct ip_args *ip, const char *name, char **value)
|
||||
{
|
||||
const char *device = get_device(section_name(ip->ip_sec));
|
||||
|
||||
if(device[0]) {
|
||||
char file[256];
|
||||
char val[64];
|
||||
|
||||
snprintf(file, sizeof(file), "/sys/class/net/%s/%s", device, name);
|
||||
dm_read_sysfs_file(file, val, sizeof(val));
|
||||
*value = dmstrdup(val);
|
||||
} else {
|
||||
*value = "0";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *ubus_call_get_value_with_two_objects(char *interface, char *obj1, char *obj2, char *key)
|
||||
{
|
||||
json_object *res, *jobj1 = NULL, *jobj2 = NULL;
|
||||
|
|
@ -493,22 +510,7 @@ int set_IPInterface_Reset(char *refparam, struct dmctx *ctx, void *data, char *i
|
|||
/*#Device.IP.Interface.{i}.MaxMTUSize!UBUS:network.interface/status/interface,@Name/mtu*/
|
||||
int get_IPInterface_MaxMTUSize(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
json_object *res, *diag;
|
||||
char *device= NULL;
|
||||
|
||||
dmuci_get_value_by_section_string(((struct ip_args *)data)->ip_sec, "mtu", value);
|
||||
if(*value[0] == '\0') {
|
||||
dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", section_name(((struct ip_args *)data)->ip_sec), String}}, 1, &res);
|
||||
DM_ASSERT(res, *value = "");
|
||||
device = dmjson_get_value(res, 1, "device");
|
||||
if(device) {
|
||||
dmubus_call("network.device", "status", UBUS_ARGS{{"name", device, String}}, 1, &diag);
|
||||
DM_ASSERT(diag, *value = "");
|
||||
*value = dmjson_get_value(diag, 1, "mtu");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "mtu", value);
|
||||
}
|
||||
|
||||
int set_IPInterface_MaxMTUSize(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||
|
|
@ -758,28 +760,31 @@ int set_ipv4_addressing_type(char *refparam, struct dmctx *ctx, void *data, char
|
|||
int get_IPInterface_LowerLayers(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
char linker[64] = "", *proto, *device, *mac;
|
||||
const struct ip_args *ip = data;
|
||||
char *section;
|
||||
|
||||
dmuci_get_value_by_section_string(((struct ip_args *)data)->ip_sec, "proto", &proto);
|
||||
dmuci_get_value_by_section_string(ip->ip_sec, "proto", &proto);
|
||||
if (strstr(proto, "ppp")) {
|
||||
snprintf(linker, sizeof(linker), "%s", section_name(((struct ip_args *)data)->ip_sec));
|
||||
adm_entry_get_linker_param(ctx, dm_print_path("%s%cPPP%cInterface%c", dmroot, dm_delim, dm_delim, dm_delim), linker, value);
|
||||
goto end;
|
||||
}
|
||||
|
||||
device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
section = section_name(ip->ip_sec);
|
||||
device = get_device(section);
|
||||
if (device[0] != '\0') {
|
||||
adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cVLANTermination%c", dmroot, dm_delim, dm_delim, dm_delim), device, value);
|
||||
if (*value != NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mac = get_macaddr(section_name(((struct ip_args *)data)->ip_sec));
|
||||
mac = get_macaddr(section);
|
||||
if (mac[0] != '\0') {
|
||||
adm_entry_get_linker_param(ctx, dm_print_path("%s%cEthernet%cLink%c", dmroot, dm_delim, dm_delim, dm_delim), mac, value);
|
||||
goto end;
|
||||
}
|
||||
|
||||
end :
|
||||
end:
|
||||
if (*value == NULL)
|
||||
*value = "";
|
||||
return 0;
|
||||
|
|
@ -1153,126 +1158,84 @@ int set_IPInterfaceIPv6Prefix_ValidLifetime(char *refparam, struct dmctx *ctx, v
|
|||
/*
|
||||
* *** Device.IP.Interface.{i}.Stats. ***
|
||||
*/
|
||||
static char *get_ip_interface_statistics(char *interface, char *key)
|
||||
{
|
||||
json_object *res, *diag;
|
||||
char *device, *value = "0";
|
||||
|
||||
dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", interface, String}}, 1, &res);
|
||||
if (!res) return value;
|
||||
device = dmjson_get_value(res, 1, "device");
|
||||
if(device[0] != '\0') {
|
||||
dmubus_call("network.device", "status", UBUS_ARGS{{"name", device, String}}, 1, &diag);
|
||||
value = dmjson_get_value(diag, 2, "statistics", key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_tx_bytes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "tx_bytes");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/tx_bytes", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_bytes(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "rx_bytes");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/rx_bytes", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_tx_packets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "tx_packets");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/tx_packets", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_packets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "rx_packets");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/rx_packets", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_tx_errors(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "tx_errors");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/tx_errors", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_errors(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "rx_errors");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/rx_errors", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_tx_discardpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "tx_dropped");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/tx_dropped", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_discardpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "rx_dropped");
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/rx_dropped", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_tx_unicastpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = "0";
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
if(device[0] != '\0')
|
||||
dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "TX", "unicast"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_unicastpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = "0";
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
if(device[0] != '\0')
|
||||
dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "RX", "unicast"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_tx_multicastpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = "0";
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
if(device[0] != '\0')
|
||||
dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "TX", "multicast"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_multicastpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = "0";
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
if(device[0] != '\0')
|
||||
dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "RX", "multicast"));
|
||||
return 0;
|
||||
return get_ip_iface_sysfs(data, "statistics/multicast", value);
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_tx_broadcastpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = "0";
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
if(device[0] != '\0')
|
||||
dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "TX", "broadcast"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_broadcastpackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = "0";
|
||||
char *device = get_device(section_name(((struct ip_args *)data)->ip_sec));
|
||||
if(device[0] != '\0')
|
||||
dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "RX", "broadcast"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_ip_interface_statistics_rx_unknownprotopackets(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||
{
|
||||
*value = get_ip_interface_statistics(section_name(((struct ip_args *)data)->ip_sec), "rx_over_errors");
|
||||
*value = "0";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1327,6 +1290,7 @@ int set_IPInterfaceTWAMPReflector_Enable(char *refparam, struct dmctx *ctx, void
|
|||
device = dmjson_get_value(res, 1, "device");
|
||||
dmuci_set_value_by_section((struct uci_section *)data, "device", device);
|
||||
}
|
||||
dmuci_set_value_by_section((struct uci_section *)data, "device", get_device(interface));
|
||||
} else {
|
||||
dmuci_set_value_by_section((struct uci_section *)data, "enable", "0");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@
|
|||
#include "dmentry.h"
|
||||
#include "usb.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
/* *** Device.USB. *** */
|
||||
DMOBJ tUSBObj[] = {
|
||||
/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/
|
||||
|
|
@ -195,55 +193,12 @@ static void init_usb_interface(struct uci_section *dm, char *iface_name, char *i
|
|||
/*************************************************************
|
||||
* ENTRY METHOD
|
||||
*************************************************************/
|
||||
static inline int char_is_valid(char c)
|
||||
{
|
||||
return c > 0x20 && c < 0x7f;
|
||||
}
|
||||
|
||||
static int __read_sysfs_file(const char *file, char *dst, unsigned len)
|
||||
{
|
||||
char *content;
|
||||
int fd;
|
||||
int rlen;
|
||||
int i, n;
|
||||
int rc = 0;
|
||||
|
||||
content = alloca(len);
|
||||
dst[0] = 0;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
rlen = read(fd, content, len - 1);
|
||||
if (rlen == -1) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
content[rlen] = 0;
|
||||
for (i = 0, n = 0; i < rlen; i++) {
|
||||
if (!char_is_valid(content[i])) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
dst[n++] = content[i];
|
||||
}
|
||||
dst[n] = 0;
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int read_sysfs_file(const char *file, char **value)
|
||||
{
|
||||
char buf[128];
|
||||
int rc;
|
||||
|
||||
rc = __read_sysfs_file(file, buf, sizeof(buf));
|
||||
rc = dm_read_sysfs_file(file, buf, sizeof(buf));
|
||||
*value = dmstrdup(buf);
|
||||
|
||||
return rc;
|
||||
|
|
@ -262,7 +217,7 @@ static int __read_sysfs(const char *path, const char *name, char *dst, unsigned
|
|||
char file[256];
|
||||
|
||||
snprintf(file, sizeof(file), "%s/%s", path, name);
|
||||
return __read_sysfs_file(file, dst, len);
|
||||
return dm_read_sysfs_file(file, dst, len);
|
||||
}
|
||||
|
||||
static int read_sysfs_usb_port(const struct usb_port *port, const char *name, char **value)
|
||||
|
|
@ -432,7 +387,7 @@ int synchronize_usb_devices_with_dmmap_opt_recursively(char *sysfsrep, char *dmm
|
|||
char deviceClass[16];
|
||||
|
||||
snprintf(deviceClassFile, sizeof(deviceClassFile), "%s/%s/bDeviceClass", sysfsrep, ent->d_name);
|
||||
__read_sysfs_file(deviceClassFile, deviceClass, sizeof(deviceClass));
|
||||
dm_read_sysfs_file(deviceClassFile, deviceClass, sizeof(deviceClass));
|
||||
|
||||
if(strncmp(deviceClass, "09", 2) == 0){
|
||||
char hubpath[256];
|
||||
|
|
@ -1061,7 +1016,7 @@ int get_USBUSBHostsHost_USBVersion(char *refparam, struct dmctx *ctx, void *data
|
|||
char buf[16] = { 0, 0 };
|
||||
|
||||
snprintf(file, sizeof(file), "%s/bcdDevice", port->folder_path);
|
||||
__read_sysfs_file(file, buf, sizeof(buf));
|
||||
dm_read_sysfs_file(file, buf, sizeof(buf));
|
||||
|
||||
dmasprintf(value, "%c.%c", buf[1], buf[2]);
|
||||
}
|
||||
|
|
@ -1082,7 +1037,7 @@ int get_number_devices(char *folderpath, int *nbre)
|
|||
char deviceClass[16];
|
||||
|
||||
snprintf(deviceClassFile, sizeof(deviceClassFile), "%s/%s/bDeviceClass", folderpath, ent->d_name);
|
||||
__read_sysfs_file(deviceClassFile, deviceClass, sizeof(deviceClass));
|
||||
dm_read_sysfs_file(deviceClassFile, deviceClass, sizeof(deviceClass));
|
||||
|
||||
if(strncmp(deviceClass, "09", 2) == 0){
|
||||
char hubpath[256];
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "dmbbf.h"
|
||||
#include "dmuci.h"
|
||||
|
|
@ -1412,11 +1413,9 @@ char *get_macaddr(char *interface_name)
|
|||
char *get_device(char *interface_name)
|
||||
{
|
||||
json_object *res;
|
||||
char *device = "";
|
||||
|
||||
dmubus_call("network.interface", "status", UBUS_ARGS{{"interface", interface_name, String}}, 1, &res);
|
||||
device = dmjson_get_value(res, 1, "device");
|
||||
return device;
|
||||
return dmjson_get_value(res, 1, "device");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1520,25 +1519,25 @@ int get_shift_time_shift(char *local_time, char *shift)
|
|||
|
||||
int get_stats_from_ifconfig_command(const char *device, char *direction, char *option)
|
||||
{
|
||||
char buf[1024], *pch, *pchr, *ret;
|
||||
int pp, stats = 0;
|
||||
char buf[1024], *pch, *pchr, *ret;
|
||||
int pp, r, stats = 0;
|
||||
|
||||
pp = dmcmd("ifconfig", 1, device);
|
||||
if (pp) {
|
||||
dmcmd_read(pp, buf, 1024);
|
||||
for(pch = strtok_r(buf, "\n", &pchr); pch != NULL; pch = strtok_r(NULL, "\n", &pchr)) {
|
||||
if(!strstr(pch, direction))
|
||||
continue;
|
||||
ret = strstr(pch, option);
|
||||
if(ret) {
|
||||
strtok_r(ret, ":", &ret);
|
||||
sscanf(ret, "%d", &stats);
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(pp);
|
||||
}
|
||||
return stats;
|
||||
pp = dmcmd("ifconfig", 1, device);
|
||||
if (pp) {
|
||||
r = dmcmd_read(pp, buf, 1024);
|
||||
for(pch = strtok_r(buf, "\n", &pchr); pch != NULL; pch = strtok_r(NULL, "\n", &pchr)) {
|
||||
if(!strstr(pch, direction))
|
||||
continue;
|
||||
ret = strstr(pch, option);
|
||||
if(ret) {
|
||||
strtok_r(ret, ":", &ret);
|
||||
sscanf(ret, "%d", &stats);
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(pp);
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
int command_exec_output_to_array(char *cmd, char **output, int *length)
|
||||
|
|
@ -1620,3 +1619,46 @@ bool match(const char *string, const char *pattern)
|
|||
if (status != 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline int char_is_valid(char c)
|
||||
{
|
||||
return c > 0x20 && c < 0x7f;
|
||||
}
|
||||
|
||||
int dm_read_sysfs_file(const char *file, char *dst, unsigned len)
|
||||
{
|
||||
char *content;
|
||||
int fd;
|
||||
int rlen;
|
||||
int i, n;
|
||||
int rc = 0;
|
||||
|
||||
content = alloca(len);
|
||||
dst[0] = 0;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
rlen = read(fd, content, len - 1);
|
||||
if (rlen == -1) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
content[rlen] = 0;
|
||||
for (i = 0, n = 0; i < rlen; i++) {
|
||||
if (!char_is_valid(content[i])) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
dst[n++] = content[i];
|
||||
}
|
||||
dst[n] = 0;
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -257,4 +257,5 @@ struct uci_section *is_dmmap_section_exist_eq(char* package, char* section, char
|
|||
int isfolderexist(char *folderpath);
|
||||
bool match(const char *string, const char *pattern);
|
||||
char * dmmap_file_path_get(const char *dmmap_package);
|
||||
int dm_read_sysfs_file(const char *file, char *dst, unsigned len);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue