#include "utils.h"
#include "ll_map.h"
#include "ip_common.h"
-#include "xdp.h"
#include "color.h"
enum {
}
}
-static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s,
- const struct rtattr *carrier_changes)
+static void __print_link_stats(FILE *fp, struct rtattr *tb[])
{
+ const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES];
+ struct rtnl_link_stats64 _s, *s = &_s;
+ int ret;
+
+ ret = get_rtnl_link_stats_rta(s, tb);
+ if (ret < 0)
+ return;
+
if (is_json_context()) {
- open_json_object("stats64");
+ open_json_object((ret == sizeof(*s)) ? "stats64" : "stats");
/* RX stats */
open_json_object("rx");
print_uint(PRINT_JSON, "multicast", NULL, s->multicast);
if (s->rx_compressed)
print_uint(PRINT_JSON,
- "compressed",
- NULL, s->rx_compressed);
+ "compressed", NULL, s->rx_compressed);
/* RX error stats */
if (show_stats > 1) {
print_uint(PRINT_JSON, "collisions", NULL, s->collisions);
if (s->tx_compressed)
print_uint(PRINT_JSON,
- "compressed",
- NULL, s->tx_compressed);
+ "compressed", NULL, s->tx_compressed);
/* TX error stats */
if (show_stats > 1) {
print_uint(PRINT_JSON, "carrier_changes", NULL,
rta_getattr_u32(carrier_changes));
}
- close_json_object();
- close_json_object();
-
- } else {
- /* RX stats */
- fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
- s->rx_compressed ? "compressed" : "", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 10, s->rx_bytes);
- print_num(fp, 8, s->rx_packets);
- print_num(fp, 7, s->rx_errors);
- print_num(fp, 7, s->rx_dropped);
- print_num(fp, 7, s->rx_over_errors);
- print_num(fp, 7, s->multicast);
- if (s->rx_compressed)
- print_num(fp, 7, s->rx_compressed);
-
- /* RX error stats */
- if (show_stats > 1) {
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
- s->rx_nohandler ? " nohandler" : "", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 8, s->rx_length_errors);
- print_num(fp, 7, s->rx_crc_errors);
- print_num(fp, 7, s->rx_frame_errors);
- print_num(fp, 7, s->rx_fifo_errors);
- print_num(fp, 7, s->rx_missed_errors);
- if (s->rx_nohandler)
- print_num(fp, 7, s->rx_nohandler);
-
- }
- fprintf(fp, "%s", _SL_);
-
- /* TX stats */
- fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
- s->tx_compressed ? "compressed" : "", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 10, s->tx_bytes);
- print_num(fp, 8, s->tx_packets);
- print_num(fp, 7, s->tx_errors);
- print_num(fp, 7, s->tx_dropped);
- print_num(fp, 7, s->tx_carrier_errors);
- print_num(fp, 7, s->collisions);
- if (s->tx_compressed)
- print_num(fp, 7, s->tx_compressed);
-
- /* TX error stats */
- if (show_stats > 1) {
- fprintf(fp, "%s", _SL_);
- fprintf(fp, " TX errors: aborted fifo window heartbeat");
- if (carrier_changes)
- fprintf(fp, " transns");
- fprintf(fp, "%s", _SL_);
-
- fprintf(fp, " ");
- print_num(fp, 8, s->tx_aborted_errors);
- print_num(fp, 7, s->tx_fifo_errors);
- print_num(fp, 7, s->tx_window_errors);
- print_num(fp, 7, s->tx_heartbeat_errors);
- if (carrier_changes)
- print_num(fp, 7,
- rta_getattr_u32(carrier_changes));
- }
- }
-}
-
-static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s,
- const struct rtattr *carrier_changes)
-{
- if (is_json_context()) {
- open_json_object("stats");
-
- /* RX stats */
- open_json_object("rx");
- print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes);
- print_uint(PRINT_JSON, "packets", NULL, s->rx_packets);
- print_uint(PRINT_JSON, "errors", NULL, s->rx_errors);
- print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped);
- print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors);
- print_uint(PRINT_JSON, "multicast", NULL, s->multicast);
- if (s->rx_compressed)
- print_int(PRINT_JSON,
- "compressed",
- NULL, s->rx_compressed);
-
- /* RX error stats */
- if (show_stats > 1) {
- print_uint(PRINT_JSON,
- "length_errors",
- NULL, s->rx_length_errors);
- print_uint(PRINT_JSON,
- "crc_errors",
- NULL, s->rx_crc_errors);
- print_uint(PRINT_JSON,
- "frame_errors",
- NULL, s->rx_frame_errors);
- print_uint(PRINT_JSON,
- "fifo_errors",
- NULL, s->rx_fifo_errors);
- print_uint(PRINT_JSON,
- "missed_errors",
- NULL, s->rx_missed_errors);
- if (s->rx_nohandler)
- print_int(PRINT_JSON,
- "nohandler",
- NULL, s->rx_nohandler);
- }
- close_json_object();
-
- /* TX stats */
- open_json_object("tx");
- print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes);
- print_uint(PRINT_JSON, "packets", NULL, s->tx_packets);
- print_uint(PRINT_JSON, "errors", NULL, s->tx_errors);
- print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped);
- print_uint(PRINT_JSON,
- "carrier_errors",
- NULL, s->tx_carrier_errors);
- print_uint(PRINT_JSON, "collisions", NULL, s->collisions);
- if (s->tx_compressed)
- print_int(PRINT_JSON,
- "compressed",
- NULL, s->tx_compressed);
-
- /* TX error stats */
- if (show_stats > 1) {
- print_uint(PRINT_JSON,
- "aborted_errors",
- NULL, s->tx_aborted_errors);
- print_uint(PRINT_JSON,
- "fifo_errors",
- NULL, s->tx_fifo_errors);
- print_uint(PRINT_JSON,
- "window_errors",
- NULL, s->tx_window_errors);
- print_uint(PRINT_JSON,
- "heartbeat_errors",
- NULL, s->tx_heartbeat_errors);
- if (carrier_changes)
- print_uint(PRINT_JSON,
- "carrier_changes",
- NULL,
- rta_getattr_u32(carrier_changes));
- }
close_json_object();
close_json_object();
fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
s->rx_compressed ? "compressed" : "", _SL_);
-
fprintf(fp, " ");
print_num(fp, 10, s->rx_bytes);
print_num(fp, 8, s->rx_packets);
}
}
-static void __print_link_stats(FILE *fp, struct rtattr **tb)
-{
- const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES];
-
- if (tb[IFLA_STATS64]) {
- struct rtnl_link_stats64 stats = { 0 };
-
- memcpy(&stats, RTA_DATA(tb[IFLA_STATS64]),
- MIN(RTA_PAYLOAD(tb[IFLA_STATS64]), sizeof(stats)));
-
- print_link_stats64(fp, &stats, carrier_changes);
- } else if (tb[IFLA_STATS]) {
- struct rtnl_link_stats stats = { 0 };
-
- memcpy(&stats, RTA_DATA(tb[IFLA_STATS]),
- MIN(RTA_PAYLOAD(tb[IFLA_STATS]), sizeof(stats)));
-
- print_link_stats32(fp, &stats, carrier_changes);
- }
-}
-
static void print_link_stats(FILE *fp, struct nlmsghdr *n)
{
struct ifinfomsg *ifi = NLMSG_DATA(n);
fprintf(fp, "%s", _SL_);
}
-int print_linkinfo_brief(const struct sockaddr_nl *who,
- struct nlmsghdr *n, void *arg,
- struct link_filter *pfilter)
+static int print_linkinfo_brief(FILE *fp, const char *name,
+ const struct ifinfomsg *ifi,
+ struct rtattr *tb[])
{
- FILE *fp = (FILE *)arg;
- struct ifinfomsg *ifi = NLMSG_DATA(n);
- struct rtattr *tb[IFLA_MAX+1];
- int len = n->nlmsg_len;
- const char *name;
- char buf[32] = { 0, };
unsigned int m_flag = 0;
- if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
- return -1;
-
- len -= NLMSG_LENGTH(sizeof(*ifi));
- if (len < 0)
- return -1;
-
- if (!pfilter)
- pfilter = &filter;
-
- if (pfilter->ifindex && ifi->ifi_index != pfilter->ifindex)
- return -1;
- if (pfilter->up && !(ifi->ifi_flags&IFF_UP))
- return -1;
-
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
- if (tb[IFLA_IFNAME] == NULL) {
- fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
- name = "<nil>";
- } else {
- name = rta_getattr_str(tb[IFLA_IFNAME]);
- }
-
- if (pfilter->label &&
- (!pfilter->family || pfilter->family == AF_PACKET) &&
- fnmatch(pfilter->label, RTA_DATA(tb[IFLA_IFNAME]), 0))
- return -1;
-
- if (tb[IFLA_GROUP]) {
- int group = rta_getattr_u32(tb[IFLA_GROUP]);
-
- if (pfilter->group != -1 && group != pfilter->group)
- return -1;
- }
-
- if (tb[IFLA_MASTER]) {
- int master = rta_getattr_u32(tb[IFLA_MASTER]);
-
- if (pfilter->master > 0 && master != pfilter->master)
- return -1;
- } else if (pfilter->master > 0)
- return -1;
-
- if (pfilter->kind && match_link_kind(tb, pfilter->kind, 0))
- return -1;
-
- if (pfilter->slave_kind && match_link_kind(tb, pfilter->slave_kind, 1))
- return -1;
-
- if (n->nlmsg_type == RTM_DELLINK)
- print_bool(PRINT_ANY, "deleted", "Deleted ", true);
-
- if (tb[IFLA_LINK]) {
- SPRINT_BUF(b1);
- int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-
- if (iflink == 0) {
- snprintf(buf, sizeof(buf), "%s@NONE", name);
- print_null(PRINT_JSON, "link", NULL, NULL);
- } else {
- const char *link = ll_idx_n2a(iflink, b1);
-
- print_string(PRINT_JSON, "link", NULL, link);
- snprintf(buf, sizeof(buf), "%s@%s", name, link);
- m_flag = ll_index_to_flags(iflink);
- m_flag = !(m_flag & IFF_UP);
- }
- } else
- snprintf(buf, sizeof(buf), "%s", name);
-
- print_string(PRINT_FP, NULL, "%-16s ", buf);
- print_string(PRINT_JSON, "ifname", NULL, name);
+ m_flag = print_name_and_link("%-16s ", name, tb);
if (tb[IFLA_OPERSTATE])
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
- if (pfilter->family == AF_PACKET) {
+ if (filter.family == AF_PACKET) {
SPRINT_BUF(b1);
if (tb[IFLA_ADDRESS]) {
}
}
- if (pfilter->family == AF_PACKET) {
+ if (filter.family == AF_PACKET) {
print_link_flags(fp, ifi->ifi_flags, m_flag);
print_string(PRINT_FP, NULL, "%s", "\n");
}
+
fflush(fp);
return 0;
}
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct rtattr *tb[IFLA_MAX+1];
int len = n->nlmsg_len;
+ const char *name;
unsigned int m_flag = 0;
+ SPRINT_BUF(b1);
if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
return 0;
return -1;
if (filter.ifindex && ifi->ifi_index != filter.ifindex)
- return 0;
+ return -1;
if (filter.up && !(ifi->ifi_flags&IFF_UP))
- return 0;
+ return -1;
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
- if (tb[IFLA_IFNAME] == NULL)
- fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
+
+ name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
+ if (!name)
+ return -1;
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
- fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
- return 0;
+ fnmatch(filter.label, name, 0))
+ return -1;
if (tb[IFLA_GROUP]) {
int group = rta_getattr_u32(tb[IFLA_GROUP]);
if (n->nlmsg_type == RTM_DELLINK)
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
- print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
- if (tb[IFLA_IFNAME]) {
- print_color_string(PRINT_ANY,
- COLOR_IFNAME,
- "ifname", "%s",
- rta_getattr_str(tb[IFLA_IFNAME]));
- } else {
- print_null(PRINT_JSON, "ifname", NULL, NULL);
- print_color_null(PRINT_FP, COLOR_IFNAME,
- "ifname", "%s", "<nil>");
- }
-
- if (tb[IFLA_LINK]) {
- int iflink = rta_getattr_u32(tb[IFLA_LINK]);
+ if (brief)
+ return print_linkinfo_brief(fp, name, ifi, tb);
- if (iflink == 0)
- print_null(PRINT_ANY, "link", "@%s: ", "NONE");
- else {
- if (tb[IFLA_LINK_NETNSID])
- print_int(PRINT_ANY,
- "link_index", "@if%d: ", iflink);
- else {
- SPRINT_BUF(b1);
+ print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
- print_string(PRINT_ANY,
- "link",
- "@%s: ",
- ll_idx_n2a(iflink, b1));
- m_flag = ll_index_to_flags(iflink);
- m_flag = !(m_flag & IFF_UP);
- }
- }
- } else {
- print_string(PRINT_FP, NULL, ": ", NULL);
- }
+ m_flag = print_name_and_link("%s: ", name, tb);
print_link_flags(fp, ifi->ifi_flags, m_flag);
if (tb[IFLA_MTU])
"qdisc %s ",
rta_getattr_str(tb[IFLA_QDISC]));
if (tb[IFLA_MASTER]) {
- SPRINT_BUF(b1);
+ int master = rta_getattr_u32(tb[IFLA_MASTER]);
print_string(PRINT_ANY,
- "master",
- "master %s ",
- ll_idx_n2a(rta_getattr_u32(tb[IFLA_MASTER]), b1));
+ "master", "master %s ",
+ ll_index_to_name(master));
}
if (tb[IFLA_OPERSTATE])
print_linkmode(fp, tb[IFLA_LINKMODE]);
if (tb[IFLA_GROUP]) {
- SPRINT_BUF(b1);
int group = rta_getattr_u32(tb[IFLA_GROUP]);
print_string(PRINT_ANY,
print_link_event(fp, rta_getattr_u32(tb[IFLA_EVENT]));
if (!filter.family || filter.family == AF_PACKET || show_details) {
- SPRINT_BUF(b1);
-
print_string(PRINT_FP, NULL, "%s", _SL_);
print_string(PRINT_ANY,
"link_type",
rta_getattr_str(tb[IFLA_PHYS_PORT_NAME]));
if (tb[IFLA_PHYS_PORT_ID]) {
- SPRINT_BUF(b1);
print_string(PRINT_ANY,
"phys_port_id",
"portid %s ",
}
if (tb[IFLA_PHYS_SWITCH_ID]) {
- SPRINT_BUF(b1);
print_string(PRINT_ANY,
"phys_switch_id",
"switchid %s ",
close_json_array(PRINT_JSON, NULL);
}
- print_string(PRINT_FP, NULL, "\n", NULL);
+ print_string(PRINT_FP, NULL, "%s", "\n");
fflush(fp);
return 1;
}
return 0;
}
+static int ifa_label_match_rta(int ifindex, const struct rtattr *rta)
+{
+ const char *label;
+
+ if (!filter.label)
+ return 0;
+
+ if (rta)
+ label = RTA_DATA(rta);
+ else
+ label = ll_index_to_name(ifindex);
+
+ return fnmatch(filter.label, label, 0);
+}
+
int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
void *arg)
{
return 0;
if ((filter.flags ^ ifa_flags) & filter.flagmask)
return 0;
- if (filter.label) {
- SPRINT_BUF(b1);
- const char *label;
-
- if (rta_tb[IFA_LABEL])
- label = RTA_DATA(rta_tb[IFA_LABEL]);
- else
- label = ll_idx_n2a(ifa->ifa_index, b1);
- if (fnmatch(filter.label, label, 0) != 0)
- return 0;
- }
if (filter.family && filter.family != ifa->ifa_family)
return 0;
+ if (ifa_label_match_rta(ifa->ifa_index, rta_tb[IFA_LABEL]))
+ return 0;
+
if (inet_addr_match_rta(&filter.pfx, rta_tb[IFA_LOCAL]))
return 0;
if ((filter.flags ^ ifa_flags) & filter.flagmask)
continue;
- if (filter.pfx.family || filter.label) {
- struct rtattr *rta =
- tb[IFA_LOCAL] ? : tb[IFA_ADDRESS];
-
- if (inet_addr_match_rta(&filter.pfx, rta))
- continue;
-
- if (filter.label) {
- SPRINT_BUF(b1);
- const char *label;
-
- if (tb[IFA_LABEL])
- label = RTA_DATA(tb[IFA_LABEL]);
- else
- label = ll_idx_n2a(ifa->ifa_index, b1);
- if (fnmatch(filter.label, label, 0) != 0)
- continue;
- }
- }
+
+ if (ifa_label_match_rta(ifa->ifa_index, tb[IFA_LABEL]))
+ continue;
+
+ if (!tb[IFA_LOCAL])
+ tb[IFA_LOCAL] = tb[IFA_ADDRESS];
+ if (inet_addr_match_rta(&filter.pfx, tb[IFA_LOCAL]))
+ continue;
ok = 1;
break;
ipaddr_filter(&linfo, ainfo);
for (l = linfo.head; l; l = l->next) {
+ struct nlmsghdr *n = &l->h;
+ struct ifinfomsg *ifi = NLMSG_DATA(n);
int res = 0;
- struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
open_json_object(NULL);
- if (brief) {
- if (print_linkinfo_brief(NULL, &l->h,
- stdout, NULL) == 0)
- if (filter.family != AF_PACKET)
- print_selected_addrinfo(ifi,
- ainfo->head,
- stdout);
- } else if (no_link ||
- (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
- if (filter.family != AF_PACKET)
- print_selected_addrinfo(ifi,
- ainfo->head, stdout);
- if (res > 0 && !do_link && show_stats)
- print_link_stats(stdout, &l->h);
- }
+ if (brief || !no_link)
+ res = print_linkinfo(NULL, n, stdout);
+ if (res >= 0 && filter.family != AF_PACKET)
+ print_selected_addrinfo(ifi, ainfo->head, stdout);
+ if (res > 0 && !do_link && show_stats)
+ print_link_stats(stdout, n);
close_json_object();
}
fflush(stdout);
if (!scoped && cmd != RTM_DELADDR)
req.ifa.ifa_scope = default_scope(&lcl);
- if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {
- fprintf(stderr, "Cannot find device \"%s\"\n", d);
- return -1;
- }
+ req.ifa.ifa_index = ll_name_to_index(d);
+ if (!req.ifa.ifa_index)
+ return nodev(d);
if (valid_lftp || preferred_lftp) {
struct ifa_cacheinfo cinfo = {};