]> git.proxmox.com Git - mirror_iproute2.git/blame - bridge/bridge.c
json_writer: Removed automatic json-object type from the constructor
[mirror_iproute2.git] / bridge / bridge.c
CommitLineData
d04bc300
SH
1/*
2 * Get/set/delete bridge with netlink
3 *
4 * Authors: Stephen Hemminger <shemminger@vyatta.com>
5 */
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <sys/socket.h>
11#include <string.h>
9de8c6d9 12#include <errno.h>
d04bc300
SH
13
14#include "SNAPSHOT.h"
15#include "utils.h"
16#include "br_common.h"
527910c8 17#include "namespace.h"
d04bc300
SH
18
19struct rtnl_handle rth = { .fd = -1 };
0849e60a 20int preferred_family = AF_UNSPEC;
d04bc300 21int resolve_hosts;
ec7aff5c 22int oneline;
d04bc300
SH
23int show_stats;
24int show_details;
a2f7934d 25int compress_vlans;
d04bc300 26int timestamp;
9de8c6d9
WK
27char *batch_file;
28int force;
ec7aff5c 29const char *_SL_;
d04bc300
SH
30
31static void usage(void) __attribute__((noreturn));
32
33static void usage(void)
34{
35 fprintf(stderr,
90698170 36"Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n"
9de8c6d9 37" bridge [ -force ] -batch filename\n"
ec7aff5c
SH
38"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
39" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
40" -o[neline] | -t[imestamp] | -n[etns] name |\n"
41" -c[ompressvlans] }\n");
d04bc300
SH
42 exit(-1);
43}
44
45static int do_help(int argc, char **argv)
46{
47 usage();
48}
49
50
51static const struct cmd {
52 const char *cmd;
53 int (*func)(int argc, char **argv);
54} cmds[] = {
ec7aff5c
SH
55 { "link", do_link },
56 { "fdb", do_fdb },
57 { "mdb", do_mdb },
9eff0e5c 58 { "vlan", do_vlan },
d04bc300
SH
59 { "monitor", do_monitor },
60 { "help", do_help },
61 { 0 }
62};
63
64static int do_cmd(const char *argv0, int argc, char **argv)
65{
66 const struct cmd *c;
67
68 for (c = cmds; c->cmd; ++c) {
69 if (matches(argv0, c->cmd) == 0)
70 return c->func(argc-1, argv+1);
71 }
72
ec7aff5c
SH
73 fprintf(stderr,
74 "Object \"%s\" is unknown, try \"bridge help\".\n", argv0);
d04bc300
SH
75 return -1;
76}
77
9de8c6d9
WK
78static int batch(const char *name)
79{
80 char *line = NULL;
81 size_t len = 0;
82 int ret = EXIT_SUCCESS;
83
84 if (name && strcmp(name, "-") != 0) {
85 if (freopen(name, "r", stdin) == NULL) {
86 fprintf(stderr,
87 "Cannot open file \"%s\" for reading: %s\n",
88 name, strerror(errno));
89 return EXIT_FAILURE;
90 }
91 }
92
93 if (rtnl_open(&rth, 0) < 0) {
94 fprintf(stderr, "Cannot open rtnetlink\n");
95 return EXIT_FAILURE;
96 }
97
98 cmdlineno = 0;
99 while (getcmdline(&line, &len, stdin) != -1) {
100 char *largv[100];
101 int largc;
102
103 largc = makeargs(line, largv, 100);
104 if (largc == 0)
105 continue; /* blank line */
106
107 if (do_cmd(largv[0], largc, largv)) {
108 fprintf(stderr, "Command failed %s:%d\n",
109 name, cmdlineno);
110 ret = EXIT_FAILURE;
111 if (!force)
112 break;
113 }
114 }
115 if (line)
116 free(line);
117
118 rtnl_close(&rth);
119 return ret;
120}
121
d04bc300
SH
122int
123main(int argc, char **argv)
124{
125 while (argc > 1) {
ec7aff5c
SH
126 const char *opt = argv[1];
127
128 if (strcmp(opt, "--") == 0) {
d04bc300
SH
129 argc--; argv++;
130 break;
131 }
132 if (opt[0] != '-')
133 break;
134 if (opt[1] == '-')
135 opt++;
136
137 if (matches(opt, "-help") == 0) {
138 usage();
139 } else if (matches(opt, "-Version") == 0) {
90698170 140 printf("bridge utility, 0.0\n");
d04bc300
SH
141 exit(0);
142 } else if (matches(opt, "-stats") == 0 ||
143 matches(opt, "-statistics") == 0) {
144 ++show_stats;
145 } else if (matches(opt, "-details") == 0) {
146 ++show_details;
4cd20da1
SH
147 } else if (matches(opt, "-oneline") == 0) {
148 ++oneline;
d04bc300
SH
149 } else if (matches(opt, "-timestamp") == 0) {
150 ++timestamp;
ec7aff5c 151 } else if (matches(opt, "-family") == 0) {
0849e60a
SH
152 argc--;
153 argv++;
154 if (argc <= 1)
155 usage();
156 if (strcmp(argv[1], "inet") == 0)
157 preferred_family = AF_INET;
158 else if (strcmp(argv[1], "inet6") == 0)
159 preferred_family = AF_INET6;
160 else if (strcmp(argv[1], "help") == 0)
161 usage();
162 else
163 invarg("invalid protocol family", argv[1]);
164 } else if (strcmp(opt, "-4") == 0) {
165 preferred_family = AF_INET;
166 } else if (strcmp(opt, "-6") == 0) {
167 preferred_family = AF_INET6;
527910c8
VK
168 } else if (matches(opt, "-netns") == 0) {
169 NEXT_ARG();
170 if (netns_switch(argv[1]))
171 exit(-1);
a2f7934d
RP
172 } else if (matches(opt, "-compressvlans") == 0) {
173 ++compress_vlans;
9de8c6d9
WK
174 } else if (matches(opt, "-force") == 0) {
175 ++force;
176 } else if (matches(opt, "-batch") == 0) {
177 argc--;
178 argv++;
179 if (argc <= 1)
180 usage();
181 batch_file = argv[1];
d04bc300 182 } else {
ec7aff5c
SH
183 fprintf(stderr,
184 "Option \"%s\" is unknown, try \"bridge help\".\n",
185 opt);
d04bc300
SH
186 exit(-1);
187 }
188 argc--; argv++;
189 }
190
ec7aff5c 191 _SL_ = oneline ? "\\" : "\n";
4cd20da1 192
9de8c6d9
WK
193 if (batch_file)
194 return batch(batch_file);
195
d04bc300
SH
196 if (rtnl_open(&rth, 0) < 0)
197 exit(1);
198
199 if (argc > 1)
200 return do_cmd(argv[1], argc-1, argv+1);
201
202 rtnl_close(&rth);
203 usage();
204}