xref: /openbmc/linux/net/ipv6/protocol.c (revision 2874c5fd)
12874c5fdSThomas 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