Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Generic parts | |
3 | * Linux ethernet bridge | |
4 | * | |
5 | * Authors: | |
6 | * Lennert Buytenhek <buytenh@gnu.org> | |
7 | * | |
1da177e4 LT |
8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License | |
10 | * as published by the Free Software Foundation; either version | |
11 | * 2 of the License, or (at your option) any later version. | |
12 | */ | |
13 | ||
1da177e4 LT |
14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | |
16 | #include <linux/netdevice.h> | |
17 | #include <linux/etherdevice.h> | |
18 | #include <linux/init.h> | |
cf0f02d0 SH |
19 | #include <linux/llc.h> |
20 | #include <net/llc.h> | |
7c85fbf0 | 21 | #include <net/stp.h> |
1da177e4 LT |
22 | |
23 | #include "br_private.h" | |
24 | ||
b86f81cc WC |
25 | static void __net_exit br_net_exit(struct net *net) |
26 | { | |
27 | struct net_device *dev; | |
28 | LIST_HEAD(list); | |
29 | ||
30 | rtnl_lock(); | |
31 | for_each_netdev(net, dev) | |
32 | if (dev->priv_flags & IFF_EBRIDGE) | |
33 | br_dev_delete(dev, &list); | |
34 | ||
35 | unregister_netdevice_many(&list); | |
36 | rtnl_unlock(); | |
37 | ||
38 | } | |
cf0f02d0 | 39 | |
712d6954 AD |
40 | static struct pernet_operations br_net_ops = { |
41 | .exit = br_net_exit, | |
42 | }; | |
43 | ||
b86f81cc WC |
44 | static const struct stp_proto br_stp_proto = { |
45 | .rcv = br_stp_rcv, | |
46 | }; | |
47 | ||
1da177e4 LT |
48 | static int __init br_init(void) |
49 | { | |
c0909713 SH |
50 | int err; |
51 | ||
7c85fbf0 PM |
52 | err = stp_proto_register(&br_stp_proto); |
53 | if (err < 0) { | |
28a16c97 | 54 | pr_err("bridge: can't register sap for STP\n"); |
7c85fbf0 | 55 | return err; |
cf0f02d0 SH |
56 | } |
57 | ||
87a596e0 AM |
58 | err = br_fdb_init(); |
59 | if (err) | |
17efdd45 | 60 | goto err_out; |
1da177e4 | 61 | |
712d6954 | 62 | err = register_pernet_subsys(&br_net_ops); |
c0909713 SH |
63 | if (err) |
64 | goto err_out1; | |
65 | ||
712d6954 | 66 | err = br_netfilter_init(); |
c0909713 SH |
67 | if (err) |
68 | goto err_out2; | |
69 | ||
712d6954 | 70 | err = register_netdevice_notifier(&br_device_notifier); |
32fe21c0 TG |
71 | if (err) |
72 | goto err_out3; | |
73 | ||
712d6954 AD |
74 | err = br_netlink_init(); |
75 | if (err) | |
76 | goto err_out4; | |
77 | ||
1da177e4 | 78 | brioctl_set(br_ioctl_deviceless_stub); |
1da177e4 | 79 | |
e6373c4c | 80 | #if IS_ENABLED(CONFIG_ATM_LANE) |
da678292 MM |
81 | br_fdb_test_addr_hook = br_fdb_test_addr; |
82 | #endif | |
1da177e4 | 83 | |
1da177e4 | 84 | return 0; |
712d6954 | 85 | err_out4: |
32fe21c0 | 86 | unregister_netdevice_notifier(&br_device_notifier); |
712d6954 | 87 | err_out3: |
c0909713 | 88 | br_netfilter_fini(); |
712d6954 AD |
89 | err_out2: |
90 | unregister_pernet_subsys(&br_net_ops); | |
c0909713 | 91 | err_out1: |
17efdd45 PE |
92 | br_fdb_fini(); |
93 | err_out: | |
7c85fbf0 | 94 | stp_proto_unregister(&br_stp_proto); |
c0909713 | 95 | return err; |
1da177e4 LT |
96 | } |
97 | ||
98 | static void __exit br_deinit(void) | |
99 | { | |
7c85fbf0 | 100 | stp_proto_unregister(&br_stp_proto); |
cf0f02d0 | 101 | |
11dc1f36 | 102 | br_netlink_fini(); |
1da177e4 LT |
103 | unregister_netdevice_notifier(&br_device_notifier); |
104 | brioctl_set(NULL); | |
105 | ||
712d6954 | 106 | unregister_pernet_subsys(&br_net_ops); |
1da177e4 | 107 | |
473c22d7 | 108 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
1da177e4 | 109 | |
d69efb16 | 110 | br_netfilter_fini(); |
e6373c4c | 111 | #if IS_ENABLED(CONFIG_ATM_LANE) |
da678292 MM |
112 | br_fdb_test_addr_hook = NULL; |
113 | #endif | |
1da177e4 | 114 | |
1da177e4 LT |
115 | br_fdb_fini(); |
116 | } | |
117 | ||
1da177e4 LT |
118 | module_init(br_init) |
119 | module_exit(br_deinit) | |
120 | MODULE_LICENSE("GPL"); | |
8cbb512e | 121 | MODULE_VERSION(BR_VERSION); |
bb900b27 | 122 | MODULE_ALIAS_RTNL_LINK("bridge"); |