static int read_counters(const char *iface, struct sample *stats) { struct rtnl_link *link; assert(nl_sock); pthread_mutex_lock(&nl_sock_mutex); /* iface index zero means use the iface name */ if (rtnl_link_get_kernel(nl_sock, 0, iface, &link) < 0) { syslog(LOG_ERR, "unknown interface/link name: %s\n", iface); pthread_mutex_unlock(&nl_sock_mutex); return -1; } /* read and return counter */ stats->rx_bytes = rtnl_link_get_stat(link, RTNL_LINK_RX_BYTES); stats->tx_bytes = rtnl_link_get_stat(link, RTNL_LINK_TX_BYTES); stats->rx_packets = rtnl_link_get_stat(link, RTNL_LINK_RX_PACKETS); stats->rx_packets += rtnl_link_get_stat(link, RTNL_LINK_RX_COMPRESSED); stats->tx_packets = rtnl_link_get_stat(link, RTNL_LINK_TX_PACKETS); stats->tx_packets += rtnl_link_get_stat(link, RTNL_LINK_TX_COMPRESSED); rtnl_link_put(link); pthread_mutex_unlock(&nl_sock_mutex); return 0; }
TError TNlLink::Load() { struct rtnl_link *link; int ret; ret = rtnl_link_get_kernel(GetSock(), rtnl_link_get_ifindex(Link), rtnl_link_get_name(Link), &link); if (ret) return Error(ret, "Cannot load link"); rtnl_link_put(Link); Link = link; return TError::Success(); }
void print_iface_stats(const char *iface, time_t since, FILE * out, cmd_params_st *params, unsigned have_more) { uint64_t tx, rx; char buf1[32], buf2[32]; time_t diff = time(0) - since; int ret; struct rtnl_link *rlink = NULL; if (iface == NULL || iface[0] == 0) return; if (open_netlink() < 0) return; ret = rtnl_link_get_kernel(sock, 0, iface, &rlink); if (ret < 0) { fprintf(stderr, "nl: cannot find %s\n", iface); return; } rx = rtnl_link_get_stat(rlink, RTNL_LINK_RX_BYTES); tx = rtnl_link_get_stat(rlink, RTNL_LINK_TX_BYTES); bytes2human(rx, buf1, sizeof(buf1), NULL); bytes2human(tx, buf2, sizeof(buf2), NULL); if (HAVE_JSON(params)) { fprintf(out, " \"RX\": \"%"PRIu64"\",\n \"TX\": \"%"PRIu64"\",\n", rx, tx); fprintf(out, " \"_RX\": \"%s\",\n \"_TX\": \"%s\",\n", buf1, buf2); } else fprintf(out, "\tRX: %"PRIu64" (%s) TX: %"PRIu64" (%s)\n", rx, buf1, tx, buf2); value2speed(rx, diff, buf1, sizeof(buf1)); value2speed(tx, diff, buf2, sizeof(buf2)); if (HAVE_JSON(params)) fprintf(out, " \"Average RX\": \"%s\",\n \"Average TX\": \"%s\"%s\n", buf1, buf2, have_more?",":""); else fprintf(out, "\tAverage bandwidth RX: %s TX: %s\n", buf1, buf2); return; }
/** * Add a link to a bond (enslave) * @arg sock netlink socket * @arg master ifindex of bonding master * @arg slave ifindex of slave link to add to bond * * This function is identical to rtnl_link_bond_enslave() except that * it takes interface indices instead of rtnl_link objcets. * * @see rtnl_link_bond_enslave() * * @return 0 on success or a negative error code. */ int rtnl_link_bond_enslave_ifindex(struct nl_sock *sock, int master, int slave) { struct rtnl_link *link; int err; if (!(link = rtnl_link_alloc())) return -NLE_NOMEM; if ((err = rtnl_link_set_type(link, "bond")) < 0) goto errout; rtnl_link_set_ifindex(link, slave); rtnl_link_set_master(link, master); if ((err = rtnl_link_change(sock, link, link, 0)) < 0) goto errout; rtnl_link_put(link); /* * Due to the kernel not signaling whether this opertion is * supported or not, we will retrieve the attribute to see if the * request was successful. If the master assigned remains unchanged * we will return NLE_OPNOTSUPP to allow performing backwards * compatibility of some sort. */ if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0) return err; if (rtnl_link_get_master(link) != master) err = -NLE_OPNOTSUPP; errout: rtnl_link_put(link); return err; }
static int init_qdisc(libxl__checkpoint_devices_state *cds, libxl__remus_device_nic *remus_nic) { int rc, ret, ifindex; struct rtnl_link *ifb = NULL; struct rtnl_qdisc *qdisc = NULL; libxl__remus_state *rs = cds->concrete_data; STATE_AO_GC(cds->ao); /* Now that we have brought up REMUS_IFB device with plug qdisc for * this vif, so we need to refill the qdisc cache. */ ret = nl_cache_refill(rs->nlsock, rs->qdisc_cache); if (ret) { LOGD(ERROR, cds->domid, "cannot refill qdisc cache: %s", nl_geterror(ret)); rc = ERROR_FAIL; goto out; } /* get a handle to the REMUS_IFB interface */ ret = rtnl_link_get_kernel(rs->nlsock, 0, remus_nic->ifb, &ifb); if (ret) { LOGD(ERROR, cds->domid, "cannot obtain handle for %s: %s", remus_nic->ifb, nl_geterror(ret)); rc = ERROR_FAIL; goto out; } ifindex = rtnl_link_get_ifindex(ifb); if (!ifindex) { LOGD(ERROR, cds->domid, "interface %s has no index", remus_nic->ifb); rc = ERROR_FAIL; goto out; } /* Get a reference to the root qdisc installed on the REMUS_IFB, by * querying the qdisc list we obtained earlier. The netbufscript * sets up the plug qdisc as the root qdisc, so we don't have to * search the entire qdisc tree on the REMUS_IFB dev. * There is no need to explicitly free this qdisc as its just a * reference from the qdisc cache we allocated earlier. */ qdisc = rtnl_qdisc_get_by_parent(rs->qdisc_cache, ifindex, TC_H_ROOT); if (qdisc) { const char *tc_kind = rtnl_tc_get_kind(TC_CAST(qdisc)); /* Sanity check: Ensure that the root qdisc is a plug qdisc. */ if (!tc_kind || strcmp(tc_kind, "plug")) { LOGD(ERROR, cds->domid, "plug qdisc is not installed on %s", remus_nic->ifb); rc = ERROR_FAIL; goto out; } remus_nic->qdisc = qdisc; } else { LOGD(ERROR, cds->domid, "Cannot get qdisc handle from ifb %s", remus_nic->ifb); rc = ERROR_FAIL; goto out; } rc = 0; out: if (ifb) rtnl_link_put(ifb); if (rc && qdisc) nl_object_put((struct nl_object *)qdisc); return rc; }