]> git.ipfire.org Git - people/ms/rstp.git/blame - rstplib/bridge.c
remove ifdef'd code
[people/ms/rstp.git] / rstplib / bridge.c
CommitLineData
ad02a0eb
SH
1/************************************************************************
2 * RSTP library - Rapid Spanning Tree (802.1t, 802.1w)
3 * Copyright (C) 2001-2003 Optical Access
4 * Author: Alex Rozin
5 *
6 * This file is part of RSTP library.
7 *
8 * RSTP library is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by the
10 * Free Software Foundation; version 2.1
11 *
12 * RSTP library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with RSTP library; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 **********************************************************************/
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <time.h>
26#include <string.h>
27#include <sys/wait.h>
28#include <sys/time.h>
29#include <sys/types.h>
30#include <signal.h>
31#include <unistd.h>
32#include <errno.h>
33#include <readline/readline.h>
34
35#include "cli.h"
36#include "uid.h"
37#include "stp_cli.h"
38
39#include "base.h"
40#include "bitmap.h"
41#include "uid_stp.h"
42#include "stp_in.h"
43
44long my_pid = 0;
45BITMAP_T enabled_ports;
46UID_SOCKET_T uid_socket;
47
48int bridge_tx_bpdu (int port_index, unsigned char *bpdu, size_t bpdu_len)
49{
50 UID_MSG_T msg;
51
52 msg.header.sender_pid = my_pid;
53 msg.header.cmd_type = UID_BPDU;
54 msg.header.source_port = port_index;
55 msg.header.body_len = bpdu_len;
56 memcpy (&msg.body, bpdu, bpdu_len);
57 UiD_SocketSendto (&uid_socket, &msg, sizeof (UID_MSG_T));
58 return 0;
59}
60
61int bridge_start (void)
62{
63 BITMAP_T ports;
64 UID_MSG_T msg;
65 UID_STP_CFG_T uid_cfg;
66 register int iii;
67
68 //rl_callback_handler_install (get_prompt (), rl_read_cli);
69
70 if (0 != UiD_SocketInit (&uid_socket, UID_REPL_PATH, UID_BIND_AS_CLIENT)) {
71 printf ("FATAL: can't init the connection\n");
72 exit (-3);
73 }
74
75 /* send HANDSHAKE */
76 msg.header.sender_pid = my_pid;
77 msg.header.cmd_type = UID_CNTRL;
78 msg.body.cntrl.cmd = UID_BRIDGE_HANDSHAKE;
79 msg.body.cntrl.param1 = NUMBER_OF_PORTS;
80 iii = UiD_SocketSendto (&uid_socket, &msg, sizeof (UID_MSG_T));
81 if (iii < 0) {
82 printf ("can't send HANDSHAKE: %s\n", strerror(errno));
83 printf ("May be 'mngr' is not alive ? :(\n");
84 return (-4);
85 }
86
87 stp_cli_init ();
88
89 STP_IN_init (NUMBER_OF_PORTS);
90 BitmapClear(&enabled_ports);
91 BitmapClear(&ports);
92 for (iii = 1; iii <= NUMBER_OF_PORTS; iii++) {
93 BitmapSetBit(&ports, iii - 1);
94 }
95
96 uid_cfg.field_mask = BR_CFG_STATE;
97 uid_cfg.stp_enabled = STP_ENABLED;
98 snprintf (uid_cfg.vlan_name, NAME_LEN - 1, "B%ld", (long) my_pid);
99 iii = STP_IN_stpm_set_cfg (0, &ports, &uid_cfg);
100 if (STP_OK != iii) {
101 printf ("FATAL: can't enable:%s\n",
102 STP_IN_get_error_explanation (iii));
103 return (-1);
104 }
105 return 0;
106}
107
108void bridge_shutdown (void)
109{
110 UID_MSG_T msg;
111 int rc;
112
113 /* send SHUTDOWN */
114 msg.header.sender_pid = my_pid;
115 msg.header.cmd_type = UID_CNTRL;
116 msg.body.cntrl.cmd = UID_BRIDGE_SHUTDOWN;
117 UiD_SocketSendto (&uid_socket, &msg, sizeof (UID_MSG_T));
118
119 rc = STP_IN_stpm_delete (0);
120 if (STP_OK != rc) {
121 printf ("FATAL: can't delete:%s\n",
122 STP_IN_get_error_explanation (rc));
123 exit (1);
124 }
125}
126
127char *get_prompt (void)
128{
129 static char prompt[MAX_CLI_PROMT];
130 snprintf (prompt, MAX_CLI_PROMT - 1, "%s B%ld > ", UT_sprint_time_stamp(), my_pid);
131 return prompt;
132}
133
134int bridge_control (int port_index,
135 UID_CNTRL_BODY_T* cntrl)
136{
137 switch (cntrl->cmd) {
138 case UID_PORT_CONNECT:
139 printf ("connected port p%02d\n", port_index);
140 BitmapSetBit(&enabled_ports, port_index - 1);
141 STP_IN_enable_port (port_index, True);
142 break;
143 case UID_PORT_DISCONNECT:
144 printf ("disconnected port p%02d\n", port_index);
145 BitmapClearBit(&enabled_ports, port_index - 1);
146 STP_IN_enable_port (port_index, False);
147 break;
148 case UID_BRIDGE_SHUTDOWN:
149 printf ("shutdown from manager :(\n");
150 return 1;
151 default:
152 printf ("Unknown control command <%d> for port %d\n",
153 cntrl->cmd, port_index);
154 }
155 return 0;
156}
157
158int bridge_rx_bpdu (UID_MSG_T* msg, size_t msgsize)
159{
160 register int port_index;
161
162 if (I_am_a_stupid_hub) { // flooding
163 msg->header.sender_pid = my_pid;
164 for (port_index = 1; port_index <= NUMBER_OF_PORTS; port_index++) {
165 if (BitmapGetBit (&enabled_ports, (port_index - 1)) &&
166 msg->header.destination_port != port_index) {
167 msg->header.source_port = port_index;
168 UiD_SocketSendto (&uid_socket, msg, msgsize);
169 }
170 }
171 } else {
172 STP_IN_rx_bpdu (0, msg->header.destination_port,
173 (BPDU_T*) (msg->body.bpdu + sizeof (MAC_HEADER_T)),
174 msg->header.body_len - sizeof (MAC_HEADER_T));
175 }
176 return 0;
177}
178
179char read_uid (UID_SOCKET_T* uid_sock)
180{
181 char buff[MAX_UID_MSG_SIZE];
182 UID_MSG_T* msg;
183 size_t msgsize;
184 int rc;
185
186 msgsize = UiD_SocketRecvfrom (uid_sock, buff, MAX_UID_MSG_SIZE, 0);
187 if (msgsize <= 0) {
188 printf ("Something wrong in UIF ?\n");
189 return 0;
190 }
191
192 msg = (UID_MSG_T*) buff;
193 switch (msg->header.cmd_type) {
194 case UID_CNTRL:
195 rc = bridge_control (msg->header.destination_port,
196 &msg->body.cntrl);
197 break;
198 case UID_BPDU:
199 rc = bridge_rx_bpdu (msg, msgsize);
200 break;
201 default:
202 printf ("Unknown message type %d\n", (int) msg->header.cmd_type);
203 rc = 0;
204 }
205
206 return rc;
207}
208
209char shutdown_flag = 0;
210
211int main_loop (void)
212{
213 fd_set readfds;
214 struct timeval tv;
215 struct timeval now, earliest;
216 int rc, numfds, sock, kkk;
217
218
219 sock = GET_FILE_DESCRIPTOR(&uid_socket);
220
221 gettimeofday (&earliest, NULL);
222 earliest.tv_sec++;
223
224 do {
225 numfds = -1;
226 FD_ZERO(&readfds);
227
228 kkk = 0; /* stdin for commands */
229 FD_SET(kkk, &readfds);
230 if (kkk > numfds) numfds = kkk;
231
232 FD_SET(sock, &readfds);
233 if (sock > numfds) numfds = sock;
234
235 if (numfds < 0)
236 numfds = 0;
237 else
238 numfds++;
239
240 gettimeofday (&now, 0);
241 tv.tv_usec = 0;
242 tv.tv_sec = 0;
243
244 if (now.tv_sec < earliest.tv_sec) { /* we must wait more than 1 sec. */
245 tv.tv_sec = 1;
246 tv.tv_usec = 0;
247 } else if (now.tv_sec == earliest.tv_sec) {
248 if (now.tv_usec < earliest.tv_usec) {
249 if (earliest.tv_usec < now.tv_usec)
250 tv.tv_usec = 0;
251 else
252 tv.tv_usec = earliest.tv_usec - now.tv_usec;
253 }
254 }
255
256 //printf ("wait %ld-%ld\n", (long) tv.tv_sec, (long) tv.tv_usec);
257 rc = select (numfds, &readfds, NULL, NULL, &tv);
258 if (rc < 0) { // Error
259 if (EINTR == errno) continue; // don't break
260 printf ("FATAL_MODE:select failed: %s\n", strerror(errno));
261 return -2;
262 }
263
264 if (! rc) { // Timeout expired
265 STP_IN_one_second ();
266 gettimeofday (&earliest, NULL);
267 //printf ("tick %ld-%ld\n", (long) earliest.tv_sec - 1005042800L, (long) earliest.tv_usec);
268
269 earliest.tv_sec++;
270 continue;
271 }
272
273 if (FD_ISSET(0, &readfds)) {
274 rl_callback_read_char ();
275 }
276
277 if (FD_ISSET(sock, &readfds)) {
278 shutdown_flag |= read_uid (&uid_socket);
279 }
280
281 } while(! shutdown_flag);
282 return 0;
283}
284
285int main (int argc, char** argv)
286{
287 rl_init ();
288
289 my_pid = getpid();
290 printf ("my pid: %ld\n", my_pid);
291
292 if (0 == bridge_start ()) {
293 main_loop ();
294 }
295
296 bridge_shutdown ();
297
298 rl_shutdown ();
299
300 return 0;
301}
302
303char* sprint_time_stump (void)
304{
305 return UT_sprint_time_stamp();
306}
307