+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Get/set/delete bridge with netlink
*
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
+#include <errno.h>
#include "SNAPSHOT.h"
#include "utils.h"
#include "br_common.h"
+#include "namespace.h"
+#include "color.h"
struct rtnl_handle rth = { .fd = -1 };
int preferred_family = AF_UNSPEC;
-int resolve_hosts;
+int oneline;
int show_stats;
int show_details;
+int show_pretty;
+int color;
+int compress_vlans;
+int json;
int timestamp;
+char *batch_file;
+int force;
static void usage(void) __attribute__((noreturn));
{
fprintf(stderr,
"Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n"
-"where OBJECT := { fdb | monitor }\n"
-" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails]\n" );
+" bridge [ -force ] -batch filename\n"
+"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
+" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
+" -o[neline] | -t[imestamp] | -n[etns] name |\n"
+" -c[ompressvlans] -color -p[retty] -j[son] }\n");
exit(-1);
}
const char *cmd;
int (*func)(int argc, char **argv);
} cmds[] = {
- { "fdb", do_fdb },
- { "mdb", do_mdb },
+ { "link", do_link },
+ { "fdb", do_fdb },
+ { "mdb", do_mdb },
+ { "vlan", do_vlan },
{ "monitor", do_monitor },
{ "help", do_help },
{ 0 }
return c->func(argc-1, argv+1);
}
- fprintf(stderr, "Object \"%s\" is unknown, try \"bridge help\".\n", argv0);
+ fprintf(stderr,
+ "Object \"%s\" is unknown, try \"bridge help\".\n", argv0);
return -1;
}
+static int batch(const char *name)
+{
+ char *line = NULL;
+ size_t len = 0;
+ int ret = EXIT_SUCCESS;
+
+ if (name && strcmp(name, "-") != 0) {
+ if (freopen(name, "r", stdin) == NULL) {
+ fprintf(stderr,
+ "Cannot open file \"%s\" for reading: %s\n",
+ name, strerror(errno));
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (rtnl_open(&rth, 0) < 0) {
+ fprintf(stderr, "Cannot open rtnetlink\n");
+ return EXIT_FAILURE;
+ }
+
+ cmdlineno = 0;
+ while (getcmdline(&line, &len, stdin) != -1) {
+ char *largv[100];
+ int largc;
+
+ largc = makeargs(line, largv, 100);
+ if (largc == 0)
+ continue; /* blank line */
+
+ if (do_cmd(largv[0], largc, largv)) {
+ fprintf(stderr, "Command failed %s:%d\n",
+ name, cmdlineno);
+ ret = EXIT_FAILURE;
+ if (!force)
+ break;
+ }
+ }
+ if (line)
+ free(line);
+
+ rtnl_close(&rth);
+ return ret;
+}
+
int
main(int argc, char **argv)
{
while (argc > 1) {
- char *opt = argv[1];
- if (strcmp(opt,"--") == 0) {
+ const char *opt = argv[1];
+
+ if (strcmp(opt, "--") == 0) {
argc--; argv++;
break;
}
++show_stats;
} else if (matches(opt, "-details") == 0) {
++show_details;
+ } else if (matches(opt, "-oneline") == 0) {
+ ++oneline;
} else if (matches(opt, "-timestamp") == 0) {
++timestamp;
- } else if (matches(opt, "-family") == 0) {
+ } else if (matches(opt, "-family") == 0) {
argc--;
argv++;
if (argc <= 1)
preferred_family = AF_INET;
} else if (strcmp(opt, "-6") == 0) {
preferred_family = AF_INET6;
+ } else if (matches(opt, "-netns") == 0) {
+ NEXT_ARG();
+ if (netns_switch(argv[1]))
+ exit(-1);
+ } else if (matches_color(opt, &color)) {
+ } else if (matches(opt, "-compressvlans") == 0) {
+ ++compress_vlans;
+ } else if (matches(opt, "-force") == 0) {
+ ++force;
+ } else if (matches(opt, "-json") == 0) {
+ ++json;
+ } else if (matches(opt, "-pretty") == 0) {
+ ++pretty;
+ } else if (matches(opt, "-batch") == 0) {
+ argc--;
+ argv++;
+ if (argc <= 1)
+ usage();
+ batch_file = argv[1];
} else {
- fprintf(stderr, "Option \"%s\" is unknown, try \"bridge help\".\n", opt);
+ fprintf(stderr,
+ "Option \"%s\" is unknown, try \"bridge help\".\n",
+ opt);
exit(-1);
}
argc--; argv++;
}
+ _SL_ = oneline ? "\\" : "\n";
+
+ check_enable_color(color, json);
+
+ if (batch_file)
+ return batch(batch_file);
+
if (rtnl_open(&rth, 0) < 0)
exit(1);