]> git.ipfire.org Git - people/ms/mstpd.git/blame - main.c
driver hooks for creating/deleting new MSTI
[people/ms/mstpd.git] / main.c
CommitLineData
1e6d2d09
VD
1/*****************************************************************************
2 Copyright (c) 2006 EMC Corporation.
3 Copyright (c) 2011 Factor-SPE
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2 of the License, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc., 59
17 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 The full GNU General Public License is included in this distribution in the
20 file called LICENSE.
21
22 Authors: Srinivas Aji <Aji_Srinivas@emc.com>
23 Authors: Vitalii Demianets <vitas@nppfactor.kiev.ua>
24
25******************************************************************************/
26
27/* #define MISC_TEST_FUNCS */
28
29#include <unistd.h>
30#include <syslog.h>
31
32#include "epoll_loop.h"
33#include "bridge_ctl.h"
34#include "netif_utils.h"
35#include "packet.h"
36#include "log.h"
37#include "mstp.h"
38#include "ctl_socket_server.h"
39
40#define APP_NAME "mstpd"
41
42static int become_daemon = 1;
43static int is_daemon = 0;
44int log_level = LOG_LEVEL_DEFAULT;
45
46#ifdef MISC_TEST_FUNCS
47static bool test_ports_trees_mesh(void);
48#endif /* MISC_TEST_FUNCS */
49
50int main(int argc, char *argv[])
51{
52 int c;
53
54 /* Sanity check */
55 {
56 bridge_identifier_t BridgeIdentifier;
57 mst_configuration_identifier_t MST_ConfigurationIdentifier;
58 TST(sizeof(BridgeIdentifier) == 8, -1);
59 TST(sizeof(BridgeIdentifier.u) == 8, -1);
60 TST(sizeof(BridgeIdentifier.s) == 8, -1);
61 TST(sizeof(BridgeIdentifier.s.priority) == 2, -1);
62 TST(sizeof(BridgeIdentifier.s.mac_address) == 6, -1);
63 TST(sizeof(MST_ConfigurationIdentifier) == 51, -1);
64 TST(sizeof(MST_ConfigurationIdentifier.a) == 51, -1);
65 TST(sizeof(MST_ConfigurationIdentifier.s) == 51, -1);
66#ifdef HMAC_MDS_TEST_FUNCTIONS
67 TST(MD5TestSuite(), -1);
68#endif /* HMAC_MDS_TEST_FUNCTIONS */
69#ifdef MISC_TEST_FUNCS
70 TST(test_ports_trees_mesh(), -1);
71#endif /* MISC_TEST_FUNCS */
72 INFO("Sanity checks succeeded");
73 }
74
75 while((c = getopt(argc, argv, "dv:")) != -1)
76 {
77 switch (c)
78 {
79 case 'd':
80 become_daemon = 0;
81 break;
82 case 'v':
83 {
84 char *end;
85 long l;
86 l = strtoul(optarg, &end, 0);
87 if(*optarg == 0 || *end != 0 || l > LOG_LEVEL_MAX)
88 {
89 ERROR("Invalid loglevel %s", optarg);
90 exit(1);
91 }
92 log_level = l;
93 break;
94 }
95 default:
96 return -1;
97 }
98 }
99
100 if(become_daemon)
101 {
102 FILE *f = fopen("/var/run/"APP_NAME".pid", "w");
103 if(!f)
104 {
105 ERROR("can't open /var/run/"APP_NAME".pid");
106 return -1;
107 }
108 openlog(APP_NAME, 0, LOG_DAEMON);
109 if(daemon(0, 0))
110 {
111 ERROR("can't daemonize");
112 return -1;
113 }
114 is_daemon = 1;
115 fprintf(f, "%d", getpid());
116 fclose(f);
117 }
118
119 TST(init_epoll() == 0, -1);
120 TST(ctl_socket_init() == 0, -1);
121 TST(packet_sock_init() == 0, -1);
122 TST(netsock_init() == 0, -1);
123 TST(init_bridge_ops() == 0, -1);
124
125 return epoll_main_loop();
126}
127
128/*********************** Logging *********************/
129
130#include <stdarg.h>
131#include <time.h>
132
133void vDprintf(int level, const char *fmt, va_list ap)
134{
135 if(level > log_level)
136 return;
137
138 if(!is_daemon)
139 {
140 char logbuf[256];
141 logbuf[255] = 0;
142 time_t clock;
143 struct tm *local_tm;
144 time(&clock);
145 local_tm = localtime(&clock);
146 int l = strftime(logbuf, sizeof(logbuf) - 1, "%F %T ", local_tm);
147 vsnprintf(logbuf + l, sizeof(logbuf) - l - 1, fmt, ap);
148 printf("%s\n", logbuf);
149 }
150 else
151 {
152 vsyslog((level <= LOG_LEVEL_INFO) ? LOG_INFO : LOG_DEBUG, fmt, ap);
153 }
154}
155
156void Dprintf(int level, const char *fmt, ...)
157{
158 va_list ap;
159 va_start(ap, fmt);
160 vDprintf(level, fmt, ap);
161 va_end(ap);
162}
163
164/*********************** Testing *********************/
165#ifdef MISC_TEST_FUNCS
166
167#include <string.h>
168#include <asm/byteorder.h>
169
170static void printout_mesh(bridge_t *br)
171{
172 tree_t *tree;
173 port_t *prt;
174 per_tree_port_t *ptp;
175
176 printf("Ports:\n");
177 list_for_each_entry(prt, &br->ports, br_list)
178 {
179 printf(" %s(%03hX)", prt->sysdeps.name, __be16_to_cpu(prt->port_number));
180 list_for_each_entry(ptp, &prt->trees, port_list)
181 printf("->%03hX", __be16_to_cpu(ptp->MSTID));
182 printf("\n");
183 }
184
185 printf("\nTrees:\n");
186 list_for_each_entry(tree, &br->trees, bridge_list)
187 {
188 printf(" %03hX", __be16_to_cpu(tree->MSTID));
189 list_for_each_entry(ptp, &tree->ports, tree_list)
190 printf("->%s", ptp->port->sysdeps.name);
191 printf("\n");
192 }
193 printf("\n");
194}
195
196static bool test_ports_trees_mesh(void)
197{
198 bridge_t *br = calloc(1, sizeof(*br));
199 if(!br)
200 return false;
201 strcpy(br->sysdeps.name, "BR_TEST");
202 br->sysdeps.macaddr[5] = 0xED;
203 if(!MSTP_IN_bridge_create(br, br->sysdeps.macaddr))
204 {
205 free(br);
206 return false;
207 }
208
209 port_t *prt[5];
210 int i;
211
212 for(i = 0; i < 5; ++i)
213 {
214 if(!(prt[i] = calloc(1, sizeof(port_t))))
215 return false;
216 prt[i]->bridge = br;
217 }
218
219 if(!MSTP_IN_create_msti(br, 0xF91))
220 {
221error_exit:
222 MSTP_IN_delete_bridge(br);
223 free(br);
224 return false;
225 }
226 if(!MSTP_IN_create_msti(br, 0xE10))
227 goto error_exit;
228
229 strcpy(prt[0]->sysdeps.name, "PRT_10C");
230 if(!MSTP_IN_port_create_and_add_tail(prt[0], 0x10C))
231 goto error_exit;
232
233 strcpy(prt[1]->sysdeps.name, "PRT_001");
234 if(!MSTP_IN_port_create_and_add_tail(prt[1], 0x001))
235 goto error_exit;
236
237 strcpy(prt[2]->sysdeps.name, "PRT_C01");
238 if(!MSTP_IN_port_create_and_add_tail(prt[2], 0xC01))
239 goto error_exit;
240
241 if(!MSTP_IN_create_msti(br, 0xE12))
242 goto error_exit;
243 if(!MSTP_IN_create_msti(br, 0x001))
244 goto error_exit;
245
246 strcpy(prt[3]->sysdeps.name, "PRT_002");
247 if(!MSTP_IN_port_create_and_add_tail(prt[3], 0x002))
248 goto error_exit;
249 strcpy(prt[4]->sysdeps.name, "PRT_003");
250 if(!MSTP_IN_port_create_and_add_tail(prt[4], 0x003))
251 goto error_exit;
252
253 if(!MSTP_IN_create_msti(br, 0x005))
254 goto error_exit;
255
256 printout_mesh(br);
257
258 list_del(&prt[1]->br_list);
259 MSTP_IN_delete_port(prt[1]);
260 if(!MSTP_IN_delete_msti(br, 0xE12))
261 goto error_exit;
262 list_del(&prt[3]->br_list);
263 MSTP_IN_delete_port(prt[3]);
264 if(!MSTP_IN_delete_msti(br, 0x005))
265 goto error_exit;
266
267 printout_mesh(br);
268
269 if(!MSTP_IN_create_msti(br, 0x102))
270 goto error_exit;
271 strcpy(prt[1]->sysdeps.name, "PRT_504");
272 if(!MSTP_IN_port_create_and_add_tail(prt[1], 0x504))
273 goto error_exit;
274
275 if(!MSTP_IN_create_msti(br, 0x105))
276 goto error_exit;
277 strcpy(prt[3]->sysdeps.name, "PRT_777");
278 if(!MSTP_IN_port_create_and_add_tail(prt[3], 0x777))
279 goto error_exit;
280
281 printout_mesh(br);
282
283 MSTP_IN_delete_bridge(br);
284 free(br);
285 return true;
286}
287#endif /* MISC_TEST_FUNCS */