]> git.ipfire.org Git - people/ms/rstp.git/blame - brmon.c
remove dead 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
96e20123 33
ad02a0eb
SH
34/* RFC 2863 operational status */
35enum {
36 IF_OPER_UNKNOWN,
37 IF_OPER_NOTPRESENT,
38 IF_OPER_DOWN,
39 IF_OPER_LOWERLAYERDOWN,
40 IF_OPER_TESTING,
41 IF_OPER_DORMANT,
42 IF_OPER_UP,
43};
44
45/* link modes */
46enum {
47 IF_LINK_MODE_DEFAULT,
48 IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */
49};
50
51static const char *port_states[] = {
52 [BR_STATE_DISABLED] = "disabled",
53 [BR_STATE_LISTENING] = "listening",
54 [BR_STATE_LEARNING] = "learning",
55 [BR_STATE_FORWARDING] = "forwarding",
56 [BR_STATE_BLOCKING] = "blocking",
57};
58
96e20123 59
ad02a0eb
SH
60static int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
61 void *arg)
62{
63 FILE *fp = arg;
64 struct ifinfomsg *ifi = NLMSG_DATA(n);
96e20123 65 struct rtattr * tb[IFLA_MAX+1];
ad02a0eb
SH
66 int len = n->nlmsg_len;
67 char b1[IFNAMSIZ];
68 int af_family = ifi->ifi_family;
69
96e20123
SH
70 if (n->nlmsg_type == NLMSG_DONE)
71 return 0;
72
ad02a0eb
SH
73 len -= NLMSG_LENGTH(sizeof(*ifi));
74 if (len < 0) {
96e20123
SH
75 return -1;
76 }
77
96e20123
SH
78 if (ifi->ifi_family != AF_BRIDGE && ifi->ifi_family != AF_UNSPEC)
79 return 0;
ad02a0eb 80
96e20123
SH
81 if (n->nlmsg_type != RTM_NEWLINK &&
82 n->nlmsg_type != RTM_DELLINK)
83 return 0;
ad02a0eb
SH
84
85 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
86
96e20123
SH
87 /* Check if we got this from bonding */
88 if (tb[IFLA_MASTER] && af_family != AF_BRIDGE)
89 return 0;
ad02a0eb 90
96e20123
SH
91 /* Check for BPDU */
92 if (tb[IFLA_PRIORITY] && af_family == AF_BRIDGE) {
93 bridge_bpdu_rcv(ifi->ifi_index,
94 RTA_DATA(tb[IFLA_PRIORITY]),
95 RTA_PAYLOAD(tb[IFLA_PRIORITY]));
96 return 0;
97 }
ad02a0eb
SH
98
99 if (tb[IFLA_IFNAME] == NULL) {
100 fprintf(stderr, "BUG: nil ifname\n");
101 return -1;
102 }
103
104 if (n->nlmsg_type == RTM_DELLINK)
105 fprintf(fp, "Deleted ");
106
107 fprintf(fp, "%d: %s ", ifi->ifi_index,
96e20123
SH
108 tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
109
ad02a0eb
SH
110
111 if (tb[IFLA_OPERSTATE]) {
96e20123 112 int state = *(int*)RTA_DATA(tb[IFLA_OPERSTATE]);
ad02a0eb 113 switch (state) {
96e20123
SH
114 case IF_OPER_UNKNOWN:
115 fprintf(fp, "Unknown "); break;
ad02a0eb 116 case IF_OPER_NOTPRESENT:
96e20123 117 fprintf(fp, "Not Present "); break;
ad02a0eb 118 case IF_OPER_DOWN:
96e20123 119 fprintf(fp, "Down "); break;
ad02a0eb 120 case IF_OPER_LOWERLAYERDOWN:
96e20123 121 fprintf(fp, "Lowerlayerdown "); break;
ad02a0eb 122 case IF_OPER_TESTING:
96e20123 123 fprintf(fp, "Testing "); break;
ad02a0eb 124 case IF_OPER_DORMANT:
96e20123 125 fprintf(fp, "Dormant "); break;
ad02a0eb 126 case IF_OPER_UP:
96e20123 127 fprintf(fp, "Up "); break;
ad02a0eb
SH
128 default:
129 fprintf(fp, "State(%d) ", state);
130 }
131 }
96e20123 132
ad02a0eb 133 if (tb[IFLA_MTU])
96e20123 134 fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
ad02a0eb
SH
135
136 if (tb[IFLA_MASTER]) {
96e20123
SH
137 fprintf(fp, "master %s ",
138 if_indextoname(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
ad02a0eb
SH
139 }
140
141 if (tb[IFLA_PROTINFO]) {
96e20123 142 uint8_t state = *(uint8_t *)RTA_DATA(tb[IFLA_PROTINFO]);
ad02a0eb
SH
143 if (state <= BR_STATE_BLOCKING)
144 fprintf(fp, "state %s", port_states[state]);
145 else
146 fprintf(fp, "state (%d)", state);
147 }
148
96e20123 149
ad02a0eb
SH
150 fprintf(fp, "\n");
151 fflush(fp);
96e20123
SH
152 {
153 int newlink = (n->nlmsg_type == RTM_NEWLINK);
154 int up = 0;
155 if (newlink && tb[IFLA_OPERSTATE]) {
156 int state = *(int*)RTA_DATA(tb[IFLA_OPERSTATE]);
157 up = (state == IF_OPER_UP) || (state == IF_OPER_UNKNOWN);
158 }
159
160 bridge_notify((tb[IFLA_MASTER]?*(int*)RTA_DATA(tb[IFLA_MASTER]):-1),
161 ifi->ifi_index, newlink, up);
162 }
ad02a0eb
SH
163 return 0;
164}
165
166#if 0
167static void usage(void)
168{
169 fprintf(stderr, "Usage: brmon\n");
170 exit(-1);
171}
172
173static int matches(const char *cmd, const char *pattern)
174{
175 int len = strlen(cmd);
176 if (len > strlen(pattern))
177 return -1;
178 return memcmp(pattern, cmd, len);
179}
180
96e20123
SH
181int
182main(int argc, char **argv)
ad02a0eb
SH
183{
184 struct rtnl_handle rth;
185 unsigned groups = ~RTMGRP_TC;
186 int llink = 0;
187 int laddr = 0;
188
189 while (argc > 1) {
190 if (matches(argv[1], "-Version") == 0) {
191 printf("brmon %s\n", SNAPSHOT);
192 exit(0);
193 } else if (matches(argv[1], "link") == 0) {
96e20123 194 llink=1;
ad02a0eb
SH
195 groups = 0;
196 } else if (matches(argv[1], "bridge") == 0) {
96e20123 197 laddr=1;
ad02a0eb
SH
198 groups = 0;
199 } else if (strcmp(argv[1], "all") == 0) {
200 groups = ~RTMGRP_TC;
201 } else if (matches(argv[1], "help") == 0) {
202 usage();
203 } else {
96e20123 204 fprintf(stderr, "Argument \"%s\" is unknown, try \"rtmon help\".\n", argv[1]);
ad02a0eb
SH
205 exit(-1);
206 }
96e20123 207 argc--; argv++;
ad02a0eb
SH
208 }
209
210 if (llink)
211 groups |= RTMGRP_LINK;
212
213 if (rtnl_open(&rth, groups) < 0)
214 exit(1);
215
216 if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
217 perror("Cannot send dump request");
218 exit(1);
219 }
220
221 if (rtnl_dump_filter(&rth, dump_msg, stdout, NULL, NULL) < 0) {
222 fprintf(stderr, "Dump terminated\n");
223 return 1;
224 }
225
226 if (rtnl_listen(&rth, dump_msg, stdout) < 0)
227 exit(2);
228
229 exit(0);
230}
231#endif
232
233#include "bridge_ctl.h"
234#include "epoll_loop.h"
235
236struct rtnl_handle rth;
237struct epoll_event_handler br_handler;
238
239struct rtnl_handle rth_state;
240
241void br_ev_handler(uint32_t events, struct epoll_event_handler *h)
242{
96e20123
SH
243 if (rtnl_listen(&rth, dump_msg, stdout) < 0) {
244 fprintf(stderr, "Error on bridge monitoring socket\n");
245 exit(-1);
246 }
ad02a0eb
SH
247}
248
249int init_bridge_ops(void)
250{
96e20123
SH
251 if (rtnl_open(&rth, ~RTMGRP_TC) < 0) {
252 fprintf(stderr, "Couldn't open rtnl socket for monitoring\n");
253 return -1;
254 }
255
256 if (rtnl_open(&rth_state, 0) < 0) {
257 fprintf(stderr, "Couldn't open rtnl socket for setting state\n");
258 return -1;
259 }
260
261 if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
262 fprintf(stderr, "Cannot send dump request: %m\n");
263 return -1;
264 }
265
266 if (rtnl_dump_filter(&rth, dump_msg, stdout, NULL, NULL) < 0) {
267 fprintf(stderr, "Dump terminated\n");
268 return -1;
269 }
270
271 if (fcntl(rth.fd, F_SETFL, O_NONBLOCK) < 0) {
272 fprintf(stderr, "Error setting O_NONBLOCK: %m\n");
273 return -1;
274 }
275
276 br_handler.fd = rth.fd;
277 br_handler.arg = NULL;
278 br_handler.handler = br_ev_handler;
279
280 if (add_epoll(&br_handler) < 0)
281 return -1;
282
283 return 0;
ad02a0eb
SH
284}
285
286/* Send message. Response is through bridge_notify */
287void bridge_get_configuration(void)
288{
96e20123
SH
289 if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
290 fprintf(stderr, "Cannot send dump request: %m\n");
291 }
ad02a0eb 292}