diff --git a/src/ethernet.c b/src/ethernet.c index 422742d9fe970b04839ad9da24445a35967591b3..05cccae0e4800871ba08b5d52e19e369071d2db1 100644 --- a/src/ethernet.c +++ b/src/ethernet.c @@ -283,7 +283,7 @@ static int browseEthernetRMONStatsInst(struct dmctx *dmctx, DMNODE *parent_node, goto handle_instance; } - if (ethmngr_get_rmon_stats(intf, &rmon) != 0) { + if (ethmngr_get_rmon_stats(intf, &rmon, ETH_TXQ_ALL, 0) != 0) { rmon.status = RMON_STATUS_ERR; goto handle_instance; } diff --git a/src/ethmngr.c b/src/ethmngr.c index c723278ac8021c5434ed668aa83d9631f6872127..d9d4dd58f2db3dd471eca78dc367ddf63e8fa307 100644 --- a/src/ethmngr.c +++ b/src/ethmngr.c @@ -50,12 +50,12 @@ static void eth_port_handler_cb(struct ubus_context *ctx, blobmsg_parse(net_dev_policy, _MAX_NET_DEV_POLICY, tb, blobmsg_data(msg), blobmsg_len(msg)); if (!tb[NET_DEV_POLICY_IFNAME]) { - syslog(LOG_ERR, "\"ifname\" not found in network.device event!\n"); + BBF_ERR("\"ifname\" not found in network.device event!"); return; } if (!tb[NET_DEV_POLICY_LINK]) { - syslog(LOG_ERR, "\"link\" not found in network.device event!\n"); + BBF_ERR("\"link\" not found in network.device event!"); return; } @@ -78,6 +78,227 @@ static int register_ethernet_event(struct ubus_context *ctx) return ret; } +#ifdef ETHMNGR_EXPOSE_ETHERNET_OBJECT +/* ifstats policy */ +enum { + IFSTATS_POLICY_IFNAME, + IFSTATS_POLICY_MAX, + NUM_IFSTATS_POLICY = IFSTATS_POLICY_MAX, +}; + +static const struct blobmsg_policy ifstats_policy[NUM_IFSTATS_POLICY] = { + [IFSTATS_POLICY_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, +}; + + +/* rmonstats policy */ +enum { + RMONSTATS_POLICY_IFNAME, + RMONSTATS_POLICY_VLANID, + RMONSTATS_POLICY_QID, + RMONSTATS_POLICY_MAX, + NUM_RMONSTATS_POLICY = RMONSTATS_POLICY_MAX, +}; + +static const struct blobmsg_policy rmonstats_policy[NUM_RMONSTATS_POLICY] = { + [RMONSTATS_POLICY_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, + [RMONSTATS_POLICY_VLANID] = { .name = "vid", .type = BLOBMSG_TYPE_INT32 }, + [RMONSTATS_POLICY_QID] = { .name = "qid", .type = BLOBMSG_TYPE_INT32 }, + +}; + + +int ethmngr_ifstats(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[NUM_IFSTATS_POLICY]; + struct eth_stats s; + char ifname[16] = {0}; + struct blob_buf bb; + int ret; + + BBF_INFO("This is deprecated please switch to \"bbfdm.ethmngr\" ubus methods."); + blobmsg_parse(ifstats_policy, IFSTATS_POLICY_MAX, tb, blob_data(msg), + (unsigned int)blob_len(msg)); + + if (!tb[IFSTATS_POLICY_IFNAME]) { + BBF_ERR("\"ifname\" not specified!"); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + strncpy(ifname, blobmsg_data(tb[IFSTATS_POLICY_IFNAME]), sizeof(ifname)-1); + + ret = ethmngr_get_if_stats(ifname, &s); + if (ret) { + return ret; + } + + memset(&bb, 0, sizeof(bb)); + blob_buf_init(&bb, 0); + blobmsg_add_string(&bb, "ifname", ifname); + blobmsg_add_u64(&bb, "tx_bytes", s.tx_bytes); + blobmsg_add_u64(&bb, "tx_packets", s.tx_packets); + blobmsg_add_u64(&bb, "tx_errors", s.tx_errors); + blobmsg_add_u64(&bb, "tx_unicast_packets", s.tx_ucast_packets); + blobmsg_add_u64(&bb, "tx_multicast_packets", s.tx_mcast_packets); + blobmsg_add_u64(&bb, "tx_broadcast_packets", s.tx_bcast_packets); + blobmsg_add_u64(&bb, "tx_discard_packets", s.tx_discard_packets); + + blobmsg_add_u64(&bb, "rx_bytes", s.rx_bytes); + blobmsg_add_u64(&bb, "rx_packets", s.rx_packets); + blobmsg_add_u64(&bb, "rx_errors", s.rx_errors); + blobmsg_add_u64(&bb, "rx_unicast_packets", s.rx_ucast_packets); + blobmsg_add_u64(&bb, "rx_multicast_packets", s.rx_mcast_packets); + blobmsg_add_u64(&bb, "rx_broadcast_packets", s.rx_bcast_packets); + blobmsg_add_u64(&bb, "rx_discard_packets", s.rx_discard_packets); + blobmsg_add_u64(&bb, "rx_unknown_packets", s.rx_unknown_packets); + + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + + return 0; +} + +int ethmngr_rmonstats(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[NUM_RMONSTATS_POLICY]; + struct eth_rmon_stats rmon; + char ifname[16] = {0}; + struct blob_buf bb; + int queueid = ETH_TXQ_ALL; + int vlanid = 0; + int ret; + + BBF_INFO("This is deprecated please switch to \"bbfdm.ethmngr\" ubus methods."); + blobmsg_parse(rmonstats_policy, RMONSTATS_POLICY_MAX, tb, + blob_data(msg), (unsigned int)blob_len(msg)); + + if (!tb[RMONSTATS_POLICY_IFNAME]) { + BBF_ERR("\"ifname\" not specified!"); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + strncpy(ifname, blobmsg_data(tb[RMONSTATS_POLICY_IFNAME]), sizeof(ifname)-1); + + if (tb[RMONSTATS_POLICY_QID]) + queueid = (int)blobmsg_get_u32(tb[RMONSTATS_POLICY_QID]); + + + if (tb[RMONSTATS_POLICY_VLANID]) + vlanid = (int)blobmsg_get_u32(tb[RMONSTATS_POLICY_VLANID]); + + if (vlanid < 0 || vlanid > 0xFFFF) { + BBF_ERR("ethmongr: VLAN ID is out of range"); + return -1; + } + + ret = ethmngr_get_rmon_stats(ifname, &rmon, queueid, vlanid); + if (ret != 0) { + return ret; + } + + memset(&bb, 0, sizeof(bb)); + blob_buf_init(&bb, 0); + blobmsg_add_string(&bb, "ifname", ifname); + + blobmsg_add_u32(&bb, "tx_priority_q", (uint32_t)rmon.txq); + blobmsg_add_u64(&bb, "tx_bytes", rmon.tx.bytes); + blobmsg_add_u64(&bb, "tx_packets", rmon.tx.packets); + blobmsg_add_u64(&bb, "tx_broadcast_packets", rmon.tx.bcast_packets); + blobmsg_add_u64(&bb, "tx_multicast_packets", rmon.tx.mcast_packets); + blobmsg_add_u64(&bb, "tx_crc_error_packets", rmon.tx.crc_err_packets); + blobmsg_add_u64(&bb, "tx_undersize_packets", rmon.tx.under_sz_packets); + blobmsg_add_u64(&bb, "tx_oversize_packets", rmon.tx.over_sz_packets); + blobmsg_add_u64(&bb, "tx_pause_packets", rmon.tx.pause_packets); + blobmsg_add_u64(&bb, "tx_packets_64bytes", rmon.tx.packets_64bytes); + blobmsg_add_u64(&bb, "tx_packets_65to127bytes", rmon.tx.packets_65to127bytes); + blobmsg_add_u64(&bb, "tx_packets_128to255bytes", rmon.tx.packets_128to255bytes); + blobmsg_add_u64(&bb, "tx_packets_256to511bytes", rmon.tx.packets_256to511bytes); + blobmsg_add_u64(&bb, "tx_packets_512to1023bytes", rmon.tx.packets_512to1023bytes); + blobmsg_add_u64(&bb, "tx_packets_1024to1518bytes", rmon.tx.packets_1024to1518bytes); + + blobmsg_add_u64(&bb, "rx_bytes", rmon.rx.bytes); + blobmsg_add_u64(&bb, "rx_packets", rmon.rx.packets); + blobmsg_add_u64(&bb, "rx_broadcast_packets", rmon.rx.bcast_packets); + blobmsg_add_u64(&bb, "rx_multicast_packets", rmon.rx.mcast_packets); + blobmsg_add_u64(&bb, "rx_crc_error_packets", rmon.rx.crc_err_packets); + blobmsg_add_u64(&bb, "rx_undersize_packets", rmon.rx.under_sz_packets); + blobmsg_add_u64(&bb, "rx_oversize_packets", rmon.rx.over_sz_packets); + blobmsg_add_u64(&bb, "rx_pause_packets", rmon.rx.pause_packets); + blobmsg_add_u64(&bb, "rx_packets_64bytes", rmon.rx.packets_64bytes); + blobmsg_add_u64(&bb, "rx_packets_65to127bytes", rmon.rx.packets_65to127bytes); + blobmsg_add_u64(&bb, "rx_packets_128to255bytes", rmon.rx.packets_128to255bytes); + blobmsg_add_u64(&bb, "rx_packets_256to511bytes", rmon.rx.packets_256to511bytes); + blobmsg_add_u64(&bb, "rx_packets_512to1023bytes", rmon.rx.packets_512to1023bytes); + blobmsg_add_u64(&bb, "rx_packets_1024to1518bytes", rmon.rx.packets_1024to1518bytes); + + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + + return 0; +} + +int ethmngr_clearstats(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[NUM_IFSTATS_POLICY]; + char ifname[16] = {0}; + int ret; + + BBF_INFO("This is deprecated please switch to \"bbfdm.ethmngr\" ubus methods."); + blobmsg_parse(ifstats_policy, IFSTATS_POLICY_MAX, tb, blob_data(msg), + blob_len(msg)); + + if (!tb[IFSTATS_POLICY_IFNAME]) { + BBF_ERR("\"ifname\" not specified!"); + return UBUS_STATUS_INVALID_ARGUMENT; + } + + strncpy(ifname, blobmsg_data(tb[IFSTATS_POLICY_IFNAME]), sizeof(ifname)-1); + + ret = ethmngr_clear_stats(ifname); + if (ret) { + BBF_ERR("ethmngr: failed to clear interface stats!"); + return ret; + } + + return 0; +} + +struct ubus_method ethmngr_methods[] = { + UBUS_METHOD("ifstats", ethmngr_ifstats, ifstats_policy), + UBUS_METHOD("rmonstats", ethmngr_rmonstats, rmonstats_policy), + UBUS_METHOD("clearstats", ethmngr_clearstats, ifstats_policy), +}; + +struct ubus_object_type ethmngr_type = + UBUS_OBJECT_TYPE("ethernet", ethmngr_methods); + +struct ubus_object ethmngr_object = { + .name = "ethernet", + .type = ðmngr_type, + .methods = ethmngr_methods, + .n_methods = ARRAY_SIZE(ethmngr_methods), +}; + + +static int ethmngr_publish_object(struct ubus_context *ctx) +{ + int ret = -1; + + ret = ubus_add_object(ctx, ðmngr_object); + if (ret) + BBF_ERR("Failed to add 'ethernet' ubus object: %s", + ubus_strerror(ret)); + + return ret; +} +#endif //ETHMNGR_EXPOSE_ETHERNET_OBJECT + static void ethmngr_usage(char *prog) { fprintf(stderr, "Usage: %s [options]\n", prog); @@ -118,6 +339,11 @@ int main(int argc, char **argv) if (bbfdm_ubus_regiter_init(&bbfdm_ctx)) goto out; +#ifdef ETHMNGR_EXPOSE_ETHERNET_OBJECT + if (ethmngr_publish_object(&bbfdm_ctx.ubus_ctx) != 0) + goto out; +#endif + if (register_ethernet_event(&bbfdm_ctx.ubus_ctx) != 0) goto out; diff --git a/src/helper.c b/src/helper.c index 05dc84ebb40d1c851a3008316246f977e437bf82..4c8aa33e0e69e360a21b720360ec85e4cbe1696a 100644 --- a/src/helper.c +++ b/src/helper.c @@ -12,7 +12,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <syslog.h> #include "helper.h" @@ -65,7 +64,7 @@ int ethmngr_clear_stats(char *ifname) return eth_clear_stats(ifname); } -int ethmngr_get_rmon_stats(char *ifname, struct eth_rmon_stats *rmon) +int ethmngr_get_rmon_stats(char *ifname, struct eth_rmon_stats *rmon, int queueid, uint16_t vlan) { if (ifname == NULL || rmon == NULL) return -1; @@ -74,12 +73,12 @@ int ethmngr_get_rmon_stats(char *ifname, struct eth_rmon_stats *rmon) return -1; memset(rmon, 0, sizeof(struct eth_rmon_stats)); - rmon->txq = ETH_TXQ_ALL; - rmon->vlanid = 0; + rmon->txq = queueid; + rmon->vlanid = vlan; int ret = eth_get_rmon_stats(ifname, rmon); if (ret != 0) { - syslog(LOG_DEBUG, "ethmngr: failed to get rmonstats!\n"); + BBF_DEBUG("ethmngr: failed to get rmonstats!"); return -1; } @@ -97,7 +96,7 @@ int ethmngr_get_if_stats(char *ifname, struct eth_stats *s) memset(s, 0, sizeof(struct eth_stats)); int ret = eth_get_stats(ifname, s); if (ret != 0) { - syslog(LOG_DEBUG, "ethmngr: failed to get interface stats!\n"); + BBF_DEBUG("ethmngr: failed to get interface stats!"); return -1; } diff --git a/src/helper.h b/src/helper.h index b03cf4a03b551b9d2c216ad5133dadc05874f1af..9d6a81237cc0102db7fefc213d406f370d56f40c 100644 --- a/src/helper.h +++ b/src/helper.h @@ -17,10 +17,11 @@ #include <ethernet.h> #include <libubus.h> #include <libubox/blobmsg.h> +#include <libbbfdm-api/dmcommon.h> void invoke_ethernet_hotplug(struct ubus_context *ctx, char *ifname, char *link); int ethmngr_get_if_stats(char *ifname, struct eth_stats *s); -int ethmngr_get_rmon_stats(char *ifname, struct eth_rmon_stats *stats); +int ethmngr_get_rmon_stats(char *ifname, struct eth_rmon_stats *stats, int queueid, uint16_t vlan); int ethmngr_clear_stats(char *ifname); #endif