0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/module.h>
0020 #include <linux/netdevice.h>
0021 #include <linux/spinlock.h>
0022 #include <net/protocol.h>
0023
0024 #if IS_ENABLED(CONFIG_IPV6)
0025 struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly;
0026 EXPORT_SYMBOL(inet6_protos);
0027
0028 int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
0029 {
0030 return !cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol],
0031 NULL, prot) ? 0 : -1;
0032 }
0033 EXPORT_SYMBOL(inet6_add_protocol);
0034
0035 int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol)
0036 {
0037 int ret;
0038
0039 ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol],
0040 prot, NULL) == prot) ? 0 : -1;
0041
0042 synchronize_net();
0043
0044 return ret;
0045 }
0046 EXPORT_SYMBOL(inet6_del_protocol);
0047 #endif
0048
0049 const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;
0050 EXPORT_SYMBOL(inet6_offloads);
0051
0052 int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
0053 {
0054 return !cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
0055 NULL, prot) ? 0 : -1;
0056 }
0057 EXPORT_SYMBOL(inet6_add_offload);
0058
0059 int inet6_del_offload(const struct net_offload *prot, unsigned char protocol)
0060 {
0061 int ret;
0062
0063 ret = (cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
0064 prot, NULL) == prot) ? 0 : -1;
0065
0066 synchronize_net();
0067
0068 return ret;
0069 }
0070 EXPORT_SYMBOL(inet6_del_offload);