OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [bridge/] [br_stp_if.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      Spanning tree protocol; interface code
3
 *      Linux ethernet bridge
4
 *
5
 *      Authors:
6
 *      Lennert Buytenhek               <buytenh@gnu.org>
7
 *
8
 *      $Id: br_stp_if.c,v 1.1.1.1 2004-04-15 01:16:26 phoenix Exp $
9
 *
10
 *      This program is free software; you can redistribute it and/or
11
 *      modify it under the terms of the GNU General Public License
12
 *      as published by the Free Software Foundation; either version
13
 *      2 of the License, or (at your option) any later version.
14
 */
15
 
16
#include <linux/kernel.h>
17
#include <linux/if_bridge.h>
18
#include <linux/smp_lock.h>
19
#include <asm/uaccess.h>
20
#include "br_private.h"
21
#include "br_private_stp.h"
22
 
23
__u16 br_make_port_id(struct net_bridge_port *p)
24
{
25
        return (p->priority << 8) | p->port_no;
26
}
27
 
28
/* called under bridge lock */
29
void br_init_port(struct net_bridge_port *p)
30
{
31
        p->port_id = br_make_port_id(p);
32
        br_become_designated_port(p);
33
        p->state = BR_STATE_BLOCKING;
34
        p->topology_change_ack = 0;
35
        p->config_pending = 0;
36
        br_timer_clear(&p->message_age_timer);
37
        br_timer_clear(&p->forward_delay_timer);
38
        br_timer_clear(&p->hold_timer);
39
}
40
 
41
/* called under bridge lock */
42
void br_stp_enable_bridge(struct net_bridge *br)
43
{
44
        struct net_bridge_port *p;
45
        struct timer_list *timer = &br->tick;
46
 
47
        init_timer(timer);
48
        timer->data = (unsigned long) br;
49
        timer->function = br_tick;
50
        timer->expires = jiffies + 1;
51
        add_timer(timer);
52
 
53
        br_timer_set(&br->hello_timer, jiffies);
54
        br_config_bpdu_generation(br);
55
 
56
        p = br->port_list;
57
        while (p != NULL) {
58
                if (p->dev->flags & IFF_UP)
59
                        br_stp_enable_port(p);
60
 
61
                p = p->next;
62
        }
63
 
64
        br_timer_set(&br->gc_timer, jiffies);
65
}
66
 
67
/* called under bridge lock */
68
void br_stp_disable_bridge(struct net_bridge *br)
69
{
70
        struct net_bridge_port *p;
71
 
72
        br->topology_change = 0;
73
        br->topology_change_detected = 0;
74
        br_timer_clear(&br->hello_timer);
75
        br_timer_clear(&br->topology_change_timer);
76
        br_timer_clear(&br->tcn_timer);
77
        br_timer_clear(&br->gc_timer);
78
        br_fdb_cleanup(br);
79
 
80
        p = br->port_list;
81
        while (p != NULL) {
82
                if (p->state != BR_STATE_DISABLED)
83
                        br_stp_disable_port(p);
84
 
85
                p = p->next;
86
        }
87
 
88
        del_timer(&br->tick);
89
}
90
 
91
/* called under bridge lock */
92
void br_stp_enable_port(struct net_bridge_port *p)
93
{
94
        br_init_port(p);
95
        br_port_state_selection(p->br);
96
}
97
 
98
/* called under bridge lock */
99
void br_stp_disable_port(struct net_bridge_port *p)
100
{
101
        struct net_bridge *br;
102
        int wasroot;
103
 
104
        br = p->br;
105
        printk(KERN_INFO "%s: port %i(%s) entering %s state\n",
106
               br->dev.name, p->port_no, p->dev->name, "disabled");
107
 
108
        wasroot = br_is_root_bridge(br);
109
        br_become_designated_port(p);
110
        p->state = BR_STATE_DISABLED;
111
        p->topology_change_ack = 0;
112
        p->config_pending = 0;
113
        br_timer_clear(&p->message_age_timer);
114
        br_timer_clear(&p->forward_delay_timer);
115
        br_timer_clear(&p->hold_timer);
116
        br_configuration_update(br);
117
        br_port_state_selection(br);
118
 
119
        if (br_is_root_bridge(br) && !wasroot)
120
                br_become_root_bridge(br);
121
}
122
 
123
/* called under bridge lock */
124
static void br_stp_change_bridge_id(struct net_bridge *br, unsigned char *addr)
125
{
126
        unsigned char oldaddr[6];
127
        struct net_bridge_port *p;
128
        int wasroot;
129
 
130
        wasroot = br_is_root_bridge(br);
131
 
132
        memcpy(oldaddr, br->bridge_id.addr, ETH_ALEN);
133
        memcpy(br->bridge_id.addr, addr, ETH_ALEN);
134
        memcpy(br->dev.dev_addr, addr, ETH_ALEN);
135
 
136
        p = br->port_list;
137
        while (p != NULL) {
138
                if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN))
139
                        memcpy(p->designated_bridge.addr, addr, ETH_ALEN);
140
 
141
                if (!memcmp(p->designated_root.addr, oldaddr, ETH_ALEN))
142
                        memcpy(p->designated_root.addr, addr, ETH_ALEN);
143
 
144
                p = p->next;
145
        }
