2005-04-17 02:20:36 +04:00
/*
* INET An implementation of the TCP / IP protocol suite for the LINUX
* operating system . INET is implemented using the BSD Socket
* interface as the means of communication with the user level .
*
* INET protocol dispatch tables .
*
2005-05-06 03:16:16 +04:00
* Authors : Ross Biro
2005-04-17 02:20:36 +04:00
* Fred N . van Kempen , < waltje @ uWalt . NL . Mugnet . ORG >
*
* Fixes :
* Alan Cox : Ahah ! udp icmp errors don ' t work because
* udp_err is never called !
* Alan Cox : Added new fields for init and ready for
* proper fragmentation ( _NO_ 4 K limits ! )
* Richard Colella : Hang on hash collision
* Vince Laviano : Modified inet_del_protocol ( ) to correctly
* maintain copy bit .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
2009-09-09 14:43:50 +04:00
# include <linux/cache.h>
2005-04-17 02:20:36 +04:00
# include <linux/module.h>
# include <linux/netdevice.h>
2009-09-09 14:43:50 +04:00
# include <linux/spinlock.h>
2005-04-17 02:20:36 +04:00
# include <net/protocol.h>
2010-10-26 01:02:28 +04:00
const struct net_protocol __rcu * inet_protos [ MAX_INET_PROTOS ] __read_mostly ;
2012-11-15 12:49:12 +04:00
const struct net_offload __rcu * inet_offloads [ MAX_INET_PROTOS ] __read_mostly ;
2005-04-17 02:20:36 +04:00
2009-09-14 16:21:47 +04:00
int inet_add_protocol ( const struct net_protocol * prot , unsigned char protocol )
2005-04-17 02:20:36 +04:00
{
2013-02-05 23:42:23 +04:00
if ( ! prot - > netns_ok ) {
pr_err ( " Protocol %u is not namespace aware, cannot register. \n " ,
protocol ) ;
return - EINVAL ;
}
2012-06-20 05:56:21 +04:00
return ! cmpxchg ( ( const struct net_protocol * * ) & inet_protos [ protocol ] ,
2010-10-26 01:02:28 +04:00
NULL , prot ) ? 0 : - 1 ;
2005-04-17 02:20:36 +04:00
}
2010-07-10 01:22:10 +04:00
EXPORT_SYMBOL ( inet_add_protocol ) ;
2005-04-17 02:20:36 +04:00
2012-11-15 12:49:12 +04:00
int inet_add_offload ( const struct net_offload * prot , unsigned char protocol )
{
return ! cmpxchg ( ( const struct net_offload * * ) & inet_offloads [ protocol ] ,
NULL , prot ) ? 0 : - 1 ;
}
EXPORT_SYMBOL ( inet_add_offload ) ;
2009-09-14 16:21:47 +04:00
int inet_del_protocol ( const struct net_protocol * prot , unsigned char protocol )
2005-04-17 02:20:36 +04:00
{
2012-06-20 05:56:21 +04:00
int ret ;
2005-04-17 02:20:36 +04:00
2012-06-20 05:56:21 +04:00
ret = ( cmpxchg ( ( const struct net_protocol * * ) & inet_protos [ protocol ] ,
2010-10-26 01:02:28 +04:00
prot , NULL ) = = prot ) ? 0 : - 1 ;
2005-04-17 02:20:36 +04:00
synchronize_net ( ) ;
return ret ;
}
EXPORT_SYMBOL ( inet_del_protocol ) ;
2012-11-15 12:49:12 +04:00
int inet_del_offload ( const struct net_offload * prot , unsigned char protocol )
{
int ret ;
ret = ( cmpxchg ( ( const struct net_offload * * ) & inet_offloads [ protocol ] ,
prot , NULL ) = = prot ) ? 0 : - 1 ;
synchronize_net ( ) ;
return ret ;
}
EXPORT_SYMBOL ( inet_del_offload ) ;