X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fnetlink.c;h=b5ae3bd2c13058ded2aa1902ebfefc2bf9a58fab;hp=8076c1fa4436b21fd52533ea379c2f09ea74b8a4;hb=7111bb6df7628edce3a8e538b386fbe27633a191;hpb=11c8a760c2d354b2f4637bdb297efb253bfaa519 diff --git a/src/netlink.c b/src/netlink.c index 8076c1fa..b5ae3bd2 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -85,6 +85,11 @@ typedef struct ir_ignorelist_s { struct ir_ignorelist_s *next; } ir_ignorelist_t; +struct qos_stats { + struct gnet_stats_basic *bs; + struct gnet_stats_queue *qs; +}; + static int ir_ignorelist_invert = 1; static ir_ignorelist_t *ir_ignorelist_head = NULL; @@ -103,13 +108,13 @@ static int add_ignorelist(const char *dev, const char *type, const char *inst) { entry = calloc(1, sizeof(*entry)); if (entry == NULL) - return (-1); + return -1; if (strcasecmp(dev, "All") != 0) { entry->device = strdup(dev); if (entry->device == NULL) { sfree(entry); - return (-1); + return -1; } } @@ -117,7 +122,7 @@ static int add_ignorelist(const char *dev, const char *type, const char *inst) { if (entry->type == NULL) { sfree(entry->device); sfree(entry); - return (-1); + return -1; } if (inst != NULL) { @@ -126,14 +131,14 @@ static int add_ignorelist(const char *dev, const char *type, const char *inst) { sfree(entry->type); sfree(entry->device); sfree(entry); - return (-1); + return -1; } } entry->next = ir_ignorelist_head; ir_ignorelist_head = entry; - return (0); + return 0; } /* int add_ignorelist */ /* @@ -145,7 +150,7 @@ static int check_ignorelist(const char *dev, const char *type, assert((dev != NULL) && (type != NULL)); if (ir_ignorelist_head == NULL) - return (ir_ignorelist_invert ? 0 : 1); + return ir_ignorelist_invert ? 0 : 1; for (ir_ignorelist_t *i = ir_ignorelist_head; i != NULL; i = i->next) { /* i->device == NULL => match all devices */ @@ -166,10 +171,10 @@ static int check_ignorelist(const char *dev, const char *type, i->device == NULL ? "(nil)" : i->device, i->type, i->inst == NULL ? "(nil)" : i->inst); - return (ir_ignorelist_invert ? 0 : 1); + return ir_ignorelist_invert ? 0 : 1; } /* for i */ - return (ir_ignorelist_invert); + return ir_ignorelist_invert; } /* int check_ignorelist */ static void submit_one(const char *dev, const char *type, @@ -216,7 +221,7 @@ static int update_iflist(struct ifinfomsg *msg, const char *dev) { temp = realloc(iflist, (msg->ifi_index + 1) * sizeof(char *)); if (temp == NULL) { ERROR("netlink plugin: update_iflist: realloc failed."); - return (-1); + return -1; } memset(temp + iflist_len, '\0', @@ -230,7 +235,7 @@ static int update_iflist(struct ifinfomsg *msg, const char *dev) { iflist[msg->ifi_index] = strdup(dev); } - return (0); + return 0; } /* int update_iflist */ static void check_ignorelist_and_submit(const char *dev, @@ -353,8 +358,10 @@ static int link_filter_cb(const struct nlmsghdr *nlh, continue; if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*stats.stats64)) < 0) { + char errbuf[1024]; ERROR("netlink plugin: link_filter_cb: IFLA_STATS64 mnl_attr_validate2 " - "failed."); + "failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return MNL_CB_ERROR; } stats.stats64 = mnl_attr_get_payload(attr); @@ -369,8 +376,10 @@ static int link_filter_cb(const struct nlmsghdr *nlh, continue; if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*stats.stats32)) < 0) { + char errbuf[1024]; ERROR("netlink plugin: link_filter_cb: IFLA_STATS mnl_attr_validate2 " - "failed."); + "failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return MNL_CB_ERROR; } stats.stats32 = mnl_attr_get_payload(attr); @@ -387,20 +396,32 @@ static int link_filter_cb(const struct nlmsghdr *nlh, #if HAVE_TCA_STATS2 static int qos_attr_cb(const struct nlattr *attr, void *data) { - struct gnet_stats_basic **bs = (struct gnet_stats_basic **)data; + struct qos_stats *q_stats = (struct qos_stats *)data; /* skip unsupported attribute in user-space */ if (mnl_attr_type_valid(attr, TCA_STATS_MAX) < 0) return MNL_CB_OK; if (mnl_attr_get_type(attr) == TCA_STATS_BASIC) { - if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(**bs)) < 0) { + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*q_stats->bs)) < 0) { + char errbuf[1024]; ERROR("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 " + "failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); + return MNL_CB_ERROR; + } + q_stats->bs = mnl_attr_get_payload(attr); + return MNL_CB_OK; + } + + if (mnl_attr_get_type(attr) == TCA_STATS_QUEUE) { + if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*q_stats->qs)) < 0) { + ERROR("netlink plugin: qos_attr_cb: TCA_STATS_QUEUE mnl_attr_validate2 " "failed."); return MNL_CB_ERROR; } - *bs = mnl_attr_get_payload(attr); - return MNL_CB_STOP; + q_stats->qs = mnl_attr_get_payload(attr); + return MNL_CB_OK; } return MNL_CB_OK; @@ -470,7 +491,7 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { if (kind == NULL) { ERROR("netlink plugin: qos_filter_cb: kind == NULL"); - return (-1); + return -1; } { /* The ID */ @@ -480,8 +501,8 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { if (strcmp(tc_type, "filter") == 0) numberic_id = tm->tcm_parent; - ssnprintf(tc_inst, sizeof(tc_inst), "%s-%x:%x", kind, numberic_id >> 16, - numberic_id & 0x0000FFFF); + snprintf(tc_inst, sizeof(tc_inst), "%s-%x:%x", kind, numberic_id >> 16, + numberic_id & 0x0000FFFF); } DEBUG("netlink plugin: qos_filter_cb: got %s for %s (%i).", tc_type, dev, @@ -492,7 +513,9 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { #if HAVE_TCA_STATS2 mnl_attr_for_each(attr, nlh, sizeof(*tm)) { - struct gnet_stats_basic *bs = NULL; + struct qos_stats q_stats; + + memset(&q_stats, 0x0, sizeof(q_stats)); if (mnl_attr_get_type(attr) != TCA_STATS2) continue; @@ -503,18 +526,22 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { return MNL_CB_ERROR; } - mnl_attr_parse_nested(attr, qos_attr_cb, &bs); + mnl_attr_parse_nested(attr, qos_attr_cb, &q_stats); - if (bs != NULL) { + if (q_stats.bs != NULL || q_stats.qs != NULL) { char type_instance[DATA_MAX_NAME_LEN]; stats_submitted = 1; - ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, - tc_inst); + snprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, tc_inst); - submit_one(dev, "ipt_bytes", type_instance, bs->bytes); - submit_one(dev, "ipt_packets", type_instance, bs->packets); + if (q_stats.bs != NULL) { + submit_one(dev, "ipt_bytes", type_instance, q_stats.bs->bytes); + submit_one(dev, "ipt_packets", type_instance, q_stats.bs->packets); + } + if (q_stats.qs != NULL) { + submit_one(dev, "if_tx_dropped", type_instance, q_stats.qs->drops); + } } break; @@ -529,8 +556,10 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { continue; if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*ts)) < 0) { + char errbuf[1024]; ERROR("netlink plugin: qos_filter_cb: TCA_STATS mnl_attr_validate2 " - "failed."); + "failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return MNL_CB_ERROR; } ts = mnl_attr_get_payload(attr); @@ -538,8 +567,7 @@ static int qos_filter_cb(const struct nlmsghdr *nlh, void *args) { if (!stats_submitted && ts != NULL) { char type_instance[DATA_MAX_NAME_LEN]; - ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, - tc_inst); + snprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, tc_inst); submit_one(dev, "ipt_bytes", type_instance, ts->bytes); submit_one(dev, "ipt_packets", type_instance, ts->packets); @@ -566,12 +594,12 @@ static int ir_config(const char *key, const char *value) { new_val = strdup(value); if (new_val == NULL) - return (-1); + return -1; fields_num = strsplit(new_val, fields, STATIC_ARRAY_SIZE(fields)); if ((fields_num < 1) || (fields_num > 8)) { sfree(new_val); - return (-1); + return -1; } if ((strcasecmp(key, "Interface") == 0) || @@ -594,7 +622,7 @@ static int ir_config(const char *key, const char *value) { ERROR("netlink plugin: Invalid number of fields for option " "`%s'. Got %i, expected 1 or 2.", key, fields_num); - return (-1); + return -1; } else { add_ignorelist(fields[0], key, (fields_num == 2) ? fields[1] : NULL); status = 0; @@ -616,22 +644,22 @@ static int ir_config(const char *key, const char *value) { sfree(new_val); - return (status); + return status; } /* int ir_config */ static int ir_init(void) { nl = mnl_socket_open(NETLINK_ROUTE); if (nl == NULL) { ERROR("netlink plugin: ir_init: mnl_socket_open failed."); - return (-1); + return -1; } if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) { ERROR("netlink plugin: ir_init: mnl_socket_bind failed."); - return (-1); + return -1; } - return (0); + return 0; } /* int ir_init */ static int ir_read(void) { @@ -655,7 +683,7 @@ static int ir_read(void) { if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { ERROR("netlink plugin: ir_read: rtnl_wilddump_request failed."); - return (-1); + return -1; } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); @@ -666,7 +694,9 @@ static int ir_read(void) { ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret < 0) { - ERROR("netlink plugin: ir_read: mnl_socket_recvfrom failed."); + char errbuf[1024]; + ERROR("netlink plugin: ir_read: mnl_socket_recvfrom failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); return (-1); } @@ -711,14 +741,15 @@ static int ir_read(void) { ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); } if (ret < 0) { - ERROR("netlink plugin: ir_read:mnl_socket_recvfrom failed."); + char errbuf[1024]; + ERROR("netlink plugin: ir_read: mnl_socket_recvfrom failed: %s", + sstrerror(errno, errbuf, sizeof(errbuf))); continue; } - } /* for (type_index) */ } /* for (if_index) */ - return (0); + return 0; } /* int ir_read */ static int ir_shutdown(void) { @@ -727,7 +758,7 @@ static int ir_shutdown(void) { nl = NULL; } - return (0); + return 0; } /* int ir_shutdown */ void module_register(void) { @@ -736,7 +767,3 @@ void module_register(void) { plugin_register_read("netlink", ir_read); plugin_register_shutdown("netlink", ir_shutdown); } /* void module_register */ - -/* - * vim: set shiftwidth=2 softtabstop=2 tabstop=8 : - */