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