From 3e903fc731cafc8186ce1b882b3b90e50ae15a39 Mon Sep 17 00:00:00 2001 From: Daniel Danzberger Date: Thu, 9 Jan 2020 03:07:14 +0100 Subject: [PATCH] tr181: ethernet: 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 --- dmtree/tr181/ethernet.c | 197 +++++++++++----------------------------- dmtree/tr181/ip.c | 14 +-- libbbf_api/dmcommon.c | 22 +++++ libbbf_api/dmcommon.h | 2 + 4 files changed, 79 insertions(+), 156 deletions(-) diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index e83313b5..db6d81fa 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -171,6 +171,19 @@ static inline int init_eth_port(struct eth_port_args *args, struct uci_section * /************************************************************* * COMMON Functions **************************************************************/ +static int eth_iface_sysfs(const struct dm_args *args, const char *name, char **value) +{ + char *device; + + dmuci_get_value_by_section_string(args->section, "device", &device); + return get_net_device_sysfs(device, name, value); +} + +static int eth_port_sysfs(const struct eth_port_args *args, const char *name, char **value) +{ + return get_net_device_sysfs(args->ifname, name, value); +} + static int is_mac_exist(char *macaddr) { struct uci_section *s = NULL; @@ -636,12 +649,7 @@ int get_EthernetInterface_Upstream(char *refparam, struct dmctx *ctx, void *data /*#Device.Ethernet.Interface.{i}.MACAddress!UBUS:network.device/status/name,@Name/macaddr*/ int get_EthernetInterface_MACAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - json_object *res; - - dmubus_call("network.device", "status", UBUS_ARGS{{"name", ((struct eth_port_args *)data)->ifname, String}}, 1, &res); - DM_ASSERT(res, *value = ""); - *value = dmjson_get_value(res, 1, "macaddr"); - return 0; + return eth_port_sysfs(data, "address", value); } /*#Device.Ethernet.Interface.{i}.MaxBitRate!UCI:ports/ethport,@i-1/speed*/ @@ -769,111 +777,93 @@ int get_EthernetInterface_EEECapability(char *refparam, struct dmctx *ctx, void return 0; } -static inline int get_ubus_ethernet_interface_stats(char **value, char *stat_mod, void *data) -{ - json_object *res; - dmubus_call("network.device", "status", UBUS_ARGS{{"name", ((struct eth_port_args *)data)->ifname, String}}, 1, &res); - DM_ASSERT(res, *value = "0"); - *value = dmjson_get_value(res, 2, "statistics", stat_mod); - return 0; -} - /*#Device.Ethernet.Interface.{i}.Stats.BytesSent!UBUS:network.device/status/name,@Name/statistics.tx_bytes*/ int get_EthernetInterfaceStats_BytesSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "tx_bytes", data); - return 0; + return eth_port_sysfs(data, "statistics/tx_bytes", value); } /*#Device.Ethernet.Interface.{i}.Stats.BytesReceived!UBUS:network.device/status/name,@Name/statistics.rx_bytes*/ int get_EthernetInterfaceStats_BytesReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "rx_bytes", data); - return 0; + return eth_port_sysfs(data, "statistics/rx_bytes", value); } /*#Device.Ethernet.Interface.{i}.Stats.PacketsSent!UBUS:network.device/status/name,@Name/statistics.tx_packets*/ int get_EthernetInterfaceStats_PacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "tx_packets", data); - return 0; + return eth_port_sysfs(data, "statistics/tx_packets", value); } /*#Device.Ethernet.Interface.{i}.Stats.PacketsReceived!UBUS:network.device/status/name,@Name/statistics.rx_packets*/ int get_EthernetInterfaceStats_PacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "rx_packets", data); - return 0; + return eth_port_sysfs(data, "statistics/rx_packets", value); } /*#Device.Ethernet.Interface.{i}.Stats.ErrorsSent!UBUS:network.device/status/name,@Name/statistics.tx_errors*/ int get_EthernetInterfaceStats_ErrorsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "tx_errors", data); - return 0; + return eth_port_sysfs(data, "statistics/tx_errors", value); } /*#Device.Ethernet.Interface.{i}.Stats.ErrorsReceived!UBUS:network.device/status/name,@Name/statistics.rx_errors*/ int get_EthernetInterfaceStats_ErrorsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "rx_errors", data); - return 0; + return eth_port_sysfs(data, "statistics/rx_errors", value); } int get_EthernetInterfaceStats_UnicastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmasprintf(value, "%d", get_stats_from_ifconfig_command(((struct eth_port_args *)data)->ifname, "TX", "unicast")); + *value = "0"; return 0; } int get_EthernetInterfaceStats_UnicastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmasprintf(value, "%d", get_stats_from_ifconfig_command(((struct eth_port_args *)data)->ifname, "RX", "unicast")); + *value = "0"; return 0; } /*#Device.Ethernet.Interface.{i}.Stats.DiscardPacketsSent!UBUS:network.device/status/name,@Name/statistics.tx_dropped*/ int get_EthernetInterfaceStats_DiscardPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "tx_dropped", data); - return 0; + return eth_port_sysfs(data, "statistics/tx_dropped", value); } /*#Device.Ethernet.Interface.{i}.Stats.DiscardPacketsReceived!UBUS:network.device/status/name,@Name/statistics.rx_dropped*/ int get_EthernetInterfaceStats_DiscardPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "rx_dropped", data); - return 0; + return eth_port_sysfs(data, "statistics/rx_dropped", value); } int get_EthernetInterfaceStats_MulticastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmasprintf(value, "%d", get_stats_from_ifconfig_command(((struct eth_port_args *)data)->ifname, "TX", "multicast")); + *value = "0"; return 0; } int get_EthernetInterfaceStats_MulticastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmasprintf(value, "%d", get_stats_from_ifconfig_command(((struct eth_port_args *)data)->ifname, "RX", "multicast")); - return 0; + return eth_port_sysfs(data, "statistics/multicast", value); } int get_EthernetInterfaceStats_BroadcastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmasprintf(value, "%d", get_stats_from_ifconfig_command(((struct eth_port_args *)data)->ifname, "TX", "broadcast")); + *value = "0"; return 0; } int get_EthernetInterfaceStats_BroadcastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - dmasprintf(value, "%d", get_stats_from_ifconfig_command(((struct eth_port_args *)data)->ifname, "RX", "broadcast")); + *value = "0"; return 0; } /*#Device.Ethernet.Interface.{i}.Stats.UnknownProtoPacketsReceived!UBUS:network.device/status/name,@Name/statistics.rx_over_errors*/ int get_EthernetInterfaceStats_UnknownProtoPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_interface_stats(value, "rx_over_errors", data); + *value = "0"; return 0; } @@ -1004,117 +994,84 @@ int get_EthernetLink_MACAddress(char *refparam, struct dmctx *ctx, void *data, c return 0; } -static inline int get_ubus_ethernet_link_stats(char **value, char *stat_mod, void *data) -{ - char *device; - json_object *res; - - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &device); - dmubus_call("network.device", "status", UBUS_ARGS{{"name", device, String}}, 1, &res); - DM_ASSERT(res, *value = "0"); - *value = dmjson_get_value(res, 2, "statistics", stat_mod); - return 0; -} - int get_EthernetLinkStats_BytesSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "tx_bytes", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_bytes", value); } int get_EthernetLinkStats_BytesReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "rx_bytes", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_bytes", value); } int get_EthernetLinkStats_PacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "tx_packets", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_packets", value); } int get_EthernetLinkStats_PacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "rx_packets", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_packets", value); } int get_EthernetLinkStats_ErrorsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "tx_errors", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_errors", value); } int get_EthernetLinkStats_ErrorsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "rx_errors", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_errors", value); } int get_EthernetLinkStats_UnicastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *device; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &device); - dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "TX", "unicast")); + *value = "0"; return 0; } int get_EthernetLinkStats_UnicastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *device; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &device); - dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "RX", "unicast")); + *value = "0"; return 0; } int get_EthernetLinkStats_DiscardPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "tx_dropped", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_dropped", value); } int get_EthernetLinkStats_DiscardPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "rx_dropped", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_dropped", value); } int get_EthernetLinkStats_MulticastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *device; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &device); - dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "TX", "multicast")); + *value = "0"; return 0; } int get_EthernetLinkStats_MulticastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *device; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &device); - dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "RX", "multicast")); - return 0; + return eth_iface_sysfs(data, "statistics/multicast", value); } int get_EthernetLinkStats_BroadcastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *device; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &device); - dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "TX", "broadcast")); + *value = "0"; return 0; } int get_EthernetLinkStats_BroadcastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *device; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "device", &device); - dmasprintf(value, "%d", get_stats_from_ifconfig_command(device, "RX", "broadcast")); + *value = "0"; return 0; } int get_EthernetLinkStats_UnknownProtoPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_link_stats(value, "rx_over_errors", data); + *value = "0"; return 0; } @@ -1322,138 +1279,92 @@ int set_EthernetVLANTermination_TPID(char *refparam, struct dmctx *ctx, void *da return 0; } -static inline int get_ubus_ethernet_vlan_termination_stats(char **value, char *stat_mod, void *data) -{ - json_object *res; - char *ifname; - - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - dmubus_call("network.device", "status", UBUS_ARGS{{"name", ifname, String}}, 1, &res); - DM_ASSERT(res, *value = "0"); - *value = dmjson_get_value(res, 2, "statistics", stat_mod); - return 0; -} - /*#Device.Ethernet.VLANTermination.{i}.Stats.BytesSent!UBUS:network.device/status/name,@Name/statistics.tx_bytes*/ int get_EthernetVLANTerminationStats_BytesSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "tx_bytes", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_bytes", value); } /*#Device.Ethernet.VLANTermination.{i}.Stats.BytesReceived!UBUS:network.device/status/name,@Name/statistics.rx_bytes*/ int get_EthernetVLANTerminationStats_BytesReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "rx_bytes", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_bytes", value); } /*#Device.Ethernet.VLANTermination.{i}.Stats.PacketsSent!UBUS:network.device/status/name,@Name/statistics.tx_packets*/ int get_EthernetVLANTerminationStats_PacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "tx_packets", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_packets", value); } /*#Device.Ethernet.VLANTermination.{i}.Stats.PacketsReceived!UBUS:network.device/status/name,@Name/statistics.rx_packets*/ int get_EthernetVLANTerminationStats_PacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "rx_packets", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_packets", value); } /*#Device.Ethernet.VLANTermination.{i}.Stats.ErrorsSent!UBUS:network.device/status/name,@Name/statistics.tx_errors*/ int get_EthernetVLANTerminationStats_ErrorsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "tx_errors", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_errors", value); } /*#Device.Ethernet.VLANTermination.{i}.Stats.ErrorsReceived!UBUS:network.device/status/name,@Name/statistics.rx_errors*/ int get_EthernetVLANTerminationStats_ErrorsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "rx_errors", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_errors", value); } int get_EthernetVLANTerminationStats_UnicastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *ifname; *value = "0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - if(!strstr(ifname, "atm") && !strstr(ifname, "ptm")) - dmasprintf(value, "%d", get_stats_from_ifconfig_command(ifname, "TX", "unicast")); return 0; } int get_EthernetVLANTerminationStats_UnicastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *ifname; *value = "0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - if(!strstr(ifname, "atm") && !strstr(ifname, "ptm")) - dmasprintf(value, "%d", get_stats_from_ifconfig_command(ifname, "RX", "unicast")); return 0; } /*#Device.Ethernet.VLANTermination.{i}.Stats.DiscardPacketsSent!UBUS:network.device/status/name,@Name/statistics.tx_dropped*/ int get_EthernetVLANTerminationStats_DiscardPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "tx_dropped", data); - return 0; + return eth_iface_sysfs(data, "statistics/tx_dropped", value); } /*#Device.Ethernet.VLANTermination.{i}.Stats.DiscardPacketsReceived!UBUS:network.device/status/name,@Name/statistics.rx_dropped*/ int get_EthernetVLANTerminationStats_DiscardPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "rx_dropped", data); - return 0; + return eth_iface_sysfs(data, "statistics/rx_dropped", value); } int get_EthernetVLANTerminationStats_MulticastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *ifname; *value = "0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - if(!strstr(ifname, "atm") && !strstr(ifname, "ptm")) { - dmasprintf(value, "%d", get_stats_from_ifconfig_command(ifname, "TX", "multicast")); - } return 0; } int get_EthernetVLANTerminationStats_MulticastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *ifname; - *value = "0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - if(!strstr(ifname, "atm") && !strstr(ifname, "ptm")) - dmasprintf(value, "%d", get_stats_from_ifconfig_command(ifname, "RX", "multicast")); - return 0; + return eth_iface_sysfs(data, "statistics/multicast", value); } int get_EthernetVLANTerminationStats_BroadcastPacketsSent(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *ifname; *value = "0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - if(!strstr(ifname, "atm") && !strstr(ifname, "ptm")) - dmasprintf(value, "%d", get_stats_from_ifconfig_command(ifname, "TX", "broadcast")); return 0; } int get_EthernetVLANTerminationStats_BroadcastPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - char *ifname; *value = "0"; - dmuci_get_value_by_section_string(((struct dm_args *)data)->section, "ifname", &ifname); - if(!strstr(ifname, "atm") && !strstr(ifname, "ptm")) - dmasprintf(value, "%d", get_stats_from_ifconfig_command(ifname, "RX", "broadcast")); return 0; } /*#Device.Ethernet.VLANTermination.{i}.Stats.UnknownProtoPacketsReceived!UBUS:network.device/status/name,@Name/statistics.rx_over_errors*/ int get_EthernetVLANTerminationStats_UnknownProtoPacketsReceived(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { - get_ubus_ethernet_vlan_termination_stats(value, "rx_over_errors", data); + *value = "0"; return 0; } diff --git a/dmtree/tr181/ip.c b/dmtree/tr181/ip.c index e08ee21b..ba801740 100644 --- a/dmtree/tr181/ip.c +++ b/dmtree/tr181/ip.c @@ -199,19 +199,7 @@ static inline int init_ipv6prefix_args(struct ipv6prefix_args *args, struct uci_ **************************************************************/ 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; + return get_net_iface_sysfs(section_name(ip->ip_sec), name, value); } static char *ubus_call_get_value_with_two_objects(char *interface, char *obj1, char *obj2, char *key) diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c index 5914d5ff..47378316 100644 --- a/libbbf_api/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -1662,3 +1662,25 @@ out: close(fd); return rc; } + +int get_net_device_sysfs(const char *device, const char *name, char **value) +{ + if (device && 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; +} + +int get_net_iface_sysfs(const char *uci_iface, const char *name, char **value) +{ + const char *device = get_device((char *)uci_iface); + + return get_net_device_sysfs(device, name, value); +} diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h index 3826406e..9850df73 100644 --- a/libbbf_api/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -258,4 +258,6 @@ 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); +int get_net_iface_sysfs(const char *uci_iface, const char *name, char **value); +int get_net_device_sysfs(const char *uci_iface, const char *name, char **value); #endif