Import 2.3.47pre1
[davej-history.git] / net / bridge / br.c
blob682012e91d2c68079267d13898e79d9538493927
1 /*
2 * Linux NET3 Bridge Support
4 * Originally by John Hayes (Network Plumbing).
5 * Minor hacks to get it to run with 1.3.x by Alan Cox <Alan.Cox@linux.org>
6 * More hacks to be able to switch protocols on and off by Christoph Lameter
7 * <clameter@debian.org>
8 * Software and more Documentation for the bridge is available from ftp.debian.org
9 * in the bridgex package
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
16 * Fixes:
17 * Yury Shevchuk : Bridge with non bridging ports
18 * Jean-Rene Peulve: jr.peulve@aix.pacwan.net Jan/Feb 98
19 * support Linux 2.0
20 * Handle Receive config bpdu
21 * kick mark_bh to send Spanning Tree pdus
22 * bridgeId comparison using htonl()
23 * make STP interoperable with other vendors
24 * wrong test in root_selection()
25 * add more STP debug info
26 * some performance improvments
27 * do not clear bridgeId.mac while setting priority
28 * do not reset port priority when starting bridge
29 * make port priority from user value and port number
30 * maintains user port state out of device state
31 * broacast/multicast storm limitation
32 * forwarding statistics
33 * stop br_tick when bridge is turn off
34 * add local MACs in avl_tree to forward up stack
35 * fake receive on right port for IP/ARP
36 * ages tree even if packet does not cross bridge
37 * add BRCMD_DISPLAY_FDB (ioctl for now)
39 * Alan Cox: Merged Jean-Rene's stuff, reformatted stuff a bit
40 * so blame me first if its broken ;)
42 * Robert Pintarelli: fixed bug in bpdu time values
44 * Matthew Grant: start ports disabled.
45 * auto-promiscuous mode on port enable/disable
46 * fleshed out interface event handling, interfaces
47 * now register with bridge on module load as well as ifup
48 * port control ioctls with ifindex support
49 * brg0 logical ethernet interface
50 * reworked brcfg to take interface arguments
51 * added support for changing the hardware address
52 * generally made bridge a lot more usable.
54 * Todo:
55 * Use a netlink notifier so a daemon can maintain the bridge
56 * port group (could we also do multiple groups ????).
57 * A nice /proc file interface.
58 * Put the path costs in the port info and devices.
59 * Put the bridge port number in the device structure for speed.
60 * Bridge SNMP stats.
64 #include <linux/module.h>
65 #include <linux/errno.h>
66 #include <linux/types.h>
67 #include <linux/socket.h>
68 #include <linux/in.h>
70 #include <linux/kernel.h>
71 #include <linux/sched.h>
72 #include <linux/timer.h>
73 #include <linux/malloc.h>
74 #include <linux/string.h>
75 #include <linux/net.h>
76 #include <linux/inet.h>
77 #include <linux/netdevice.h>
78 #include <linux/inetdevice.h>
79 #include <linux/etherdevice.h>
80 #include <linux/skbuff.h>
81 #include <linux/if_arp.h>
82 #include <linux/ip.h>
83 #include <linux/version.h>
84 #include <linux/init.h>
85 #include <asm/uaccess.h>
86 #include <asm/system.h>
87 #include <linux/rtnetlink.h>
88 #include <net/br.h>
89 #include <linux/proc_fs.h>
90 #include <linux/delay.h>
91 #include <net/pkt_sched.h>
93 #ifndef min
94 #define min(a, b) (((a) <= (b)) ? (a) : (b))
95 #endif
97 static void transmit_config(int port_no);
98 static int root_bridge(void);
99 static int supersedes_port_info(int port_no, Config_bpdu *config);
100 static void record_config_information(int port_no, Config_bpdu *config);
101 static void record_config_timeout_values(Config_bpdu *config);
102 static void config_bpdu_generation(void);
103 static int designated_port(int port_no);
104 static void reply(int port_no);
105 static void transmit_tcn(void);
106 static void configuration_update(void);
107 static void root_selection(void);
108 static void designated_port_selection(void);
109 static void become_designated_port(int port_no);
110 static void port_state_selection(void);
111 static void make_forwarding(int port_no);
112 static void topology_change_detection(void);
113 static void topology_change_acknowledged(void);
114 static void acknowledge_topology_change(int port_no);
115 static void make_blocking(int port_no);
116 static void set_port_state(int port_no, int state);
117 static void received_config_bpdu(int port_no, Config_bpdu *config);
118 static void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn);
119 static void hello_timer_expiry(void);
120 static void message_age_timer_expiry(int port_no);
121 static void forward_delay_timer_expiry(int port_no);
122 static int designated_for_some_port(void);
123 static void tcn_timer_expiry(void);
124 static void topology_change_timer_expiry(void);
125 static void hold_timer_expiry(int port_no);
126 static void br_init_port(int port_no);
127 static void enable_port(int port_no);
128 static void disable_port(int port_no);
129 static void set_bridge_priority(bridge_id_t *new_bridge_id);
130 static void set_port_priority(int port_no);
131 static void set_path_cost(int port_no, unsigned short path_cost);
132 static void start_hello_timer(void);
133 static void stop_hello_timer(void);
134 static int hello_timer_expired(void);
135 static void start_tcn_timer(void);
136 static void stop_tcn_timer(void);
137 static int tcn_timer_expired(void);
138 static void start_topology_change_timer(void);
139 static void stop_topology_change_timer(void);
140 static int topology_change_timer_expired(void);
141 static void start_message_age_timer(int port_no, unsigned short message_age);
142 static void stop_message_age_timer(int port_no);
143 static int message_age_timer_expired(int port_no);
144 static void start_forward_delay_timer(int port_no);
145 static void stop_forward_delay_timer(int port_no);
146 static int forward_delay_timer_expired(int port_no);
147 static void start_hold_timer(int port_no);
148 static void stop_hold_timer(int port_no);
149 static int hold_timer_expired(int port_no);
150 static int br_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
151 static void br_tick(unsigned long arg);
152 static int br_forward(struct sk_buff *skb, int port); /* 3.7 */
153 static int br_port_cost(struct net_device *dev); /* 4.10.2 */
154 static void br_bpdu(struct sk_buff *skb, int port); /* consumes skb */
155 static int br_cmp(unsigned int *a, unsigned int *b);
156 static int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu);
157 static int send_config_bpdu(int port_no, Config_bpdu *config_bpdu);
158 static int find_port(struct net_device *dev);
159 static void br_add_local_mac(unsigned char *mac);
160 static int br_flood(struct sk_buff *skb, int port);
161 static int br_drop(struct sk_buff *skb);
162 static int br_learn(struct sk_buff *skb, int port); /* 3.8 */
163 static int br_protocol_ok(unsigned short protocol);
164 static int br_find_port(int ifindex);
165 static void br_get_ifnames(void);
166 static int brg_rx(struct sk_buff *skb, int port);
168 static unsigned char bridge_ula[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
169 static Bridge_data bridge_info; /* (4.5.3) */
170 Port_data port_info[All_ports]; /* (4.5.5) */
172 /* MAG: Maximum port registered - used to speed up flooding and to make
173 * have a large ports array more efficient
175 static int max_port_used = 0;
177 /* JRP: fdb cache 1/port save kmalloc/kfree on every frame */
178 struct fdb *newfdb[All_ports];
179 int allocated_fdb_cnt = 0;
181 /* broacast/multicast storm limitation */
182 int max_mcast_per_period = MAX_MCAST_PER_PERIOD;
183 int mcast_hold_time = MCAST_HOLD_TIME;
185 /* JRP: next two bpdu are copied to skbuff so we need only 1 of each */
186 static Config_bpdu config_bpdu;
187 static Tcn_bpdu tcn_bpdu;
188 static unsigned char port_priority[All_ports];
189 static unsigned char user_port_state[All_ports];
191 static Timer hello_timer; /* (4.5.4.1) */
192 static Timer tcn_timer; /* (4.5.4.2) */
193 static Timer topology_change_timer; /* (4.5.4.3) */
194 static Timer message_age_timer[All_ports]; /* (4.5.6.1) */
195 static Timer forward_delay_timer[All_ports]; /* (4.5.6.2) */
196 static Timer hold_timer[All_ports]; /* (4.5.6.3) */
198 /* entries timeout after this many seconds */
199 unsigned int fdb_aging_time = FDB_TIMEOUT;
201 struct br_stat br_stats;
202 #define br_stats_cnt br_stats.packet_cnts
204 static struct timer_list tl; /* for 1 second timer... */
207 * the following structure is required so that we receive
208 * event notifications when network devices are enabled and
209 * disabled (ifconfig up and down).
211 static struct notifier_block br_dev_notifier={
212 br_device_event,
213 NULL,
219 * the following data is for the bridge network device
221 struct brg_if {
222 struct net_device dev;
223 char name[IFNAMSIZ];
225 static struct brg_if brg_if;
228 * Here to save linkage? problems
231 static inline int find_port(struct net_device *dev)
233 int i;
235 for (i = One; i <= No_of_ports; i++)
236 if (port_info[i].dev == dev)
237 return(i);
238 return(0);
242 * Implementation of Protocol specific bridging
244 * The protocols to be bridged or not to be bridged are stored in a hashed array. This is the old type
245 * of unlinked hash array where one simply takes the next cell if the one the hash function points to
246 * is occupied.
249 #define BR_PROTOCOL_HASH(x) (x % BR_MAX_PROTOCOLS)
251 /* Checks if that protocol type is to be bridged */
253 static int inline br_protocol_ok(unsigned short protocol)
255 unsigned x;
257 /* See if protocol statistics are to be kept */
258 if (br_stats.flags & BR_PROT_STATS)
260 for(x=0;x<BR_MAX_PROT_STATS && br_stats.prot_id[x]!=protocol && br_stats.prot_id[x];x++);
261 if (x<BR_MAX_PROT_STATS)
263 br_stats.prot_id[x]=protocol;br_stats.prot_counter[x]++;
267 for (x=BR_PROTOCOL_HASH(protocol); br_stats.protocols[x]!=0;)
269 if (br_stats.protocols[x]==protocol)
270 return !br_stats.policy;
271 x++;
272 if (x==BR_MAX_PROTOCOLS)
273 x=0;
275 return br_stats.policy;
278 /* Add a protocol to be handled opposite to the standard policy of the bridge */
280 static int br_add_exempt_protocol(unsigned short p)
282 unsigned x;
283 if (p == 0) return -EINVAL;
284 if (br_stats.exempt_protocols > BR_MAX_PROTOCOLS-2) return -EXFULL;
285 for (x=BR_PROTOCOL_HASH(p);br_stats.protocols[x]!=0;) {
286 if (br_stats.protocols[x]==p) return 0; /* Attempt to add the protocol a second time */
287 x++;
288 if (x==BR_MAX_PROTOCOLS) x=0;
290 br_stats.protocols[x]=p;
291 br_stats.exempt_protocols++;
292 return 0;
295 /* Valid Policies are 0=No Protocols bridged 1=Bridge all protocols */
296 static int br_set_policy(int policy)
298 if (policy>1) return -EINVAL;
299 br_stats.policy=policy;
300 /* Policy change means initializing the exempt table */
301 memset(br_stats.protocols,0,sizeof(br_stats.protocols));
302 br_stats.exempt_protocols = 0;
303 return 0;
307 /** Elements of Procedure (4.6) **/
310 * this section of code was graciously borrowed from the IEEE 802.1d
311 * specification section 4.9.1 starting on pg 69. It has been
312 * modified somewhat to fit within our framework and structure. It
313 * implements the spanning tree algorithm that is the heart of the
314 * 802.1d bridging protocol.
317 static void transmit_config(int port_no) /* (4.6.1) */
319 if (hold_timer[port_no].active) { /* (4.6.1.3.1) */
320 port_info[port_no].config_pending = TRUE; /* (4.6.1.3.1) */
321 } else { /* (4.6.1.3.2) */
322 config_bpdu.type = BPDU_TYPE_CONFIG;
323 config_bpdu.root_id = bridge_info.designated_root;
324 /* (4.6.1.3.2(1)) */
325 config_bpdu.root_path_cost = bridge_info.root_path_cost;
326 /* (4.6.1.3.2(2)) */
327 config_bpdu.bridge_id = bridge_info.bridge_id;
328 /* (4.6.1.3.2(3)) */
329 config_bpdu.port_id = port_info[port_no].port_id;
331 * (4.6.1.3.2(4))
333 if (root_bridge()) {
334 config_bpdu.message_age = Zero; /* (4.6.1.3.2(5)) */
335 } else {
336 config_bpdu.message_age
337 = (message_age_timer[bridge_info.root_port].value
338 + Message_age_increment) << 8; /* (4.6.1.3.2(6)) */
341 config_bpdu.max_age = bridge_info.max_age << 8;/* (4.6.1.3.2(7)) */
342 config_bpdu.hello_time = bridge_info.hello_time << 8;
343 config_bpdu.forward_delay = bridge_info.forward_delay << 8;
344 config_bpdu.top_change_ack =
345 port_info[port_no].top_change_ack;
346 /* (4.6.1.3.2(8)) */
347 port_info[port_no].top_change_ack = 0;
349 config_bpdu.top_change =
350 bridge_info.top_change; /* (4.6.1.3.2(9)) */
352 send_config_bpdu(port_no, &config_bpdu);
353 port_info[port_no].config_pending = FALSE; /* (4.6.1.3.2(10)) */
354 start_hold_timer(port_no); /* (4.6.1.3.2(11)) */
358 static int root_bridge(void)
360 return (br_cmp(bridge_info.designated_root.BRIDGE_ID,
361 bridge_info.bridge_id.BRIDGE_ID)?FALSE:TRUE);
364 static int supersedes_port_info(int port_no, Config_bpdu *config) /* (4.6.2.2) */
366 return (
367 (br_cmp(config->root_id.BRIDGE_ID,
368 port_info[port_no].designated_root.BRIDGE_ID) < 0) /* (4.6.2.2.1) */
370 ((br_cmp(config->root_id.BRIDGE_ID,
371 port_info[port_no].designated_root.BRIDGE_ID) == 0
374 ((config->root_path_cost
375 < port_info[port_no].designated_cost /* (4.6.2.2.2) */
378 ((config->root_path_cost
379 == port_info[port_no].designated_cost
382 ((br_cmp(config->bridge_id.BRIDGE_ID,
383 port_info[port_no].designated_bridge.BRIDGE_ID) < 0 /* (4.6.2.2.3) */
386 ((br_cmp(config->bridge_id.BRIDGE_ID,
387 port_info[port_no].designated_bridge.BRIDGE_ID) == 0
388 ) /* (4.6.2.2.4) */
390 ((br_cmp(config->bridge_id.BRIDGE_ID,
391 bridge_info.bridge_id.BRIDGE_ID) != 0
392 ) /* (4.6.2.2.4(1)) */
394 (config->port_id <=
395 port_info[port_no].designated_port
396 ) /* (4.6.2.2.4(2)) */
397 ))))))
401 static void record_config_information(int port_no, Config_bpdu *config) /* (4.6.2) */
403 port_info[port_no].designated_root = config->root_id; /* (4.6.2.3.1) */
404 port_info[port_no].designated_cost = config->root_path_cost;
405 port_info[port_no].designated_bridge = config->bridge_id;
406 port_info[port_no].designated_port = config->port_id;
407 start_message_age_timer(port_no, config->message_age); /* (4.6.2.3.2) */
410 static void record_config_timeout_values(Config_bpdu *config) /* (4.6.3) */
412 bridge_info.max_age = config->max_age >> 8; /* (4.6.3.3) */
413 bridge_info.hello_time = config->hello_time >> 8;
414 bridge_info.forward_delay = config->forward_delay >> 8;
415 bridge_info.top_change = config->top_change >> 8;
418 static void config_bpdu_generation(void)
419 { /* (4.6.4) */
420 int port_no;
421 for (port_no = One; port_no <= No_of_ports; port_no++) { /* (4.6.4.3) */
422 if (designated_port(port_no) /* (4.6.4.3) */
424 (port_info[port_no].state != Disabled)
426 transmit_config(port_no); /* (4.6.4.3) */
427 } /* (4.6.1.2) */
431 static int designated_port(int port_no)
433 return ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
434 bridge_info.bridge_id.BRIDGE_ID) == 0
437 (port_info[port_no].designated_port
438 == port_info[port_no].port_id
443 static void reply(int port_no) /* (4.6.5) */
445 transmit_config(port_no); /* (4.6.5.3) */
448 static void transmit_tcn(void)
449 { /* (4.6.6) */
450 int port_no;
452 port_no = bridge_info.root_port;
453 tcn_bpdu.type = BPDU_TYPE_TOPO_CHANGE;
454 send_tcn_bpdu(port_no, &tcn_bpdu); /* (4.6.6.3) */
457 static void configuration_update(void) /* (4.6.7) */
459 root_selection(); /* (4.6.7.3.1) */
460 /* (4.6.8.2) */
461 designated_port_selection(); /* (4.6.7.3.2) */
462 /* (4.6.9.2) */
465 static void root_selection(void)
466 { /* (4.6.8) */
467 int root_port;
468 int port_no;
469 root_port = No_port;
470 for (port_no = One; port_no <= No_of_ports; port_no++) { /* (4.6.8.3.1) */
471 if (((!designated_port(port_no))
473 (port_info[port_no].state != Disabled)
475 (br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
476 bridge_info.bridge_id.BRIDGE_ID) < 0)
479 ((root_port == No_port)
481 (br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
482 port_info[root_port].designated_root.BRIDGE_ID) < 0
485 ((br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
486 port_info[root_port].designated_root.BRIDGE_ID) == 0
489 (((port_info[port_no].designated_cost
490 + port_info[port_no].path_cost
493 (port_info[root_port].designated_cost
494 + port_info[root_port].path_cost
495 ) /* (4.6.8.3.1(2)) */
498 (((port_info[port_no].designated_cost
499 + port_info[port_no].path_cost
502 (port_info[root_port].designated_cost
503 + port_info[root_port].path_cost
507 ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
508 port_info[root_port].designated_bridge.BRIDGE_ID) < 0
509 ) /* (4.6.8.3.1(3)) */
511 ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
512 port_info[root_port].designated_bridge.BRIDGE_ID) == 0
515 ((port_info[port_no].designated_port
516 < port_info[root_port].designated_port
517 ) /* (4.6.8.3.1(4)) */
519 ((port_info[port_no].designated_port
520 /* JRP: was missing an "=" ! */ == port_info[root_port].designated_port
523 (port_info[port_no].port_id
524 < port_info[root_port].port_id
525 ) /* (4.6.8.3.1(5)) */
526 ))))))))) {
527 root_port = port_no;
530 bridge_info.root_port = root_port; /* (4.6.8.3.1) */
532 if (root_port == No_port) { /* (4.6.8.3.2) */
533 #ifdef DEBUG_STP
534 if (br_stats.flags & BR_DEBUG)
535 printk(KERN_DEBUG "root_selection: becomes root\n");
536 #endif
537 bridge_info.designated_root = bridge_info.bridge_id;
538 /* (4.6.8.3.2(1)) */
539 bridge_info.root_path_cost = Zero;/* (4.6.8.3.2(2)) */
540 } else { /* (4.6.8.3.3) */
541 bridge_info.designated_root = port_info[root_port].designated_root;
542 /* (4.6.8.3.3(1)) */
543 bridge_info.root_path_cost = (port_info[root_port].designated_cost
544 + port_info[root_port].path_cost
545 ); /* (4.6.8.3.3(2)) */
549 static void designated_port_selection(void)
550 { /* (4.6.9) */
551 int port_no;
553 for (port_no = One; port_no <= No_of_ports; port_no++) { /* (4.6.9.3) */
554 if(port_info[port_no].state == Disabled)
555 continue;
556 if (designated_port(port_no) /* (4.6.9.3.1) */
559 br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
560 bridge_info.designated_root.BRIDGE_ID) != 0
563 (bridge_info.root_path_cost
564 < port_info[port_no].designated_cost
565 ) /* (4.6.9.3.3) */
567 ((bridge_info.root_path_cost
568 == port_info[port_no].designated_cost
571 ((br_cmp(bridge_info.bridge_id.BRIDGE_ID,
572 port_info[port_no].designated_bridge.BRIDGE_ID) < 0
573 ) /* (4.6.9.3.4) */
575 ((br_cmp(bridge_info.bridge_id.BRIDGE_ID,
576 port_info[port_no].designated_bridge.BRIDGE_ID) == 0
579 (port_info[port_no].port_id
580 <= port_info[port_no].designated_port
581 ) /* (4.6.9.3.5) */
582 )))) {
583 become_designated_port(port_no); /* (4.6.10.3.2.2) */
588 static void become_designated_port(int port_no)
589 { /* (4.6.10) */
591 /* (4.6.10.3.1) */
592 port_info[port_no].designated_root = bridge_info.designated_root;
593 /* (4.6.10.3.2) */
594 port_info[port_no].designated_cost = bridge_info.root_path_cost;
595 /* (4.6.10.3.3) */
596 port_info[port_no].designated_bridge = bridge_info.bridge_id;
597 /* (4.6.10.3.4) */
598 port_info[port_no].designated_port = port_info[port_no].port_id;
601 static void port_state_selection(void)
602 { /* (4.6.11) */
603 int port_no;
604 char *state_str;
605 for (port_no = One; port_no <= No_of_ports; port_no++) {
607 if(port_info[port_no].state == Disabled)
608 continue;
609 if (port_no == bridge_info.root_port) { /* (4.6.11.3.1) */
610 state_str = "root";
611 port_info[port_no].config_pending = FALSE; /* (4.6.11.3.1(1)) */
612 port_info[port_no].top_change_ack = 0;
613 make_forwarding(port_no); /* (4.6.11.3.1(2)) */
614 } else if (designated_port(port_no)) { /* (4.6.11.3.2) */
615 state_str = "designated";
616 stop_message_age_timer(port_no); /* (4.6.11.3.2(1)) */
617 make_forwarding(port_no); /* (4.6.11.3.2(2)) */
618 } else { /* (4.6.11.3.3) */
619 state_str = "blocking";
620 port_info[port_no].config_pending = FALSE; /* (4.6.11.3.3(1)) */
621 port_info[port_no].top_change_ack = 0;
622 make_blocking(port_no); /* (4.6.11.3.3(2)) */
624 #ifdef DEBUG_STP
625 if (br_stats.flags & BR_DEBUG)
626 printk(KERN_DEBUG "port_state_selection: becomes %s port %d\n",
627 state_str, port_no);
628 #endif
634 static void make_forwarding(int port_no)
635 { /* (4.6.12) */
636 if (port_info[port_no].state == Blocking) { /* (4.6.12.3) */
637 set_port_state(port_no, Listening); /* (4.6.12.3.1) */
638 start_forward_delay_timer(port_no); /* (4.6.12.3.2) */
642 static void topology_change_detection(void)
643 { /* (4.6.14) */
644 #ifdef DEBUG_STP
645 if ((br_stats.flags & BR_DEBUG)
646 && (bridge_info.top_change_detected == 0))
647 printk(KERN_DEBUG "topology_change_detected\n");
648 #endif
649 if (root_bridge()) { /* (4.6.14.3.1) */
650 bridge_info.top_change = 1;
651 start_topology_change_timer(); /* (4.6.14.3.1(2)) */
652 } else if (!(bridge_info.top_change_detected)) {
653 transmit_tcn(); /* (4.6.14.3.2(1)) */
654 start_tcn_timer(); /* (4.6.14.3.2(2)) */
656 bridge_info.top_change_detected = 1; /* (4.6.14.3.3) */
659 static void topology_change_acknowledged(void)
660 { /* (4.6.15) */
661 #ifdef DEBUG_STP
662 if (br_stats.flags & BR_DEBUG)
663 printk(KERN_DEBUG "topology_change_acked\n");
664 #endif
665 bridge_info.top_change_detected = 0; /* (4.6.15.3.1) */
666 stop_tcn_timer(); /* (4.6.15.3.2) */
669 static void acknowledge_topology_change(int port_no)
670 { /* (4.6.16) */
671 port_info[port_no].top_change_ack = 1;
672 transmit_config(port_no); /* (4.6.16.3.2) */
675 static void make_blocking(int port_no) /* (4.6.13) */
678 if ((port_info[port_no].state != Disabled)
680 (port_info[port_no].state != Blocking)
681 /* (4.6.13.3) */
683 if ((port_info[port_no].state == Forwarding)
685 (port_info[port_no].state == Learning)
687 topology_change_detection(); /* (4.6.13.3.1) */
688 /* (4.6.14.2.3) */
690 set_port_state(port_no, Blocking);/* (4.6.13.3.2) */
691 stop_forward_delay_timer(port_no);/* (4.6.13.3.3) */
695 static void set_port_state(int port_no, int state)
697 port_info[port_no].state = state;
700 static void received_config_bpdu(int port_no, Config_bpdu *config) /* (4.7.1) */
702 int root;
704 root = root_bridge();
705 if (port_info[port_no].state != Disabled) {
707 #ifdef DEBUG_STP
708 if (br_stats.flags & BR_DEBUG)
709 printk(KERN_DEBUG "received_config_bpdu: port %d\n",
710 port_no);
711 #endif
712 if (supersedes_port_info(port_no, config)) { /* (4.7.1.1) *//* (4.
713 * 6.2.2) */
714 record_config_information(port_no, config); /* (4.7.1.1.1) */
715 /* (4.6.2.2) */
716 configuration_update(); /* (4.7.1.1.2) */
717 /* (4.6.7.2.1) */
718 port_state_selection(); /* (4.7.1.1.3) */
719 /* (4.6.11.2.1) */
720 if ((!root_bridge()) && root) { /* (4.7.1.1.4) */
721 stop_hello_timer();
722 if (bridge_info.top_change_detected) { /* (4.7.1.1.5 */
723 stop_topology_change_timer();
724 transmit_tcn(); /* (4.6.6.1) */
725 start_tcn_timer();
728 if (port_no == bridge_info.root_port) {
729 record_config_timeout_values(config); /* (4.7.1.1.6) */
730 /* (4.6.3.2) */
731 config_bpdu_generation(); /* (4.6.4.2.1) */
732 if (config->top_change_ack) { /* (4.7.1.1.7) */
733 topology_change_acknowledged(); /* (4.6.15.2) */
736 } else if (designated_port(port_no)) { /* (4.7.1.2) */
737 reply(port_no); /* (4.7.1.2.1) */
738 /* (4.6.5.2) */
743 static void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn) /* (4.7.2) */
745 if (port_info[port_no].state != Disabled) {
746 #ifdef DEBUG_STP
747 if (br_stats.flags & BR_DEBUG)
748 printk(KERN_DEBUG "received_tcn_bpdu: port %d\n",
749 port_no);
750 #endif
751 if (designated_port(port_no)) {
752 topology_change_detection(); /* (4.7.2.1) */
753 /* (4.6.14.2.1) */
754 acknowledge_topology_change(port_no); /* (4.7.2.2) */
755 } /* (4.6.16.2) */
759 static void hello_timer_expiry(void)
760 { /* (4.7.3) */
761 config_bpdu_generation(); /* (4.6.4.2.2) */
762 start_hello_timer();
765 static void message_age_timer_expiry(int port_no) /* (4.7.4) */
767 int root;
768 root = root_bridge();
770 #ifdef DEBUG_STP
771 if (br_stats.flags & BR_DEBUG)
772 printk(KERN_DEBUG "message_age_timer_expiry: port %d\n",
773 port_no);
774 #endif
775 become_designated_port(port_no); /* (4.7.4.1) */
776 /* (4.6.10.2.1) */
777 configuration_update(); /* (4.7.4.2) */
778 /* (4.6.7.2.2) */
779 port_state_selection(); /* (4.7.4.3) */
780 /* (4.6.11.2.2) */
781 if ((root_bridge()) && (!root)) { /* (4.7.4.4) */
783 bridge_info.max_age = bridge_info.bridge_max_age; /* (4.7.4.4.1) */
784 bridge_info.hello_time = bridge_info.bridge_hello_time;
785 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
786 topology_change_detection(); /* (4.7.4.4.2) */
787 /* (4.6.14.2.4) */
788 stop_tcn_timer(); /* (4.7.4.4.3) */
789 config_bpdu_generation(); /* (4.7.4.4.4) */
790 /* (4.6.4.4.3) */
791 start_hello_timer();
795 static void forward_delay_timer_expiry(int port_no) /* (4.7.5) */
797 if (port_info[port_no].state == Listening)
798 { /* (4.7.5.1) */
799 set_port_state(port_no, Learning); /* (4.7.5.1.1) */
800 start_forward_delay_timer(port_no); /* (4.7.5.1.2) */
802 else if (port_info[port_no].state == Learning)
804 /* (4.7.5.2) */
805 set_port_state(port_no, Forwarding); /* (4.7.5.2.1) */
806 if (designated_for_some_port())
807 { /* (4.7.5.2.2) */
808 topology_change_detection(); /* (4.6.14.2.2) */
814 static int designated_for_some_port(void)
816 int port_no;
818 for (port_no = One; port_no <= No_of_ports; port_no++)
820 if(port_info[port_no].state == Disabled)
821 continue;
822 if ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
823 bridge_info.bridge_id.BRIDGE_ID) == 0))
825 return (TRUE);
828 return (FALSE);
831 static void tcn_timer_expiry(void)
832 { /* (4.7.6) */
833 transmit_tcn(); /* (4.7.6.1) */
834 start_tcn_timer(); /* (4.7.6.2) */
837 static void topology_change_timer_expiry(void)
838 { /* (4.7.7) */
839 bridge_info.top_change_detected = 0; /* (4.7.7.1) */
840 bridge_info.top_change = 0;
841 /* (4.7.7.2) */
844 static void hold_timer_expiry(int port_no) /* (4.7.8) */
846 if (port_info[port_no].config_pending)
848 transmit_config(port_no); /* (4.7.8.1) */
849 } /* (4.6.1.2.3) */
852 /* Vova Oksman: Write the buffer (contents of the Bridge table) */
853 /* to a PROCfs file */
854 static int br_tree_get_info(char *buffer, char **start, off_t offset, int length)
856 int size;
857 int len=0;
858 off_t pos=0;
859 char* pbuffer;
861 if(0==offset)
863 /* first time write the header */
864 size = sprintf(buffer,"%s","MAC address Device Flags Age (sec.)\n");
865 len=size;
868 pbuffer=&buffer[len];
869 sprintf_avl(&pbuffer,NULL,&pos,&len,offset,length);
871 *start = buffer+len-(pos-offset); /* Start of wanted data */
872 len = pos-offset; /* Start slop */
873 if (len>length)
874 len = length; /* Ending slop */
876 return len;
879 void __init br_init(void)
880 { /* (4.8.1) */
881 int port_no;
883 printk(KERN_INFO "NET4: Ethernet Bridge 006 for NET4.0\n");
885 /* Set up brg device information */
886 bridge_info.instance = 0;
887 brg_init();
889 max_port_used = 0;
892 * Form initial topology change time.
893 * The topology change timer is only used if this is the root bridge.
896 bridge_info.topology_change_time = BRIDGE_MAX_AGE + BRIDGE_FORWARD_DELAY; /* (4.5.3.13) */
898 bridge_info.designated_root = bridge_info.bridge_id; /* (4.8.1.1) */
899 bridge_info.root_path_cost = Zero;
900 bridge_info.root_port = No_port;
901 #ifdef DEBUG_STP
902 printk(KERN_INFO "br_init: becomes root\n");
903 #endif
905 bridge_info.bridge_max_age = BRIDGE_MAX_AGE;
906 bridge_info.bridge_hello_time = BRIDGE_HELLO_TIME;
907 bridge_info.bridge_forward_delay = BRIDGE_FORWARD_DELAY;
908 bridge_info.hold_time = HOLD_TIME;
910 bridge_info.max_age = bridge_info.bridge_max_age; /* (4.8.1.2) */
911 bridge_info.hello_time = bridge_info.bridge_hello_time;
912 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
914 bridge_info.top_change_detected = 0;
915 bridge_info.top_change = 0;
916 stop_tcn_timer();
917 stop_topology_change_timer();
918 memset(newfdb, 0, sizeof(newfdb));
919 for (port_no = One; port_no <= No_of_ports; port_no++) { /* (4.8.1.4) */
920 /* initial state = Disable */
921 user_port_state[port_no] = Disabled;
922 port_priority[port_no] = 128;
923 br_init_port(port_no);
924 disable_port(port_no);
926 #if 0 /* JRP: We are not UP ! Wait for the start command */
927 port_state_selection(); /* (4.8.1.5) */
928 config_bpdu_generation(); /* (4.8.1.6) */
929 /* initialize system timer */
930 tl.expires = jiffies+HZ; /* 1 second */
931 tl.function = br_tick;
932 add_timer(&tl);
933 #endif
935 register_netdevice_notifier(&br_dev_notifier);
936 br_stats.flags = 0; /*BR_UP | BR_DEBUG*/; /* enable bridge */
937 br_stats.policy = BR_ACCEPT; /* Enable bridge to accpet all protocols */
938 br_stats.exempt_protocols = 0;
939 /*start_hello_timer();*/
940 /* Vova Oksman: register the function for the PROCfs "bridge" file */
941 proc_net_create("bridge", 0, br_tree_get_info);
944 static inline unsigned short make_port_id(int port_no)
946 return (port_priority[port_no] << 8) | port_no;
949 static void br_init_port(int port_no)
951 port_info[port_no].port_id = make_port_id(port_no);
952 become_designated_port(port_no); /* (4.8.1.4.1) */
953 set_port_state(port_no, Blocking); /* (4.8.1.4.2) */
954 port_info[port_no].top_change_ack = 0;
955 port_info[port_no].config_pending = FALSE;/* (4.8.1.4.4) */
956 stop_message_age_timer(port_no); /* (4.8.1.4.5) */
957 stop_forward_delay_timer(port_no); /* (4.8.1.4.6) */
958 stop_hold_timer(port_no); /* (4.8.1.4.7) */
961 static void enable_port(int port_no) /* (4.8.2) */
963 br_init_port(port_no);
964 port_state_selection(); /* (4.8.2.7) */
965 } /* */
967 static void disable_port(int port_no) /* (4.8.3) */
969 int root;
971 root = root_bridge();
972 become_designated_port(port_no); /* (4.8.3.1) */
973 set_port_state(port_no, Disabled); /* (4.8.3.2) */
974 port_info[port_no].top_change_ack = 0;
975 port_info[port_no].config_pending = FALSE;/* (4.8.3.4) */
976 stop_message_age_timer(port_no); /* (4.8.3.5) */
977 stop_forward_delay_timer(port_no); /* (4.8.3.6) */
978 configuration_update();
979 port_state_selection(); /* (4.8.3.7) */
980 if ((root_bridge()) && (!root)) { /* (4.8.3.8) */
981 bridge_info.max_age = bridge_info.bridge_max_age; /* (4.8.3.8.1) */
982 bridge_info.hello_time = bridge_info.bridge_hello_time;
983 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
984 topology_change_detection(); /* (4.8.3.8.2) */
985 stop_tcn_timer(); /* (4.8.3.8.3) */
986 config_bpdu_generation(); /* (4.8.3.8.4) */
987 start_hello_timer();
992 static void set_bridge_priority(bridge_id_t *new_bridge_id)
993 /* (4.8.4) */
996 int root;
997 int port_no;
998 root = root_bridge();
999 for (port_no = One; port_no <= No_of_ports; port_no++) { /* (4.8.4.2) */
1000 if(port_info[port_no].state == Disabled)
1001 continue;
1002 if (designated_port(port_no)) {
1003 port_info[port_no].designated_bridge = *new_bridge_id;
1007 bridge_info.bridge_id = *new_bridge_id; /* (4.8.4.3) */
1008 configuration_update(); /* (4.8.4.4) */
1009 port_state_selection(); /* (4.8.4.5) */
1010 if ((root_bridge()) && (!root)) { /* (4.8.4.6) */
1011 bridge_info.max_age = bridge_info.bridge_max_age; /* (4.8.4.6.1) */
1012 bridge_info.hello_time = bridge_info.bridge_hello_time;
1013 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
1014 topology_change_detection(); /* (4.8.4.6.2) */
1015 stop_tcn_timer(); /* (4.8.4.6.3) */
1016 config_bpdu_generation(), /* (4.8.4.6.4) */
1017 start_hello_timer();
1021 static void set_port_priority(int port_no)
1022 /* (4.8.5) */
1023 {int new_port_id = make_port_id(port_no);
1025 if (designated_port(port_no)) { /* (4.8.5.2) */
1026 port_info[port_no].designated_port = new_port_id;
1028 port_info[port_no].port_id = new_port_id; /* (4.8.5.3) */
1029 if ((br_cmp(bridge_info.bridge_id.BRIDGE_ID,
1030 port_info[port_no].designated_bridge.BRIDGE_ID) == 0
1033 (port_info[port_no].port_id
1034 < port_info[port_no].designated_port
1039 become_designated_port(port_no); /* (4.8.5.4.1) */
1040 port_state_selection(); /* (4.8.5.4.2) */
1044 static void set_path_cost(int port_no, unsigned short path_cost)
1045 /* (4.8.6) */
1047 port_info[port_no].path_cost = path_cost; /* (4.8.6.1) */
1048 configuration_update(); /* (4.8.6.2) */
1049 port_state_selection(); /* (4.8.6.3) */
1052 static void br_tick(unsigned long arg)
1054 int port_no;
1056 if(!(br_stats.flags & BR_UP))
1057 return; /* JRP: we have been shot down */
1059 if (hello_timer_expired())
1060 hello_timer_expiry();
1062 if (tcn_timer_expired())
1063 tcn_timer_expiry();
1065 if (topology_change_timer_expired())
1066 topology_change_timer_expiry();
1068 for (port_no = One; port_no <= No_of_ports; port_no++)
1070 if(port_info[port_no].state == Disabled)
1071 continue;
1073 if (forward_delay_timer_expired(port_no))
1074 forward_delay_timer_expiry(port_no);
1076 if (message_age_timer_expired(port_no))
1077 message_age_timer_expiry(port_no);
1079 if (hold_timer_expired(port_no))
1080 hold_timer_expiry(port_no);
1082 /* call me again sometime... */
1083 tl.expires = jiffies+HZ; /* 1 second */
1084 tl.function = br_tick;
1085 add_timer(&tl);
1088 static void start_hello_timer(void)
1090 hello_timer.value = 0;
1091 hello_timer.active = TRUE;
1094 static void stop_hello_timer(void)
1096 hello_timer.active = FALSE;
1099 static int hello_timer_expired(void)
1101 if (hello_timer.active && (++hello_timer.value >= bridge_info.hello_time))
1103 hello_timer.active = FALSE;
1104 return (TRUE);
1106 return (FALSE);
1109 static void start_tcn_timer(void)
1111 tcn_timer.value = 0;
1112 tcn_timer.active = TRUE;
1115 static void stop_tcn_timer(void)
1117 tcn_timer.active = FALSE;
1120 static int tcn_timer_expired(void)
1122 if (tcn_timer.active && (++tcn_timer.value >= bridge_info.bridge_hello_time))
1124 tcn_timer.active = FALSE;
1125 return (TRUE);
1127 return (FALSE);
1131 static void start_topology_change_timer(void)
1133 topology_change_timer.value = 0;
1134 topology_change_timer.active = TRUE;
1137 static void stop_topology_change_timer(void)
1139 topology_change_timer.active = FALSE;
1142 static int topology_change_timer_expired(void)
1144 if (topology_change_timer.active
1145 && (++topology_change_timer.value >= bridge_info.topology_change_time ))
1147 topology_change_timer.active = FALSE;
1148 return (TRUE);
1150 return (FALSE);
1153 static void start_message_age_timer(int port_no, unsigned short message_age)
1155 message_age_timer[port_no].value = message_age;
1156 message_age_timer[port_no].active = TRUE;
1159 static void stop_message_age_timer(int port_no)
1161 message_age_timer[port_no].active = FALSE;
1164 static int message_age_timer_expired(int port_no)
1166 if (message_age_timer[port_no].active && (++message_age_timer[port_no].value >= bridge_info.max_age))
1168 message_age_timer[port_no].active = FALSE;
1169 return (TRUE);
1171 return (FALSE);
1174 static void start_forward_delay_timer(int port_no)
1176 forward_delay_timer[port_no].value = 0;
1177 forward_delay_timer[port_no].active = TRUE;
1180 static void stop_forward_delay_timer(int port_no)
1182 forward_delay_timer[port_no].active = FALSE;
1185 static int forward_delay_timer_expired(int port_no)
1187 if (forward_delay_timer[port_no].active && (++forward_delay_timer[port_no].value >= bridge_info.forward_delay))
1189 forward_delay_timer[port_no].active = FALSE;
1190 return (TRUE);
1192 return (FALSE);
1195 static void start_hold_timer(int port_no)
1197 hold_timer[port_no].value = 0;
1198 hold_timer[port_no].active = TRUE;
1201 static void stop_hold_timer(int port_no)
1203 hold_timer[port_no].active = FALSE;
1206 static int hold_timer_expired(int port_no)
1208 if (hold_timer[port_no].active &&
1209 (++hold_timer[port_no].value >= bridge_info.hold_time))
1211 hold_timer[port_no].active = FALSE;
1212 return (TRUE);
1214 return (FALSE);
1218 static struct sk_buff *alloc_bridge_skb(int port_no, int pdu_size, char *pdu_name)
1220 struct sk_buff *skb;
1221 struct net_device *dev = port_info[port_no].dev;
1222 struct ethhdr *eth;
1223 int size = dev->hard_header_len + BRIDGE_LLC1_HS + pdu_size;
1224 unsigned char *llc_buffer;
1225 int pad_size = 60 - size;
1227 size = 60; /* minimum Ethernet frame - CRC */
1229 if (port_info[port_no].state == Disabled)
1231 printk(KERN_DEBUG "send_%s_bpdu: port %i not valid\n", pdu_name, port_no);
1232 return NULL;
1235 skb = alloc_skb(size, GFP_ATOMIC);
1236 if (skb == NULL)
1238 printk(KERN_DEBUG "send_%s_bpdu: no skb available\n", pdu_name);
1239 return NULL;
1241 skb->dev = dev;
1242 skb->mac.raw = skb->nh.raw = skb_put(skb,size);
1243 memset(skb->nh.raw + 60 - pad_size, 0xa5, pad_size);
1244 eth = skb->mac.ethernet;
1245 memcpy(eth->h_dest, bridge_ula, ETH_ALEN);
1246 memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
1248 if (br_stats.flags & BR_DEBUG)
1249 printk(KERN_DEBUG "send_%s_bpdu: port %i src %02x:%02x:%02x:%02x:%02x:%02x\n",
1250 pdu_name,
1251 port_no,
1252 eth->h_source[0],
1253 eth->h_source[1],
1254 eth->h_source[2],
1255 eth->h_source[3],
1256 eth->h_source[4],
1257 eth->h_source[5]);
1258 #if 0
1259 /* 8038 is used in older DEC spanning tree protocol which uses a
1260 * different pdu layout as well
1262 eth->h_proto = htons(0x8038);
1263 #endif
1264 eth->h_proto = htons(pdu_size + BRIDGE_LLC1_HS);
1266 skb->nh.raw += skb->dev->hard_header_len;
1267 llc_buffer = skb->nh.raw;
1268 *llc_buffer++ = BRIDGE_LLC1_DSAP;
1269 *llc_buffer++ = BRIDGE_LLC1_SSAP;
1270 *llc_buffer++ = BRIDGE_LLC1_CTRL;
1271 /* set nh.raw to where the bpdu starts */
1272 skb->nh.raw += BRIDGE_LLC1_HS;
1274 /* mark that we've been here... */
1275 skb->pkt_bridged = IS_BRIDGED;
1276 return skb;
1279 static int send_config_bpdu(int port_no, Config_bpdu *config_bpdu)
1281 struct sk_buff *skb;
1284 * Keep silent when disabled or when STP disabled
1287 if(!(br_stats.flags & BR_UP) || (br_stats.flags & BR_STP_DISABLED))
1288 return -1;
1291 * Create and send the message
1294 skb = alloc_bridge_skb(port_no, BRIDGE_BPDU_8021_CONFIG_SIZE,
1295 "config");
1296 if (skb == NULL)
1297 return(-1);
1299 /* copy fields before "flags" */
1300 memcpy(skb->nh.raw, config_bpdu, BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
1302 /* build the "flags" field */
1303 *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) = 0;
1304 if (config_bpdu->top_change_ack)
1305 *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x80;
1306 if (config_bpdu->top_change)
1307 *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x01;
1309 config_bpdu_hton(config_bpdu);
1310 /* copy the rest */
1311 memcpy(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET+1,
1312 (char*)&(config_bpdu->root_id),
1313 BRIDGE_BPDU_8021_CONFIG_SIZE-1-BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
1315 dev_queue_xmit(skb);
1316 return(0);
1319 static int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu)
1321 struct sk_buff *skb;
1324 * Keep silent when disabled or when STP disabled
1327 if(!(br_stats.flags & BR_UP) || (br_stats.flags & BR_STP_DISABLED))
1328 return -1;
1331 skb = alloc_bridge_skb(port_no, sizeof(Tcn_bpdu), "tcn");
1332 if (skb == NULL)
1333 return(-1);
1335 memcpy(skb->nh.raw, bpdu, sizeof(Tcn_bpdu));
1337 dev_queue_xmit(skb);
1338 return(0);
1341 static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
1343 struct net_device *dev = ptr;
1344 int i;
1346 /* check for loopback devices */
1347 if (dev->flags & IFF_LOOPBACK)
1348 return(NOTIFY_DONE);
1350 if (dev == &brg_if.dev)
1351 return(NOTIFY_DONE); /* Don't attach the brg device to a port! */
1353 switch (event)
1355 case NETDEV_DOWN:
1356 if (br_stats.flags & BR_DEBUG)
1357 printk(KERN_DEBUG "br_device_event: NETDEV_DOWN...\n");
1358 /* find our device and mark it down */
1359 for (i = One; i <= No_of_ports; i++)
1361 if (port_info[i].dev == dev)
1363 disable_port(i);
1364 return NOTIFY_DONE;
1365 break;
1368 break;
1369 case NETDEV_UP:
1370 if (br_stats.flags & BR_DEBUG)
1371 printk(KERN_DEBUG "br_device_event: NETDEV_UP...\n");
1372 /* Only handle ethernet ports */
1373 if(dev->type!=ARPHRD_ETHER && dev->type!=ARPHRD_LOOPBACK)
1374 return NOTIFY_DONE;
1375 /* look up an unused device and enable it */
1376 for (i = One; i <= No_of_ports; i++)
1378 if (port_info[i].dev == NULL || port_info[i].dev == dev)
1380 port_info[i].dev = dev;
1381 port_info[i].port_id = i;
1382 dev->bridge_port_id = i;
1383 if( i > max_port_used )
1384 max_port_used = i;
1385 /* set bridge addr from 1st device addr */
1386 if (((htonl(bridge_info.bridge_id.BRIDGE_ID[0])&0xffff) == 0) &&
1387 (bridge_info.bridge_id.BRIDGE_ID[1] == 0))
1389 memcpy(bridge_info.bridge_id.BRIDGE_ID_ULA, dev->dev_addr, 6);
1390 if(bridge_info.bridge_id.BRIDGE_PRIORITY == 0)
1391 bridge_info.bridge_id.BRIDGE_PRIORITY = htons(32768);
1392 set_bridge_priority(&bridge_info.bridge_id);
1394 /* Add local MAC address */
1395 br_add_local_mac(dev->dev_addr);
1396 /* Save MAC address for latter change address events */
1397 memcpy(port_info[i].ifmac.BRIDGE_ID_ULA, dev->dev_addr, 6);
1398 if((br_stats.flags & BR_UP) &&
1399 (user_port_state[i] != Disabled))
1401 /* don't start if user said so */
1402 enable_port(i);
1403 set_path_cost(i, br_port_cost(dev));
1404 set_port_priority(i);
1405 if (br_stats.flags & BR_STP_DISABLED)
1406 port_info[i].state = Forwarding;
1407 else
1408 make_forwarding(i);
1410 return NOTIFY_DONE;
1411 break;
1414 break;
1415 case NETDEV_REGISTER:
1416 if (br_stats.flags & BR_DEBUG)
1417 printk(KERN_DEBUG "br_device_event: NETDEV_REGISTER...\n");
1418 /* printk(KERN_ERR "br_device_event: NETDEV_REGISTER...\n"); */
1419 /* printk(KERN_ERR "br_device_event: dev->type: 0x%X\n", dev->type); */
1420 /* Only handle ethernet ports */
1421 if(dev->type!=ARPHRD_ETHER && dev->type!=ARPHRD_LOOPBACK)
1422 return NOTIFY_DONE;
1423 /* printk(KERN_ERR "br_device_event: Looking for port...\n"); */
1424 for (i = One; i <= No_of_ports; i++)
1426 if (port_info[i].dev == NULL || port_info[i].dev == dev)
1428 /* printk(KERN_ERR "br_device_event: Found port %d\n", i); */
1429 port_info[i].dev = dev;
1430 port_info[i].port_id = i;
1431 dev->bridge_port_id = i;
1432 if( i > max_port_used )
1433 max_port_used = i;
1434 /* handle local MAC address minuplations */
1435 br_add_local_mac(dev->dev_addr);
1436 memcpy(port_info[i].ifmac.BRIDGE_ID_ULA, dev->dev_addr, 6);
1437 return NOTIFY_DONE;
1438 break;
1441 break;
1442 case NETDEV_UNREGISTER:
1443 if (br_stats.flags & BR_DEBUG)
1444 printk(KERN_DEBUG "br_device_event: NETDEV_UNREGISTER...\n");
1445 i = find_port(dev);
1446 if (i > 0) {
1447 br_avl_delete_by_port(i);
1448 memset(port_info[i].ifmac.BRIDGE_ID_ULA, 0, 6);
1449 port_info[i].dev = NULL;
1451 break;
1452 case NETDEV_CHANGEADDR:
1453 if (br_stats.flags & BR_DEBUG)
1454 printk(KERN_DEBUG "br_device_event: NETDEV_CHANGEADDR...\n");
1455 i = find_port(dev);
1456 if (i <= 0)
1457 break;
1458 if (memcmp(port_info[i].ifmac.BRIDGE_ID_ULA, dev->dev_addr, 6) != 0)
1459 break; /* Don't worry about a change of hardware broadcast address! */
1460 if (netif_running(dev)) {
1461 printk(KERN_CRIT "br_device_event: NETDEV_CHANGEADDR on busy device %s - FIX DRIVER!\n",
1462 dev->name);
1463 /* return NOTIFY_BAD; It SHOULD be this, but I want to be friendly... */
1464 return NOTIFY_DONE;
1466 br_avl_delete_by_port(i);
1467 memset(port_info[i].ifmac.BRIDGE_ID_ULA, 0, 6);
1468 break;
1470 return NOTIFY_DONE;
1473 /* Routine to loop over device list and register
1474 * interfaces to bridge. Called from last part of net_dev_init just before
1475 * bootp/rarp interface setup
1477 void br_spacedevice_register(void)
1479 struct net_device *dev;
1480 for( dev = dev_base; dev != NULL; dev = dev->next)
1482 br_device_event(NULL, NETDEV_REGISTER, dev);
1487 /* This is for SPEED in the kernel in net_bh.c */
1489 int br_call_bridge(struct sk_buff *skb, unsigned short type)
1491 int port;
1492 struct net_device *dev;
1494 #if 0 /* Checked first in handle_bridge to save expense of function call */
1495 if(!(br_stats.flags & BR_UP))
1496 return 0;
1497 #endif
1499 dev = skb->dev;
1500 port = dev->bridge_port_id;
1502 if(!port)
1503 return 0;
1505 /* Sanity - make sure we are not leaping off into fairy space! */
1506 if ( port < 0 || port > max_port_used || port_info[port].dev != dev) {
1507 if (net_ratelimit())
1508 printk(KERN_CRIT "br_call_bridge: device %s has invalid port ID %d!\n",
1509 dev->name,
1510 dev->bridge_port_id);
1511 return 0;
1514 if(user_port_state[port] == Disabled)
1515 return 0;
1517 if (!br_protocol_ok(ntohs(type)))
1518 return 0;
1520 return 1;
1526 * following routine is called when a frame is received
1527 * from an interface, it returns 1 when it consumes the
1528 * frame, 0 when it does not
1531 int br_receive_frame(struct sk_buff *skb) /* 3.5 */
1533 int port;
1534 Port_data *p;
1535 struct ethhdr *eth;
1536 struct net_device *dev;
1538 /* sanity */
1539 if (!skb) {
1540 printk(KERN_CRIT "br_receive_frame: no skb!\n");
1541 return(1);
1544 dev = skb->dev;
1546 skb->pkt_bridged = IS_BRIDGED;
1548 /* check for loopback */
1549 if (dev->flags & IFF_LOOPBACK)
1550 return 0 ;
1552 #if 0
1553 port = find_port(dev);
1554 #else
1555 port = dev->bridge_port_id;
1556 #endif
1558 if(!port)
1559 return 0;
1561 /* Hand off to brg_rx BEFORE we screw up the skb */
1562 if(brg_rx(skb, port))
1563 return(1);
1565 skb->nh.raw = skb->mac.raw;
1566 eth = skb->mac.ethernet;
1567 p = &port_info[port];
1569 if(p->state == Disabled)
1571 /* We are here if BR_UP even if this port is Disabled.
1572 * Send everything up
1574 skb->pkt_type = PACKET_HOST;
1575 ++br_stats_cnt.port_disable_up_stack;
1576 return(0); /* pass frame up our stack (this will */
1577 /* happen in net_bh() in dev.c) */
1580 /* Here only if not disable.
1581 * Remark: only frames going up will show up in NIT (tcpdump)
1584 /* JRP: even if port is Blocking we need to process the Spanning Tree
1585 * frames to keep the port in that state
1587 if (memcmp(eth->h_dest, bridge_ula, ETH_ALEN) == 0)
1589 ++br_stats_cnt.rcv_bpdu;
1590 br_bpdu(skb, port); /* br_bpdu consumes skb */
1591 return(1);
1593 switch (p->state)
1595 case Learning:
1596 if(br_learn(skb, port))
1597 { /* 3.8 */
1598 ++br_stats_cnt.drop_multicast;
1599 return br_drop(skb);
1601 /* fall through */
1602 case Listening:
1603 /* fall through */
1604 case Blocking:
1605 ++br_stats_cnt.notForwarding;
1606 return(br_drop(skb));
1608 case Disabled: is now handled before this switch !
1609 Keep the break to allow GCC to use a jmp table.
1611 break;
1612 case Forwarding:
1613 if(br_learn(skb, port)) { /* 3.8 */
1614 ++br_stats_cnt.drop_multicast;
1615 return br_drop(skb);
1617 /* Now this frame came from one of bridged
1618 ports this means we should attempt to forward it.
1619 JRP: local addresses are now in the AVL tree,
1620 br_forward will pass frames up if it matches
1621 one of our local MACs or if it is a multicast
1622 group address.
1623 br_forward() will not consume the frame if this
1624 is the case */
1625 return(br_forward(skb, port));
1626 default:
1627 printk(KERN_DEBUG "br_receive_frame: port [%i] unknown state [%i]\n",
1628 port, p->state);
1629 ++br_stats_cnt.unknown_state;
1630 return(br_drop(skb)); /* discard frame */
1635 * the following routine is called to transmit frames from the host
1636 * stack. it returns 1 when it consumes the frame and
1637 * 0 when it does not.
1640 int br_tx_frame(struct sk_buff *skb) /* 3.5 */
1642 int port;
1643 struct ethhdr *eth;
1645 /* sanity */
1646 if (!skb)
1648 printk(KERN_CRIT "br_tx_frame: no skb!\n");
1649 return(0);
1652 if (!skb->dev)
1654 printk(KERN_CRIT "br_tx_frame: no dev!\n");
1655 return(0);
1658 /* check for loopback */
1659 if (skb->dev->flags & IFF_LOOPBACK)
1660 return(0);
1662 /* if bridging is not enabled on the port we are going to send
1663 to, we have nothing to do with this frame, hands off */
1664 if (((port=find_port(skb->dev))==0)||(port_info[port].state==Disabled)) {
1665 ++br_stats_cnt.port_disable;
1666 return(0);
1668 ++br_stats_cnt.port_not_disable;
1669 skb->mac.raw = skb->nh.raw = skb->data;
1670 eth = skb->mac.ethernet;
1671 port = 0; /* an impossible port (locally generated) */
1672 if (br_stats.flags & BR_DEBUG)
1673 printk(KERN_DEBUG "br_tx_fr : port %i src %02x:%02x:%02x:%02x:%02x:%02x"
1674 " dest %02x:%02x:%02x:%02x:%02x:%02x\n",
1675 port,
1676 eth->h_source[0],
1677 eth->h_source[1],
1678 eth->h_source[2],
1679 eth->h_source[3],
1680 eth->h_source[4],
1681 eth->h_source[5],
1682 eth->h_dest[0],
1683 eth->h_dest[1],
1684 eth->h_dest[2],
1685 eth->h_dest[3],
1686 eth->h_dest[4],
1687 eth->h_dest[5]);
1688 return(br_forward(skb, port));
1691 static void br_add_local_mac(unsigned char *mac)
1693 struct fdb *f;
1694 f = (struct fdb *)kmalloc(sizeof(struct fdb), GFP_ATOMIC);
1695 if (!f)
1697 printk(KERN_CRIT "br_add_local_mac: unable to malloc fdb\n");
1698 return;
1700 f->port = 0; /* dest port == 0 =>local */
1701 memcpy(f->ula, mac, 6);
1702 f->timer = 0; /* will not aged anyway */
1703 f->flags = 0; /* not valid => br_forward special route */
1705 * add entity to AVL tree. If entity already
1706 * exists in the tree, update the fields with
1707 * what we have here.
1709 if (br_avl_insert(f) != NULL)
1711 /* Already in */
1712 kfree(f);
1716 /* Avoid broadcast loop by limiting the number of broacast frames per
1717 * period. The idea is to limit this per source
1718 * returns: 0 if limit is not reached
1719 * 1 if frame should be dropped
1722 static inline int mcast_quench(struct fdb *f)
1724 if(f->mcast_count++ == 0) /* first time */
1725 f->mcast_timer = jiffies;
1726 else {
1727 if(f->mcast_count > max_mcast_per_period) {
1728 if(time_after(jiffies, f->mcast_timer + mcast_hold_time))
1729 f->mcast_count = 0;
1730 else return 1;
1733 return 0;
1737 * this routine returns 0 when it learns (or updates) from the
1738 * frame, and 1 if we must dropped the frame.
1741 static int br_learn(struct sk_buff *skb, int port) /* 3.8 */
1743 struct fdb *f, *oldfdb;
1744 Port_data *p = &port_info[port];
1745 struct ethhdr *eth = skb->mac.ethernet;
1747 /* JRP: no reason to check port state again. We are called by
1748 * br_receive_frame() only when in Learning or Forwarding
1749 * Remark: code not realigned yet to keep diffs smaller
1752 /* don't keep group addresses in the tree */
1753 if (eth->h_source[0] & 0x01)
1754 return 0;
1756 if((f= newfdb[port]) == NULL)
1758 newfdb[port] = f = (struct fdb *)kmalloc(sizeof(struct fdb), GFP_ATOMIC);
1759 if (!f)
1761 printk(KERN_DEBUG "br_learn: unable to malloc fdb\n");
1762 return(-1); /* this drop the frame */
1765 f->port = port; /* source port */
1766 memcpy(f->ula, eth->h_source, 6);
1767 f->timer = CURRENT_TIME;
1768 f->flags = FDB_ENT_VALID;
1770 * add entity to AVL tree. If entity already
1771 * exists in the tree, update the fields with
1772 * what we have here.
1774 if ((oldfdb = br_avl_insert(f)))
1776 /* update if !NULL */
1777 if((eth->h_dest[0] & 0x01) && /* multicast */ mcast_quench(oldfdb))
1778 return 1;
1779 return 0;
1781 newfdb[port] = NULL; /* force kmalloc next time */
1782 f->mcast_count = 0;
1783 /* add to head of port chain */
1784 f->fdb_next = p->fdb;
1785 p->fdb = f;
1786 allocated_fdb_cnt++;
1787 return 0;
1790 /* JRP: always called under br_receive_frame(). No need for Q protection. */
1792 void requeue_fdb(struct fdb *node, int new_port)
1794 Port_data *p = &port_info[node->port];
1796 /* dequeue */
1797 if(p->fdb == node)
1798 p->fdb = node->fdb_next;
1799 else
1801 struct fdb *prev;
1803 for(prev = p->fdb; prev; prev = prev->fdb_next)
1804 if (prev->fdb_next == node)
1805 break;
1807 if(prev != NULL)
1808 prev->fdb_next = node->fdb_next;
1809 else
1811 /* Forget about this update. */
1812 printk(KERN_ERR "br:requeue_fdb\n");
1813 return;
1816 /* enqueue */
1817 node->port = new_port;
1818 node->fdb_next = port_info[new_port].fdb;
1819 port_info[new_port].fdb = node;
1823 * this routine always consumes the frame
1826 static int br_drop(struct sk_buff *skb)
1828 kfree_skb(skb);
1829 return(1);
1833 * this routine always consumes the frame
1836 static int br_dev_drop(struct sk_buff *skb)
1838 dev_kfree_skb(skb);
1839 return(1);
1843 * Forward the frame SKB to proper port[s]. PORT is the port that the
1844 * frame has come from; we will not send the frame back there. PORT == 0
1845 * means we have been called from br_tx_fr(), not from br_receive_frame().
1847 * this routine returns 1 if it consumes the frame, 0
1848 * if not...
1851 static int br_forward(struct sk_buff *skb, int port) /* 3.7 */
1853 struct fdb *f;
1856 * flood all ports with frames destined for a group
1857 * address. If frame came from above, drop it,
1858 * otherwise it will be handled in br_receive_frame()
1859 * Multicast frames will also need to be seen
1860 * by our upper layers.
1862 if (skb->mac.ethernet->h_dest[0] & 0x01)
1864 /* group address */
1865 br_flood(skb, port);
1867 * External groups are fed out via the normal source
1868 * This probably should be dropped since the flood will
1869 * have sent it anyway.
1871 if (port == 0)
1873 /* Locally generated */
1874 ++br_stats_cnt.local_multicast;
1875 return(br_dev_drop(skb));
1877 ++br_stats_cnt.forwarded_multicast;
1878 return(0);
1880 else
1882 /* unicast frame, locate port to forward to */
1883 f = br_avl_find_addr(skb->mac.ethernet->h_dest);
1885 * Send flood and drop.
1887 if (!f || !(f->flags & FDB_ENT_VALID))
1889 if(f && (f->port == 0))
1891 skb->pkt_type = PACKET_HOST;
1892 ++br_stats_cnt.forwarded_unicast_up_stack;
1893 return(0);
1895 /* not found or too old; flood all ports */
1896 ++br_stats_cnt.flood_unicast;
1897 br_flood(skb, port);
1898 return(br_dev_drop(skb));
1901 * Sending
1903 if (f->port!=port && port_info[f->port].state == Forwarding)
1905 /* Has entry expired? */
1906 if (f->timer + fdb_aging_time < CURRENT_TIME)
1908 /* timer expired, invalidate entry */
1909 f->flags &= ~FDB_ENT_VALID;
1910 if (br_stats.flags & BR_DEBUG)
1911 printk(KERN_DEBUG "fdb entry expired...\n");
1913 * Send flood and drop original
1915 ++br_stats_cnt.aged_flood_unicast;
1916 br_flood(skb, port);
1917 return(br_dev_drop(skb));
1919 ++br_stats_cnt.forwarded_unicast;
1920 /* mark that's we've been here... */
1921 skb->pkt_bridged = IS_BRIDGED;
1923 /* reset the skb->ip pointer */
1924 skb->nh.raw = skb->data + ETH_HLEN;
1927 * Send the buffer out.
1930 skb->dev=port_info[f->port].dev;
1933 * We send this still locked
1935 skb->priority = 1;
1936 dev_queue_xmit(skb);
1937 return(1); /* skb has been consumed */
1939 else
1941 /* JRP: Needs to aged entry as well, if topology changes
1942 * the entry would not age. Got this while swapping
1943 * two cables !
1945 * Has entry expired?
1948 if (f->timer + fdb_aging_time < CURRENT_TIME)
1950 /* timer expired, invalidate entry */
1951 f->flags &= ~FDB_ENT_VALID;
1952 if (br_stats.flags & BR_DEBUG)
1953 printk(KERN_DEBUG "fdb entry expired...\n");
1954 ++br_stats_cnt.drop_same_port_aged;
1956 else ++br_stats_cnt.drop_same_port;
1958 * Arrived on the right port, we discard
1960 return(br_dev_drop(skb));
1966 * this routine sends a copy of the frame to all forwarding ports
1967 * with the exception of the port given. This routine never
1968 * consumes the original frame.
1971 static int br_flood(struct sk_buff *skb, int port)
1973 int i;
1974 struct sk_buff *nskb;
1976 for (i = One; i <= No_of_ports; i++)
1978 if (i == port) /* don't send back where we got it */
1979 continue;
1980 if (i > max_port_used)
1981 /* Don't go scanning empty port entries */
1982 break;
1983 if (port_info[i].state == Forwarding)
1985 nskb = skb_clone(skb, GFP_ATOMIC);
1986 if(nskb==NULL)
1987 continue;
1988 /* mark that's we've been here... */
1989 nskb->pkt_bridged = IS_BRIDGED;
1990 /* Send to each port in turn */
1991 nskb->dev= port_info[i].dev;
1992 /* To get here we must have done ARP already,
1993 or have a received valid MAC header */
1995 /* printk(KERN_DEBUG "Flood to port %d\n",i);*/
1996 nskb->nh.raw = nskb->data + ETH_HLEN;
1997 nskb->priority = 1;
1998 dev_queue_xmit(nskb);
2001 return(0);
2005 * FIXME: This needs to come from the device structs, eg for
2006 * 10,100,1Gbit ethernet.
2009 static int br_port_cost(struct net_device *dev) /* 4.10.2 */
2011 if (strncmp(dev->name, "lec", 3) == 0) /* ATM Lan Emulation (LANE) */
2012 return(7); /* 155 Mbs */
2013 if (strncmp(dev->name, "eth", 3) == 0) /* ethernet */
2014 return(100);
2015 if (strncmp(dev->name, "plip",4) == 0) /* plip */
2016 return (1600);
2017 return(100); /* default */
2021 * this routine always consumes the skb
2024 static void br_bpdu(struct sk_buff *skb, int port) /* consumes skb */
2026 char *bufp = skb->data + ETH_HLEN;
2027 Tcn_bpdu *bpdu = (Tcn_bpdu *) (bufp + BRIDGE_LLC1_HS);
2028 Config_bpdu rcv_bpdu;
2030 if(!(br_stats.flags & BR_STP_DISABLED) &&
2031 (*bufp++ == BRIDGE_LLC1_DSAP) && (*bufp++ == BRIDGE_LLC1_SSAP) &&
2032 (*bufp++ == BRIDGE_LLC1_CTRL) &&
2033 (bpdu->protocol_id == BRIDGE_BPDU_8021_PROTOCOL_ID) &&
2034 (bpdu->protocol_version_id == BRIDGE_BPDU_8021_PROTOCOL_VERSION_ID))
2037 switch (bpdu->type)
2039 case BPDU_TYPE_CONFIG:
2040 /* realign for portability to RISC */
2041 memcpy((char*)&rcv_bpdu, bufp,
2042 BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
2043 bufp+= BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET;
2044 rcv_bpdu.top_change_ack =
2045 (*bufp & TOPOLOGY_CHANGE_ACK) != 0;
2046 rcv_bpdu.top_change =
2047 (*bufp & TOPOLOGY_CHANGE) != 0;
2048 bufp++;
2049 memcpy((char*)&rcv_bpdu.root_id, bufp,
2050 BRIDGE_BPDU_8021_CONFIG_SIZE-1
2051 -BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
2052 config_bpdu_ntoh(&rcv_bpdu);
2053 received_config_bpdu(port, &rcv_bpdu);
2054 break;
2056 case BPDU_TYPE_TOPO_CHANGE:
2057 received_tcn_bpdu(port, bpdu);
2058 break;
2059 default:
2060 printk(KERN_DEBUG "br_bpdu: received unknown bpdu, type = %i\n", bpdu->type);
2061 /* break; */
2064 br_drop(skb);
2067 struct fdb_info *get_fdb_info(int user_buf_size, int *copied,int *notcopied)
2069 int fdb_size, i, built = 0;
2070 struct fdb_info *fdbi, *fdbis;
2072 *copied = user_buf_size - sizeof(struct fdb_info_hdr);
2073 *copied /= sizeof(struct fdb_info);
2074 *copied = min(*copied, allocated_fdb_cnt);
2075 *notcopied = allocated_fdb_cnt - *copied;
2076 if(*copied == 0)
2077 return NULL;
2078 fdb_size = *copied * sizeof(struct fdb_info);
2079 fdbis = kmalloc(fdb_size, GFP_KERNEL);
2080 if(fdbis == NULL)
2081 return NULL;
2082 fdbi = fdbis;
2084 for(i=One; i<=No_of_ports;i++)
2086 struct fdb *fdb;
2088 cli();
2089 fdb = port_info[i].fdb;
2090 while(fdb)
2092 memcpy(fdbi->ula, fdb->ula, ETH_ALEN);
2093 fdbi->port = fdb->port;
2094 fdbi->flags = fdb->flags;
2095 fdbi->timer = fdb->timer;
2096 fdbi++;
2097 if(++built == *copied)
2099 sti();
2100 return fdbis;
2102 fdb = fdb->fdb_next;
2104 sti();
2106 printk(KERN_DEBUG "get_fdb_info: built=%d\n", built);
2107 return fdbis;
2111 /* Fill in interface names in port_info structure
2113 static void br_get_ifnames(void) {
2114 int i;
2116 for(i=One;i<=No_of_ports; i++) {
2117 /* memset IS needed. Kernel strncpy does NOT NULL terminate strings when limit
2118 reached */
2119 memset(port_info[i].ifname, 0, IFNAMSIZ);
2120 if( port_info[i].dev == 0 )
2121 continue;
2122 strncpy(port_info[i].ifname, port_info[i].dev->name, IFNAMSIZ-1);
2123 /* Being paranoid */
2124 port_info[i].ifname[IFNAMSIZ-1] = '\0';
2128 /* Given an interface index, loop over port array to see if configured. If
2129 so, return port number, otherwise error */
2130 static int br_find_port(int ifindex)
2132 int i;
2134 for(i=1; i <= No_of_ports; i++) {
2135 if (port_info[i].dev == 0)
2136 continue;
2137 if (port_info[i].dev->ifindex == ifindex)
2138 return(i);
2141 return -EUNATCH; /* Tell me if this is incorrect error code for this case */
2145 int br_ioctl(unsigned int cmd, void *arg)
2147 int err, i, ifflags;
2148 struct br_cf bcf;
2149 bridge_id_t new_id;
2150 struct net_device *dev;
2152 switch(cmd)
2154 case SIOCGIFBR: /* get bridging control blocks */
2155 memcpy(&br_stats.bridge_data, &bridge_info, sizeof(Bridge_data));
2157 /* Fill in interface names in port_info*/
2158 br_get_ifnames();
2160 br_stats.num_ports = No_of_ports;
2161 memcpy(&br_stats.port_data, &port_info, sizeof(Port_data)*All_ports);
2163 err = copy_to_user(arg, &br_stats, sizeof(struct br_stat));
2164 if (err)
2166 err = -EFAULT;
2168 return err;
2169 case SIOCSIFBR:
2170 err = copy_from_user(&bcf, arg, sizeof(struct br_cf));
2171 if (err)
2172 return -EFAULT;
2173 if (bcf.cmd != BRCMD_DISPLAY_FDB && !suser())
2174 return -EPERM;
2175 switch (bcf.cmd)
2177 case BRCMD_BRIDGE_ENABLE:
2178 if (br_stats.flags & BR_UP)
2179 return(-EALREADY);
2180 printk(KERN_DEBUG "br: enabling bridging function\n");
2181 br_stats.flags |= BR_UP; /* enable bridge */
2182 for(i=One;i<=No_of_ports; i++)
2184 /* don't start if user said so */
2185 if((user_port_state[i] != Disabled)
2186 && port_info[i].dev)
2188 enable_port(i);
2191 port_state_selection(); /* (4.8.1.5) */
2192 if (br_stats.flags & BR_STP_DISABLED)
2193 for(i=One;i<=No_of_ports; i++)
2194 if((user_port_state[i] != Disabled) && port_info[i].dev)
2195 port_info[i].state = Forwarding;
2196 config_bpdu_generation(); /* (4.8.1.6) */
2197 /* initialize system timer */
2198 tl.expires = jiffies+HZ; /* 1 second */
2199 tl.function = br_tick;
2200 add_timer(&tl);
2201 start_hello_timer();
2202 break;
2203 case BRCMD_BRIDGE_DISABLE:
2204 if (!(br_stats.flags & BR_UP))
2205 return(-EALREADY);
2206 printk(KERN_DEBUG "br: disabling bridging function\n");
2207 br_stats.flags &= ~BR_UP; /* disable bridge */
2208 stop_hello_timer();
2209 for (i = One; i <= No_of_ports; i++)
2210 if (port_info[i].state != Disabled)
2211 disable_port(i);
2212 break;
2213 case BRCMD_TOGGLE_STP:
2214 printk(KERN_DEBUG "br: %s spanning tree protcol\n",
2215 (br_stats.flags & BR_STP_DISABLED) ? "enabling" : "disabling");
2216 if (br_stats.flags & BR_STP_DISABLED) { /* enable STP */
2217 for(i=One;i<=No_of_ports; i++)
2218 if((user_port_state[i] != Disabled) && port_info[i].dev)
2219 enable_port(i);
2220 } else { /* STP was enabled, now disable it */
2221 for (i = One; i <= No_of_ports; i++)
2222 if (port_info[i].state != Disabled && port_info[i].dev)
2223 port_info[i].state = Forwarding;
2225 br_stats.flags ^= BR_STP_DISABLED;
2226 break;
2227 case BRCMD_IF_ENABLE:
2228 bcf.arg1 = br_find_port(bcf.arg1);
2229 if (bcf.arg1 < 0)
2230 return(bcf.arg1);
2231 case BRCMD_PORT_ENABLE:
2232 if (port_info[bcf.arg1].dev == 0)
2233 return(-EINVAL);
2234 if (user_port_state[bcf.arg1] != Disabled)
2235 return(-EALREADY);
2236 printk(KERN_DEBUG "br: enabling port %i\n",bcf.arg1);
2237 dev = port_info[bcf.arg1].dev;
2238 ifflags = (dev->flags&~(IFF_PROMISC|IFF_ALLMULTI))
2239 |(dev->gflags&(IFF_PROMISC|IFF_ALLMULTI));
2240 dev_change_flags(dev, ifflags|IFF_PROMISC);
2241 user_port_state[bcf.arg1] = ~Disabled;
2242 if(br_stats.flags & BR_UP)
2243 enable_port(bcf.arg1);
2244 break;
2245 case BRCMD_IF_DISABLE:
2246 bcf.arg1 = br_find_port(bcf.arg1);
2247 if (bcf.arg1 < 0)
2248 return(bcf.arg1);
2249 case BRCMD_PORT_DISABLE:
2250 if (port_info[bcf.arg1].dev == 0)
2251 return(-EINVAL);
2252 if (user_port_state[bcf.arg1] == Disabled)
2253 return(-EALREADY);
2254 printk(KERN_DEBUG "br: disabling port %i\n",bcf.arg1);
2255 user_port_state[bcf.arg1] = Disabled;
2256 if(br_stats.flags & BR_UP)
2257 disable_port(bcf.arg1);
2258 dev = port_info[bcf.arg1].dev;
2259 ifflags = (dev->flags&~(IFF_PROMISC|IFF_ALLMULTI))
2260 |(dev->gflags&(IFF_PROMISC|IFF_ALLMULTI));
2261 dev_change_flags(port_info[bcf.arg1].dev, ifflags & ~IFF_PROMISC);
2262 break;
2263 case BRCMD_SET_BRIDGE_PRIORITY:
2264 new_id = bridge_info.bridge_id;
2265 new_id.BRIDGE_PRIORITY = htons(bcf.arg1);
2266 set_bridge_priority(&new_id);
2267 break;
2268 case BRCMD_SET_IF_PRIORITY:
2269 bcf.arg1 = br_find_port(bcf.arg1);
2270 if (bcf.arg1 < 0)
2271 return(bcf.arg1);
2272 case BRCMD_SET_PORT_PRIORITY:
2273 if((port_info[bcf.arg1].dev == 0)
2274 || (bcf.arg2 & ~0xff))
2275 return(-EINVAL);
2276 port_priority[bcf.arg1] = bcf.arg2;
2277 set_port_priority(bcf.arg1);
2278 break;
2279 case BRCMD_SET_IF_PATH_COST:
2280 bcf.arg1 = br_find_port(bcf.arg1);
2281 if (bcf.arg1 < 0)
2282 return(bcf.arg1);
2283 case BRCMD_SET_PATH_COST:
2284 if (port_info[bcf.arg1].dev == 0)
2285 return(-EINVAL);
2286 set_path_cost(bcf.arg1, bcf.arg2);
2287 break;
2288 case BRCMD_ENABLE_DEBUG:
2289 br_stats.flags |= BR_DEBUG;
2290 break;
2291 case BRCMD_DISABLE_DEBUG:
2292 br_stats.flags &= ~BR_DEBUG;
2293 break;
2294 case BRCMD_SET_POLICY:
2295 return br_set_policy(bcf.arg1);
2296 case BRCMD_EXEMPT_PROTOCOL:
2297 return br_add_exempt_protocol(bcf.arg1);
2298 case BRCMD_ENABLE_PROT_STATS:
2299 br_stats.flags |= BR_PROT_STATS;
2300 break;
2301 case BRCMD_DISABLE_PROT_STATS:
2302 br_stats.flags &= ~BR_PROT_STATS;
2303 break;
2304 case BRCMD_ZERO_PROT_STATS:
2305 memset(&br_stats.prot_id,0,sizeof(br_stats.prot_id));
2306 memset(&br_stats.prot_counter,0,sizeof(br_stats.prot_counter));
2307 break;
2308 case BRCMD_DISPLAY_FDB:
2310 struct fdb_info_hdr *user_buf = (void*) bcf.arg1;
2311 struct fdb_info *u_fdbs, *fdbis;
2312 int copied, notcopied;
2313 u32 j = CURRENT_TIME;
2315 if(bcf.arg2<sizeof(struct fdb_info_hdr))
2316 return -EINVAL;
2317 put_user(j, &user_buf->cmd_time);
2318 if(allocated_fdb_cnt == 0)
2320 put_user(0, &user_buf->copied);
2321 put_user(0, &user_buf->not_copied);
2322 return 0;
2324 fdbis = get_fdb_info(bcf.arg2, &copied, &notcopied);
2325 put_user(copied, &user_buf->copied);
2326 put_user(notcopied, &user_buf->not_copied);
2327 if(!fdbis)
2328 return -ENOMEM;
2329 u_fdbs = (struct fdb_info *) (user_buf+1);
2330 err = copy_to_user(u_fdbs, fdbis, copied*sizeof(struct fdb_info));
2331 kfree(fdbis);
2332 if (err)
2334 err = -EFAULT;
2336 return err;
2338 default:
2339 return -EINVAL;
2341 return(0);
2342 default:
2343 return -EINVAL;
2345 /*NOTREACHED*/
2346 return 0;
2349 static int br_cmp(unsigned int *a, unsigned int *b)
2351 int i;
2352 for (i=0; i<2; i++)
2354 /* JRP: compares prty then MAC address in memory byte order
2355 * OK optimizer does htonl() only once per long !
2357 if (htonl(a[i]) < htonl(b[i]))
2358 return(-1);
2359 if (htonl(a[i]) > htonl(b[i]))
2360 return(1);
2362 return(0);
2368 /* --------------------------------------------------------------------------------
2371 * Bridge network device here for future modularization - device structures
2372 * must be 'static' inside bridge instance
2373 * Modelled after sch_teql.c
2380 * Index to functions.
2383 int brg_probe(struct net_device *dev);
2384 static int brg_open(struct net_device *dev);
2385 static int brg_start_xmit(struct sk_buff *skb, struct net_device *dev);
2386 static int brg_close(struct net_device *dev);
2387 static struct net_device_stats *brg_get_stats(struct net_device *dev);
2388 static void brg_set_multicast_list(struct net_device *dev);
2391 * Board-specific info in dev->priv.
2394 struct net_local
2396 __u32 groups;
2397 struct net_device_stats stats;
2404 * To call this a probe is a bit misleading, however for real
2405 * hardware it would have to check what was present.
2408 int __init brg_probe(struct net_device *dev)
2410 unsigned int bogomips;
2411 struct timeval utime;
2413 printk(KERN_INFO "%s: network interface for Ethernet Bridge 006/NET4.0\n", dev->name);
2416 * Initialize the device structure.
2419 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
2420 if (dev->priv == NULL)
2421 return -ENOMEM;
2422 memset(dev->priv, 0, sizeof(struct net_local));
2424 /* Set up MAC address based on BogoMIPs figure for first CPU and time
2426 bogomips = (loops_per_sec+2500)/500000 ;
2427 get_fast_time(&utime);
2429 /* Ummmm.... YES! */
2430 dev->dev_addr[0] = '\xFE';
2431 dev->dev_addr[1] = '\xFD';
2432 dev->dev_addr[2] = (bridge_info.instance & 0x0F) << 4;
2433 dev->dev_addr[2] |= ((utime.tv_sec & 0x000F0000) >> 16);
2434 dev->dev_addr[3] = bogomips & 0xFF;
2435 dev->dev_addr[4] = (utime.tv_sec & 0x0000FF00) >> 8;
2436 dev->dev_addr[5] = (utime.tv_sec & 0x000000FF);
2438 printk(KERN_INFO "%s: generated MAC address %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2439 dev->name,
2440 dev->dev_addr[0],
2441 dev->dev_addr[1],
2442 dev->dev_addr[2],
2443 dev->dev_addr[3],
2444 dev->dev_addr[4],
2445 dev->dev_addr[5]);
2448 printk(KERN_INFO "%s: attached to bridge instance %lu\n", dev->name, dev->base_addr);
2451 * The brg specific entries in the device structure.
2454 dev->open = brg_open;
2455 dev->hard_start_xmit = brg_start_xmit;
2456 dev->stop = brg_close;
2457 dev->get_stats = brg_get_stats;
2458 dev->set_multicast_list = brg_set_multicast_list;
2461 * Setup the generic properties
2464 ether_setup(dev);
2466 dev->tx_queue_len = 0;
2468 return 0;
2472 * Open/initialize the board.
2475 static int brg_open(struct net_device *dev)
2477 if (br_stats.flags & BR_DEBUG)
2478 printk(KERN_DEBUG "%s: Doing brg_open()...", dev->name);
2480 if (memcmp(dev->dev_addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
2481 return -EFAULT;
2483 netif_start_queue(dev);
2484 return 0;
2487 static unsigned brg_mc_hash(__u8 *dest)
2489 unsigned idx = 0;
2490 idx ^= dest[0];
2491 idx ^= dest[1];
2492 idx ^= dest[2];
2493 idx ^= dest[3];
2494 idx ^= dest[4];
2495 idx ^= dest[5];
2496 return 1U << (idx&0x1F);
2499 static void brg_set_multicast_list(struct net_device *dev)
2501 unsigned groups = ~0;
2502 struct net_local *lp = (struct net_local *)dev->priv;
2504 if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) {
2505 struct dev_mc_list *dmi;
2507 groups = brg_mc_hash(dev->broadcast);
2509 for (dmi=dev->mc_list; dmi; dmi=dmi->next) {
2510 if (dmi->dmi_addrlen != 6)
2511 continue;
2512 groups |= brg_mc_hash(dmi->dmi_addr);
2515 lp->groups = groups;
2519 * We transmit by throwing the packet at the bridge.
2522 static int brg_start_xmit(struct sk_buff *skb, struct net_device *dev)
2524 struct net_local *lp = (struct net_local *)dev->priv;
2525 struct ethhdr *eth = (struct ethhdr*)skb->data;
2526 int port;
2528 /* Deal with the bridge being disabled */
2529 if(!(br_stats.flags & BR_UP)) {
2530 /* Either this */
2531 /* lp->stats.tx_errors++; */ /* this condition is NOT an error */
2532 /* or this (implied by RFC 2233) */
2533 lp->stats.tx_dropped++;
2534 dev_kfree_skb(skb);
2535 return 0;
2538 lp->stats.tx_bytes+=skb->len;
2539 lp->stats.tx_packets++;
2541 #if 0
2542 ++br_stats_cnt.port_not_disable;
2543 #endif
2544 skb->mac.raw = skb->nh.raw = skb->data;
2545 eth = skb->mac.ethernet;
2546 port = 0; /* an impossible port (locally generated) */
2548 if (br_stats.flags & BR_DEBUG)
2549 printk(KERN_DEBUG "%s: brg_start_xmit - src %02x:%02x:%02x:%02x:%02x:%02x"
2550 " dest %02x:%02x:%02x:%02x:%02x:%02x\n",
2551 dev->name,
2552 eth->h_source[0],
2553 eth->h_source[1],
2554 eth->h_source[2],
2555 eth->h_source[3],
2556 eth->h_source[4],
2557 eth->h_source[5],
2558 eth->h_dest[0],
2559 eth->h_dest[1],
2560 eth->h_dest[2],
2561 eth->h_dest[3],
2562 eth->h_dest[4],
2563 eth->h_dest[5]);
2565 /* Forward the packet ! */
2566 if(br_forward(skb, port))
2567 return(0);
2569 /* Throw packet initially */
2570 dev_kfree_skb(skb);
2571 return 0;
2576 * The typical workload of the driver:
2577 * Handle the ether interface interrupts.
2579 * (In this case handle the packets posted from the bridge)
2582 static int brg_rx(struct sk_buff *skb, int port)
2584 struct net_device *dev = &brg_if.dev;
2585 struct net_local *lp = (struct net_local *)dev->priv;
2586 struct ethhdr *eth = (struct ethhdr*)(skb->data);
2587 int len = skb->len;
2588 int clone = 0;
2590 if (br_stats.flags & BR_DEBUG)
2591 printk(KERN_DEBUG "%s: brg_rx()\n", dev->name);
2593 /* Get out of here if the bridge interface is not up
2595 if(!(dev->flags & IFF_UP))
2596 return(0);
2598 /* Check that the port that this thing came off is in the forwarding state
2599 * We sould only listen to the same address scope we will transmit to.
2601 if(port_info[port].state != Forwarding)
2602 return(0);
2604 /* Is this for us? - broadcast/mulitcast/promiscuous packets need cloning,
2605 * with uni-cast we eat the packet
2607 clone = 0;
2608 if (dev->flags & IFF_PROMISC) {
2609 clone = 1;
2611 else if (eth->h_dest[0]&1) {
2612 if (!(dev->flags&(IFF_ALLMULTI))
2613 && !(brg_mc_hash(eth->h_dest)&lp->groups))
2614 return(0);
2615 clone = 1;
2617 else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN) != 0) {
2618 return(0);
2621 /* Clone things here - we want to be transparent before we check packet data
2622 * integrity
2624 if(clone) {
2625 struct sk_buff *skb2 = skb;
2626 skb = skb_clone(skb2, GFP_ATOMIC);
2627 if (skb == NULL) {
2628 return(0);
2633 /* Check packet length
2635 if (len < 16) {
2636 printk(KERN_DEBUG "%s : rx len = %d\n", dev->name, len);
2637 kfree_skb(skb);
2638 return(!clone);
2641 if (br_stats.flags & BR_DEBUG)
2642 printk(KERN_DEBUG "%s: brg_rx - src %02x:%02x:%02x:%02x:%02x:%02x"
2643 " dest %02x:%02x:%02x:%02x:%02x:%02x\n",
2644 dev->name,
2645 eth->h_source[0],
2646 eth->h_source[1],
2647 eth->h_source[2],
2648 eth->h_source[3],
2649 eth->h_source[4],
2650 eth->h_source[5],
2651 eth->h_dest[0],
2652 eth->h_dest[1],
2653 eth->h_dest[2],
2654 eth->h_dest[3],
2655 eth->h_dest[4],
2656 eth->h_dest[5]);
2658 /* Do it */
2659 skb->pkt_type = PACKET_HOST;
2660 skb->dev = dev;
2661 skb->protocol=eth_type_trans(skb,dev);
2662 memset(skb->cb, 0, sizeof(skb->cb));
2663 lp->stats.rx_packets++;
2664 lp->stats.rx_bytes+=len;
2665 netif_rx(skb);
2666 return(!clone);
2669 static int brg_close(struct net_device *dev)
2671 if (br_stats.flags & BR_DEBUG)
2672 printk(KERN_DEBUG "%s: Shutting down.\n", dev->name);
2674 netif_stop_queue(dev);
2676 return 0;
2679 static struct net_device_stats *brg_get_stats(struct net_device *dev)
2681 struct net_local *lp = (struct net_local *)dev->priv;
2682 return &lp->stats;
2689 int __init brg_init(void)
2691 int err;
2693 memset(&brg_if, 0, sizeof(brg_if));
2695 rtnl_lock();
2697 brg_if.dev.base_addr = bridge_info.instance;
2698 sprintf (brg_if.name, "brg%d", bridge_info.instance);
2699 brg_if.dev.name = (void*)&brg_if.name;
2700 if(dev_get(brg_if.name)) {
2701 printk(KERN_INFO "%s already loaded.\n", brg_if.name);
2702 return -EBUSY;
2704 brg_if.dev.init = brg_probe;
2706 err = register_netdevice(&brg_if.dev);
2707 rtnl_unlock();
2708 return err;
2712 #if 0 /* Its here if we ever need it... */
2713 #ifdef MODULE
2715 void cleanup_module(void)
2719 * Unregister the device
2721 rtnl_lock();
2722 unregister_netdevice(&the_master.dev);
2723 rtnl_unlock();
2726 * Free up the private structure.
2729 kfree(brg_if.dev.priv);
2730 brg_if.dev.priv = NULL; /* gets re-allocated by brg_probe */
2733 #endif /* MODULE */
2735 #endif