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