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