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 * $Id: br.c,v 1.47 2001/12/24 00:56:41 davem Exp $ 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or 111da177e4SLinus Torvalds * modify it under the terms of the GNU General Public License 121da177e4SLinus Torvalds * as published by the Free Software Foundation; either version 131da177e4SLinus Torvalds * 2 of the License, or (at your option) any later version. 141da177e4SLinus Torvalds */ 151da177e4SLinus Torvalds 161da177e4SLinus Torvalds #include <linux/module.h> 171da177e4SLinus Torvalds #include <linux/kernel.h> 181da177e4SLinus Torvalds #include <linux/netdevice.h> 191da177e4SLinus Torvalds #include <linux/etherdevice.h> 201da177e4SLinus Torvalds #include <linux/init.h> 21cf0f02d0SStephen Hemminger #include <linux/llc.h> 22cf0f02d0SStephen Hemminger #include <net/llc.h> 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds #include "br_private.h" 251da177e4SLinus Torvalds 263db05feaSHerbert Xu int (*br_should_route_hook)(struct sk_buff *skb); 271da177e4SLinus Torvalds 28cf0f02d0SStephen Hemminger static struct llc_sap *br_stp_sap; 29cf0f02d0SStephen Hemminger 301da177e4SLinus Torvalds static int __init br_init(void) 311da177e4SLinus Torvalds { 32c0909713SStephen Hemminger int err; 33c0909713SStephen Hemminger 34cf0f02d0SStephen Hemminger br_stp_sap = llc_sap_open(LLC_SAP_BSPAN, br_stp_rcv); 35cf0f02d0SStephen Hemminger if (!br_stp_sap) { 36cf0f02d0SStephen Hemminger printk(KERN_ERR "bridge: can't register sap for STP\n"); 37c0909713SStephen Hemminger return -EADDRINUSE; 38cf0f02d0SStephen Hemminger } 39cf0f02d0SStephen Hemminger 4087a596e0SAkinobu Mita err = br_fdb_init(); 4187a596e0SAkinobu Mita if (err) 4217efdd45SPavel Emelyanov goto err_out; 431da177e4SLinus Torvalds 44c0909713SStephen Hemminger err = br_netfilter_init(); 45c0909713SStephen Hemminger if (err) 46c0909713SStephen Hemminger goto err_out1; 47c0909713SStephen Hemminger 48c0909713SStephen Hemminger err = register_netdevice_notifier(&br_device_notifier); 49c0909713SStephen Hemminger if (err) 50c0909713SStephen Hemminger goto err_out2; 51c0909713SStephen Hemminger 5232fe21c0SThomas Graf err = br_netlink_init(); 5332fe21c0SThomas Graf if (err) 5432fe21c0SThomas Graf goto err_out3; 5532fe21c0SThomas Graf 561da177e4SLinus Torvalds brioctl_set(br_ioctl_deviceless_stub); 571da177e4SLinus Torvalds br_handle_frame_hook = br_handle_frame; 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds br_fdb_get_hook = br_fdb_get; 601da177e4SLinus Torvalds br_fdb_put_hook = br_fdb_put; 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds return 0; 6332fe21c0SThomas Graf err_out3: 6432fe21c0SThomas Graf unregister_netdevice_notifier(&br_device_notifier); 65c0909713SStephen Hemminger err_out2: 66c0909713SStephen Hemminger br_netfilter_fini(); 67c0909713SStephen Hemminger err_out1: 6817efdd45SPavel Emelyanov br_fdb_fini(); 6917efdd45SPavel Emelyanov err_out: 70c0909713SStephen Hemminger llc_sap_put(br_stp_sap); 71c0909713SStephen Hemminger return err; 721da177e4SLinus Torvalds } 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds static void __exit br_deinit(void) 751da177e4SLinus Torvalds { 76387e2b04SStephen Hemminger rcu_assign_pointer(br_stp_sap->rcv_func, NULL); 77cf0f02d0SStephen Hemminger 7811dc1f36SStephen Hemminger br_netlink_fini(); 791da177e4SLinus Torvalds unregister_netdevice_notifier(&br_device_notifier); 801da177e4SLinus Torvalds brioctl_set(NULL); 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds br_cleanup_bridges(); 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds synchronize_net(); 851da177e4SLinus Torvalds 86d69efb16SBodo Stroesser br_netfilter_fini(); 87387e2b04SStephen Hemminger llc_sap_put(br_stp_sap); 881da177e4SLinus Torvalds br_fdb_get_hook = NULL; 891da177e4SLinus Torvalds br_fdb_put_hook = NULL; 901da177e4SLinus Torvalds 911da177e4SLinus Torvalds br_handle_frame_hook = NULL; 921da177e4SLinus Torvalds br_fdb_fini(); 931da177e4SLinus Torvalds } 941da177e4SLinus Torvalds 951da177e4SLinus Torvalds EXPORT_SYMBOL(br_should_route_hook); 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds module_init(br_init) 981da177e4SLinus Torvalds module_exit(br_deinit) 991da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 1008cbb512eSStephen Hemminger MODULE_VERSION(BR_VERSION); 101