static void print_users(struct rd *rd, uint64_t val) { if (rd->json_output) jsonw_uint_field(rd->jw, "users", val); else pr_out("users %" PRIu64 " ", val); }
static void print_mrlen(struct rd *rd, uint64_t val) { if (rd->json_output) jsonw_uint_field(rd->jw, "mrlen", val); else pr_out("mrlen %" PRIu64 " ", val); }
static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; struct rd *rd = data; const char *name; uint32_t idx; mnl_attr_parse(nlh, 0, rd_attr_cb, tb); if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_RES_SUMMARY]) return MNL_CB_ERROR; idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); if (rd->json_output) { jsonw_uint_field(rd->jw, "ifindex", idx); jsonw_string_field(rd->jw, "ifname", name); } else { pr_out("%u: %s: ", idx, name); } res_print_summary(rd, tb); if (!rd->json_output) pr_out("\n"); return MNL_CB_OK; }
static void print_cqe(struct rd *rd, uint32_t val) { if (rd->json_output) jsonw_uint_field(rd->jw, "cqe", val); else pr_out("cqe %u ", val); }
static void print_sqpsn(struct rd *rd, uint32_t val) { if (rd->json_output) jsonw_uint_field(rd->jw, "sq-psn", val); else pr_out("sq-psn %u ", val); }
static void print_pid(struct rd *rd, uint32_t val) { if (rd->json_output) jsonw_uint_field(rd->jw, "pid", val); else pr_out("pid %u ", val); }
static void print_lqpn(struct rd *rd, uint32_t val) { if (rd->json_output) jsonw_uint_field(rd->jw, "lqpn", val); else pr_out("lqpn %u ", val); }
static void print_link(struct rd *rd, uint32_t idx, const char *name, uint32_t port, struct nlattr **nla_line) { if (rd->json_output) { jsonw_uint_field(rd->jw, "ifindex", idx); if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) jsonw_uint_field(rd->jw, "port", port); jsonw_string_field(rd->jw, "ifname", name); } else { if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) pr_out("link %s/%u ", name, port); else pr_out("link %s/- ", name); } }
static void print_dev(struct rd *rd, uint32_t idx, const char *name) { if (rd->json_output) { jsonw_uint_field(rd->jw, "ifindex", idx); jsonw_string_field(rd->jw, "ifname", name); } else { pr_out("dev %s ", name); } }
static void dump_raw_db(FILE *fp, int to_hist) { json_writer_t *jw = json_output ? jsonw_new(fp) : NULL; struct ifstat_ent *n, *h; h = hist_db; if (jw) { jsonw_start_object(jw); jsonw_pretty(jw, pretty); jsonw_name(jw, info_source); jsonw_start_object(jw); } else fprintf(fp, "#%s\n", info_source); for (n = kern_db; n; n = n->next) { int i; unsigned long long *vals = n->val; double *rates = n->rate; if (!match(n->name)) { struct ifstat_ent *h1; if (!to_hist) continue; for (h1 = h; h1; h1 = h1->next) { if (h1->ifindex == n->ifindex) { vals = h1->val; rates = h1->rate; h = h1->next; break; } } } if (jw) { jsonw_name(jw, n->name); jsonw_start_object(jw); for (i = 0; i < MAXS && stats[i]; i++) jsonw_uint_field(jw, stats[i], vals[i]); jsonw_end_object(jw); } else { fprintf(fp, "%d %s ", n->ifindex, n->name); for (i = 0; i < MAXS; i++) fprintf(fp, "%llu %u ", vals[i], (unsigned int)rates[i]); fprintf(fp, "\n"); } } if (jw) { jsonw_end_object(jw); jsonw_end_object(jw); jsonw_destroy(&jw); } }
static void print_rqpsn(struct rd *rd, uint32_t val, struct nlattr **nla_line) { if (!nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) return; if (rd->json_output) jsonw_uint_field(rd->jw, "rq-psn", val); else pr_out("rq-psn %u ", val); }
static void print_one_json(json_writer_t *jw, const struct ifstat_ent *n, const unsigned long long *vals) { int i, m = show_errors ? 20 : 10; jsonw_name(jw, n->name); jsonw_start_object(jw); for (i = 0; i < m && stats[i]; i++) jsonw_uint_field(jw, stats[i], vals[i]); jsonw_end_object(jw); }
int main(int argc, char **argv) { json_writer_t *wr = jsonw_new(stdout); jsonw_start_object(wr); jsonw_pretty(wr, true); jsonw_name(wr, "Vyatta"); jsonw_start_object(wr); jsonw_string_field(wr, "url", "http://vyatta.com"); jsonw_uint_field(wr, "downloads", 2000000ul); jsonw_float_field(wr, "stock", 8.16); jsonw_name(wr, "ARGV"); jsonw_start_array(wr); while (--argc) jsonw_string(wr, *++argv); jsonw_end_array(wr); jsonw_name(wr, "empty"); jsonw_start_array(wr); jsonw_end_array(wr); jsonw_name(wr, "NIL"); jsonw_start_object(wr); jsonw_end_object(wr); jsonw_null_field(wr, "my_null"); jsonw_name(wr, "special chars"); jsonw_start_array(wr); jsonw_string_field(wr, "slash", "/"); jsonw_string_field(wr, "newline", "\n"); jsonw_string_field(wr, "tab", "\t"); jsonw_string_field(wr, "ff", "\f"); jsonw_string_field(wr, "quote", "\""); jsonw_string_field(wr, "tick", "\'"); jsonw_string_field(wr, "backslash", "\\"); jsonw_end_array(wr); jsonw_end_object(wr); jsonw_end_object(wr); jsonw_destroy(&wr); return 0; }
static int show_bpf_prog(int id, const char *attach_type_str, const char *attach_flags_str, int level) { struct bpf_prog_info info = {}; __u32 info_len = sizeof(info); int prog_fd; prog_fd = bpf_prog_get_fd_by_id(id); if (prog_fd < 0) return -1; if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) { close(prog_fd); return -1; } if (json_output) { jsonw_start_object(json_wtr); jsonw_uint_field(json_wtr, "id", info.id); jsonw_string_field(json_wtr, "attach_type", attach_type_str); jsonw_string_field(json_wtr, "attach_flags", attach_flags_str); jsonw_string_field(json_wtr, "name", info.name); jsonw_end_object(json_wtr); } else { printf("%s%-8u %-15s %-15s %-15s\n", level ? " " : "", info.id, attach_type_str, attach_flags_str, info.name); } close(prog_fd); return 0; }
static int dump_btf_type(const struct btf *btf, __u32 id, const struct btf_type *t) { json_writer_t *w = json_wtr; int kind, safe_kind; kind = BTF_INFO_KIND(t->info); safe_kind = kind <= BTF_KIND_MAX ? kind : BTF_KIND_UNKN; if (json_output) { jsonw_start_object(w); jsonw_uint_field(w, "id", id); jsonw_string_field(w, "kind", btf_kind_str[safe_kind]); jsonw_string_field(w, "name", btf_str(btf, t->name_off)); } else { printf("[%u] %s '%s'", id, btf_kind_str[safe_kind], btf_str(btf, t->name_off)); } switch (BTF_INFO_KIND(t->info)) { case BTF_KIND_INT: { __u32 v = *(__u32 *)(t + 1); const char *enc; enc = btf_int_enc_str(BTF_INT_ENCODING(v)); if (json_output) { jsonw_uint_field(w, "size", t->size); jsonw_uint_field(w, "bits_offset", BTF_INT_OFFSET(v)); jsonw_uint_field(w, "nr_bits", BTF_INT_BITS(v)); jsonw_string_field(w, "encoding", enc); } else { printf(" size=%u bits_offset=%u nr_bits=%u encoding=%s", t->size, BTF_INT_OFFSET(v), BTF_INT_BITS(v), enc); } break; } case BTF_KIND_PTR: case BTF_KIND_CONST: case BTF_KIND_VOLATILE: case BTF_KIND_RESTRICT: case BTF_KIND_TYPEDEF: if (json_output) jsonw_uint_field(w, "type_id", t->type); else printf(" type_id=%u", t->type); break; case BTF_KIND_ARRAY: { const struct btf_array *arr = (const void *)(t + 1); if (json_output) { jsonw_uint_field(w, "type_id", arr->type); jsonw_uint_field(w, "index_type_id", arr->index_type); jsonw_uint_field(w, "nr_elems", arr->nelems); } else { printf(" type_id=%u index_type_id=%u nr_elems=%u", arr->type, arr->index_type, arr->nelems); } break; } case BTF_KIND_STRUCT: case BTF_KIND_UNION: { const struct btf_member *m = (const void *)(t + 1); __u16 vlen = BTF_INFO_VLEN(t->info); int i; if (json_output) { jsonw_uint_field(w, "size", t->size); jsonw_uint_field(w, "vlen", vlen); jsonw_name(w, "members"); jsonw_start_array(w); } else { printf(" size=%u vlen=%u", t->size, vlen); } for (i = 0; i < vlen; i++, m++) { const char *name = btf_str(btf, m->name_off); __u32 bit_off, bit_sz; if (BTF_INFO_KFLAG(t->info)) { bit_off = BTF_MEMBER_BIT_OFFSET(m->offset); bit_sz = BTF_MEMBER_BITFIELD_SIZE(m->offset); } else { bit_off = m->offset; bit_sz = 0; } if (json_output) { jsonw_start_object(w); jsonw_string_field(w, "name", name); jsonw_uint_field(w, "type_id", m->type); jsonw_uint_field(w, "bits_offset", bit_off); if (bit_sz) { jsonw_uint_field(w, "bitfield_size", bit_sz); } jsonw_end_object(w); } else { printf("\n\t'%s' type_id=%u bits_offset=%u", name, m->type, bit_off); if (bit_sz) printf(" bitfield_size=%u", bit_sz); } } if (json_output) jsonw_end_array(w); break; } case BTF_KIND_ENUM: { const struct btf_enum *v = (const void *)(t + 1); __u16 vlen = BTF_INFO_VLEN(t->info); int i; if (json_output) { jsonw_uint_field(w, "size", t->size); jsonw_uint_field(w, "vlen", vlen); jsonw_name(w, "values"); jsonw_start_array(w); } else { printf(" size=%u vlen=%u", t->size, vlen); } for (i = 0; i < vlen; i++, v++) { const char *name = btf_str(btf, v->name_off); if (json_output) { jsonw_start_object(w); jsonw_string_field(w, "name", name); jsonw_uint_field(w, "val", v->val); jsonw_end_object(w); } else { printf("\n\t'%s' val=%u", name, v->val); } } if (json_output) jsonw_end_array(w); break; } case BTF_KIND_FWD: { const char *fwd_kind = BTF_INFO_KFLAG(t->info) ? "union" : "struct"; if (json_output) jsonw_string_field(w, "fwd_kind", fwd_kind); else printf(" fwd_kind=%s", fwd_kind); break; } case BTF_KIND_FUNC: if (json_output) jsonw_uint_field(w, "type_id", t->type); else printf(" type_id=%u", t->type); break; case BTF_KIND_FUNC_PROTO: { const struct btf_param *p = (const void *)(t + 1); __u16 vlen = BTF_INFO_VLEN(t->info); int i; if (json_output) { jsonw_uint_field(w, "ret_type_id", t->type); jsonw_uint_field(w, "vlen", vlen); jsonw_name(w, "params"); jsonw_start_array(w); } else { printf(" ret_type_id=%u vlen=%u", t->type, vlen); } for (i = 0; i < vlen; i++, p++) { const char *name = btf_str(btf, p->name_off); if (json_output) { jsonw_start_object(w); jsonw_string_field(w, "name", name); jsonw_uint_field(w, "type_id", p->type); jsonw_end_object(w); } else { printf("\n\t'%s' type_id=%u", name, p->type); } } if (json_output) jsonw_end_array(w); break; } case BTF_KIND_VAR: { const struct btf_var *v = (const void *)(t + 1); const char *linkage; linkage = btf_var_linkage_str(v->linkage); if (json_output) { jsonw_uint_field(w, "type_id", t->type); jsonw_string_field(w, "linkage", linkage); } else { printf(" type_id=%u, linkage=%s", t->type, linkage); } break; } case BTF_KIND_DATASEC: { const struct btf_var_secinfo *v = (const void *)(t+1); __u16 vlen = BTF_INFO_VLEN(t->info); int i; if (json_output) { jsonw_uint_field(w, "size", t->size); jsonw_uint_field(w, "vlen", vlen); jsonw_name(w, "vars"); jsonw_start_array(w); } else { printf(" size=%u vlen=%u", t->size, vlen); } for (i = 0; i < vlen; i++, v++) { if (json_output) { jsonw_start_object(w); jsonw_uint_field(w, "type_id", v->type); jsonw_uint_field(w, "offset", v->offset); jsonw_uint_field(w, "size", v->size); jsonw_end_object(w); } else { printf("\n\ttype_id=%u offset=%u size=%u", v->type, v->offset, v->size); } } if (json_output) jsonw_end_array(w); break; } default: break; } if (json_output) jsonw_end_object(json_wtr); else printf("\n"); return 0; }
static int vlan_modify(int cmd, int argc, char **argv) { struct { struct nlmsghdr n; struct ifinfomsg ifm; char buf[1024]; } req = { .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), .n.nlmsg_flags = NLM_F_REQUEST, .n.nlmsg_type = cmd, .ifm.ifi_family = PF_BRIDGE, }; char *d = NULL; short vid = -1; short vid_end = -1; struct rtattr *afspec; struct bridge_vlan_info vinfo = {}; unsigned short flags = 0; while (argc > 0) { if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); d = *argv; } else if (strcmp(*argv, "vid") == 0) { char *p; NEXT_ARG(); p = strchr(*argv, '-'); if (p) { *p = '\0'; p++; vid = atoi(*argv); vid_end = atoi(p); vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN; } else { vid = atoi(*argv); } } else if (strcmp(*argv, "self") == 0) { flags |= BRIDGE_FLAGS_SELF; } else if (strcmp(*argv, "master") == 0) { flags |= BRIDGE_FLAGS_MASTER; } else if (strcmp(*argv, "pvid") == 0) { vinfo.flags |= BRIDGE_VLAN_INFO_PVID; } else if (strcmp(*argv, "untagged") == 0) { vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED; } else { if (matches(*argv, "help") == 0) { NEXT_ARG(); } } argc--; argv++; } if (d == NULL || vid == -1) { fprintf(stderr, "Device and VLAN ID are required arguments.\n"); return -1; } req.ifm.ifi_index = ll_name_to_index(d); if (req.ifm.ifi_index == 0) { fprintf(stderr, "Cannot find bridge device \"%s\"\n", d); return -1; } if (vid >= 4096) { fprintf(stderr, "Invalid VLAN ID \"%hu\"\n", vid); return -1; } if (vinfo.flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) { if (vid_end == -1 || vid_end >= 4096 || vid >= vid_end) { fprintf(stderr, "Invalid VLAN range \"%hu-%hu\"\n", vid, vid_end); return -1; } if (vinfo.flags & BRIDGE_VLAN_INFO_PVID) { fprintf(stderr, "pvid cannot be configured for a vlan range\n"); return -1; } } afspec = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC); if (flags) addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags); vinfo.vid = vid; if (vid_end != -1) { /* send vlan range start */ addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo, sizeof(vinfo)); vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN; /* Now send the vlan range end */ vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END; vinfo.vid = vid_end; addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo, sizeof(vinfo)); } else { addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo, sizeof(vinfo)); } addattr_nest_end(&req.n, afspec); if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) return -1; return 0; } /* In order to use this function for both filtering and non-filtering cases * we need to make it a tristate: * return -1 - if filtering we've gone over so don't continue * return 0 - skip entry and continue (applies to range start or to entries * which are less than filter_vlan) * return 1 - print the entry and continue */ static int filter_vlan_check(struct bridge_vlan_info *vinfo) { /* if we're filtering we should stop on the first greater entry */ if (filter_vlan && vinfo->vid > filter_vlan && !(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END)) return -1; if ((vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) || vinfo->vid < filter_vlan) return 0; return 1; } static void print_vlan_port(FILE *fp, int ifi_index) { if (jw_global) { jsonw_pretty(jw_global, 1); jsonw_name(jw_global, ll_index_to_name(ifi_index)); jsonw_start_array(jw_global); } else { fprintf(fp, "%s", ll_index_to_name(ifi_index)); } } static void start_json_vlan_flags_array(bool *vlan_flags) { if (*vlan_flags) return; jsonw_name(jw_global, "flags"); jsonw_start_array(jw_global); *vlan_flags = true; } static int print_vlan(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = arg; struct ifinfomsg *ifm = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[IFLA_MAX+1]; bool vlan_flags; if (n->nlmsg_type != RTM_NEWLINK) { fprintf(stderr, "Not RTM_NEWLINK: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); return 0; } len -= NLMSG_LENGTH(sizeof(*ifm)); if (len < 0) { fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); return -1; } if (ifm->ifi_family != AF_BRIDGE) return 0; if (filter_index && filter_index != ifm->ifi_index) return 0; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len); /* if AF_SPEC isn't there, vlan table is not preset for this port */ if (!tb[IFLA_AF_SPEC]) { if (!filter_vlan) fprintf(fp, "%s\tNone\n", ll_index_to_name(ifm->ifi_index)); return 0; } else { struct rtattr *i, *list = tb[IFLA_AF_SPEC]; int rem = RTA_PAYLOAD(list); __u16 last_vid_start = 0; if (!filter_vlan) print_vlan_port(fp, ifm->ifi_index); for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { struct bridge_vlan_info *vinfo; int vcheck_ret; if (i->rta_type != IFLA_BRIDGE_VLAN_INFO) continue; vinfo = RTA_DATA(i); if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END)) last_vid_start = vinfo->vid; vcheck_ret = filter_vlan_check(vinfo); if (vcheck_ret == -1) break; else if (vcheck_ret == 0) continue; if (filter_vlan) print_vlan_port(fp, ifm->ifi_index); if (jw_global) { jsonw_start_object(jw_global); jsonw_uint_field(jw_global, "vlan", last_vid_start); if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) continue; } else { fprintf(fp, "\t %hu", last_vid_start); } if (last_vid_start != vinfo->vid) { if (jw_global) jsonw_uint_field(jw_global, "vlanEnd", vinfo->vid); else fprintf(fp, "-%hu", vinfo->vid); } if (vinfo->flags & BRIDGE_VLAN_INFO_PVID) { if (jw_global) { start_json_vlan_flags_array(&vlan_flags); jsonw_string(jw_global, "PVID"); } else { fprintf(fp, " PVID"); } } if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED) { if (jw_global) { start_json_vlan_flags_array(&vlan_flags); jsonw_string(jw_global, "Egress Untagged"); } else { fprintf(fp, " Egress Untagged"); } } if (vlan_flags) { jsonw_end_array(jw_global); vlan_flags = false; } if (jw_global) jsonw_end_object(jw_global); else fprintf(fp, "\n"); } } if (!filter_vlan) { if (jw_global) jsonw_end_array(jw_global); else fprintf(fp, "\n"); } fflush(fp); return 0; }