mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-08-17 11:03:26 +00:00
bridge: add json support for bridge vlan show
$bridge -c vlan show port vlan ids swp1 1 PVID Egress Untagged 10-13 swp2 1 PVID Egress Untagged 10-13 br0 1 PVID Egress Untagged $bridge -json vlan show { "swp1": [{ "vlan": 1, "flags": ["PVID","Egress Untagged" ] },{ "vlan": 10 },{ "vlan": 11 },{ "vlan": 12 },{ "vlan": 13 } ], "swp2": [{ "vlan": 1, "flags": ["PVID","Egress Untagged" ] },{ "vlan": 10 },{ "vlan": 11 },{ "vlan": 12 },{ "vlan": 13 } ], "br0": [{ "vlan": 1, "flags": ["PVID","Egress Untagged" ] } ] } $bridge -c -json vlan show { "swp1": [{ "vlan": 1, "flags": ["PVID","Egress Untagged" ] },{ "vlan": 10, "vlanEnd": 13 } ], "swp2": [{ "vlan": 1, "flags": ["PVID","Egress Untagged" ] },{ "vlan": 10, "vlanEnd": 13 } ], "br0": [{ "vlan": 1, "flags": ["PVID","Egress Untagged" ] } ] } Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
This commit is contained in:
parent
d721a14590
commit
d82a49ce85
@ -23,4 +23,5 @@ extern int show_stats;
|
|||||||
extern int show_details;
|
extern int show_details;
|
||||||
extern int timestamp;
|
extern int timestamp;
|
||||||
extern int compress_vlans;
|
extern int compress_vlans;
|
||||||
|
extern int json_output;
|
||||||
extern struct rtnl_handle rth;
|
extern struct rtnl_handle rth;
|
||||||
|
@ -23,6 +23,7 @@ int oneline;
|
|||||||
int show_stats;
|
int show_stats;
|
||||||
int show_details;
|
int show_details;
|
||||||
int compress_vlans;
|
int compress_vlans;
|
||||||
|
int json_output;
|
||||||
int timestamp;
|
int timestamp;
|
||||||
char *batch_file;
|
char *batch_file;
|
||||||
int force;
|
int force;
|
||||||
@ -38,7 +39,7 @@ static void usage(void)
|
|||||||
"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
|
"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
|
||||||
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
|
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
|
||||||
" -o[neline] | -t[imestamp] | -n[etns] name |\n"
|
" -o[neline] | -t[imestamp] | -n[etns] name |\n"
|
||||||
" -c[ompressvlans] }\n");
|
" -c[ompressvlans] -j{son} }\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,6 +174,8 @@ main(int argc, char **argv)
|
|||||||
++compress_vlans;
|
++compress_vlans;
|
||||||
} else if (matches(opt, "-force") == 0) {
|
} else if (matches(opt, "-force") == 0) {
|
||||||
++force;
|
++force;
|
||||||
|
} else if (matches(opt, "-json") == 0) {
|
||||||
|
++json_output;
|
||||||
} else if (matches(opt, "-batch") == 0) {
|
} else if (matches(opt, "-batch") == 0) {
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <linux/if_bridge.h>
|
#include <linux/if_bridge.h>
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
|
#include <json_writer.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "libnetlink.h"
|
#include "libnetlink.h"
|
||||||
@ -15,6 +16,8 @@
|
|||||||
|
|
||||||
static unsigned int filter_index, filter_vlan;
|
static unsigned int filter_index, filter_vlan;
|
||||||
|
|
||||||
|
json_writer_t *jw_global = NULL;
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
|
fprintf(stderr, "Usage: bridge vlan { add | del } vid VLAN_ID dev DEV [ pvid] [ untagged ]\n");
|
||||||
@ -158,6 +161,28 @@ static int filter_vlan_check(struct bridge_vlan_info *vinfo)
|
|||||||
return 1;
|
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,
|
static int print_vlan(const struct sockaddr_nl *who,
|
||||||
struct nlmsghdr *n,
|
struct nlmsghdr *n,
|
||||||
void *arg)
|
void *arg)
|
||||||
@ -166,6 +191,8 @@ static int print_vlan(const struct sockaddr_nl *who,
|
|||||||
struct ifinfomsg *ifm = NLMSG_DATA(n);
|
struct ifinfomsg *ifm = NLMSG_DATA(n);
|
||||||
int len = n->nlmsg_len;
|
int len = n->nlmsg_len;
|
||||||
struct rtattr *tb[IFLA_MAX+1];
|
struct rtattr *tb[IFLA_MAX+1];
|
||||||
|
bool vlan_flags;
|
||||||
|
char flags[80];
|
||||||
|
|
||||||
if (n->nlmsg_type != RTM_NEWLINK) {
|
if (n->nlmsg_type != RTM_NEWLINK) {
|
||||||
fprintf(stderr, "Not RTM_NEWLINK: %08x %08x %08x\n",
|
fprintf(stderr, "Not RTM_NEWLINK: %08x %08x %08x\n",
|
||||||
@ -199,7 +226,8 @@ static int print_vlan(const struct sockaddr_nl *who,
|
|||||||
__u16 last_vid_start = 0;
|
__u16 last_vid_start = 0;
|
||||||
|
|
||||||
if (!filter_vlan)
|
if (!filter_vlan)
|
||||||
fprintf(fp, "%s", ll_index_to_name(ifm->ifi_index));
|
print_vlan_port(fp, ifm->ifi_index);
|
||||||
|
|
||||||
for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
||||||
struct bridge_vlan_info *vinfo;
|
struct bridge_vlan_info *vinfo;
|
||||||
int vcheck_ret;
|
int vcheck_ret;
|
||||||
@ -218,20 +246,58 @@ static int print_vlan(const struct sockaddr_nl *who,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (filter_vlan)
|
if (filter_vlan)
|
||||||
fprintf(fp, "%s",
|
print_vlan_port(fp, ifm->ifi_index);
|
||||||
ll_index_to_name(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);
|
fprintf(fp, "\t %hu", last_vid_start);
|
||||||
if (last_vid_start != vinfo->vid)
|
}
|
||||||
|
if (last_vid_start != vinfo->vid) {
|
||||||
|
if (jw_global)
|
||||||
|
jsonw_uint_field(jw_global, "vlanEnd",
|
||||||
|
vinfo->vid);
|
||||||
|
else
|
||||||
fprintf(fp, "-%hu", vinfo->vid);
|
fprintf(fp, "-%hu", vinfo->vid);
|
||||||
if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
|
}
|
||||||
|
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");
|
fprintf(fp, " PVID");
|
||||||
if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
|
}
|
||||||
|
}
|
||||||
|
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");
|
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");
|
fprintf(fp, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!filter_vlan)
|
if (!filter_vlan) {
|
||||||
|
if (jw_global)
|
||||||
|
jsonw_end_array(jw_global);
|
||||||
|
else
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
}
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -271,12 +337,27 @@ static int vlan_show(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (json_output) {
|
||||||
|
jw_global = jsonw_new(stdout);
|
||||||
|
if (!jw_global) {
|
||||||
|
fprintf(stderr, "Error allocation json object\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
jsonw_start_object(jw_global);
|
||||||
|
} else {
|
||||||
printf("port\tvlan ids\n");
|
printf("port\tvlan ids\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (rtnl_dump_filter(&rth, print_vlan, stdout) < 0) {
|
if (rtnl_dump_filter(&rth, print_vlan, stdout) < 0) {
|
||||||
fprintf(stderr, "Dump ternminated\n");
|
fprintf(stderr, "Dump ternminated\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (jw_global) {
|
||||||
|
jsonw_end_object(jw_global);
|
||||||
|
jsonw_destroy(&jw_global);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user