aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Lewis <martin.lewis.x84@gmail.com>2019-09-15 18:04:49 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-10-08 14:43:51 +0200
commit6c1af283f73fb8640cd7273c2bf13eb102f80954 (patch)
tree58d367bf3a3f63be48aa97e18ddb686c7c5f366e
parent71b268c7d962a819f88050c2567dced975aa249e (diff)
downloadbusybox-w32-6c1af283f73fb8640cd7273c2bf13eb102f80954.tar.gz
busybox-w32-6c1af283f73fb8640cd7273c2bf13eb102f80954.tar.bz2
busybox-w32-6c1af283f73fb8640cd7273c2bf13eb102f80954.zip
brctl: add support for showmacs command
function old new delta brctl_main 680 974 +294 packed_usage 33167 33187 +20 compare_fdbs - 19 +19 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/0 up/down: 333/0) Total: 333 bytes Signed-off-by: Martin Lewis <martin.lewis.x84@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/brctl.c111
1 files changed, 92 insertions, 19 deletions
diff --git a/networking/brctl.c b/networking/brctl.c
index 586ca9b0c..ba5b6226f 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -61,10 +61,10 @@
61//usage: "\n setbridgeprio BRIDGE PRIO Set bridge priority" 61//usage: "\n setbridgeprio BRIDGE PRIO Set bridge priority"
62//usage: "\n setportprio BRIDGE IFACE PRIO Set port priority" 62//usage: "\n setportprio BRIDGE IFACE PRIO Set port priority"
63//usage: "\n setpathcost BRIDGE IFACE COST Set path cost" 63//usage: "\n setpathcost BRIDGE IFACE COST Set path cost"
64//usage: "\n showmacs BRIDGE List MAC addresses"
64//usage: ) 65//usage: )
65// Not yet implemented: 66// Not yet implemented:
66// hairpin BRIDGE IFACE on|off Hairpin on/off 67// hairpin BRIDGE IFACE on|off Hairpin on/off
67// showmacs BRIDGE List mac addrs
68// showstp BRIDGE Show stp info 68// showstp BRIDGE Show stp info
69 69
70#include "libbb.h" 70#include "libbb.h"
@@ -196,6 +196,89 @@ static void write_uint(const char *name, const char *leaf, unsigned val)
196 bb_simple_perror_msg_and_die(name); 196 bb_simple_perror_msg_and_die(name);
197 close(fd); 197 close(fd);
198} 198}
199
200struct fdb_entry {
201 uint8_t mac_addr[6];
202 uint8_t port_no;
203 uint8_t is_local;
204 uint32_t ageing_timer_value;
205 uint8_t port_hi;
206 uint8_t pad0;
207 uint16_t unused;
208};
209
210static int compare_fdbs(const void *_f0, const void *_f1)
211{
212 const struct fdb_entry *f0 = _f0;
213 const struct fdb_entry *f1 = _f1;
214
215 return memcmp(f0->mac_addr, f1->mac_addr, 6);
216}
217
218static size_t read_bridge_forward_db(const char *name, struct fdb_entry **_fdb)
219{
220 struct fdb_entry *fdb;
221 size_t nentries;
222 char *path;
223 int fd;
224 ssize_t cc;
225
226 path = concat_path_file(name, "brforward");
227 fd = open(path, O_RDONLY);
228 free(path);
229 if (fd < 0)
230 bb_error_msg_and_die("bridge %s does not exist", name);
231
232 fdb = NULL;
233 nentries = 0;
234 for (;;) {
235 fdb = xrealloc_vector(fdb, 4, nentries);
236 cc = full_read(fd, &fdb[nentries], sizeof(*fdb));
237 if (cc == 0) {
238 break;
239 }
240 if (cc != sizeof(*fdb)) {
241 bb_perror_msg_and_die("can't read bridge %s forward db", name);
242 }
243 ++nentries;
244 }
245
246 close(fd);
247
248 qsort(fdb, nentries, sizeof(*fdb), compare_fdbs);
249
250 *_fdb = fdb;
251 return nentries;
252}
253
254static void show_bridge_macs(const char *name)
255{
256 struct fdb_entry *fdb;
257 size_t nentries;
258 size_t i;
259
260 nentries = read_bridge_forward_db(name, &fdb);
261
262 printf("port no\tmac addr\t\tis local?\tageing timer\n");
263 for (i = 0; i < nentries; ++i) {
264 const struct fdb_entry *f = &fdb[i];
265 unsigned long tvmsec = 10UL * f->ageing_timer_value;
266 unsigned tv_sec = tvmsec / 1000;
267 unsigned tv_msec = tvmsec % 1000;
268 printf("%3u\t"
269 "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t"
270 "%s\t\t"
271 "%4u.%.2u\n",
272 f->port_no,
273 f->mac_addr[0], f->mac_addr[1], f->mac_addr[2],
274 f->mac_addr[3], f->mac_addr[4], f->mac_addr[5],
275 (f->is_local ? "yes" : "no"),
276 tv_sec, tv_msec / 10
277 );
278 }
279
280 free(fdb);
281}
199#endif 282#endif
200 283
201int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 284int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -208,6 +291,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
208 "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" 291 "setageing\0" "setfd\0" "sethello\0" "setmaxage\0"
209 "setpathcost\0" "setportprio\0" 292 "setpathcost\0" "setportprio\0"
210 "setbridgeprio\0" 293 "setbridgeprio\0"
294 "showmacs\0"
211 ) 295 )
212 IF_FEATURE_BRCTL_SHOW("show\0"); 296 IF_FEATURE_BRCTL_SHOW("show\0");
213 enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif 297 enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif
@@ -215,7 +299,8 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
215 ARG_stp, 299 ARG_stp,
216 ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, 300 ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage,
217 ARG_setpathcost, ARG_setportprio, 301 ARG_setpathcost, ARG_setportprio,
218 ARG_setbridgeprio 302 ARG_setbridgeprio,
303 ARG_showmacs
219 ) 304 )
220 IF_FEATURE_BRCTL_SHOW(, ARG_show) 305 IF_FEATURE_BRCTL_SHOW(, ARG_show)
221 }; 306 };
@@ -299,6 +384,11 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
299 return EXIT_SUCCESS; 384 return EXIT_SUCCESS;
300 } 385 }
301 386
387 if (key == ARG_showmacs) {
388 show_bridge_macs(br);
389 return EXIT_SUCCESS;
390 }
391
302 if (!*argv) /* all but 'addbr/delbr' need at least two arguments */ 392 if (!*argv) /* all but 'addbr/delbr' need at least two arguments */
303 bb_show_usage(); 393 bb_show_usage();
304 394
@@ -365,23 +455,6 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
365 //goto done_next_argv; 455 //goto done_next_argv;
366 return EXIT_SUCCESS; 456 return EXIT_SUCCESS;
367 } 457 }
368
369/* TODO: "showmacs BR"
370 * port no\tmac addr\t\tis local?\tageing timer
371 * <sp><sp>1\txx:xx:xx:xx:xx:xx\tno\t\t<sp><sp><sp>1.31
372 * port no mac addr is local? ageing timer
373 * 1 xx:xx:xx:xx:xx:xx no 1.31
374 * Read fixed-sized records from /sys/class/net/BR/brforward:
375 * struct __fdb_entry {
376 * uint8_t mac_addr[ETH_ALEN];
377 * uint8_t port_no; //lsb
378 * uint8_t is_local;
379 * uint32_t ageing_timer_value;
380 * uint8_t port_hi;
381 * uint8_t pad0;
382 * uint16_t unused;
383 * };
384 */
385#endif 458#endif
386 /* always true: if (key == ARG_addif || key == ARG_delif) */ { 459 /* always true: if (key == ARG_addif || key == ARG_delif) */ {
387 /* addif or delif */ 460 /* addif or delif */