3 * Linux ethernet bridge
6 * Lennert Buytenhek <buytenh@gnu.org>
8 * $Id: br_if.c,v 1.7 2001/12/24 00:59:55 davem Exp $
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.
16 #include <linux/kernel.h>
17 #include <linux/if_arp.h>
18 #include <linux/if_bridge.h>
19 #include <linux/inetdevice.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/rtnetlink.h>
24 #include <asm/uaccess.h>
25 #include "br_private.h"
27 static int br_initial_port_cost(struct net_device
*dev
)
29 if (!strncmp(dev
->name
, "lec", 3))
32 if (!strncmp(dev
->name
, "eth", 3))
33 return 100; /* FIXME handle 100Mbps */
35 if (!strncmp(dev
->name
, "plip", 4))
41 static void destroy_nbp(void *arg
)
43 struct net_bridge_port
*p
= arg
;
48 /* called under bridge lock */
49 static void del_nbp(struct net_bridge_port
*p
)
51 struct net_device
*dev
= p
->dev
;
53 br_stp_disable_port(p
);
55 dev_set_promiscuity(dev
, -1);
58 list_del_rcu(&p
->list
);
60 br_fdb_delete_by_port(p
->br
, p
);
62 call_rcu(&p
->rcu
, destroy_nbp
, p
);
65 static void del_ifs(struct net_bridge
*br
)
67 struct list_head
*p
, *n
;
69 spin_lock_bh(&br
->lock
);
70 list_for_each_safe(p
, n
, &br
->port_list
) {
71 del_nbp(list_entry(p
, struct net_bridge_port
, list
));
73 spin_unlock_bh(&br
->lock
);
76 static struct net_bridge
*new_nb(const char *name
)
78 struct net_bridge
*br
;
79 struct net_device
*dev
;
81 dev
= alloc_netdev(sizeof(struct net_bridge
), name
,
90 br
->lock
= SPIN_LOCK_UNLOCKED
;
91 INIT_LIST_HEAD(&br
->port_list
);
92 br
->hash_lock
= RW_LOCK_UNLOCKED
;
94 br
->bridge_id
.prio
[0] = 0x80;
95 br
->bridge_id
.prio
[1] = 0x00;
96 memset(br
->bridge_id
.addr
, 0, ETH_ALEN
);
99 br
->designated_root
= br
->bridge_id
;
100 br
->root_path_cost
= 0;
102 br
->bridge_max_age
= br
->max_age
= 20 * HZ
;
103 br
->bridge_hello_time
= br
->hello_time
= 2 * HZ
;
104 br
->bridge_forward_delay
= br
->forward_delay
= 15 * HZ
;
105 br
->topology_change
= 0;
106 br
->topology_change_detected
= 0;
107 br
->ageing_time
= 300 * HZ
;
108 INIT_LIST_HEAD(&br
->age_list
);
110 br_stp_timer_init(br
);
115 /* called under bridge lock */
116 static struct net_bridge_port
*new_nbp(struct net_bridge
*br
, struct net_device
*dev
)
119 struct net_bridge_port
*p
;
121 p
= kmalloc(sizeof(*p
), GFP_ATOMIC
);
125 memset(p
, 0, sizeof(*p
));
128 p
->path_cost
= br_initial_port_cost(dev
);
132 if (br_get_port(br
, i
) == NULL
)
144 p
->state
= BR_STATE_DISABLED
;
146 list_add_rcu(&p
->list
, &br
->port_list
);
151 int br_add_bridge(const char *name
)
153 struct net_bridge
*br
;
156 if ((br
= new_nb(name
)) == NULL
)
159 ret
= register_netdev(br
->dev
);
165 int br_del_bridge(const char *name
)
167 struct net_device
*dev
;
171 dev
= __dev_get_by_name(name
);
173 ret
= -ENXIO
; /* Could not find device */
175 else if (!(dev
->priv_flags
& IFF_EBRIDGE
)) {
176 /* Attempt to delete non bridge device! */
180 else if (dev
->flags
& IFF_UP
) {
181 /* Not shutdown yet. */
186 del_ifs((struct net_bridge
*) dev
->priv
);
187 unregister_netdevice(dev
);
194 int br_add_if(struct net_bridge
*br
, struct net_device
*dev
)
196 struct net_bridge_port
*p
;
198 if (dev
->br_port
!= NULL
)
201 if (dev
->flags
& IFF_LOOPBACK
|| dev
->type
!= ARPHRD_ETHER
)
204 if (dev
->hard_start_xmit
== br_dev_xmit
)
208 spin_lock_bh(&br
->lock
);
209 if ((p
= new_nbp(br
, dev
)) == NULL
) {
210 spin_unlock_bh(&br
->lock
);
215 dev_set_promiscuity(dev
, 1);
217 br_stp_recalculate_bridge_id(br
);
218 br_fdb_insert(br
, p
, dev
->dev_addr
, 1);
219 if ((br
->dev
->flags
& IFF_UP
) && (dev
->flags
& IFF_UP
))
220 br_stp_enable_port(p
);
221 spin_unlock_bh(&br
->lock
);
226 int br_del_if(struct net_bridge
*br
, struct net_device
*dev
)
228 struct net_bridge_port
*p
;
231 spin_lock_bh(&br
->lock
);
232 if ((p
= dev
->br_port
) == NULL
|| p
->br
!= br
)
236 br_stp_recalculate_bridge_id(br
);
238 spin_unlock_bh(&br
->lock
);
243 int br_get_bridge_ifindices(int *indices
, int num
)
245 struct net_device
*dev
;
249 for (dev
= dev_base
; dev
&& i
< num
; dev
= dev
->next
) {
250 if (dev
->priv_flags
& IFF_EBRIDGE
)
251 indices
[i
++] = dev
->ifindex
;
258 void br_get_port_ifindices(struct net_bridge
*br
, int *ifindices
)
260 struct net_bridge_port
*p
;
263 list_for_each_entry_rcu(p
, &br
->port_list
, list
) {
264 ifindices
[p
->port_no
] = p
->dev
->ifindex
;
270 void __exit
br_cleanup_bridges(void)
272 struct net_device
*dev
, *nxt
;
275 for (dev
= dev_base
; dev
; dev
= nxt
) {
277 if (dev
->priv_flags
& IFF_EBRIDGE
) {
278 pr_debug("cleanup %s\n", dev
->name
);
280 del_ifs((struct net_bridge
*) dev
->priv
);
282 unregister_netdevice(dev
);