version 1.1.1.2, 2014/07/30 07:55:27
|
version 1.1.1.3, 2019/10/21 14:58:35
|
Line 37 static int c_notc = 0;
|
Line 37 static int c_notc = 0;
|
static struct element_group *grp; |
static struct element_group *grp; |
static struct bmon_module netlink_ops; |
static struct bmon_module netlink_ops; |
|
|
|
#include <linux/if.h> |
|
|
#include <netlink/netlink.h> |
#include <netlink/netlink.h> |
#include <netlink/cache.h> |
#include <netlink/cache.h> |
#include <netlink/utils.h> |
#include <netlink/utils.h> |
Line 47 static struct bmon_module netlink_ops;
|
Line 49 static struct bmon_module netlink_ops;
|
#include <netlink/route/classifier.h> |
#include <netlink/route/classifier.h> |
#include <netlink/route/qdisc/htb.h> |
#include <netlink/route/qdisc/htb.h> |
|
|
|
/* These counters are not available prior to libnl 3.2.25. Set them to -1 so |
|
* rtnl_link_get_stat() won't be called for them. */ |
|
#if LIBNL_CURRENT < 220 |
|
# define RTNL_LINK_ICMP6_CSUMERRORS -1 |
|
# define RTNL_LINK_IP6_CSUMERRORS -1 |
|
# define RTNL_LINK_IP6_NOECTPKTS -1 |
|
# define RTNL_LINK_IP6_ECT1PKTS -1 |
|
# define RTNL_LINK_IP6_ECT0PKTS -1 |
|
# define RTNL_LINK_IP6_CEPKTS -1 |
|
#endif |
|
|
|
/* Not available prior to libnl 3.2.29 */ |
|
#if LIBNL_CURRENT < 224 |
|
# define RTNL_LINK_RX_NOHANDLER -1 |
|
#endif |
|
|
static struct attr_map link_attrs[] = { |
static struct attr_map link_attrs[] = { |
{ |
{ |
.name = "bytes", |
.name = "bytes", |
Line 89 static struct attr_map link_attrs[] = {
|
Line 107 static struct attr_map link_attrs[] = {
|
.txid = RTNL_LINK_TX_COMPRESSED, |
.txid = RTNL_LINK_TX_COMPRESSED, |
}, |
}, |
{ |
{ |
|
.name = "nohandler", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "No Handler", |
|
.rxid = RTNL_LINK_RX_NOHANDLER, |
|
.txid = -1, |
|
}, |
|
{ |
.name = "fifoerr", |
.name = "fifoerr", |
.type = ATTR_TYPE_COUNTER, |
.type = ATTR_TYPE_COUNTER, |
.unit = UNIT_NUMBER, |
.unit = UNIT_NUMBER, |
Line 281 static struct attr_map link_attrs[] = {
|
Line 307 static struct attr_map link_attrs[] = {
|
.txid = RTNL_LINK_ICMP6_OUTERRORS, |
.txid = RTNL_LINK_ICMP6_OUTERRORS, |
}, |
}, |
{ |
{ |
|
.name = "icmp6csumerr", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "ICMPv6 Checksum Errors", |
|
.rxid = RTNL_LINK_ICMP6_CSUMERRORS, |
|
.txid = -1, |
|
}, |
|
{ |
.name = "ip6inhdrerr", |
.name = "ip6inhdrerr", |
.type = ATTR_TYPE_COUNTER, |
.type = ATTR_TYPE_COUNTER, |
.unit = UNIT_NUMBER, |
.unit = UNIT_NUMBER, |
Line 321 static struct attr_map link_attrs[] = {
|
Line 355 static struct attr_map link_attrs[] = {
|
.txid = -1, |
.txid = -1, |
}, |
}, |
{ |
{ |
|
.name = "ip6csumerr", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Ip6 Checksum Error", |
|
.rxid = RTNL_LINK_IP6_CSUMERRORS, |
|
.txid = -1, |
|
}, |
|
{ |
.name = "ip6reasmtimeo", |
.name = "ip6reasmtimeo", |
.type = ATTR_TYPE_COUNTER, |
.type = ATTR_TYPE_COUNTER, |
.unit = UNIT_NUMBER, |
.unit = UNIT_NUMBER, |
Line 351 static struct attr_map link_attrs[] = {
|
Line 393 static struct attr_map link_attrs[] = {
|
.description = "Ip6 Reasm/Frag Requests", |
.description = "Ip6 Reasm/Frag Requests", |
.rxid = RTNL_LINK_IP6_REASMREQDS, |
.rxid = RTNL_LINK_IP6_REASMREQDS, |
.txid = RTNL_LINK_IP6_FRAGCREATES, |
.txid = RTNL_LINK_IP6_FRAGCREATES, |
|
}, |
|
{ |
|
.name = "ip6noectpkts", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Ip6 Non-ECT Packets", |
|
.rxid = RTNL_LINK_IP6_NOECTPKTS, |
|
.txid = -1, |
|
}, |
|
{ |
|
.name = "ip6ect1pkts", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Ip6 ECT(1) Packets", |
|
.rxid = RTNL_LINK_IP6_ECT1PKTS, |
|
.txid = -1, |
|
}, |
|
{ |
|
.name = "ip6ect0pkts", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Ip6 ECT(0) Packets", |
|
.rxid = RTNL_LINK_IP6_ECT0PKTS, |
|
.txid = -1, |
|
}, |
|
{ |
|
.name = "ip6cepkts", |
|
.type = ATTR_TYPE_COUNTER, |
|
.unit = UNIT_NUMBER, |
|
.description = "Ip6 CE Packets", |
|
.rxid = RTNL_LINK_IP6_CEPKTS, |
|
.txid = -1, |
} |
} |
}; |
}; |
|
|
Line 430 static struct attr_map tc_attrs[] = {
|
Line 504 static struct attr_map tc_attrs[] = {
|
}; |
}; |
|
|
struct rdata { |
struct rdata { |
|
struct nl_cache * class_cache; |
struct element * parent; |
struct element * parent; |
int level; |
int level; |
}; |
}; |
|
|
static struct nl_sock *sock; |
static struct nl_sock *sock; |
static struct nl_cache *link_cache, *qdisc_cache, *class_cache; | static struct nl_cache *link_cache, *qdisc_cache; |
|
|
static void update_tc_attrs(struct element *e, struct rtnl_tc *tc) |
static void update_tc_attrs(struct element *e, struct rtnl_tc *tc) |
{ |
{ |
Line 470 static void update_tc_infos(struct element *e, struct
|
Line 545 static void update_tc_infos(struct element *e, struct
|
|
|
static void handle_qdisc(struct nl_object *obj, void *); |
static void handle_qdisc(struct nl_object *obj, void *); |
static void find_classes(uint32_t, struct rdata *); |
static void find_classes(uint32_t, struct rdata *); |
static void find_qdiscs(uint32_t, struct rdata *); | static void find_qdiscs(int, uint32_t, struct rdata *); |
|
|
static struct element *handle_tc_obj(struct rtnl_tc *tc, const char *prefix, |
static struct element *handle_tc_obj(struct rtnl_tc *tc, const char *prefix, |
struct rdata *rdata) | const struct rdata *rdata) |
{ |
{ |
char buf[IFNAME_MAX], name[IFNAME_MAX]; |
char buf[IFNAME_MAX], name[IFNAME_MAX]; |
uint32_t id = rtnl_tc_get_handle(tc); |
uint32_t id = rtnl_tc_get_handle(tc); |
Line 483 static struct element *handle_tc_obj(struct rtnl_tc *t
|
Line 558 static struct element *handle_tc_obj(struct rtnl_tc *t
|
snprintf(name, sizeof(name), "%s %s (%s)", |
snprintf(name, sizeof(name), "%s %s (%s)", |
prefix, buf, rtnl_tc_get_kind(tc)); |
prefix, buf, rtnl_tc_get_kind(tc)); |
|
|
if (!(e = element_lookup(grp, name, id, rdata ? rdata->parent : NULL, ELEMENT_CREAT))) | if (!rdata || !rdata->parent) |
| BUG(); |
| |
| if (!(e = element_lookup(grp, name, id, rdata->parent, ELEMENT_CREAT))) |
return NULL; |
return NULL; |
|
|
if (e->e_flags & ELEMENT_FLAG_CREATED) { |
if (e->e_flags & ELEMENT_FLAG_CREATED) { |
e->e_level = rdata ? rdata->level : 0; | e->e_level = rdata->level; |
|
|
if (element_set_key_attr(e, "tc_bytes", "tc_packets") || |
if (element_set_key_attr(e, "tc_bytes", "tc_packets") || |
element_set_usage_attr(e, "tc_bytes")) |
element_set_usage_attr(e, "tc_bytes")) |
Line 518 static void handle_class(struct nl_object *obj, void *
|
Line 596 static void handle_class(struct nl_object *obj, void *
|
{ |
{ |
struct rtnl_tc *tc = (struct rtnl_tc *) obj; |
struct rtnl_tc *tc = (struct rtnl_tc *) obj; |
struct element *e; |
struct element *e; |
struct rdata *rdata = arg; | const struct rdata *rdata = arg; |
struct rdata ndata = { |
struct rdata ndata = { |
|
.class_cache = rdata->class_cache, |
.level = rdata->level + 1, |
.level = rdata->level + 1, |
}; |
}; |
|
|
Line 532 static void handle_class(struct nl_object *obj, void *
|
Line 611 static void handle_class(struct nl_object *obj, void *
|
element_set_txmax(e, rtnl_htb_get_rate((struct rtnl_class *) tc)); |
element_set_txmax(e, rtnl_htb_get_rate((struct rtnl_class *) tc)); |
|
|
find_classes(rtnl_tc_get_handle(tc), &ndata); |
find_classes(rtnl_tc_get_handle(tc), &ndata); |
find_qdiscs(rtnl_tc_get_handle(tc), &ndata); | find_qdiscs(rtnl_tc_get_ifindex(tc), rtnl_tc_get_handle(tc), &ndata); |
} |
} |
|
|
static void find_qdiscs(uint32_t parent, struct rdata *rdata) | static void find_qdiscs(int ifindex, uint32_t parent, struct rdata *rdata) |
{ |
{ |
struct rtnl_qdisc *filter; |
struct rtnl_qdisc *filter; |
|
|
Line 543 static void find_qdiscs(uint32_t parent, struct rdata
|
Line 622 static void find_qdiscs(uint32_t parent, struct rdata
|
return; |
return; |
|
|
rtnl_tc_set_parent((struct rtnl_tc *) filter, parent); |
rtnl_tc_set_parent((struct rtnl_tc *) filter, parent); |
|
rtnl_tc_set_ifindex((struct rtnl_tc *) filter, ifindex); |
|
|
nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(filter), |
nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(filter), |
handle_qdisc, rdata); |
handle_qdisc, rdata); |
Line 571 static void find_classes(uint32_t parent, struct rdata
|
Line 651 static void find_classes(uint32_t parent, struct rdata
|
|
|
rtnl_tc_set_parent((struct rtnl_tc *) filter, parent); |
rtnl_tc_set_parent((struct rtnl_tc *) filter, parent); |
|
|
nl_cache_foreach_filter(class_cache, OBJ_CAST(filter), | nl_cache_foreach_filter(rdata->class_cache, OBJ_CAST(filter), |
handle_class, rdata); |
handle_class, rdata); |
|
|
rtnl_class_put(filter); |
rtnl_class_put(filter); |
Line 581 static void handle_qdisc(struct nl_object *obj, void *
|
Line 661 static void handle_qdisc(struct nl_object *obj, void *
|
{ |
{ |
struct rtnl_tc *tc = (struct rtnl_tc *) obj; |
struct rtnl_tc *tc = (struct rtnl_tc *) obj; |
struct element *e; |
struct element *e; |
struct rdata *rdata = arg; | const struct rdata *rdata = arg; |
struct rdata ndata = { |
struct rdata ndata = { |
|
.class_cache = rdata->class_cache, |
.level = rdata->level + 1, |
.level = rdata->level + 1, |
}; |
}; |
|
|
Line 604 static void handle_qdisc(struct nl_object *obj, void *
|
Line 685 static void handle_qdisc(struct nl_object *obj, void *
|
static void handle_tc(struct element *e, struct rtnl_link *link) |
static void handle_tc(struct element *e, struct rtnl_link *link) |
{ |
{ |
struct rtnl_qdisc *qdisc; |
struct rtnl_qdisc *qdisc; |
|
struct nl_cache *class_cache; |
int ifindex = rtnl_link_get_ifindex(link); |
int ifindex = rtnl_link_get_ifindex(link); |
struct rdata rdata = { |
struct rdata rdata = { |
.level = 1, |
.level = 1, |
Line 613 static void handle_tc(struct element *e, struct rtnl_l
|
Line 695 static void handle_tc(struct element *e, struct rtnl_l
|
if (rtnl_class_alloc_cache(sock, ifindex, &class_cache) < 0) |
if (rtnl_class_alloc_cache(sock, ifindex, &class_cache) < 0) |
return; |
return; |
|
|
|
rdata.class_cache = class_cache; |
|
|
qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_ROOT); |
qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_ROOT); |
if (qdisc) { |
if (qdisc) { |
handle_qdisc(OBJ_CAST(qdisc), &rdata); |
handle_qdisc(OBJ_CAST(qdisc), &rdata); |
Line 736 static void do_link(struct nl_object *obj, void *arg)
|
Line 820 static void do_link(struct nl_object *obj, void *arg)
|
attr_update(e, m->attrid, c_rx, c_tx, flags); |
attr_update(e, m->attrid, c_rx, c_tx, flags); |
} |
} |
|
|
if (!c_notc) | if (!c_notc && qdisc_cache) |
handle_tc(e, link); |
handle_tc(e, link); |
|
|
element_notify_update(e, NULL); |
element_notify_update(e, NULL); |
Line 752 static void netlink_read(void)
|
Line 836 static void netlink_read(void)
|
goto disable; |
goto disable; |
} |
} |
|
|
if ((err = nl_cache_resync(sock, qdisc_cache, NULL, NULL)) < 0) { | if (qdisc_cache && |
| (err = nl_cache_resync(sock, qdisc_cache, NULL, NULL)) < 0) { |
fprintf(stderr, "Unable to resync qdisc cache: %s\n", nl_geterror(err)); |
fprintf(stderr, "Unable to resync qdisc cache: %s\n", nl_geterror(err)); |
goto disable; |
goto disable; |
} |
} |
Line 772 static void netlink_shutdown(void)
|
Line 857 static void netlink_shutdown(void)
|
nl_socket_free(sock); |
nl_socket_free(sock); |
} |
} |
|
|
|
static void netlink_use_bit(struct attr_map *map, const int size) |
|
{ |
|
if(cfg_getbool(cfg, "use_bit")) { |
|
for(int i = 0; i < size; ++i) { |
|
if(!strcmp(map[i].description, "Bytes")) { |
|
map[i].description = "Bits"; |
|
} |
|
} |
|
} |
|
} |
|
|
static int netlink_do_init(void) |
static int netlink_do_init(void) |
{ |
{ |
int err, i; | int err; |
|
|
if (!(sock = nl_socket_alloc())) { |
if (!(sock = nl_socket_alloc())) { |
fprintf(stderr, "Unable to allocate netlink socket\n"); |
fprintf(stderr, "Unable to allocate netlink socket\n"); |
Line 792 static int netlink_do_init(void)
|
Line 888 static int netlink_do_init(void)
|
} |
} |
|
|
if ((err = rtnl_qdisc_alloc_cache(sock, &qdisc_cache)) < 0) { |
if ((err = rtnl_qdisc_alloc_cache(sock, &qdisc_cache)) < 0) { |
fprintf(stderr, "Unable to allocate qdisc cache: %s\n", nl_geterror(err)); | fprintf(stderr, "Warning: Unable to allocate qdisc cache: %s\n", nl_geterror(err)); |
goto disable; | fprintf(stderr, "Disabling QoS statistics.\n"); |
| qdisc_cache = NULL; |
} |
} |
|
|
|
netlink_use_bit(link_attrs, ARRAY_SIZE(link_attrs)); |
|
netlink_use_bit(tc_attrs, ARRAY_SIZE(tc_attrs)); |
if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs)) || |
if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs)) || |
attr_map_load(tc_attrs, ARRAY_SIZE(tc_attrs))) |
attr_map_load(tc_attrs, ARRAY_SIZE(tc_attrs))) |
BUG(); |
BUG(); |
Line 817 static int netlink_probe(void)
|
Line 916 static int netlink_probe(void)
|
|
|
if (!(sock = nl_socket_alloc())) |
if (!(sock = nl_socket_alloc())) |
return 0; |
return 0; |
| |
if (nl_connect(sock, NETLINK_ROUTE) < 0) |
if (nl_connect(sock, NETLINK_ROUTE) < 0) |
return 0; |
return 0; |
| |
if (rtnl_link_alloc_cache(sock, AF_UNSPEC, &lc) == 0) { |
if (rtnl_link_alloc_cache(sock, AF_UNSPEC, &lc) == 0) { |
nl_cache_free(lc); |
nl_cache_free(lc); |
ret = 1; |
ret = 1; |
} |
} |
|
|
nl_socket_free(sock); |
nl_socket_free(sock); |
| |
return ret; |
return ret; |
} |
} |
|
|