11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * INET An implementation of the TCP/IP protocol suite for the LINUX 31da177e4SLinus Torvalds * operating system. INET is implemented using the BSD Socket 41da177e4SLinus Torvalds * interface as the means of communication with the user level. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * PF_INET6 protocol dispatch tables. 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * Authors: Pedro Roque <roque@di.fc.ul.pt> 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 /* 171da177e4SLinus Torvalds * Changes: 181da177e4SLinus Torvalds * 191da177e4SLinus Torvalds * Vince Laviano (vince@cs.stanford.edu) 16 May 2001 201da177e4SLinus Torvalds * - Removed unused variable 'inet6_protocol_base' 211da177e4SLinus Torvalds * - Modified inet6_del_protocol() to correctly maintain copy bit. 221da177e4SLinus Torvalds */ 23fa1a9c68SAlexey Dobriyan #include <linux/module.h> 241da177e4SLinus Torvalds #include <linux/netdevice.h> 25fa1a9c68SAlexey Dobriyan #include <linux/spinlock.h> 261da177e4SLinus Torvalds #include <net/protocol.h> 271da177e4SLinus Torvalds 28*41135cc8SAlexey Dobriyan const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; 291da177e4SLinus Torvalds static DEFINE_SPINLOCK(inet6_proto_lock); 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds 32*41135cc8SAlexey Dobriyan int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) 331da177e4SLinus Torvalds { 341da177e4SLinus Torvalds int ret, hash = protocol & (MAX_INET_PROTOS - 1); 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds spin_lock_bh(&inet6_proto_lock); 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds if (inet6_protos[hash]) { 391da177e4SLinus Torvalds ret = -1; 401da177e4SLinus Torvalds } else { 411da177e4SLinus Torvalds inet6_protos[hash] = prot; 421da177e4SLinus Torvalds ret = 0; 431da177e4SLinus Torvalds } 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds spin_unlock_bh(&inet6_proto_lock); 461da177e4SLinus Torvalds 471da177e4SLinus Torvalds return ret; 481da177e4SLinus Torvalds } 491da177e4SLinus Torvalds 507159039aSYOSHIFUJI Hideaki EXPORT_SYMBOL(inet6_add_protocol); 517159039aSYOSHIFUJI Hideaki 521da177e4SLinus Torvalds /* 531da177e4SLinus Torvalds * Remove a protocol from the hash tables. 541da177e4SLinus Torvalds */ 551da177e4SLinus Torvalds 56*41135cc8SAlexey Dobriyan int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol) 571da177e4SLinus Torvalds { 581da177e4SLinus Torvalds int ret, hash = protocol & (MAX_INET_PROTOS - 1); 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds spin_lock_bh(&inet6_proto_lock); 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds if (inet6_protos[hash] != prot) { 631da177e4SLinus Torvalds ret = -1; 641da177e4SLinus Torvalds } else { 651da177e4SLinus Torvalds inet6_protos[hash] = NULL; 661da177e4SLinus Torvalds ret = 0; 671da177e4SLinus Torvalds } 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds spin_unlock_bh(&inet6_proto_lock); 701da177e4SLinus Torvalds 711da177e4SLinus Torvalds synchronize_net(); 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds return ret; 741da177e4SLinus Torvalds } 757159039aSYOSHIFUJI Hideaki 767159039aSYOSHIFUJI Hideaki EXPORT_SYMBOL(inet6_del_protocol); 77