xref: /openbmc/linux/net/bridge/br.c (revision bb900b27)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *	Generic parts
31da177e4SLinus Torvalds  *	Linux ethernet bridge
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *	Authors:
61da177e4SLinus Torvalds  *	Lennert Buytenhek		<buytenh@gnu.org>
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  *	This program is free software; you can redistribute it and/or
91da177e4SLinus Torvalds  *	modify it under the terms of the GNU General Public License
101da177e4SLinus Torvalds  *	as published by the Free Software Foundation; either version
111da177e4SLinus Torvalds  *	2 of the License, or (at your option) any later version.
121da177e4SLinus Torvalds  */
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds #include <linux/module.h>
151da177e4SLinus Torvalds #include <linux/kernel.h>
161da177e4SLinus Torvalds #include <linux/netdevice.h>
171da177e4SLinus Torvalds #include <linux/etherdevice.h>
181da177e4SLinus Torvalds #include <linux/init.h>
19cf0f02d0SStephen Hemminger #include <linux/llc.h>
20cf0f02d0SStephen Hemminger #include <net/llc.h>
217c85fbf0SPatrick McHardy #include <net/stp.h>
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds #include "br_private.h"
241da177e4SLinus Torvalds 
257c85fbf0SPatrick McHardy static const struct stp_proto br_stp_proto = {
267c85fbf0SPatrick McHardy 	.rcv	= br_stp_rcv,
277c85fbf0SPatrick McHardy };
28cf0f02d0SStephen Hemminger 
29712d6954SAlexey Dobriyan static struct pernet_operations br_net_ops = {
30712d6954SAlexey Dobriyan 	.exit	= br_net_exit,
31712d6954SAlexey Dobriyan };
32712d6954SAlexey Dobriyan 
331da177e4SLinus Torvalds static int __init br_init(void)
341da177e4SLinus Torvalds {
35c0909713SStephen Hemminger 	int err;
36c0909713SStephen Hemminger 
377c85fbf0SPatrick McHardy 	err = stp_proto_register(&br_stp_proto);
387c85fbf0SPatrick McHardy 	if (err < 0) {
3928a16c97Sstephen hemminger 		pr_err("bridge: can't register sap for STP\n");
407c85fbf0SPatrick McHardy 		return err;
41cf0f02d0SStephen Hemminger 	}
42cf0f02d0SStephen Hemminger 
4387a596e0SAkinobu Mita 	err = br_fdb_init();
4487a596e0SAkinobu Mita 	if (err)
4517efdd45SPavel Emelyanov 		goto err_out;
461da177e4SLinus Torvalds 
47712d6954SAlexey Dobriyan 	err = register_pernet_subsys(&br_net_ops);
48c0909713SStephen Hemminger 	if (err)
49c0909713SStephen Hemminger 		goto err_out1;
50c0909713SStephen Hemminger 
51712d6954SAlexey Dobriyan 	err = br_netfilter_init();
52c0909713SStephen Hemminger 	if (err)
53c0909713SStephen Hemminger 		goto err_out2;
54c0909713SStephen Hemminger 
55712d6954SAlexey Dobriyan 	err = register_netdevice_notifier(&br_device_notifier);
5632fe21c0SThomas Graf 	if (err)
5732fe21c0SThomas Graf 		goto err_out3;
5832fe21c0SThomas Graf 
59712d6954SAlexey Dobriyan 	err = br_netlink_init();
60712d6954SAlexey Dobriyan 	if (err)
61712d6954SAlexey Dobriyan 		goto err_out4;
62712d6954SAlexey Dobriyan 
631da177e4SLinus Torvalds 	brioctl_set(br_ioctl_deviceless_stub);
641da177e4SLinus Torvalds 
65da678292SMichał Mirosław #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
66da678292SMichał Mirosław 	br_fdb_test_addr_hook = br_fdb_test_addr;
67da678292SMichał Mirosław #endif
681da177e4SLinus Torvalds 
691da177e4SLinus Torvalds 	return 0;
70712d6954SAlexey Dobriyan err_out4:
7132fe21c0SThomas Graf 	unregister_netdevice_notifier(&br_device_notifier);
72712d6954SAlexey Dobriyan err_out3:
73c0909713SStephen Hemminger 	br_netfilter_fini();
74712d6954SAlexey Dobriyan err_out2:
75712d6954SAlexey Dobriyan 	unregister_pernet_subsys(&br_net_ops);
76c0909713SStephen Hemminger err_out1:
7717efdd45SPavel Emelyanov 	br_fdb_fini();
7817efdd45SPavel Emelyanov err_out:
797c85fbf0SPatrick McHardy 	stp_proto_unregister(&br_stp_proto);
80c0909713SStephen Hemminger 	return err;
811da177e4SLinus Torvalds }
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds static void __exit br_deinit(void)
841da177e4SLinus Torvalds {
857c85fbf0SPatrick McHardy 	stp_proto_unregister(&br_stp_proto);
86cf0f02d0SStephen Hemminger 
8711dc1f36SStephen Hemminger 	br_netlink_fini();
881da177e4SLinus Torvalds 	unregister_netdevice_notifier(&br_device_notifier);
891da177e4SLinus Torvalds 	brioctl_set(NULL);
901da177e4SLinus Torvalds 
91712d6954SAlexey Dobriyan 	unregister_pernet_subsys(&br_net_ops);
921da177e4SLinus Torvalds 
93473c22d7SJesper Dangaard Brouer 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
941da177e4SLinus Torvalds 
95d69efb16SBodo Stroesser 	br_netfilter_fini();
96da678292SMichał Mirosław #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
97da678292SMichał Mirosław 	br_fdb_test_addr_hook = NULL;
98da678292SMichał Mirosław #endif
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds 	br_fdb_fini();
1011da177e4SLinus Torvalds }
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds module_init(br_init)
1041da177e4SLinus Torvalds module_exit(br_deinit)
1051da177e4SLinus Torvalds MODULE_LICENSE("GPL");
1068cbb512eSStephen Hemminger MODULE_VERSION(BR_VERSION);
107bb900b27Sstephen hemminger MODULE_ALIAS_RTNL_LINK("bridge");
108