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/config.h> 171da177e4SLinus Torvalds #include <linux/module.h> 181da177e4SLinus Torvalds #include <linux/kernel.h> 191da177e4SLinus Torvalds #include <linux/netdevice.h> 201da177e4SLinus Torvalds #include <linux/etherdevice.h> 211da177e4SLinus Torvalds #include <linux/init.h> 22cf0f02d0SStephen Hemminger #include <linux/llc.h> 23cf0f02d0SStephen Hemminger #include <net/llc.h> 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds #include "br_private.h" 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds int (*br_should_route_hook) (struct sk_buff **pskb) = NULL; 281da177e4SLinus Torvalds 29cf0f02d0SStephen Hemminger static struct llc_sap *br_stp_sap; 30cf0f02d0SStephen Hemminger 311da177e4SLinus Torvalds static int __init br_init(void) 321da177e4SLinus Torvalds { 33c0909713SStephen Hemminger int err; 34c0909713SStephen Hemminger 35cf0f02d0SStephen Hemminger br_stp_sap = llc_sap_open(LLC_SAP_BSPAN, br_stp_rcv); 36cf0f02d0SStephen Hemminger if (!br_stp_sap) { 37cf0f02d0SStephen Hemminger printk(KERN_ERR "bridge: can't register sap for STP\n"); 38c0909713SStephen Hemminger return -EADDRINUSE; 39cf0f02d0SStephen Hemminger } 40cf0f02d0SStephen Hemminger 411da177e4SLinus Torvalds br_fdb_init(); 421da177e4SLinus Torvalds 43c0909713SStephen Hemminger err = br_netfilter_init(); 44c0909713SStephen Hemminger if (err) 45c0909713SStephen Hemminger goto err_out1; 46c0909713SStephen Hemminger 47c0909713SStephen Hemminger err = register_netdevice_notifier(&br_device_notifier); 48c0909713SStephen Hemminger if (err) 49c0909713SStephen Hemminger goto err_out2; 50c0909713SStephen Hemminger 5111dc1f36SStephen Hemminger br_netlink_init(); 521da177e4SLinus Torvalds brioctl_set(br_ioctl_deviceless_stub); 531da177e4SLinus Torvalds br_handle_frame_hook = br_handle_frame; 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds br_fdb_get_hook = br_fdb_get; 561da177e4SLinus Torvalds br_fdb_put_hook = br_fdb_put; 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds return 0; 59c0909713SStephen Hemminger 60c0909713SStephen Hemminger err_out2: 61c0909713SStephen Hemminger br_netfilter_fini(); 62c0909713SStephen Hemminger err_out1: 63c0909713SStephen Hemminger llc_sap_put(br_stp_sap); 64c0909713SStephen Hemminger return err; 651da177e4SLinus Torvalds } 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds static void __exit br_deinit(void) 681da177e4SLinus Torvalds { 69387e2b04SStephen Hemminger rcu_assign_pointer(br_stp_sap->rcv_func, NULL); 70cf0f02d0SStephen Hemminger 7111dc1f36SStephen Hemminger br_netlink_fini(); 721da177e4SLinus Torvalds br_netfilter_fini(); 731da177e4SLinus Torvalds unregister_netdevice_notifier(&br_device_notifier); 741da177e4SLinus Torvalds brioctl_set(NULL); 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds br_cleanup_bridges(); 771da177e4SLinus Torvalds 781da177e4SLinus Torvalds synchronize_net(); 791da177e4SLinus Torvalds 80387e2b04SStephen Hemminger llc_sap_put(br_stp_sap); 811da177e4SLinus Torvalds br_fdb_get_hook = NULL; 821da177e4SLinus Torvalds br_fdb_put_hook = NULL; 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds br_handle_frame_hook = NULL; 851da177e4SLinus Torvalds br_fdb_fini(); 861da177e4SLinus Torvalds } 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds EXPORT_SYMBOL(br_should_route_hook); 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds module_init(br_init) 911da177e4SLinus Torvalds module_exit(br_deinit) 921da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 938cbb512eSStephen Hemminger MODULE_VERSION(BR_VERSION); 94