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