1 /*****************************************************************************
2 Copyright (c) 2006 EMC Corporation.
3 Copyright (c) 2011 Factor-SPE
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)
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
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.
19 The full GNU General Public License is included in this distribution in the
22 Authors: Srinivas Aji <Aji_Srinivas@emc.com>
23 Authors: Vitalii Demianets <vitas@nppfactor.kiev.ua>
25 ******************************************************************************/
27 /* #define MISC_TEST_FUNCS */
32 #include "epoll_loop.h"
33 #include "bridge_ctl.h"
34 #include "netif_utils.h"
38 #include "ctl_socket_server.h"
40 #define APP_NAME "mstpd"
42 static int become_daemon
= 1;
43 static int is_daemon
= 0;
44 int log_level
= LOG_LEVEL_DEFAULT
;
46 #ifdef MISC_TEST_FUNCS
47 static bool test_ports_trees_mesh(void);
48 #endif /* MISC_TEST_FUNCS */
50 int main(int argc
, char *argv
[])
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");
75 while((c
= getopt(argc
, argv
, "dv:")) != -1)
86 l
= strtoul(optarg
, &end
, 0);
87 if(*optarg
== 0 || *end
!= 0 || l
> LOG_LEVEL_MAX
)
89 ERROR("Invalid loglevel %s", optarg
);
102 FILE *f
= fopen("/var/run/"APP_NAME
".pid", "w");
105 ERROR("can't open /var/run/"APP_NAME
".pid");
108 openlog(APP_NAME
, 0, LOG_DAEMON
);
111 ERROR("can't daemonize");
115 fprintf(f
, "%d", getpid());
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);
125 return epoll_main_loop();
128 /*********************** Logging *********************/
133 void vDprintf(int level
, const char *fmt
, va_list ap
)
135 if(level
> log_level
)
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
);
152 vsyslog((level
<= LOG_LEVEL_INFO
) ? LOG_INFO
: LOG_DEBUG
, fmt
, ap
);
156 void Dprintf(int level
, const char *fmt
, ...)
160 vDprintf(level
, fmt
, ap
);
164 /*********************** Testing *********************/
165 #ifdef MISC_TEST_FUNCS
168 #include <asm/byteorder.h>
170 static void printout_mesh(bridge_t
*br
)
174 per_tree_port_t
*ptp
;
177 list_for_each_entry(prt
, &br
->ports
, br_list
)
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
));
185 printf("\nTrees:\n");
186 list_for_each_entry(tree
, &br
->trees
, bridge_list
)
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
);
196 static bool test_ports_trees_mesh(void)
198 bridge_t
*br
= calloc(1, sizeof(*br
));
201 strcpy(br
->sysdeps
.name
, "BR_TEST");
202 br
->sysdeps
.macaddr
[5] = 0xED;
203 if(!MSTP_IN_bridge_create(br
, br
->sysdeps
.macaddr
))
212 for(i
= 0; i
< 5; ++i
)
214 if(!(prt
[i
] = calloc(1, sizeof(port_t
))))
219 if(!MSTP_IN_create_msti(br
, 0xF91))
222 MSTP_IN_delete_bridge(br
);
226 if(!MSTP_IN_create_msti(br
, 0xE10))
229 strcpy(prt
[0]->sysdeps
.name
, "PRT_10C");
230 if(!MSTP_IN_port_create_and_add_tail(prt
[0], 0x10C))
233 strcpy(prt
[1]->sysdeps
.name
, "PRT_001");
234 if(!MSTP_IN_port_create_and_add_tail(prt
[1], 0x001))
237 strcpy(prt
[2]->sysdeps
.name
, "PRT_C01");
238 if(!MSTP_IN_port_create_and_add_tail(prt
[2], 0xC01))
241 if(!MSTP_IN_create_msti(br
, 0xE12))
243 if(!MSTP_IN_create_msti(br
, 0x001))
246 strcpy(prt
[3]->sysdeps
.name
, "PRT_002");
247 if(!MSTP_IN_port_create_and_add_tail(prt
[3], 0x002))
249 strcpy(prt
[4]->sysdeps
.name
, "PRT_003");
250 if(!MSTP_IN_port_create_and_add_tail(prt
[4], 0x003))
253 if(!MSTP_IN_create_msti(br
, 0x005))
258 list_del(&prt
[1]->br_list
);
259 MSTP_IN_delete_port(prt
[1]);
260 if(!MSTP_IN_delete_msti(br
, 0xE12))
262 list_del(&prt
[3]->br_list
);
263 MSTP_IN_delete_port(prt
[3]);
264 if(!MSTP_IN_delete_msti(br
, 0x005))
269 if(!MSTP_IN_create_msti(br
, 0x102))
271 strcpy(prt
[1]->sysdeps
.name
, "PRT_504");
272 if(!MSTP_IN_port_create_and_add_tail(prt
[1], 0x504))
275 if(!MSTP_IN_create_msti(br
, 0x105))
277 strcpy(prt
[3]->sysdeps
.name
, "PRT_777");
278 if(!MSTP_IN_port_create_and_add_tail(prt
[3], 0x777))
283 MSTP_IN_delete_bridge(br
);
287 #endif /* MISC_TEST_FUNCS */