]> git.ipfire.org Git - people/ms/rstp.git/blame - brmon.c
Fix monitoring code
[people/ms/rstp.git] / brmon.c
CommitLineData
ad02a0eb
SH
1/*
2 * brmon.c RTnetlink listener.
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@osdl.org>
10 *
11 * Modified by Srinivas Aji <Aji_Srinivas@emc.com> for use
12 * in RSTP daemon. - 2006-09-01
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <unistd.h>
18#include <syslog.h>
19#include <fcntl.h>
20#include <sys/socket.h>
21#include <sys/time.h>
22#include <net/if.h>
23#include <netinet/in.h>
24#include <linux/if_bridge.h>
25#include <string.h>
26
27#include "libnetlink.h"
28
29#include "bridge_ctl.h"
30
31static const char SNAPSHOT[] = "v0.1";
32
54aa4d79
SH
33static int is_up(const struct ifinfomsg *ifi)
34{
35 return (ifi->ifi_flags & IFF_UP) && (ifi->ifi_flags & IFF_RUNNING);
36}
96e20123 37
ad02a0eb
SH
38static int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
39 void *arg)
40{
41 FILE *fp = arg;
42 struct ifinfomsg *ifi = NLMSG_DATA(n);
96e20123 43 struct rtattr * tb[IFLA_MAX+1];
ad02a0eb 44 int len = n->nlmsg_len;
54aa4d79 45 int master = -1;
ad02a0eb 46 char b1[IFNAMSIZ];
ad02a0eb 47
96e20123
SH
48 if (n->nlmsg_type == NLMSG_DONE)
49 return 0;
54aa4d79 50
ad02a0eb 51 len -= NLMSG_LENGTH(sizeof(*ifi));
54aa4d79 52 if (len < 0)
96e20123 53 return -1;
54aa4d79 54
96e20123
SH
55 if (ifi->ifi_family != AF_BRIDGE && ifi->ifi_family != AF_UNSPEC)
56 return 0;
ad02a0eb 57
96e20123
SH
58 if (n->nlmsg_type != RTM_NEWLINK &&
59 n->nlmsg_type != RTM_DELLINK)
60 return 0;
ad02a0eb
SH
61
62 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
63
96e20123 64 /* Check if we got this from bonding */
54aa4d79
SH
65 if (tb[IFLA_MASTER] && ifi->ifi_family != AF_BRIDGE)
66 return 0;
67
68 /* Check if hearing our own state changes */
69 if (n->nlmsg_type == RTM_NEWLINK && tb[IFLA_PROTINFO]) {
70 uint8_t state = *(uint8_t *)RTA_DATA(tb[IFLA_PROTINFO]);
71
72 if (state != BR_STATE_DISABLED)
73 return 0;
74 }
ad02a0eb 75
ad02a0eb 76 if (tb[IFLA_IFNAME] == NULL) {
54aa4d79
SH
77 fprintf(stderr, "BUG: nil ifname\n");
78 return -1;
ad02a0eb
SH
79 }
80
81 if (n->nlmsg_type == RTM_DELLINK)
54aa4d79 82 fprintf(fp, "Deleted ");
ad02a0eb
SH
83
84 fprintf(fp, "%d: %s ", ifi->ifi_index,
54aa4d79 85 (const char*)RTA_DATA(tb[IFLA_IFNAME]));
ad02a0eb
SH
86
87 if (tb[IFLA_MASTER]) {
54aa4d79
SH
88 master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
89 fprintf(fp, "master %s ", if_indextoname(master, b1));
ad02a0eb
SH
90 }
91
ad02a0eb
SH
92 fprintf(fp, "\n");
93 fflush(fp);
54aa4d79
SH
94
95
96 bridge_notify(master, ifi->ifi_index,
97 (n->nlmsg_type == RTM_NEWLINK),
98 is_up(ifi));
99
ad02a0eb
SH
100 return 0;
101}
102
103#if 0
104static void usage(void)
105{
106 fprintf(stderr, "Usage: brmon\n");
107 exit(-1);
108}
109
110static int matches(const char *cmd, const char *pattern)
111{
112 int len = strlen(cmd);
113 if (len > strlen(pattern))
114 return -1;
115 return memcmp(pattern, cmd, len);
116}
117
96e20123
SH
118int
119main(int argc, char **argv)
ad02a0eb
SH
120{
121 struct rtnl_handle rth;
122 unsigned groups = ~RTMGRP_TC;
123 int llink = 0;
124 int laddr = 0;
125
126 while (argc > 1) {
127 if (matches(argv[1], "-Version") == 0) {
128 printf("brmon %s\n", SNAPSHOT);
129 exit(0);
130 } else if (matches(argv[1], "link") == 0) {
96e20123 131 llink=1;
ad02a0eb
SH
132 groups = 0;
133 } else if (matches(argv[1], "bridge") == 0) {
96e20123 134 laddr=1;
ad02a0eb
SH
135 groups = 0;
136 } else if (strcmp(argv[1], "all") == 0) {
137 groups = ~RTMGRP_TC;
138 } else if (matches(argv[1], "help") == 0) {
139 usage();
140 } else {
96e20123 141 fprintf(stderr, "Argument \"%s\" is unknown, try \"rtmon help\".\n", argv[1]);
ad02a0eb
SH
142 exit(-1);
143 }
96e20123 144 argc--; argv++;
ad02a0eb
SH
145 }
146
147 if (llink)
148 groups |= RTMGRP_LINK;
149
150 if (rtnl_open(&rth, groups) < 0)
151 exit(1);
152
153 if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
154 perror("Cannot send dump request");
155 exit(1);
156 }
157
158 if (rtnl_dump_filter(&rth, dump_msg, stdout, NULL, NULL) < 0) {
159 fprintf(stderr, "Dump terminated\n");
160 return 1;
161 }
162
163 if (rtnl_listen(&rth, dump_msg, stdout) < 0)
164 exit(2);
165
166 exit(0);
167}
168#endif
169
170#include "bridge_ctl.h"
171#include "epoll_loop.h"
172
173struct rtnl_handle rth;
174struct epoll_event_handler br_handler;
175
176struct rtnl_handle rth_state;
177
178void br_ev_handler(uint32_t events, struct epoll_event_handler *h)
179{
96e20123
SH
180 if (rtnl_listen(&rth, dump_msg, stdout) < 0) {
181 fprintf(stderr, "Error on bridge monitoring socket\n");
182 exit(-1);
183 }
ad02a0eb
SH
184}
185
186int init_bridge_ops(void)
187{
96e20123
SH
188 if (rtnl_open(&rth, ~RTMGRP_TC) < 0) {
189 fprintf(stderr, "Couldn't open rtnl socket for monitoring\n");
190 return -1;
191 }
54aa4d79 192
96e20123
SH
193 if (rtnl_open(&rth_state, 0) < 0) {
194 fprintf(stderr, "Couldn't open rtnl socket for setting state\n");
195 return -1;
196 }
197
198 if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
199 fprintf(stderr, "Cannot send dump request: %m\n");
200 return -1;
201 }
54aa4d79 202
96e20123
SH
203 if (rtnl_dump_filter(&rth, dump_msg, stdout, NULL, NULL) < 0) {
204 fprintf(stderr, "Dump terminated\n");
205 return -1;
206 }
207
208 if (fcntl(rth.fd, F_SETFL, O_NONBLOCK) < 0) {
209 fprintf(stderr, "Error setting O_NONBLOCK: %m\n");
210 return -1;
211 }
212
213 br_handler.fd = rth.fd;
214 br_handler.arg = NULL;
215 br_handler.handler = br_ev_handler;
54aa4d79 216
96e20123
SH
217 if (add_epoll(&br_handler) < 0)
218 return -1;
54aa4d79 219
96e20123 220 return 0;
ad02a0eb
SH
221}
222
223/* Send message. Response is through bridge_notify */
224void bridge_get_configuration(void)
225{
96e20123
SH
226 if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
227 fprintf(stderr, "Cannot send dump request: %m\n");
228 }
ad02a0eb 229}