static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {}; char *req_bearer = data; const char *bname; const char title[] = "node status monitored generation applied_node_status [non_applied_node:status]"; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_MON]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs); bname = mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME]); if (*req_bearer && (strcmp(req_bearer, bname) != 0)) return MNL_CB_OK; open_json_object(NULL); print_string(PRINT_ANY, "bearer", "\nbearer %s\n", bname); print_string(PRINT_FP, NULL, "%s\n", title); open_json_array(PRINT_JSON, bname); if (mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT])) link_mon_peer_list(mnl_attr_get_u32(attrs[TIPC_NLA_MON_REF])); close_json_array(PRINT_JSON, bname); close_json_object(); return MNL_CB_OK; }
static void vlan_print_map(FILE *f, const char *name_json, const char *name_fp, struct rtattr *attr) { struct ifla_vlan_qos_mapping *m; struct rtattr *i; int rem; open_json_array(PRINT_JSON, name_json); print_string(PRINT_FP, NULL, "\n %s { ", name_fp); rem = RTA_PAYLOAD(attr); for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { m = RTA_DATA(i); if (is_json_context()) { open_json_object(NULL); print_uint(PRINT_JSON, "from", NULL, m->from); print_uint(PRINT_JSON, "to", NULL, m->to); close_json_object(); } else { fprintf(f, "%u:%u ", m->from, m->to); } } close_json_array(PRINT_JSON, NULL); print_string(PRINT_FP, NULL, "%s ", "}"); }
static void vlan_print_flags(FILE *fp, __u32 flags) { open_json_array(PRINT_ANY, is_json_context() ? "flags" : "<"); #define _PF(f) if (flags & VLAN_FLAG_##f) { \ flags &= ~VLAN_FLAG_##f; \ print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); \ } _PF(REORDER_HDR); _PF(GVRP); _PF(MVRP); _PF(LOOSE_BINDING); #undef _PF if (flags) print_hex(PRINT_ANY, NULL, "%x", flags); close_json_array(PRINT_ANY, "> "); }
/* print the applied members, since we know the the members * are listed in ascending order, we print only the state */ static void link_mon_print_applied(uint16_t applied, uint64_t up_map) { int i; open_json_array(PRINT_JSON, "applied_node_status"); for (i = 0; i < applied; i++) { char state_str[2] = {0}; /* print the delimiter for every -n- entry */ if (i && !(i % APPL_NODE_STATUS_WIDTH)) print_string(PRINT_FP, NULL, "%s", ","); sprintf(state_str, "%c", map_get(up_map, i) ? 'U' : 'D'); print_string(PRINT_ANY, NULL, "%s", state_str); } close_json_array(PRINT_JSON, "applied_node_status"); }
static void print_tx_sc(const char *prefix, __u64 sci, __u8 encoding_sa, struct rtattr *txsc_stats, struct rtattr *secy_stats, struct rtattr *sa) { struct rtattr *sa_attr[MACSEC_SA_ATTR_MAX + 1]; struct rtattr *a; int rem; print_string(PRINT_FP, NULL, "%s", prefix); print_0xhex(PRINT_ANY, "sci", "TXSC: %016llx", ntohll(sci)); print_uint(PRINT_ANY, "encoding_sa", " on SA %d\n", encoding_sa); print_secy_stats(prefix, secy_stats); print_txsc_stats(prefix, txsc_stats); open_json_array(PRINT_JSON, "sa_list"); rem = RTA_PAYLOAD(sa); for (a = RTA_DATA(sa); RTA_OK(a, rem); a = RTA_NEXT(a, rem)) { bool state; open_json_object(NULL); parse_rtattr_nested(sa_attr, MACSEC_SA_ATTR_MAX + 1, a); state = rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_ACTIVE]); print_string(PRINT_FP, NULL, "%s", prefix); print_string(PRINT_FP, NULL, "%s", prefix); print_uint(PRINT_ANY, "an", "%d:", rta_getattr_u8(sa_attr[MACSEC_SA_ATTR_AN])); print_uint(PRINT_ANY, "pn", " PN %u,", rta_getattr_u32(sa_attr[MACSEC_SA_ATTR_PN])); print_bool(PRINT_JSON, "active", NULL, state); print_string(PRINT_FP, NULL, " state %s,", state ? "on" : "off"); print_key(sa_attr[MACSEC_SA_ATTR_KEYID]); print_txsa_stats(prefix, sa_attr[MACSEC_SA_ATTR_STATS]); close_json_object(); } close_json_array(PRINT_JSON, NULL); }
static void print_rxsc_list(struct rtattr *sc) { int rem = RTA_PAYLOAD(sc); struct rtattr *c; open_json_array(PRINT_JSON, "rx_sc"); for (c = RTA_DATA(sc); RTA_OK(c, rem); c = RTA_NEXT(c, rem)) { struct rtattr *sc_attr[MACSEC_RXSC_ATTR_MAX + 1]; open_json_object(NULL); parse_rtattr_nested(sc_attr, MACSEC_RXSC_ATTR_MAX + 1, c); print_rx_sc(" ", rta_getattr_u64(sc_attr[MACSEC_RXSC_ATTR_SCI]), rta_getattr_u32(sc_attr[MACSEC_RXSC_ATTR_ACTIVE]), sc_attr[MACSEC_RXSC_ATTR_STATS], sc_attr[MACSEC_RXSC_ATTR_SA_LIST]); close_json_object(); } close_json_array(PRINT_JSON, NULL); }
/* print the non applied members, since we don't know * the members, we print them along with the state */ static void link_mon_print_non_applied(uint16_t applied, uint16_t member_cnt, uint64_t up_map, uint32_t *members) { int i; char state; open_json_array(PRINT_JSON, "[non_applied_node:status]"); print_string(PRINT_FP, NULL, " %s", "["); for (i = applied; i < member_cnt; i++) { char addr_str[16]; char full_state[17] = {0}; /* print the delimiter for every entry */ if (i != applied) print_string(PRINT_FP, NULL, "%s", ","); sprintf(addr_str, "%x:", members[i]); state = map_get(up_map, i) ? 'U' : 'D'; sprintf(full_state, "%s%c", addr_str, state); print_string(PRINT_ANY, NULL, "%s", full_state); } print_string(PRINT_FP, NULL, "%s", "]"); close_json_array(PRINT_JSON, "[non_applied_node:status]"); }
static int ipneigh_modify(int cmd, int flags, int argc, char **argv) { struct { struct nlmsghdr n; struct ndmsg ndm; char buf[256]; } req = { .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)), .n.nlmsg_flags = NLM_F_REQUEST | flags, .n.nlmsg_type = cmd, .ndm.ndm_family = preferred_family, .ndm.ndm_state = NUD_PERMANENT, }; char *dev = NULL; int dst_ok = 0; int dev_ok = 0; int lladdr_ok = 0; char *lla = NULL; inet_prefix dst; while (argc > 0) { if (matches(*argv, "lladdr") == 0) { NEXT_ARG(); if (lladdr_ok) duparg("lladdr", *argv); lla = *argv; lladdr_ok = 1; } else if (strcmp(*argv, "nud") == 0) { unsigned int state; NEXT_ARG(); if (nud_state_a2n(&state, *argv)) invarg("nud state is bad", *argv); req.ndm.ndm_state = state; } else if (matches(*argv, "proxy") == 0) { NEXT_ARG(); if (matches(*argv, "help") == 0) usage(); if (dst_ok) duparg("address", *argv); get_addr(&dst, *argv, preferred_family); dst_ok = 1; dev_ok = 1; req.ndm.ndm_flags |= NTF_PROXY; } else if (strcmp(*argv, "router") == 0) { req.ndm.ndm_flags |= NTF_ROUTER; } else if (matches(*argv, "extern_learn") == 0) { req.ndm.ndm_flags |= NTF_EXT_LEARNED; } else if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); dev = *argv; dev_ok = 1; } else if (matches(*argv, "protocol") == 0) { __u32 proto; NEXT_ARG(); if (rtnl_rtprot_a2n(&proto, *argv)) invarg("\"protocol\" value is invalid\n", *argv); if (addattr8(&req.n, sizeof(req), NDA_PROTOCOL, proto)) return -1; } else { if (strcmp(*argv, "to") == 0) { NEXT_ARG(); } if (matches(*argv, "help") == 0) { NEXT_ARG(); } if (dst_ok) duparg2("to", *argv); get_addr(&dst, *argv, preferred_family); dst_ok = 1; } argc--; argv++; } if (!dev_ok || !dst_ok || dst.family == AF_UNSPEC) { fprintf(stderr, "Device and destination are required arguments.\n"); exit(-1); } req.ndm.ndm_family = dst.family; if (addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen) < 0) return -1; if (lla && strcmp(lla, "null")) { char llabuf[20]; int l; l = ll_addr_a2n(llabuf, sizeof(llabuf), lla); if (l < 0) return -1; if (addattr_l(&req.n, sizeof(req), NDA_LLADDR, llabuf, l) < 0) return -1; } ll_init_map(&rth); if (dev) { req.ndm.ndm_ifindex = ll_name_to_index(dev); if (!req.ndm.ndm_ifindex) return nodev(dev); } if (rtnl_talk(&rth, &req.n, NULL) < 0) exit(2); return 0; } static void print_cacheinfo(const struct nda_cacheinfo *ci) { static int hz; if (!hz) hz = get_user_hz(); if (ci->ndm_refcnt) print_uint(PRINT_ANY, "refcnt", " ref %u", ci->ndm_refcnt); print_uint(PRINT_ANY, "used", " used %u", ci->ndm_used / hz); print_uint(PRINT_ANY, "confirmed", "/%u", ci->ndm_confirmed / hz); print_uint(PRINT_ANY, "updated", "/%u", ci->ndm_updated / hz); } static void print_neigh_state(unsigned int nud) { open_json_array(PRINT_JSON, is_json_context() ? "state" : ""); #define PRINT_FLAG(f) \ if (nud & NUD_##f) { \ nud &= ~NUD_##f; \ print_string(PRINT_ANY, NULL, " %s", #f); \ } PRINT_FLAG(INCOMPLETE); PRINT_FLAG(REACHABLE); PRINT_FLAG(STALE); PRINT_FLAG(DELAY); PRINT_FLAG(PROBE); PRINT_FLAG(FAILED); PRINT_FLAG(NOARP); PRINT_FLAG(PERMANENT); #undef PRINT_FLAG close_json_array(PRINT_JSON, NULL); }
static int _show_link_stat(const char *name, struct nlattr *attrs[], struct nlattr *prop[], struct nlattr *stats[]) { uint32_t proft; open_json_object(NULL); print_string(PRINT_ANY, "link", "\nLink <%s>\n", name); print_string(PRINT_JSON, "state", "", NULL); open_json_array(PRINT_JSON, NULL); if (attrs[TIPC_NLA_LINK_ACTIVE]) print_string(PRINT_ANY, NULL, " %s", "ACTIVE"); else if (attrs[TIPC_NLA_LINK_UP]) print_string(PRINT_ANY, NULL, " %s", "STANDBY"); else print_string(PRINT_ANY, NULL, " %s", "DEFUNCT"); close_json_array(PRINT_JSON, NULL); print_uint(PRINT_ANY, "mtu", " MTU:%u", mnl_attr_get_u32(attrs[TIPC_NLA_LINK_MTU])); print_uint(PRINT_ANY, PRIORITY_STR, " Priority:%u", mnl_attr_get_u32(prop[TIPC_NLA_PROP_PRIO])); print_uint(PRINT_ANY, TOLERANCE_STR, " Tolerance:%u ms", mnl_attr_get_u32(prop[TIPC_NLA_PROP_TOL])); print_uint(PRINT_ANY, WINDOW_STR, " Window:%u packets\n", mnl_attr_get_u32(prop[TIPC_NLA_PROP_WIN])); open_json_object("rx packets"); print_uint(PRINT_ANY, "rx packets", " RX packets:%u", mnl_attr_get_u32(attrs[TIPC_NLA_LINK_RX]) - mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_INFO])); print_uint(PRINT_ANY, "fragments", " fragments:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTS])); print_uint(PRINT_ANY, "fragmented", "/%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_FRAGMENTED])); print_uint(PRINT_ANY, "bundles", " bundles:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLES])); print_uint(PRINT_ANY, "bundled", "/%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_BUNDLED])); close_json_object(); open_json_object("tx packets"); print_uint(PRINT_ANY, "tx packets", " TX packets:%u", mnl_attr_get_u32(attrs[TIPC_NLA_LINK_TX]) - mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_INFO])); print_uint(PRINT_ANY, "fragments", " fragments:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTS])); print_uint(PRINT_ANY, "fragmented", "/%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_FRAGMENTED])); print_uint(PRINT_ANY, "bundles", " bundles:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLES])); print_uint(PRINT_ANY, "bundled", "/%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_BUNDLED])); close_json_object(); proft = mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_PROF_TOT]); print_uint(PRINT_ANY, "tx profile sample", " TX profile sample:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_CNT])); print_uint(PRINT_ANY, "packets average", " packets average:%u octets\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_TOT]) / proft); print_uint(PRINT_ANY, "0-64", " 0-64:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P0]), proft)); print_uint(PRINT_ANY, "-256", " -256:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P1]), proft)); print_uint(PRINT_ANY, "-1024", " -1024:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P2]), proft)); print_uint(PRINT_ANY, "-4096", " -4096:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P3]), proft)); print_uint(PRINT_ANY, "-16384", " -16384:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P4]), proft)); print_uint(PRINT_ANY, "-32768", " -32768:%u%%", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P5]), proft)); print_uint(PRINT_ANY, "-66000", " -66000:%u%%\n", perc(mnl_attr_get_u32(stats[TIPC_NLA_STATS_MSG_LEN_P6]), proft)); open_json_object("rx states"); print_uint(PRINT_ANY, "rx states", " RX states:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_STATES])); print_uint(PRINT_ANY, "probes", " probes:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_PROBES])); print_uint(PRINT_ANY, "naks", " naks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_NACKS])); print_uint(PRINT_ANY, "defs", " defs:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RX_DEFERRED])); print_uint(PRINT_ANY, "dups", " dups:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_DUPLICATES])); close_json_object(); open_json_object("tx states"); print_uint(PRINT_ANY, "tx states", " TX states:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_STATES])); print_uint(PRINT_ANY, "probes", " probes:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_PROBES])); print_uint(PRINT_ANY, "naks", " naks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_NACKS])); print_uint(PRINT_ANY, "acks", " acks:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_TX_ACKS])); print_uint(PRINT_ANY, "retrans", " retrans:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_RETRANSMITTED])); close_json_object(); print_uint(PRINT_ANY, "congestion link", " Congestion link:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_LINK_CONGS])); print_uint(PRINT_ANY, "send queue max", " Send queue max:%u", mnl_attr_get_u32(stats[TIPC_NLA_STATS_MAX_QUEUE])); print_uint(PRINT_ANY, "avg", " avg:%u\n", mnl_attr_get_u32(stats[TIPC_NLA_STATS_AVG_QUEUE])); close_json_object(); return MNL_CB_OK; }