Branch data 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 : 168 : int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) 33 : : { 34 [ - + ]: 168 : 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 : 168 : return !cmpxchg((const struct net_protocol **)&inet_protos[protocol], 41 [ - + ]: 168 : NULL, prot) ? 0 : -1; 42 : : } 43 : : EXPORT_SYMBOL(inet_add_protocol); 44 : : 45 : 105 : int inet_add_offload(const struct net_offload *prot, unsigned char protocol) 46 : : { 47 : 105 : return !cmpxchg((const struct net_offload **)&inet_offloads[protocol], 48 [ - + ]: 105 : 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);