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.
17 * Yury Shevchuk : Bridge with non bridging ports
18 * Jean-Rene Peulve: jr.peulve@aix.pacwan.net Jan/Feb 98
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.
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.
64 #include <linux/module.h>
65 #include <linux/errno.h>
66 #include <linux/types.h>
67 #include <linux/socket.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>
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>
89 #include <linux/proc_fs.h>
90 #include <linux/delay.h>
91 #include <net/pkt_sched.h>
94 #define min(a, b) (((a) <= (b)) ? (a) : (b))
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
={
219 * the following data is for the bridge network device
222 struct net_device dev
;
225 static struct brg_if brg_if
;
228 * Here to save linkage? problems
231 static inline int find_port(struct net_device
*dev
)
235 for (i
= One
; i
<= No_of_ports
; i
++)
236 if (port_info
[i
].dev
== dev
)
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
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
)
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
;
272 if (x
==BR_MAX_PROTOCOLS
)
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
)
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 */
288 if (x
==BR_MAX_PROTOCOLS
) x
=0;
290 br_stats
.protocols
[x
]=p
;
291 br_stats
.exempt_protocols
++;
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;
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
;
325 config_bpdu
.root_path_cost
= bridge_info
.root_path_cost
;
327 config_bpdu
.bridge_id
= bridge_info
.bridge_id
;
329 config_bpdu
.port_id
= port_info
[port_no
].port_id
;
334 config_bpdu
.message_age
= Zero
; /* (4.6.1.3.2(5)) */
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
;
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) */
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
390 ((br_cmp(config
->bridge_id
.BRIDGE_ID
,
391 bridge_info
.bridge_id
.BRIDGE_ID
) != 0
392 ) /* (4.6.2.2.4(1)) */
395 port_info
[port_no
].designated_port
396 ) /* (4.6.2.2.4(2)) */
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)
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) */
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)
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) */
461 designated_port_selection(); /* (4.6.7.3.2) */
465 static void root_selection(void)
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)) */
530 bridge_info
.root_port
= root_port
; /* (4.6.8.3.1) */
532 if (root_port
== No_port
) { /* (4.6.8.3.2) */
534 if (br_stats
.flags
& BR_DEBUG
)
535 printk(KERN_DEBUG
"root_selection: becomes root\n");
537 bridge_info
.designated_root
= bridge_info
.bridge_id
;
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
;
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)
553 for (port_no
= One
; port_no
<= No_of_ports
; port_no
++) { /* (4.6.9.3) */
554 if(port_info
[port_no
].state
== Disabled
)
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
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
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
583 become_designated_port(port_no
); /* (4.6.10.3.2.2) */
588 static void become_designated_port(int port_no
)
592 port_info
[port_no
].designated_root
= bridge_info
.designated_root
;
594 port_info
[port_no
].designated_cost
= bridge_info
.root_path_cost
;
596 port_info
[port_no
].designated_bridge
= bridge_info
.bridge_id
;
598 port_info
[port_no
].designated_port
= port_info
[port_no
].port_id
;
601 static void port_state_selection(void)
605 for (port_no
= One
; port_no
<= No_of_ports
; port_no
++) {
607 if(port_info
[port_no
].state
== Disabled
)
609 if (port_no
== bridge_info
.root_port
) { /* (4.6.11.3.1) */
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)) */
625 if (br_stats
.flags
& BR_DEBUG
)
626 printk(KERN_DEBUG
"port_state_selection: becomes %s port %d\n",
634 static void make_forwarding(int port_no
)
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)
645 if ((br_stats
.flags
& BR_DEBUG
)
646 && (bridge_info
.top_change_detected
== 0))
647 printk(KERN_DEBUG
"topology_change_detected\n");
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)
662 if (br_stats
.flags
& BR_DEBUG
)
663 printk(KERN_DEBUG
"topology_change_acked\n");
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
)
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
)
683 if ((port_info
[port_no
].state
== Forwarding
)
685 (port_info
[port_no
].state
== Learning
)
687 topology_change_detection(); /* (4.6.13.3.1) */
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) */
704 root
= root_bridge();
705 if (port_info
[port_no
].state
!= Disabled
) {
708 if (br_stats
.flags
& BR_DEBUG
)
709 printk(KERN_DEBUG
"received_config_bpdu: port %d\n",
712 if (supersedes_port_info(port_no
, config
)) { /* (4.7.1.1) *//* (4.
714 record_config_information(port_no
, config
); /* (4.7.1.1.1) */
716 configuration_update(); /* (4.7.1.1.2) */
718 port_state_selection(); /* (4.7.1.1.3) */
720 if ((!root_bridge()) && root
) { /* (4.7.1.1.4) */
722 if (bridge_info
.top_change_detected
) { /* (4.7.1.1.5 */
723 stop_topology_change_timer();
724 transmit_tcn(); /* (4.6.6.1) */
728 if (port_no
== bridge_info
.root_port
) {
729 record_config_timeout_values(config
); /* (4.7.1.1.6) */
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) */
743 static void received_tcn_bpdu(int port_no
, Tcn_bpdu
*tcn
) /* (4.7.2) */
745 if (port_info
[port_no
].state
!= Disabled
) {
747 if (br_stats
.flags
& BR_DEBUG
)
748 printk(KERN_DEBUG
"received_tcn_bpdu: port %d\n",
751 if (designated_port(port_no
)) {
752 topology_change_detection(); /* (4.7.2.1) */
754 acknowledge_topology_change(port_no
); /* (4.7.2.2) */
759 static void hello_timer_expiry(void)
761 config_bpdu_generation(); /* (4.6.4.2.2) */
765 static void message_age_timer_expiry(int port_no
) /* (4.7.4) */
768 root
= root_bridge();
771 if (br_stats
.flags
& BR_DEBUG
)
772 printk(KERN_DEBUG
"message_age_timer_expiry: port %d\n",
775 become_designated_port(port_no
); /* (4.7.4.1) */
777 configuration_update(); /* (4.7.4.2) */
779 port_state_selection(); /* (4.7.4.3) */
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) */
788 stop_tcn_timer(); /* (4.7.4.4.3) */
789 config_bpdu_generation(); /* (4.7.4.4.4) */
795 static void forward_delay_timer_expiry(int port_no
) /* (4.7.5) */
797 if (port_info
[port_no
].state
== Listening
)
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
)
805 set_port_state(port_no
, Forwarding
); /* (4.7.5.2.1) */
806 if (designated_for_some_port())
808 topology_change_detection(); /* (4.6.14.2.2) */
814 static int designated_for_some_port(void)
818 for (port_no
= One
; port_no
<= No_of_ports
; port_no
++)
820 if(port_info
[port_no
].state
== Disabled
)
822 if ((br_cmp(port_info
[port_no
].designated_bridge
.BRIDGE_ID
,
823 bridge_info
.bridge_id
.BRIDGE_ID
) == 0))
831 static void tcn_timer_expiry(void)
833 transmit_tcn(); /* (4.7.6.1) */
834 start_tcn_timer(); /* (4.7.6.2) */
837 static void topology_change_timer_expiry(void)
839 bridge_info
.top_change_detected
= 0; /* (4.7.7.1) */
840 bridge_info
.top_change
= 0;
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) */
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
)
863 /* first time write the header */
864 size
= sprintf(buffer
,"%s","MAC address Device Flags Age (sec.)\n");
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 */
874 len
= length
; /* Ending slop */
879 void __init
br_init(void)
883 printk(KERN_INFO
"NET4: Ethernet Bridge 006 for NET4.0\n");
885 /* Set up brg device information */
886 bridge_info
.instance
= 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
;
902 printk(KERN_INFO
"br_init: becomes root\n");
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;
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
;
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) */
967 static void disable_port(int port_no
) /* (4.8.3) */
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) */
992 static void set_bridge_priority(bridge_id_t
*new_bridge_id
)
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
)
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
)
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
)
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
)
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())
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
)
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
);
1235 skb
= alloc_skb(size
, GFP_ATOMIC
);
1238 printk(KERN_DEBUG
"send_%s_bpdu: no skb available\n", pdu_name
);
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",
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);
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
;
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
))
1291 * Create and send the message
1294 skb
= alloc_bridge_skb(port_no
, BRIDGE_BPDU_8021_CONFIG_SIZE
,
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
);
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
);
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
))
1331 skb
= alloc_bridge_skb(port_no
, sizeof(Tcn_bpdu
), "tcn");
1335 memcpy(skb
->nh
.raw
, bpdu
, sizeof(Tcn_bpdu
));
1337 dev_queue_xmit(skb
);
1341 static int br_device_event(struct notifier_block
*unused
, unsigned long event
, void *ptr
)
1343 struct net_device
*dev
= ptr
;
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! */
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
)
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
)
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
)
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 */
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
;
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
)
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
)
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);
1442 case NETDEV_UNREGISTER
:
1443 if (br_stats
.flags
& BR_DEBUG
)
1444 printk(KERN_DEBUG
"br_device_event: NETDEV_UNREGISTER...\n");
1447 br_avl_delete_by_port(i
);
1448 memset(port_info
[i
].ifmac
.BRIDGE_ID_ULA
, 0, 6);
1449 port_info
[i
].dev
= NULL
;
1452 case NETDEV_CHANGEADDR
:
1453 if (br_stats
.flags
& BR_DEBUG
)
1454 printk(KERN_DEBUG
"br_device_event: NETDEV_CHANGEADDR...\n");
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",
1463 /* return NOTIFY_BAD; It SHOULD be this, but I want to be friendly... */
1466 br_avl_delete_by_port(i
);
1467 memset(port_info
[i
].ifmac
.BRIDGE_ID_ULA
, 0, 6);
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
)
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
))
1500 port
= dev
->bridge_port_id
;
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",
1510 dev
->bridge_port_id
);
1514 if(user_port_state
[port
] == Disabled
)
1517 if (!br_protocol_ok(ntohs(type
)))
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 */
1536 struct net_device
*dev
;
1540 printk(KERN_CRIT
"br_receive_frame: no skb!\n");
1546 skb
->pkt_bridged
= IS_BRIDGED
;
1548 /* check for loopback */
1549 if (dev
->flags
& IFF_LOOPBACK
)
1553 port
= find_port(dev
);
1555 port
= dev
->bridge_port_id
;
1561 /* Hand off to brg_rx BEFORE we screw up the skb */
1562 if(brg_rx(skb
, port
))
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 */
1596 if(br_learn(skb
, port
))
1598 ++br_stats_cnt
.drop_multicast
;
1599 return br_drop(skb
);
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.
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
1623 br_forward() will not consume the frame if this
1625 return(br_forward(skb
, port
));
1627 printk(KERN_DEBUG
"br_receive_frame: port [%i] unknown state [%i]\n",
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 */
1648 printk(KERN_CRIT
"br_tx_frame: no skb!\n");
1654 printk(KERN_CRIT
"br_tx_frame: no dev!\n");
1658 /* check for loopback */
1659 if (skb
->dev
->flags
& IFF_LOOPBACK
)
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
;
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",
1688 return(br_forward(skb
, port
));
1691 static void br_add_local_mac(unsigned char *mac
)
1694 f
= (struct fdb
*)kmalloc(sizeof(struct fdb
), GFP_ATOMIC
);
1697 printk(KERN_CRIT
"br_add_local_mac: unable to malloc fdb\n");
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
)
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
;
1727 if(f
->mcast_count
> max_mcast_per_period
) {
1728 if(time_after(jiffies
, f
->mcast_timer
+ mcast_hold_time
))
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)
1756 if((f
= newfdb
[port
]) == NULL
)
1758 newfdb
[port
] = f
= (struct fdb
*)kmalloc(sizeof(struct fdb
), GFP_ATOMIC
);
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
))
1781 newfdb
[port
] = NULL
; /* force kmalloc next time */
1783 /* add to head of port chain */
1784 f
->fdb_next
= p
->fdb
;
1786 allocated_fdb_cnt
++;
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
];
1798 p
->fdb
= node
->fdb_next
;
1803 for(prev
= p
->fdb
; prev
; prev
= prev
->fdb_next
)
1804 if (prev
->fdb_next
== node
)
1808 prev
->fdb_next
= node
->fdb_next
;
1811 /* Forget about this update. */
1812 printk(KERN_ERR
"br:requeue_fdb\n");
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
)
1833 * this routine always consumes the frame
1836 static int br_dev_drop(struct sk_buff
*skb
)
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
1851 static int br_forward(struct sk_buff
*skb
, int port
) /* 3.7 */
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)
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.
1873 /* Locally generated */
1874 ++br_stats_cnt
.local_multicast
;
1875 return(br_dev_drop(skb
));
1877 ++br_stats_cnt
.forwarded_multicast
;
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
;
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
));
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
1936 dev_queue_xmit(skb
);
1937 return(1); /* skb has been consumed */
1941 /* JRP: Needs to aged entry as well, if topology changes
1942 * the entry would not age. Got this while swapping
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
)
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 */
1980 if (i
> max_port_used
)
1981 /* Don't go scanning empty port entries */
1983 if (port_info
[i
].state
== Forwarding
)
1985 nskb
= skb_clone(skb
, GFP_ATOMIC
);
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
;
1998 dev_queue_xmit(nskb
);
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 */
2015 if (strncmp(dev
->name
, "plip",4) == 0) /* plip */
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
))
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;
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
);
2056 case BPDU_TYPE_TOPO_CHANGE
:
2057 received_tcn_bpdu(port
, bpdu
);
2060 printk(KERN_DEBUG
"br_bpdu: received unknown bpdu, type = %i\n", bpdu
->type
);
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
;
2078 fdb_size
= *copied
* sizeof(struct fdb_info
);
2079 fdbis
= kmalloc(fdb_size
, GFP_KERNEL
);
2084 for(i
=One
; i
<=No_of_ports
;i
++)
2089 fdb
= port_info
[i
].fdb
;
2092 memcpy(fdbi
->ula
, fdb
->ula
, ETH_ALEN
);
2093 fdbi
->port
= fdb
->port
;
2094 fdbi
->flags
= fdb
->flags
;
2095 fdbi
->timer
= fdb
->timer
;
2097 if(++built
== *copied
)
2102 fdb
= fdb
->fdb_next
;
2106 printk(KERN_DEBUG
"get_fdb_info: built=%d\n", built
);
2111 /* Fill in interface names in port_info structure
2113 static void br_get_ifnames(void) {
2116 for(i
=One
;i
<=No_of_ports
; i
++) {
2117 /* memset IS needed. Kernel strncpy does NOT NULL terminate strings when limit
2119 memset(port_info
[i
].ifname
, 0, IFNAMSIZ
);
2120 if( port_info
[i
].dev
== 0 )
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
)
2134 for(i
=1; i
<= No_of_ports
; i
++) {
2135 if (port_info
[i
].dev
== 0)
2137 if (port_info
[i
].dev
->ifindex
== ifindex
)
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
;
2150 struct net_device
*dev
;
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*/
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
));
2170 err
= copy_from_user(&bcf
, arg
, sizeof(struct br_cf
));
2173 if (bcf
.cmd
!= BRCMD_DISPLAY_FDB
&& !suser())
2177 case BRCMD_BRIDGE_ENABLE
:
2178 if (br_stats
.flags
& BR_UP
)
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
)
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
;
2201 start_hello_timer();
2203 case BRCMD_BRIDGE_DISABLE
:
2204 if (!(br_stats
.flags
& BR_UP
))
2206 printk(KERN_DEBUG
"br: disabling bridging function\n");
2207 br_stats
.flags
&= ~BR_UP
; /* disable bridge */
2209 for (i
= One
; i
<= No_of_ports
; i
++)
2210 if (port_info
[i
].state
!= Disabled
)
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
)
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
;
2227 case BRCMD_IF_ENABLE
:
2228 bcf
.arg1
= br_find_port(bcf
.arg1
);
2231 case BRCMD_PORT_ENABLE
:
2232 if (port_info
[bcf
.arg1
].dev
== 0)
2234 if (user_port_state
[bcf
.arg1
] != Disabled
)
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
);
2245 case BRCMD_IF_DISABLE
:
2246 bcf
.arg1
= br_find_port(bcf
.arg1
);
2249 case BRCMD_PORT_DISABLE
:
2250 if (port_info
[bcf
.arg1
].dev
== 0)
2252 if (user_port_state
[bcf
.arg1
] == Disabled
)
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
);
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
);
2268 case BRCMD_SET_IF_PRIORITY
:
2269 bcf
.arg1
= br_find_port(bcf
.arg1
);
2272 case BRCMD_SET_PORT_PRIORITY
:
2273 if((port_info
[bcf
.arg1
].dev
== 0)
2274 || (bcf
.arg2
& ~0xff))
2276 port_priority
[bcf
.arg1
] = bcf
.arg2
;
2277 set_port_priority(bcf
.arg1
);
2279 case BRCMD_SET_IF_PATH_COST
:
2280 bcf
.arg1
= br_find_port(bcf
.arg1
);
2283 case BRCMD_SET_PATH_COST
:
2284 if (port_info
[bcf
.arg1
].dev
== 0)
2286 set_path_cost(bcf
.arg1
, bcf
.arg2
);
2288 case BRCMD_ENABLE_DEBUG
:
2289 br_stats
.flags
|= BR_DEBUG
;
2291 case BRCMD_DISABLE_DEBUG
:
2292 br_stats
.flags
&= ~BR_DEBUG
;
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
;
2301 case BRCMD_DISABLE_PROT_STATS
:
2302 br_stats
.flags
&= ~BR_PROT_STATS
;
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
));
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
))
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
);
2324 fdbis
= get_fdb_info(bcf
.arg2
, &copied
, ¬copied
);
2325 put_user(copied
, &user_buf
->copied
);
2326 put_user(notcopied
, &user_buf
->not_copied
);
2329 u_fdbs
= (struct fdb_info
*) (user_buf
+1);
2330 err
= copy_to_user(u_fdbs
, fdbis
, copied
*sizeof(struct fdb_info
));
2349 static int br_cmp(unsigned int *a
, unsigned int *b
)
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
]))
2359 if (htonl(a
[i
]) > htonl(b
[i
]))
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.
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
)
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",
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
2466 dev
->tx_queue_len
= 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)
2483 netif_start_queue(dev
);
2487 static unsigned brg_mc_hash(__u8
*dest
)
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)
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
;
2528 /* Deal with the bridge being disabled */
2529 if(!(br_stats
.flags
& BR_UP
)) {
2531 /* lp->stats.tx_errors++; */ /* this condition is NOT an error */
2532 /* or this (implied by RFC 2233) */
2533 lp
->stats
.tx_dropped
++;
2538 lp
->stats
.tx_bytes
+=skb
->len
;
2539 lp
->stats
.tx_packets
++;
2542 ++br_stats_cnt
.port_not_disable
;
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",
2565 /* Forward the packet ! */
2566 if(br_forward(skb
, port
))
2569 /* Throw packet initially */
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
);
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
))
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
)
2604 /* Is this for us? - broadcast/mulitcast/promiscuous packets need cloning,
2605 * with uni-cast we eat the packet
2608 if (dev
->flags
& IFF_PROMISC
) {
2611 else if (eth
->h_dest
[0]&1) {
2612 if (!(dev
->flags
&(IFF_ALLMULTI
))
2613 && !(brg_mc_hash(eth
->h_dest
)&lp
->groups
))
2617 else if (memcmp(eth
->h_dest
, dev
->dev_addr
, ETH_ALEN
) != 0) {
2621 /* Clone things here - we want to be transparent before we check packet data
2625 struct sk_buff
*skb2
= skb
;
2626 skb
= skb_clone(skb2
, GFP_ATOMIC
);
2633 /* Check packet length
2636 printk(KERN_DEBUG
"%s : rx len = %d\n", dev
->name
, len
);
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",
2659 skb
->pkt_type
= PACKET_HOST
;
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
;
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
);
2679 static struct net_device_stats
*brg_get_stats(struct net_device
*dev
)
2681 struct net_local
*lp
= (struct net_local
*)dev
->priv
;
2689 int __init
brg_init(void)
2693 memset(&brg_if
, 0, sizeof(brg_if
));
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
);
2704 brg_if
.dev
.init
= brg_probe
;
2706 err
= register_netdevice(&brg_if
.dev
);
2712 #if 0 /* Its here if we ever need it... */
2715 void cleanup_module(void)
2719 * Unregister the device
2722 unregister_netdevice(&the_master
.dev
);
2726 * Free up the private structure.
2729 kfree(brg_if
.dev
.priv
);
2730 brg_if
.dev
.priv
= NULL
; /* gets re-allocated by brg_probe */