iproute2/bridge/monitor.c
<<
>>
Prefs
   1/*
   2 * brmonitor.c          "bridge monitor"
   3 *
   4 *              This program is free software; you can redistribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 * Authors:     Stephen Hemminger <shemminger@vyatta.com>
  10 *
  11 */
  12
  13#include <stdio.h>
  14#include <stdlib.h>
  15#include <unistd.h>
  16#include <time.h>
  17#include <sys/socket.h>
  18#include <sys/time.h>
  19#include <net/if.h>
  20#include <netinet/in.h>
  21#include <linux/if_bridge.h>
  22#include <linux/neighbour.h>
  23#include <string.h>
  24
  25#include "utils.h"
  26#include "br_common.h"
  27
  28
  29static void usage(void) __attribute__((noreturn));
  30static int prefix_banner;
  31
  32static void usage(void)
  33{
  34        fprintf(stderr, "Usage: bridge monitor [file | link | fdb | mdb | vlan | all]\n");
  35        exit(-1);
  36}
  37
  38static int accept_msg(struct rtnl_ctrl_data *ctrl,
  39                      struct nlmsghdr *n, void *arg)
  40{
  41        FILE *fp = arg;
  42
  43        if (timestamp)
  44                print_timestamp(fp);
  45
  46        switch (n->nlmsg_type) {
  47        case RTM_NEWLINK:
  48        case RTM_DELLINK:
  49                if (prefix_banner)
  50                        fprintf(fp, "[LINK]");
  51
  52                return print_linkinfo(n, arg);
  53
  54        case RTM_NEWNEIGH:
  55        case RTM_DELNEIGH:
  56                if (prefix_banner)
  57                        fprintf(fp, "[NEIGH]");
  58                return print_fdb(n, arg);
  59
  60        case RTM_NEWMDB:
  61        case RTM_DELMDB:
  62                if (prefix_banner)
  63                        fprintf(fp, "[MDB]");
  64                return print_mdb_mon(n, arg);
  65
  66        case NLMSG_TSTAMP:
  67                print_nlmsg_timestamp(fp, n);
  68                return 0;
  69
  70        case RTM_NEWVLAN:
  71        case RTM_DELVLAN:
  72                if (prefix_banner)
  73                        fprintf(fp, "[VLAN]");
  74                return print_vlan_rtm(n, arg, true, false);
  75
  76        default:
  77                return 0;
  78        }
  79}
  80
  81int do_monitor(int argc, char **argv)
  82{
  83        char *file = NULL;
  84        unsigned int groups = ~RTMGRP_TC;
  85        int llink = 0;
  86        int lneigh = 0;
  87        int lmdb = 0;
  88        int lvlan = 0;
  89
  90        rtnl_close(&rth);
  91
  92        while (argc > 0) {
  93                if (matches(*argv, "file") == 0) {
  94                        NEXT_ARG();
  95                        file = *argv;
  96                } else if (matches(*argv, "link") == 0) {
  97                        llink = 1;
  98                        groups = 0;
  99                } else if (matches(*argv, "fdb") == 0) {
 100                        lneigh = 1;
 101                        groups = 0;
 102                } else if (matches(*argv, "mdb") == 0) {
 103                        lmdb = 1;
 104                        groups = 0;
 105                } else if (matches(*argv, "vlan") == 0) {
 106                        lvlan = 1;
 107                        groups = 0;
 108                } else if (strcmp(*argv, "all") == 0) {
 109                        groups = ~RTMGRP_TC;
 110                        lvlan = 1;
 111                        prefix_banner = 1;
 112                } else if (matches(*argv, "help") == 0) {
 113                        usage();
 114                } else {
 115                        fprintf(stderr, "Argument \"%s\" is unknown, try \"bridge monitor help\".\n", *argv);
 116                        exit(-1);
 117                }
 118                argc--; argv++;
 119        }
 120
 121        if (llink)
 122                groups |= nl_mgrp(RTNLGRP_LINK);
 123
 124        if (lneigh) {
 125                groups |= nl_mgrp(RTNLGRP_NEIGH);
 126        }
 127
 128        if (lmdb) {
 129                groups |= nl_mgrp(RTNLGRP_MDB);
 130        }
 131
 132        if (file) {
 133                FILE *fp;
 134                int err;
 135
 136                fp = fopen(file, "r");
 137                if (fp == NULL) {
 138                        perror("Cannot fopen");
 139                        exit(-1);
 140                }
 141                err = rtnl_from_file(fp, accept_msg, stdout);
 142                fclose(fp);
 143                return err;
 144        }
 145
 146        if (rtnl_open(&rth, groups) < 0)
 147                exit(1);
 148
 149        if (lvlan && rtnl_add_nl_group(&rth, RTNLGRP_BRVLAN) < 0) {
 150                fprintf(stderr, "Failed to add bridge vlan group to list\n");
 151                exit(1);
 152        }
 153
 154        ll_init_map(&rth);
 155
 156        if (rtnl_listen(&rth, accept_msg, stdout) < 0)
 157                exit(2);
 158
 159        return 0;
 160}
 161