1 /* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * INET protocol dispatch tables. 7 * 8 * Authors: Ross Biro 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 10 * 11 * Fixes: 12 * Alan Cox : Ahah! udp icmp errors don't work because 13 * udp_err is never called! 14 * Alan Cox : Added new fields for init and ready for 15 * proper fragmentation (_NO_ 4K limits!) 16 * Richard Colella : Hang on hash collision 17 * Vince Laviano : Modified inet_del_protocol() to correctly 18 * maintain copy bit. 19 * 20 * This program is free software; you can redistribute it and/or 21 * modify it under the terms of the GNU General Public License 22 * as published by the Free Software Foundation; either version 23 * 2 of the License, or (at your option) any later version. 24 */ 25 #include <linux/cache.h> 26 #include <linux/module.h> 27 #include <linux/netdevice.h> 28 #include <linux/spinlock.h> 29 #include <net/protocol.h> 30 31 const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly; 32 const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly; 33 34 /* 35 * Add a protocol handler to the hash tables 36 */ 37 38 int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) 39 { 40 if (!prot->netns_ok) { 41 pr_err("Protocol %u is not namespace aware, cannot register.\n", 42 protocol); 43 return -EINVAL; 44 } 45 46 return !cmpxchg((const struct net_protocol **)&inet_protos[protocol], 47 NULL, prot) ? 0 : -1; 48 } 49 EXPORT_SYMBOL(inet_add_protocol); 50 51 int inet_add_offload(const struct net_offload *prot, unsigned char protocol) 52 { 53 return !cmpxchg((const struct net_offload **)&inet_offloads[protocol], 54 NULL, prot) ? 0 : -1; 55 } 56 EXPORT_SYMBOL(inet_add_offload); 57 58 /* 59 * Remove a protocol from the hash tables. 60 */ 61 62 int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) 63 { 64 int ret; 65 66 ret = (cmpxchg((const struct net_protocol **)&inet_protos[protocol], 67 prot, NULL) == prot) ? 0 : -1; 68 69 synchronize_net(); 70 71 return ret; 72 } 73 EXPORT_SYMBOL(inet_del_protocol); 74 75 int inet_del_offload(const struct net_offload *prot, unsigned char protocol) 76 { 77 int ret; 78 79 ret = (cmpxchg((const struct net_offload **)&inet_offloads[protocol], 80 prot, NULL) == prot) ? 0 : -1; 81 82 synchronize_net(); 83 84 return ret; 85 } 86 EXPORT_SYMBOL(inet_del_offload); 87