1*2874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * INET An implementation of the TCP/IP protocol suite for the LINUX
41da177e4SLinus Torvalds * operating system. INET is implemented using the BSD Socket
51da177e4SLinus Torvalds * interface as the means of communication with the user level.
61da177e4SLinus Torvalds *
71da177e4SLinus Torvalds * PF_INET6 protocol dispatch tables.
81da177e4SLinus Torvalds *
91da177e4SLinus Torvalds * Authors: Pedro Roque <roque@di.fc.ul.pt>
101da177e4SLinus Torvalds */
111da177e4SLinus Torvalds
121da177e4SLinus Torvalds /*
131da177e4SLinus Torvalds * Changes:
141da177e4SLinus Torvalds *
151da177e4SLinus Torvalds * Vince Laviano (vince@cs.stanford.edu) 16 May 2001
161da177e4SLinus Torvalds * - Removed unused variable 'inet6_protocol_base'
171da177e4SLinus Torvalds * - Modified inet6_del_protocol() to correctly maintain copy bit.
181da177e4SLinus Torvalds */
19fa1a9c68SAlexey Dobriyan #include <linux/module.h>
201da177e4SLinus Torvalds #include <linux/netdevice.h>
21fa1a9c68SAlexey Dobriyan #include <linux/spinlock.h>
221da177e4SLinus Torvalds #include <net/protocol.h>
231da177e4SLinus Torvalds
24c6b641a4SVlad Yasevich #if IS_ENABLED(CONFIG_IPV6)
25dddb64bcSsubashab@codeaurora.org struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly;
26c6b641a4SVlad Yasevich EXPORT_SYMBOL(inet6_protos);
271da177e4SLinus Torvalds
inet6_add_protocol(const struct inet6_protocol * prot,unsigned char protocol)2841135cc8SAlexey Dobriyan int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
291da177e4SLinus Torvalds {
30f9242b6bSDavid S. Miller return !cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol],
31e0ad61ecSEric Dumazet NULL, prot) ? 0 : -1;
321da177e4SLinus Torvalds }
337159039aSYOSHIFUJI Hideaki EXPORT_SYMBOL(inet6_add_protocol);
347159039aSYOSHIFUJI Hideaki
inet6_del_protocol(const struct inet6_protocol * prot,unsigned char protocol)3541135cc8SAlexey Dobriyan int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol)
361da177e4SLinus Torvalds {
37f9242b6bSDavid S. Miller int ret;
381da177e4SLinus Torvalds
39f9242b6bSDavid S. Miller ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[protocol],
40e0ad61ecSEric Dumazet prot, NULL) == prot) ? 0 : -1;
411da177e4SLinus Torvalds
421da177e4SLinus Torvalds synchronize_net();
431da177e4SLinus Torvalds
441da177e4SLinus Torvalds return ret;
451da177e4SLinus Torvalds }
467159039aSYOSHIFUJI Hideaki EXPORT_SYMBOL(inet6_del_protocol);
47c6b641a4SVlad Yasevich #endif
48c6b641a4SVlad Yasevich
49c6b641a4SVlad Yasevich const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;
50ce3e0286STom Herbert EXPORT_SYMBOL(inet6_offloads);
51c6b641a4SVlad Yasevich
inet6_add_offload(const struct net_offload * prot,unsigned char protocol)52c6b641a4SVlad Yasevich int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
53c6b641a4SVlad Yasevich {
54c6b641a4SVlad Yasevich return !cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
55c6b641a4SVlad Yasevich NULL, prot) ? 0 : -1;
56c6b641a4SVlad Yasevich }
57c6b641a4SVlad Yasevich EXPORT_SYMBOL(inet6_add_offload);
588ca896cfSVlad Yasevich
inet6_del_offload(const struct net_offload * prot,unsigned char protocol)598ca896cfSVlad Yasevich int inet6_del_offload(const struct net_offload *prot, unsigned char protocol)
608ca896cfSVlad Yasevich {
618ca896cfSVlad Yasevich int ret;
628ca896cfSVlad Yasevich
638ca896cfSVlad Yasevich ret = (cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
648ca896cfSVlad Yasevich prot, NULL) == prot) ? 0 : -1;
658ca896cfSVlad Yasevich
668ca896cfSVlad Yasevich synchronize_net();
678ca896cfSVlad Yasevich
688ca896cfSVlad Yasevich return ret;
698ca896cfSVlad Yasevich }
708ca896cfSVlad Yasevich EXPORT_SYMBOL(inet6_del_offload);
71