146
 
147
        br_configuration_update(br);
148
        br_port_state_selection(br);
149
        if (br_is_root_bridge(br) && !wasroot)
150
                br_become_root_bridge(br);
151
}
152
 
153
static unsigned char br_mac_zero[6] = {0,0,0,0,0,0};
154
 
155
/* called under bridge lock */
156
void br_stp_recalculate_bridge_id(struct net_bridge *br)
157
{
158
        unsigned char *addr;
159
        struct net_bridge_port *p;
160
 
161
        addr = br_mac_zero;
162
 
163
        p = br->port_list;
164
        while (p != NULL) {
165
                if (addr == br_mac_zero ||
166
                    memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
167
                        addr = p->dev->dev_addr;
168
 
169
                p = p->next;
170
        }
171
 
172
        if (memcmp(br->bridge_id.addr, addr, ETH_ALEN))
173
                br_stp_change_bridge_id(br, addr);
174
}
175
 
176
/* called under bridge lock */
177
void br_stp_set_bridge_priority(struct net_bridge *br, int newprio)
178
{
179
        struct net_bridge_port *p;
180
        int wasroot;
181
 
182
        wasroot = br_is_root_bridge(br);
183
 
184
        p = br->port_list;
185
        while (p != NULL) {
186
                if (p->state != BR_STATE_DISABLED &&
187
                    br_is_designated_port(p)) {
188
                        p->designated_bridge.prio[0] = (newprio >> 8) & 0xFF;
189
                        p->designated_bridge.prio[1] = newprio & 0xFF;
190
                }
191
 
192
                p = p->next;
193
        }
194
 
195
        br->bridge_id.prio[0] = (newprio >> 8) & 0xFF;
196
        br->bridge_id.prio[1] = newprio & 0xFF;
197
        br_configuration_update(br);
198
        br_port_state_selection(br);
199
        if (br_is_root_bridge(br) && !wasroot)
200
                br_become_root_bridge(br);
201
}
202
 
203
/* called under bridge lock */
204
void br_stp_set_port_priority(struct net_bridge_port *p, int newprio)
205
{
206
        __u16 new_port_id;
207
 
208
        p->priority = newprio & 0xFF;
209
        new_port_id = br_make_port_id(p);
210
 
211
        if (br_is_designated_port(p))
212
                p->designated_port = new_port_id;
213
 
214
        p->port_id = new_port_id;
215
        if (!memcmp(&p->br->bridge_id, &p->designated_bridge, 8) &&
216
            p->port_id < p->designated_port) {
217
                br_become_designated_port(p);
218
                br_port_state_selection(p->br);
219
        }
220
}
221
 
222
/* called under bridge lock */
223
void br_stp_set_path_cost(struct net_bridge_port *p, int path_cost)
224
{
225
        p->path_cost = path_cost;
226
        br_configuration_update(p->br);
227
        br_port_state_selection(p->br);
228
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.