00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include <linux/config.h>
00065 #include <linux/module.h>
00066 #include <linux/errno.h>
00067 #include <linux/types.h>
00068 #include <linux/socket.h>
00069 #include <linux/in.h>
00070
00071 #include <linux/kernel.h>
00072 #include <linux/sched.h>
00073 #include <linux/timer.h>
00074 #include <linux/malloc.h>
00075 #include <linux/string.h>
00076 #include <linux/net.h>
00077 #include <linux/inet.h>
00078 #include <linux/netdevice.h>
00079 #include <linux/inetdevice.h>
00080 #include <linux/etherdevice.h>
00081 #include <linux/skbuff.h>
00082 #include <linux/if_arp.h>
00083 #include <linux/ip.h>
00084 #include <linux/version.h>
00085 #include <linux/init.h>
00086 #include <asm/uaccess.h>
00087 #include <asm/system.h>
00088 #include <linux/rtnetlink.h>
00089 #include <net/br.h>
00090 #include <linux/proc_fs.h>
00091 #include <linux/delay.h>
00092
00093 #ifndef min
00094 #define min(a, b) (((a) <= (b)) ? (a) : (b))
00095 #endif
00096
00097 static void transmit_config(int port_no);
00098 static int root_bridge(void);
00099 static int supersedes_port_info(int port_no, Config_bpdu *config);
00100 static void record_config_information(int port_no, Config_bpdu *config);
00101 static void record_config_timeout_values(Config_bpdu *config);
00102 static void config_bpdu_generation(void);
00103 static int designated_port(int port_no);
00104 static void reply(int port_no);
00105 static void transmit_tcn(void);
00106 static void configuration_update(void);
00107 static void root_selection(void);
00108 static void designated_port_selection(void);
00109 static void become_designated_port(int port_no);
00110 static void port_state_selection(void);
00111 static void make_forwarding(int port_no);
00112 static void topology_change_detection(void);
00113 static void topology_change_acknowledged(void);
00114 static void acknowledge_topology_change(int port_no);
00115 static void make_blocking(int port_no);
00116 static void set_port_state(int port_no, int state);
00117 static void received_config_bpdu(int port_no, Config_bpdu *config);
00118 static void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn);
00119 static void hello_timer_expiry(void);
00120 static void message_age_timer_expiry(int port_no);
00121 static void forward_delay_timer_expiry(int port_no);
00122 static int designated_for_some_port(void);
00123 static void tcn_timer_expiry(void);
00124 static void topology_change_timer_expiry(void);
00125 static void hold_timer_expiry(int port_no);
00126 static void br_init_port(int port_no);
00127 static void enable_port(int port_no);
00128 static void disable_port(int port_no);
00129 static void set_bridge_priority(bridge_id_t *new_bridge_id);
00130 static void set_port_priority(int port_no);
00131 static void set_path_cost(int port_no, unsigned short path_cost);
00132 static void start_hello_timer(void);
00133 static void stop_hello_timer(void);
00134 static int hello_timer_expired(void);
00135 static void start_tcn_timer(void);
00136 static void stop_tcn_timer(void);
00137 static int tcn_timer_expired(void);
00138 static void start_topology_change_timer(void);
00139 static void stop_topology_change_timer(void);
00140 static int topology_change_timer_expired(void);
00141 static void start_message_age_timer(int port_no, unsigned short message_age);
00142 static void stop_message_age_timer(int port_no);
00143 static int message_age_timer_expired(int port_no);
00144 static void start_forward_delay_timer(int port_no);
00145 static void stop_forward_delay_timer(int port_no);
00146 static int forward_delay_timer_expired(int port_no);
00147 static void start_hold_timer(int port_no);
00148 static void stop_hold_timer(int port_no);
00149 static int hold_timer_expired(int port_no);
00150 static int br_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
00151 static void br_tick(unsigned long arg);
00152 static int br_forward(struct sk_buff *skb, int port);
00153 static int br_port_cost(struct device *dev);
00154 static void br_bpdu(struct sk_buff *skb, int port);
00155 static int br_cmp(unsigned int *a, unsigned int *b);
00156 static int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu);
00157 static int send_config_bpdu(int port_no, Config_bpdu *config_bpdu);
00158 static int find_port(struct device *dev);
00159 static void br_add_local_mac(unsigned char *mac);
00160 static int br_flood(struct sk_buff *skb, int port);
00161 static int br_drop(struct sk_buff *skb);
00162 static int br_learn(struct sk_buff *skb, int port);
00163 static int br_protocol_ok(unsigned short protocol);
00164 static int br_find_port(int ifindex);
00165 static void br_get_ifnames(void);
00166 static int brg_rx(struct sk_buff *skb, int port);
00167
00168 static unsigned char bridge_ula[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
00169 static Bridge_data bridge_info;
00170 Port_data port_info[All_ports];
00171
00172
00173
00174
00175 static int max_port_used = 0;
00176
00177
00178 struct fdb *newfdb[All_ports];
00179 int allocated_fdb_cnt = 0;
00180
00181
00182 int max_mcast_per_period = MAX_MCAST_PER_PERIOD;
00183 int mcast_hold_time = MCAST_HOLD_TIME;
00184
00185
00186 static Config_bpdu config_bpdu;
00187 static Tcn_bpdu tcn_bpdu;
00188 static unsigned char port_priority[All_ports];
00189 static unsigned char user_port_state[All_ports];
00190
00191 static Timer hello_timer;
00192 static Timer tcn_timer;
00193 static Timer topology_change_timer;
00194 static Timer message_age_timer[All_ports];
00195 static Timer forward_delay_timer[All_ports];
00196 static Timer hold_timer[All_ports];
00197
00198
00199 unsigned int fdb_aging_time = FDB_TIMEOUT;
00200
00201 struct br_stat br_stats;
00202 #define br_stats_cnt br_stats.packet_cnts
00203
00204 static struct timer_list tl;
00205
00206
00207
00208
00209
00210
00211 static struct notifier_block br_dev_notifier={
00212 br_device_event,
00213 NULL,
00214 0
00215 };
00216
00217
00218
00219
00220
00221 struct brg_if {
00222 struct device dev;
00223 char name[IFNAMSIZ];
00224 };
00225 static struct brg_if brg_if;
00226
00227
00228
00229
00230
00231 static inline int find_port(struct device *dev)
00232 {
00233 int i;
00234
00235 for (i = One; i <= No_of_ports; i++)
00236 if (port_info[i].dev == dev)
00237 return(i);
00238 return(0);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 #define BR_PROTOCOL_HASH(x) (x % BR_MAX_PROTOCOLS)
00250
00251
00252
00253 static int inline br_protocol_ok(unsigned short protocol)
00254 {
00255 unsigned x;
00256
00257
00258 if (br_stats.flags & BR_PROT_STATS)
00259 {
00260 for(x=0;x<BR_MAX_PROT_STATS && br_stats.prot_id[x]!=protocol && br_stats.prot_id[x];x++);
00261 if (x<BR_MAX_PROT_STATS)
00262 {
00263 br_stats.prot_id[x]=protocol;br_stats.prot_counter[x]++;
00264 }
00265 }
00266
00267 for (x=BR_PROTOCOL_HASH(protocol); br_stats.protocols[x]!=0;)
00268 {
00269 if (br_stats.protocols[x]==protocol)
00270 return !br_stats.policy;
00271 x++;
00272 if (x==BR_MAX_PROTOCOLS)
00273 x=0;
00274 }
00275 return br_stats.policy;
00276 }
00277
00278
00279
00280 static int br_add_exempt_protocol(unsigned short p)
00281 {
00282 unsigned x;
00283 if (p == 0) return -EINVAL;
00284 if (br_stats.exempt_protocols > BR_MAX_PROTOCOLS-2) return -EXFULL;
00285 for (x=BR_PROTOCOL_HASH(p);br_stats.protocols[x]!=0;) {
00286 if (br_stats.protocols[x]==p) return 0;
00287 x++;
00288 if (x==BR_MAX_PROTOCOLS) x=0;
00289 }
00290 br_stats.protocols[x]=p;
00291 br_stats.exempt_protocols++;
00292 return 0;
00293 }
00294
00295
00296 static int br_set_policy(int policy)
00297 {
00298 if (policy>1) return -EINVAL;
00299 br_stats.policy=policy;
00300
00301 memset(br_stats.protocols,0,sizeof(br_stats.protocols));
00302 br_stats.exempt_protocols = 0;
00303 return 0;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 static void transmit_config(int port_no)
00318 {
00319 if (hold_timer[port_no].active) {
00320 port_info[port_no].config_pending = TRUE;
00321 } else {
00322 config_bpdu.type = BPDU_TYPE_CONFIG;
00323 config_bpdu.root_id = bridge_info.designated_root;
00324
00325 config_bpdu.root_path_cost = bridge_info.root_path_cost;
00326
00327 config_bpdu.bridge_id = bridge_info.bridge_id;
00328
00329 config_bpdu.port_id = port_info[port_no].port_id;
00330
00331
00332
00333 if (root_bridge()) {
00334 config_bpdu.message_age = Zero;
00335 } else {
00336 config_bpdu.message_age
00337 = (message_age_timer[bridge_info.root_port].value
00338 + Message_age_increment) << 8;
00339 }
00340
00341 config_bpdu.max_age = bridge_info.max_age << 8;
00342 config_bpdu.hello_time = bridge_info.hello_time << 8;
00343 config_bpdu.forward_delay = bridge_info.forward_delay << 8;
00344 config_bpdu.top_change_ack =
00345 port_info[port_no].top_change_ack;
00346
00347 port_info[port_no].top_change_ack = 0;
00348
00349 config_bpdu.top_change =
00350 bridge_info.top_change;
00351
00352 send_config_bpdu(port_no, &config_bpdu);
00353 port_info[port_no].config_pending = FALSE;
00354 start_hold_timer(port_no);
00355 }
00356
00357
00358
00359 mark_bh(NET_BH);
00360 }
00361
00362 static int root_bridge(void)
00363 {
00364 return (br_cmp(bridge_info.designated_root.BRIDGE_ID,
00365 bridge_info.bridge_id.BRIDGE_ID)?FALSE:TRUE);
00366 }
00367
00368 static int supersedes_port_info(int port_no, Config_bpdu *config)
00369 {
00370 return (
00371 (br_cmp(config->root_id.BRIDGE_ID,
00372 port_info[port_no].designated_root.BRIDGE_ID) < 0)
00373 ||
00374 ((br_cmp(config->root_id.BRIDGE_ID,
00375 port_info[port_no].designated_root.BRIDGE_ID) == 0
00376 )
00377 &&
00378 ((config->root_path_cost
00379 < port_info[port_no].designated_cost
00380 )
00381 ||
00382 ((config->root_path_cost
00383 == port_info[port_no].designated_cost
00384 )
00385 &&
00386 ((br_cmp(config->bridge_id.BRIDGE_ID,
00387 port_info[port_no].designated_bridge.BRIDGE_ID) < 0
00388 )
00389 ||
00390 ((br_cmp(config->bridge_id.BRIDGE_ID,
00391 port_info[port_no].designated_bridge.BRIDGE_ID) == 0
00392 )
00393 &&
00394 ((br_cmp(config->bridge_id.BRIDGE_ID,
00395 bridge_info.bridge_id.BRIDGE_ID) != 0
00396 )
00397 ||
00398 (config->port_id <=
00399 port_info[port_no].designated_port
00400 )
00401 ))))))
00402 );
00403 }
00404
00405 static void record_config_information(int port_no, Config_bpdu *config)
00406 {
00407 port_info[port_no].designated_root = config->root_id;
00408 port_info[port_no].designated_cost = config->root_path_cost;
00409 port_info[port_no].designated_bridge = config->bridge_id;
00410 port_info[port_no].designated_port = config->port_id;
00411 start_message_age_timer(port_no, config->message_age);
00412 }
00413
00414 static void record_config_timeout_values(Config_bpdu *config)
00415 {
00416 bridge_info.max_age = config->max_age >> 8;
00417 bridge_info.hello_time = config->hello_time >> 8;
00418 bridge_info.forward_delay = config->forward_delay >> 8;
00419 bridge_info.top_change = config->top_change >> 8;
00420 }
00421
00422 static void config_bpdu_generation(void)
00423 {
00424 int port_no;
00425 for (port_no = One; port_no <= No_of_ports; port_no++) {
00426 if (designated_port(port_no)
00427 &&
00428 (port_info[port_no].state != Disabled)
00429 ) {
00430 transmit_config(port_no);
00431 }
00432 }
00433 }
00434
00435 static int designated_port(int port_no)
00436 {
00437 return ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
00438 bridge_info.bridge_id.BRIDGE_ID) == 0
00439 )
00440 &&
00441 (port_info[port_no].designated_port
00442 == port_info[port_no].port_id
00443 )
00444 );
00445 }
00446
00447 static void reply(int port_no)
00448 {
00449 transmit_config(port_no);
00450 }
00451
00452 static void transmit_tcn(void)
00453 {
00454 int port_no;
00455
00456 port_no = bridge_info.root_port;
00457 tcn_bpdu.type = BPDU_TYPE_TOPO_CHANGE;
00458 send_tcn_bpdu(port_no, &tcn_bpdu);
00459 }
00460
00461 static void configuration_update(void)
00462 {
00463 root_selection();
00464
00465 designated_port_selection();
00466
00467 }
00468
00469 static void root_selection(void)
00470 {
00471 int root_port;
00472 int port_no;
00473 root_port = No_port;
00474 for (port_no = One; port_no <= No_of_ports; port_no++) {
00475 if (((!designated_port(port_no))
00476 &&
00477 (port_info[port_no].state != Disabled)
00478 &&
00479 (br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
00480 bridge_info.bridge_id.BRIDGE_ID) < 0)
00481 )
00482 &&
00483 ((root_port == No_port)
00484 ||
00485 (br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
00486 port_info[root_port].designated_root.BRIDGE_ID) < 0
00487 )
00488 ||
00489 ((br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
00490 port_info[root_port].designated_root.BRIDGE_ID) == 0
00491 )
00492 &&
00493 (((port_info[port_no].designated_cost
00494 + port_info[port_no].path_cost
00495 )
00496 <
00497 (port_info[root_port].designated_cost
00498 + port_info[root_port].path_cost
00499 )
00500 )
00501 ||
00502 (((port_info[port_no].designated_cost
00503 + port_info[port_no].path_cost
00504 )
00505 ==
00506 (port_info[root_port].designated_cost
00507 + port_info[root_port].path_cost
00508 )
00509 )
00510 &&
00511 ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
00512 port_info[root_port].designated_bridge.BRIDGE_ID) < 0
00513 )
00514 ||
00515 ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
00516 port_info[root_port].designated_bridge.BRIDGE_ID) == 0
00517 )
00518 &&
00519 ((port_info[port_no].designated_port
00520 < port_info[root_port].designated_port
00521 )
00522 ||
00523 ((port_info[port_no].designated_port
00524 == port_info[root_port].designated_port
00525 )
00526 &&
00527 (port_info[port_no].port_id
00528 < port_info[root_port].port_id
00529 )
00530 ))))))))) {
00531 root_port = port_no;
00532 }
00533 }
00534 bridge_info.root_port = root_port;
00535
00536 if (root_port == No_port) {
00537 #ifdef DEBUG_STP
00538 if (br_stats.flags & BR_DEBUG)
00539 printk(KERN_DEBUG "root_selection: becomes root\n");
00540 #endif
00541 bridge_info.designated_root = bridge_info.bridge_id;
00542
00543 bridge_info.root_path_cost = Zero;
00544 } else {
00545 bridge_info.designated_root = port_info[root_port].designated_root;
00546
00547 bridge_info.root_path_cost = (port_info[root_port].designated_cost
00548 + port_info[root_port].path_cost
00549 );
00550 }
00551 }
00552
00553 static void designated_port_selection(void)
00554 {
00555 int port_no;
00556
00557 for (port_no = One; port_no <= No_of_ports; port_no++) {
00558 if(port_info[port_no].state == Disabled)
00559 continue;
00560 if (designated_port(port_no)
00561 ||
00562 (
00563 br_cmp(port_info[port_no].designated_root.BRIDGE_ID,
00564 bridge_info.designated_root.BRIDGE_ID) != 0
00565 )
00566 ||
00567 (bridge_info.root_path_cost
00568 < port_info[port_no].designated_cost
00569 )
00570 ||
00571 ((bridge_info.root_path_cost
00572 == port_info[port_no].designated_cost
00573 )
00574 &&
00575 ((br_cmp(bridge_info.bridge_id.BRIDGE_ID,
00576 port_info[port_no].designated_bridge.BRIDGE_ID) < 0
00577 )
00578 ||
00579 ((br_cmp(bridge_info.bridge_id.BRIDGE_ID,
00580 port_info[port_no].designated_bridge.BRIDGE_ID) == 0
00581 )
00582 &&
00583 (port_info[port_no].port_id
00584 <= port_info[port_no].designated_port
00585 )
00586 )))) {
00587 become_designated_port(port_no);
00588 }
00589 }
00590 }
00591
00592 static void become_designated_port(int port_no)
00593 {
00594
00595
00596 port_info[port_no].designated_root = bridge_info.designated_root;
00597
00598 port_info[port_no].designated_cost = bridge_info.root_path_cost;
00599
00600 port_info[port_no].designated_bridge = bridge_info.bridge_id;
00601
00602 port_info[port_no].designated_port = port_info[port_no].port_id;
00603 }
00604
00605 static void port_state_selection(void)
00606 {
00607 int port_no;
00608 char *state_str;
00609 for (port_no = One; port_no <= No_of_ports; port_no++) {
00610
00611 if(port_info[port_no].state == Disabled)
00612 continue;
00613 if (port_no == bridge_info.root_port) {
00614 state_str = "root";
00615 port_info[port_no].config_pending = FALSE;
00616 port_info[port_no].top_change_ack = 0;
00617 make_forwarding(port_no);
00618 } else if (designated_port(port_no)) {
00619 state_str = "designated";
00620 stop_message_age_timer(port_no);
00621 make_forwarding(port_no);
00622 } else {
00623 state_str = "blocking";
00624 port_info[port_no].config_pending = FALSE;
00625 port_info[port_no].top_change_ack = 0;
00626 make_blocking(port_no);
00627 }
00628 #ifdef DEBUG_STP
00629 if (br_stats.flags & BR_DEBUG)
00630 printk(KERN_DEBUG "port_state_selection: becomes %s port %d\n",
00631 state_str, port_no);
00632 #endif
00633
00634 }
00635
00636 }
00637
00638 static void make_forwarding(int port_no)
00639 {
00640 if (port_info[port_no].state == Blocking) {
00641 set_port_state(port_no, Listening);
00642 start_forward_delay_timer(port_no);
00643 }
00644 }
00645
00646 static void topology_change_detection(void)
00647 {
00648 #ifdef DEBUG_STP
00649 if ((br_stats.flags & BR_DEBUG)
00650 && (bridge_info.top_change_detected == 0))
00651 printk(KERN_DEBUG "topology_change_detected\n");
00652 #endif
00653 if (root_bridge()) {
00654 bridge_info.top_change = 1;
00655 start_topology_change_timer();
00656 } else if (!(bridge_info.top_change_detected)) {
00657 transmit_tcn();
00658 start_tcn_timer();
00659 }
00660 bridge_info.top_change_detected = 1;
00661 }
00662
00663 static void topology_change_acknowledged(void)
00664 {
00665 #ifdef DEBUG_STP
00666 if (br_stats.flags & BR_DEBUG)
00667 printk(KERN_DEBUG "topology_change_acked\n");
00668 #endif
00669 bridge_info.top_change_detected = 0;
00670 stop_tcn_timer();
00671 }
00672
00673 static void acknowledge_topology_change(int port_no)
00674 {
00675 port_info[port_no].top_change_ack = 1;
00676 transmit_config(port_no);
00677 }
00678
00679 static void make_blocking(int port_no)
00680 {
00681
00682 if ((port_info[port_no].state != Disabled)
00683 &&
00684 (port_info[port_no].state != Blocking)
00685
00686 ) {
00687 if ((port_info[port_no].state == Forwarding)
00688 ||
00689 (port_info[port_no].state == Learning)
00690 ) {
00691 topology_change_detection();
00692
00693 }
00694 set_port_state(port_no, Blocking);
00695 stop_forward_delay_timer(port_no);
00696 }
00697 }
00698
00699 static void set_port_state(int port_no, int state)
00700 {
00701 port_info[port_no].state = state;
00702 }
00703
00704 static void received_config_bpdu(int port_no, Config_bpdu *config)
00705 {
00706 int root;
00707
00708 root = root_bridge();
00709 if (port_info[port_no].state != Disabled) {
00710
00711 #ifdef DEBUG_STP
00712 if (br_stats.flags & BR_DEBUG)
00713 printk(KERN_DEBUG "received_config_bpdu: port %d\n",
00714 port_no);
00715 #endif
00716 if (supersedes_port_info(port_no, config)) {
00717
00718 record_config_information(port_no, config);
00719
00720 configuration_update();
00721
00722 port_state_selection();
00723
00724 if ((!root_bridge()) && root) {
00725 stop_hello_timer();
00726 if (bridge_info.top_change_detected) {
00727 stop_topology_change_timer();
00728 transmit_tcn();
00729 start_tcn_timer();
00730 }
00731 }
00732 if (port_no == bridge_info.root_port) {
00733 record_config_timeout_values(config);
00734
00735 config_bpdu_generation();
00736 if (config->top_change_ack) {
00737 topology_change_acknowledged();
00738 }
00739 }
00740 } else if (designated_port(port_no)) {
00741 reply(port_no);
00742
00743 }
00744 }
00745 }
00746
00747 static void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn)
00748 {
00749 if (port_info[port_no].state != Disabled) {
00750 #ifdef DEBUG_STP
00751 if (br_stats.flags & BR_DEBUG)
00752 printk(KERN_DEBUG "received_tcn_bpdu: port %d\n",
00753 port_no);
00754 #endif
00755 if (designated_port(port_no)) {
00756 topology_change_detection();
00757
00758 acknowledge_topology_change(port_no);
00759 }
00760 }
00761 }
00762
00763 static void hello_timer_expiry(void)
00764 {
00765 config_bpdu_generation();
00766 start_hello_timer();
00767 }
00768
00769 static void message_age_timer_expiry(int port_no)
00770 {
00771 int root;
00772 root = root_bridge();
00773
00774 #ifdef DEBUG_STP
00775 if (br_stats.flags & BR_DEBUG)
00776 printk(KERN_DEBUG "message_age_timer_expiry: port %d\n",
00777 port_no);
00778 #endif
00779 become_designated_port(port_no);
00780
00781 configuration_update();
00782
00783 port_state_selection();
00784
00785 if ((root_bridge()) && (!root)) {
00786
00787 bridge_info.max_age = bridge_info.bridge_max_age;
00788 bridge_info.hello_time = bridge_info.bridge_hello_time;
00789 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
00790 topology_change_detection();
00791
00792 stop_tcn_timer();
00793 config_bpdu_generation();
00794
00795 start_hello_timer();
00796 }
00797 }
00798
00799 static void forward_delay_timer_expiry(int port_no)
00800 {
00801 if (port_info[port_no].state == Listening)
00802 {
00803 set_port_state(port_no, Learning);
00804 start_forward_delay_timer(port_no);
00805 }
00806 else if (port_info[port_no].state == Learning)
00807 {
00808
00809 set_port_state(port_no, Forwarding);
00810 if (designated_for_some_port())
00811 {
00812 topology_change_detection();
00813
00814 }
00815 }
00816 }
00817
00818 static int designated_for_some_port(void)
00819 {
00820 int port_no;
00821
00822 for (port_no = One; port_no <= No_of_ports; port_no++)
00823 {
00824 if(port_info[port_no].state == Disabled)
00825 continue;
00826 if ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID,
00827 bridge_info.bridge_id.BRIDGE_ID) == 0))
00828 {
00829 return (TRUE);
00830 }
00831 }
00832 return (FALSE);
00833 }
00834
00835 static void tcn_timer_expiry(void)
00836 {
00837 transmit_tcn();
00838 start_tcn_timer();
00839 }
00840
00841 static void topology_change_timer_expiry(void)
00842 {
00843 bridge_info.top_change_detected = 0;
00844 bridge_info.top_change = 0;
00845
00846 }
00847
00848 static void hold_timer_expiry(int port_no)
00849 {
00850 if (port_info[port_no].config_pending)
00851 {
00852 transmit_config(port_no);
00853 }
00854 }
00855
00856
00857
00858 int br_tree_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
00859 {
00860 int size;
00861 int len=0;
00862 off_t pos=0;
00863 char* pbuffer;
00864
00865 if(0==offset)
00866 {
00867
00868 size = sprintf(buffer,"%s","MAC address Device Flags Age (sec.)\n");
00869 len=size;
00870 }
00871
00872 pbuffer=&buffer[len];
00873 sprintf_avl(&pbuffer,NULL,&pos,&len,offset,length);
00874
00875 *start = buffer+len-(pos-offset);
00876 len = pos-offset;
00877 if (len>length)
00878 len = length;
00879
00880 return len;
00881 }
00882 #ifdef CONFIG_PROC_FS
00883 struct proc_dir_entry proc_net_bridge= {
00884 PROC_NET_BRIDGE, 6, "bridge",
00885 S_IFREG | S_IRUGO, 1, 0, 0,
00886 0, &proc_net_inode_operations,
00887 br_tree_get_info
00888 };
00889 #endif
00890 __initfunc(void br_init(void))
00891 {
00892 int port_no;
00893
00894 printk(KERN_INFO "NET4: Ethernet Bridge 007 for NET4.0\n");
00895
00896
00897 bridge_info.instance = 0;
00898 brg_init();
00899
00900 max_port_used = 0;
00901
00902
00903
00904
00905
00906
00907 bridge_info.topology_change_time = BRIDGE_MAX_AGE + BRIDGE_FORWARD_DELAY;
00908
00909 bridge_info.designated_root = bridge_info.bridge_id;
00910 bridge_info.root_path_cost = Zero;
00911 bridge_info.root_port = No_port;
00912 #ifdef DEBUG_STP
00913 printk(KERN_INFO "br_init: becomes root\n");
00914 #endif
00915
00916 bridge_info.bridge_max_age = BRIDGE_MAX_AGE;
00917 bridge_info.bridge_hello_time = BRIDGE_HELLO_TIME;
00918 bridge_info.bridge_forward_delay = BRIDGE_FORWARD_DELAY;
00919 bridge_info.hold_time = HOLD_TIME;
00920
00921 bridge_info.max_age = bridge_info.bridge_max_age;
00922 bridge_info.hello_time = bridge_info.bridge_hello_time;
00923 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
00924
00925 bridge_info.top_change_detected = 0;
00926 bridge_info.top_change = 0;
00927 stop_tcn_timer();
00928 stop_topology_change_timer();
00929 memset(newfdb, 0, sizeof(newfdb));
00930 for (port_no = One; port_no <= No_of_ports; port_no++) {
00931
00932 user_port_state[port_no] = Disabled;
00933 port_priority[port_no] = 128;
00934 br_init_port(port_no);
00935 disable_port(port_no);
00936 }
00937 #if 0
00938 port_state_selection();
00939 config_bpdu_generation();
00940
00941 tl.expires = jiffies+HZ;
00942 tl.function = br_tick;
00943 add_timer(&tl);
00944 #endif
00945
00946 register_netdevice_notifier(&br_dev_notifier);
00947 br_stats.flags = 0; ;
00948 br_stats.policy = BR_ACCEPT;
00949 br_stats.exempt_protocols = 0;
00950
00951
00952 #ifdef CONFIG_PROC_FS
00953 proc_net_register(&proc_net_bridge);
00954 #endif
00955 }
00956
00957 static inline unsigned short make_port_id(int port_no)
00958 {
00959 return (port_priority[port_no] << 8) | port_no;
00960 }
00961
00962 static void br_init_port(int port_no)
00963 {
00964 port_info[port_no].port_id = make_port_id(port_no);
00965 become_designated_port(port_no);
00966 set_port_state(port_no, Blocking);
00967 port_info[port_no].top_change_ack = 0;
00968 port_info[port_no].config_pending = FALSE;
00969 stop_message_age_timer(port_no);
00970 stop_forward_delay_timer(port_no);
00971 stop_hold_timer(port_no);
00972 }
00973
00974 static void enable_port(int port_no)
00975 {
00976 br_init_port(port_no);
00977 port_state_selection();
00978 }
00979
00980 static void disable_port(int port_no)
00981 {
00982 int root;
00983
00984 root = root_bridge();
00985 become_designated_port(port_no);
00986 set_port_state(port_no, Disabled);
00987 port_info[port_no].top_change_ack = 0;
00988 port_info[port_no].config_pending = FALSE;
00989 stop_message_age_timer(port_no);
00990 stop_forward_delay_timer(port_no);
00991 configuration_update();
00992 port_state_selection();
00993 if ((root_bridge()) && (!root)) {
00994 bridge_info.max_age = bridge_info.bridge_max_age;
00995 bridge_info.hello_time = bridge_info.bridge_hello_time;
00996 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
00997 topology_change_detection();
00998 stop_tcn_timer();
00999 config_bpdu_generation();
01000 start_hello_timer();
01001 }
01002 }
01003
01004
01005 static void set_bridge_priority(bridge_id_t *new_bridge_id)
01006
01007 {
01008
01009 int root;
01010 int port_no;
01011 root = root_bridge();
01012 for (port_no = One; port_no <= No_of_ports; port_no++) {
01013 if(port_info[port_no].state == Disabled)
01014 continue;
01015 if (designated_port(port_no)) {
01016 port_info[port_no].designated_bridge = *new_bridge_id;
01017 }
01018 }
01019
01020 bridge_info.bridge_id = *new_bridge_id;
01021 configuration_update();
01022 port_state_selection();
01023 if ((root_bridge()) && (!root)) {
01024 bridge_info.max_age = bridge_info.bridge_max_age;
01025 bridge_info.hello_time = bridge_info.bridge_hello_time;
01026 bridge_info.forward_delay = bridge_info.bridge_forward_delay;
01027 topology_change_detection();
01028 stop_tcn_timer();
01029 config_bpdu_generation(),
01030 start_hello_timer();
01031 }
01032 }
01033
01034 static void set_port_priority(int port_no)
01035
01036 {int new_port_id = make_port_id(port_no);
01037
01038 if (designated_port(port_no)) {
01039 port_info[port_no].designated_port = new_port_id;
01040 }
01041 port_info[port_no].port_id = new_port_id;
01042 if ((br_cmp(bridge_info.bridge_id.BRIDGE_ID,
01043 port_info[port_no].designated_bridge.BRIDGE_ID) == 0
01044 )
01045 &&
01046 (port_info[port_no].port_id
01047 < port_info[port_no].designated_port
01048
01049 )
01050 )
01051 {
01052 become_designated_port(port_no);
01053 port_state_selection();
01054 }
01055 }
01056
01057 static void set_path_cost(int port_no, unsigned short path_cost)
01058
01059 {
01060 port_info[port_no].path_cost = path_cost;
01061 configuration_update();
01062 port_state_selection();
01063 }
01064
01065 static void br_tick(unsigned long arg)
01066 {
01067 int port_no;
01068
01069 if(!(br_stats.flags & BR_UP))
01070 return;
01071
01072 if (hello_timer_expired())
01073 hello_timer_expiry();
01074
01075 if (tcn_timer_expired())
01076 tcn_timer_expiry();
01077
01078 if (topology_change_timer_expired())
01079 topology_change_timer_expiry();
01080
01081 for (port_no = One; port_no <= No_of_ports; port_no++)
01082 {
01083 if(port_info[port_no].state == Disabled)
01084 continue;
01085
01086 if (forward_delay_timer_expired(port_no))
01087 forward_delay_timer_expiry(port_no);
01088
01089 if (message_age_timer_expired(port_no))
01090 message_age_timer_expiry(port_no);
01091
01092 if (hold_timer_expired(port_no))
01093 hold_timer_expiry(port_no);
01094 }
01095
01096 tl.expires = jiffies+HZ;
01097 tl.function = br_tick;
01098 add_timer(&tl);
01099 }
01100
01101 static void start_hello_timer(void)
01102 {
01103 hello_timer.value = 0;
01104 hello_timer.active = TRUE;
01105 }
01106
01107 static void stop_hello_timer(void)
01108 {
01109 hello_timer.active = FALSE;
01110 }
01111
01112 static int hello_timer_expired(void)
01113 {
01114 if (hello_timer.active && (++hello_timer.value >= bridge_info.hello_time))
01115 {
01116 hello_timer.active = FALSE;
01117 return (TRUE);
01118 }
01119 return (FALSE);
01120 }
01121
01122 static void start_tcn_timer(void)
01123 {
01124 tcn_timer.value = 0;
01125 tcn_timer.active = TRUE;
01126 }
01127
01128 static void stop_tcn_timer(void)
01129 {
01130 tcn_timer.active = FALSE;
01131 }
01132
01133 static int tcn_timer_expired(void)
01134 {
01135 if (tcn_timer.active && (++tcn_timer.value >= bridge_info.bridge_hello_time))
01136 {
01137 tcn_timer.active = FALSE;
01138 return (TRUE);
01139 }
01140 return (FALSE);
01141
01142 }
01143
01144 static void start_topology_change_timer(void)
01145 {
01146 topology_change_timer.value = 0;
01147 topology_change_timer.active = TRUE;
01148 }
01149
01150 static void stop_topology_change_timer(void)
01151 {
01152 topology_change_timer.