2005-04-17 02:20:36 +04:00
/*
* Linux INET6 implementation
*
* Authors :
* Pedro Roque < roque @ di . fc . ul . pt >
*
* 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 .
*/
# ifndef _NET_IPV6_H
# define _NET_IPV6_H
# include <linux/ipv6.h>
# include <linux/hardirq.h>
2007-07-31 04:05:49 +04:00
# include <net/if_inet6.h>
2005-04-17 02:20:36 +04:00
# include <net/ndisc.h>
# include <net/flow.h>
# include <net/snmp.h>
# define SIN6_LEN_RFC2133 24
# define IPV6_MAXPLEN 65535
/*
* NextHeader field of IPv6 header
*/
# define NEXTHDR_HOP 0 /* Hop-by-hop option header. */
# define NEXTHDR_TCP 6 /* TCP segment. */
# define NEXTHDR_UDP 17 /* UDP message. */
# define NEXTHDR_IPV6 41 /* IPv6 in IPv6 */
# define NEXTHDR_ROUTING 43 /* Routing header. */
# define NEXTHDR_FRAGMENT 44 /* Fragmentation/reassembly header. */
# define NEXTHDR_ESP 50 /* Encapsulating security payload. */
# define NEXTHDR_AUTH 51 /* Authentication header. */
# define NEXTHDR_ICMP 58 /* ICMP for IPv6. */
# define NEXTHDR_NONE 59 /* No next header */
# define NEXTHDR_DEST 60 /* Destination options header. */
2006-08-24 07:34:26 +04:00
# define NEXTHDR_MOBILITY 135 /* Mobility header. */
2005-04-17 02:20:36 +04:00
# define NEXTHDR_MAX 255
# define IPV6_DEFAULT_HOPLIMIT 64
# define IPV6_DEFAULT_MCASTHOPS 1
/*
* Addr type
*
* type - unicast | multicast
* scope - local | site | global
* v4 - compat
* v4mapped
* any
* loopback
*/
# define IPV6_ADDR_ANY 0x0000U
# define IPV6_ADDR_UNICAST 0x0001U
# define IPV6_ADDR_MULTICAST 0x0002U
# define IPV6_ADDR_LOOPBACK 0x0010U
# define IPV6_ADDR_LINKLOCAL 0x0020U
# define IPV6_ADDR_SITELOCAL 0x0040U
# define IPV6_ADDR_COMPATv4 0x0080U
# define IPV6_ADDR_SCOPE_MASK 0x00f0U
# define IPV6_ADDR_MAPPED 0x1000U
# define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */
/*
* Addr scopes
*/
# ifdef __KERNEL__
# define IPV6_ADDR_MC_SCOPE(a) \
( ( a ) - > s6_addr [ 1 ] & 0x0f ) /* nonstandard */
# define __IPV6_ADDR_SCOPE_INVALID -1
# endif
# define IPV6_ADDR_SCOPE_NODELOCAL 0x01
# define IPV6_ADDR_SCOPE_LINKLOCAL 0x02
# define IPV6_ADDR_SCOPE_SITELOCAL 0x05
# define IPV6_ADDR_SCOPE_ORGLOCAL 0x08
# define IPV6_ADDR_SCOPE_GLOBAL 0x0e
/*
* fragmentation header
*/
struct frag_hdr {
2006-11-08 11:21:46 +03:00
__u8 nexthdr ;
__u8 reserved ;
__be16 frag_off ;
__be32 identification ;
2005-04-17 02:20:36 +04:00
} ;
# define IP6_MF 0x0001
# ifdef __KERNEL__
# include <net/sock.h>
/* sysctls */
extern int sysctl_mld_max_msf ;
2008-01-09 11:33:11 +03:00
extern struct ctl_path net_ipv6_ctl_path [ ] ;
2008-10-08 21:35:11 +04:00
# define _DEVINC(net, statname, modifier, idev, field) \
2007-09-17 03:52:35 +04:00
( { \
2006-11-04 14:11:37 +03:00
struct inet6_dev * _idev = ( idev ) ; \
2008-10-08 21:35:11 +04:00
( void ) ( net ) ; \
2006-11-04 14:11:37 +03:00
if ( likely ( _idev ! = NULL ) ) \
2007-09-17 03:52:35 +04:00
SNMP_INC_STATS # # modifier ( ( _idev ) - > stats . statname , ( field ) ) ; \
SNMP_INC_STATS # # modifier ( statname # # _statistics , ( field ) ) ; \
2006-11-04 14:11:37 +03:00
} )
2007-09-17 03:52:35 +04:00
2008-10-08 21:35:11 +04:00
# define _DEVADD(net, statname, modifier, idev, field, val) \
2007-10-15 13:40:06 +04:00
( { \
struct inet6_dev * _idev = ( idev ) ; \
2008-10-08 21:35:11 +04:00
( void ) ( net ) ; \
2007-10-15 13:40:06 +04:00
if ( likely ( _idev ! = NULL ) ) \
SNMP_ADD_STATS # # modifier ( ( _idev ) - > stats . statname , ( field ) , ( val ) ) ; \
SNMP_ADD_STATS # # modifier ( statname # # _statistics , ( field ) , ( val ) ) ; \
} )
2007-09-17 03:52:35 +04:00
/* MIBs */
DECLARE_SNMP_STAT ( struct ipstats_mib , ipv6_statistics ) ;
2008-10-08 21:35:11 +04:00
# define IP6_INC_STATS(net, idev,field) \
_DEVINC ( net , ipv6 , , idev , field )
# define IP6_INC_STATS_BH(net, idev,field) \
_DEVINC ( net , ipv6 , _BH , idev , field )
# define IP6_ADD_STATS_BH(net, idev,field,val) \
_DEVADD ( net , ipv6 , _BH , idev , field , val )
2007-09-17 03:52:35 +04:00
2005-04-17 02:20:36 +04:00
DECLARE_SNMP_STAT ( struct icmpv6_mib , icmpv6_statistics ) ;
2007-09-17 03:52:35 +04:00
DECLARE_SNMP_STAT ( struct icmpv6msg_mib , icmpv6msg_statistics ) ;
2008-10-08 21:35:11 +04:00
# define ICMP6_INC_STATS(net, idev, field) \
_DEVINC ( net , icmpv6 , , idev , field )
# define ICMP6_INC_STATS_BH(net, idev, field) \
_DEVINC ( net , icmpv6 , _BH , idev , field )
# define ICMP6MSGOUT_INC_STATS(net, idev, field) \
_DEVINC ( net , icmpv6msg , , idev , field + 256 )
# define ICMP6MSGOUT_INC_STATS_BH(net, idev, field) \
_DEVINC ( net , icmpv6msg , _BH , idev , field + 256 )
# define ICMP6MSGIN_INC_STATS_BH(net, idev, field) \
_DEVINC ( net , icmpv6msg , _BH , idev , field )
2007-09-17 03:52:35 +04:00
2005-04-17 02:20:36 +04:00
struct ip6_ra_chain
{
struct ip6_ra_chain * next ;
struct sock * sk ;
int sel ;
void ( * destructor ) ( struct sock * ) ;
} ;
extern struct ip6_ra_chain * ip6_ra_chain ;
extern rwlock_t ip6_ra_lock ;
/*
This structure is prepared by protocol , when parsing
ancillary data and passed to IPv6 .
*/
struct ipv6_txoptions
{
/* Length of this structure */
int tot_len ;
/* length of extension headers */
__u16 opt_flen ; /* after fragment hdr */
__u16 opt_nflen ; /* before fragment hdr */
struct ipv6_opt_hdr * hopopt ;
struct ipv6_opt_hdr * dst0opt ;
struct ipv6_rt_hdr * srcrt ; /* Routing Header */
struct ipv6_opt_hdr * dst1opt ;
/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
} ;
struct ip6_flowlabel
{
struct ip6_flowlabel * next ;
2006-11-08 11:25:17 +03:00
__be32 label ;
2007-05-04 04:39:04 +04:00
atomic_t users ;
2005-04-17 02:20:36 +04:00
struct in6_addr dst ;
struct ipv6_txoptions * opt ;
unsigned long linger ;
u8 share ;
u32 owner ;
unsigned long lastuse ;
unsigned long expires ;
2008-03-27 02:53:08 +03:00
struct net * fl_net ;
2005-04-17 02:20:36 +04:00
} ;
# define IPV6_FLOWINFO_MASK __constant_htonl(0x0FFFFFFF)
# define IPV6_FLOWLABEL_MASK __constant_htonl(0x000FFFFF)
struct ipv6_fl_socklist
{
struct ipv6_fl_socklist * next ;
struct ip6_flowlabel * fl ;
} ;
2006-11-08 11:25:17 +03:00
extern struct ip6_flowlabel * fl6_sock_lookup ( struct sock * sk , __be32 label ) ;
2005-04-17 02:20:36 +04:00
extern struct ipv6_txoptions * fl6_merge_options ( struct ipv6_txoptions * opt_space ,
struct ip6_flowlabel * fl ,
struct ipv6_txoptions * fopt ) ;
extern void fl6_free_socklist ( struct sock * sk ) ;
extern int ipv6_flowlabel_opt ( struct sock * sk , char __user * optval , int optlen ) ;
2007-12-11 13:23:18 +03:00
extern int ip6_flowlabel_init ( void ) ;
2005-04-17 02:20:36 +04:00
extern void ip6_flowlabel_cleanup ( void ) ;
static inline void fl6_sock_release ( struct ip6_flowlabel * fl )
{
if ( fl )
atomic_dec ( & fl - > users ) ;
}
2008-07-19 11:28:58 +04:00
extern int ip6_ra_control ( struct sock * sk , int sel ) ;
2005-04-17 02:20:36 +04:00
2007-10-15 23:50:28 +04:00
extern int ipv6_parse_hopopts ( struct sk_buff * skb ) ;
2005-04-17 02:20:36 +04:00
extern struct ipv6_txoptions * ipv6_dup_options ( struct sock * sk , struct ipv6_txoptions * opt ) ;
[IPV6]: Support several new sockopt / ancillary data in Advanced API (RFC3542).
Support several new socket options / ancillary data:
IPV6_RECVPKTINFO, IPV6_PKTINFO,
IPV6_RECVHOPOPTS, IPV6_HOPOPTS,
IPV6_RECVDSTOPTS, IPV6_DSTOPTS, IPV6_RTHDRDSTOPTS,
IPV6_RECVRTHDR, IPV6_RTHDR,
IPV6_RECVHOPOPTS, IPV6_HOPOPTS
Old semantics are preserved as IPV6_2292xxxx so that
we can maintain backward compatibility.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
2005-09-08 04:59:17 +04:00
extern struct ipv6_txoptions * ipv6_renew_options ( struct sock * sk , struct ipv6_txoptions * opt ,
int newtype ,
struct ipv6_opt_hdr __user * newopt ,
int newoptlen ) ;
2005-11-20 06:23:18 +03:00
struct ipv6_txoptions * ipv6_fixup_options ( struct ipv6_txoptions * opt_space ,
struct ipv6_txoptions * opt ) ;
2005-04-17 02:20:36 +04:00
2005-12-14 10:24:28 +03:00
extern int ipv6_opt_accepted ( struct sock * sk , struct sk_buff * skb ) ;
2008-01-22 17:06:23 +03:00
int ip6_frag_nqueues ( struct net * net ) ;
2008-01-22 17:07:25 +03:00
int ip6_frag_mem ( struct net * net ) ;
2005-04-17 02:20:36 +04:00
# define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */
2005-11-08 20:38:12 +03:00
extern int __ipv6_addr_type ( const struct in6_addr * addr ) ;
static inline int ipv6_addr_type ( const struct in6_addr * addr )
{
return __ipv6_addr_type ( addr ) & 0xffff ;
}
2005-04-17 02:20:36 +04:00
static inline int ipv6_addr_scope ( const struct in6_addr * addr )
{
2005-11-08 20:38:12 +03:00
return __ipv6_addr_type ( addr ) & IPV6_ADDR_SCOPE_MASK ;
}
static inline int __ipv6_addr_src_scope ( int type )
{
return ( type = = IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : ( type > > 16 ) ) ;
}
static inline int ipv6_addr_src_scope ( const struct in6_addr * addr )
{
return __ipv6_addr_src_scope ( __ipv6_addr_type ( addr ) ) ;
2005-04-17 02:20:36 +04:00
}
static inline int ipv6_addr_cmp ( const struct in6_addr * a1 , const struct in6_addr * a2 )
{
2007-05-04 04:39:04 +04:00
return memcmp ( a1 , a2 , sizeof ( struct in6_addr ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-21 05:03:16 +03:00
static inline int
ipv6_masked_addr_cmp ( const struct in6_addr * a1 , const struct in6_addr * m ,
const struct in6_addr * a2 )
{
2008-04-11 15:17:55 +04:00
return ( ! ! ( ( ( a1 - > s6_addr32 [ 0 ] ^ a2 - > s6_addr32 [ 0 ] ) & m - > s6_addr32 [ 0 ] ) |
( ( a1 - > s6_addr32 [ 1 ] ^ a2 - > s6_addr32 [ 1 ] ) & m - > s6_addr32 [ 1 ] ) |
( ( a1 - > s6_addr32 [ 2 ] ^ a2 - > s6_addr32 [ 2 ] ) & m - > s6_addr32 [ 2 ] ) |
( ( a1 - > s6_addr32 [ 3 ] ^ a2 - > s6_addr32 [ 3 ] ) & m - > s6_addr32 [ 3 ] ) ) ) ;
2006-03-21 05:03:16 +03:00
}
2005-04-17 02:20:36 +04:00
static inline void ipv6_addr_copy ( struct in6_addr * a1 , const struct in6_addr * a2 )
{
2007-05-04 04:39:04 +04:00
memcpy ( a1 , a2 , sizeof ( struct in6_addr ) ) ;
2005-04-17 02:20:36 +04:00
}
static inline void ipv6_addr_prefix ( struct in6_addr * pfx ,
const struct in6_addr * addr ,
int plen )
{
/* caller must guarantee 0 <= plen <= 128 */
int o = plen > > 3 ,
b = plen & 0x7 ;
2007-05-04 04:39:04 +04:00
memset ( pfx - > s6_addr , 0 , sizeof ( pfx - > s6_addr ) ) ;
2005-04-17 02:20:36 +04:00
memcpy ( pfx - > s6_addr , addr , o ) ;
2007-05-04 04:39:04 +04:00
if ( b ! = 0 )
2005-04-17 02:20:36 +04:00
pfx - > s6_addr [ o ] = addr - > s6_addr [ o ] & ( 0xff00 > > b ) ;
}
static inline void ipv6_addr_set ( struct in6_addr * addr ,
2006-09-28 05:44:54 +04:00
__be32 w1 , __be32 w2 ,
__be32 w3 , __be32 w4 )
2005-04-17 02:20:36 +04:00
{
addr - > s6_addr32 [ 0 ] = w1 ;
addr - > s6_addr32 [ 1 ] = w2 ;
addr - > s6_addr32 [ 2 ] = w3 ;
addr - > s6_addr32 [ 3 ] = w4 ;
}
static inline int ipv6_addr_equal ( const struct in6_addr * a1 ,
const struct in6_addr * a2 )
{
2008-04-11 15:17:55 +04:00
return ( ( ( a1 - > s6_addr32 [ 0 ] ^ a2 - > s6_addr32 [ 0 ] ) |
( a1 - > s6_addr32 [ 1 ] ^ a2 - > s6_addr32 [ 1 ] ) |
( a1 - > s6_addr32 [ 2 ] ^ a2 - > s6_addr32 [ 2 ] ) |
( a1 - > s6_addr32 [ 3 ] ^ a2 - > s6_addr32 [ 3 ] ) ) = = 0 ) ;
2005-04-17 02:20:36 +04:00
}
2006-09-28 05:44:54 +04:00
static inline int __ipv6_prefix_equal ( const __be32 * a1 , const __be32 * a2 ,
2005-04-17 02:20:36 +04:00
unsigned int prefixlen )
{
unsigned pdw , pbi ;
/* check complete u32 in prefix */
pdw = prefixlen > > 5 ;
if ( pdw & & memcmp ( a1 , a2 , pdw < < 2 ) )
return 0 ;
/* check incomplete u32 in prefix */
pbi = prefixlen & 0x1f ;
if ( pbi & & ( ( a1 [ pdw ] ^ a2 [ pdw ] ) & htonl ( ( 0xffffffff ) < < ( 32 - pbi ) ) ) )
return 0 ;
return 1 ;
}
static inline int ipv6_prefix_equal ( const struct in6_addr * a1 ,
const struct in6_addr * a2 ,
unsigned int prefixlen )
{
return __ipv6_prefix_equal ( a1 - > s6_addr32 , a2 - > s6_addr32 ,
prefixlen ) ;
}
2007-10-18 06:44:34 +04:00
struct inet_frag_queue ;
2007-10-18 06:46:47 +04:00
struct ip6_create_arg {
__be32 id ;
struct in6_addr * src ;
struct in6_addr * dst ;
} ;
void ip6_frag_init ( struct inet_frag_queue * q , void * a ) ;
2007-10-18 06:47:21 +04:00
int ip6_frag_match ( struct inet_frag_queue * q , void * a ) ;
2007-10-18 06:46:47 +04:00
2005-04-17 02:20:36 +04:00
static inline int ipv6_addr_any ( const struct in6_addr * a )
{
return ( ( a - > s6_addr32 [ 0 ] | a - > s6_addr32 [ 1 ] |
a - > s6_addr32 [ 2 ] | a - > s6_addr32 [ 3 ] ) = = 0 ) ;
}
2008-06-20 03:33:57 +04:00
static inline int ipv6_addr_loopback ( const struct in6_addr * a )
{
return ( ( a - > s6_addr32 [ 0 ] | a - > s6_addr32 [ 1 ] |
a - > s6_addr32 [ 2 ] | ( a - > s6_addr32 [ 3 ] ^ htonl ( 1 ) ) ) = = 0 ) ;
}
2007-08-25 10:16:08 +04:00
static inline int ipv6_addr_v4mapped ( const struct in6_addr * a )
{
2008-04-11 15:17:55 +04:00
return ( ( a - > s6_addr32 [ 0 ] | a - > s6_addr32 [ 1 ] |
( a - > s6_addr32 [ 2 ] ^ htonl ( 0x0000ffff ) ) ) = = 0 ) ;
2007-08-25 10:16:08 +04:00
}
2008-02-29 07:55:46 +03:00
/*
* Check for a RFC 4843 ORCHID address
* ( Overlay Routable Cryptographic Hash Identifiers )
*/
static inline int ipv6_addr_orchid ( const struct in6_addr * a )
{
return ( ( a - > s6_addr32 [ 0 ] & htonl ( 0xfffffff0 ) )
= = htonl ( 0x20010010 ) ) ;
}
2008-01-18 17:50:56 +03:00
static inline void ipv6_addr_set_v4mapped ( const __be32 addr ,
struct in6_addr * v4mapped )
{
ipv6_addr_set ( v4mapped ,
0 , 0 ,
htonl ( 0x0000FFFF ) ,
addr ) ;
}
2005-11-08 20:37:56 +03:00
/*
* find the first different bit between two addresses
* length of address must be a multiple of 32 bits
*/
static inline int __ipv6_addr_diff ( const void * token1 , const void * token2 , int addrlen )
{
2006-11-15 07:56:33 +03:00
const __be32 * a1 = token1 , * a2 = token2 ;
2005-11-08 20:37:56 +03:00
int i ;
addrlen > > = 2 ;
for ( i = 0 ; i < addrlen ; i + + ) {
2006-11-15 07:56:33 +03:00
__be32 xb = a1 [ i ] ^ a2 [ i ] ;
if ( xb )
return i * 32 + 32 - fls ( ntohl ( xb ) ) ;
2005-11-08 20:37:56 +03:00
}
/*
* we should * never * get to this point since that
* would mean the addrs are equal
*
* However , we do get to it 8 ) And exacly , when
* addresses are equal 8 )
*
* ip route add 1111 : : / 128 via . . .
* ip route add 1111 : : / 64 via . . .
* and we are here .
*
* Ideally , this function should stop comparison
* at prefix length . It does not , but it is still OK ,
* if returned value is greater than prefix length .
* - - ANK ( 980803 )
*/
return ( addrlen < < 5 ) ;
}
static inline int ipv6_addr_diff ( const struct in6_addr * a1 , const struct in6_addr * a2 )
{
return __ipv6_addr_diff ( a1 , a2 , sizeof ( struct in6_addr ) ) ;
}
2005-04-17 02:20:36 +04:00
/*
* Prototypes exported by ipv6
*/
/*
* rcv function ( called from netdevice level )
*/
extern int ipv6_rcv ( struct sk_buff * skb ,
struct net_device * dev ,
2005-08-10 06:34:12 +04:00
struct packet_type * pt ,
struct net_device * orig_dev ) ;
2005-04-17 02:20:36 +04:00
2006-01-07 10:03:34 +03:00
extern int ip6_rcv_finish ( struct sk_buff * skb ) ;
2005-04-17 02:20:36 +04:00
/*
* upper - layer output functions
*/
extern int ip6_xmit ( struct sock * sk ,
struct sk_buff * skb ,
struct flowi * fl ,
struct ipv6_txoptions * opt ,
int ipfragok ) ;
extern int ip6_nd_hdr ( struct sock * sk ,
struct sk_buff * skb ,
struct net_device * dev ,
[IPV6]: Make address arguments const.
- net/ipv6/addrconf.c:
ipv6_get_ifaddr(), ipv6_dev_get_saddr()
- net/ipv6/mcast.c:
ipv6_sock_mc_join(), ipv6_sock_mc_drop(),
inet6_mc_check(),
ipv6_dev_mc_inc(), __ipv6_dev_mc_dec(), ipv6_dev_mc_dec(),
ipv6_chk_mcast_addr()
- net/ipv6/route.c:
rt6_lookup(), icmp6_dst_alloc()
- net/ipv6/ip6_output.c:
ip6_nd_hdr()
- net/ipv6/ndisc.c:
ndisc_send_ns(), ndisc_send_rs(), ndisc_send_redirect(),
ndisc_get_neigh(), __ndisc_send()
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
2008-04-10 10:42:10 +04:00
const struct in6_addr * saddr ,
const struct in6_addr * daddr ,
2005-04-17 02:20:36 +04:00
int proto , int len ) ;
extern int ip6_find_1stfragopt ( struct sk_buff * skb , u8 * * nexthdr ) ;
extern int ip6_append_data ( struct sock * sk ,
int getfrag ( void * from , char * to , int offset , int len , int odd , struct sk_buff * skb ) ,
void * from ,
int length ,
int transhdrlen ,
int hlimit ,
2005-09-08 05:19:03 +04:00
int tclass ,
2005-04-17 02:20:36 +04:00
struct ipv6_txoptions * opt ,
struct flowi * fl ,
struct rt6_info * rt ,
unsigned int flags ) ;
extern int ip6_push_pending_frames ( struct sock * sk ) ;
extern void ip6_flush_pending_frames ( struct sock * sk ) ;
extern int ip6_dst_lookup ( struct sock * sk ,
struct dst_entry * * dst ,
struct flowi * fl ) ;
2007-05-25 05:17:54 +04:00
extern int ip6_dst_blackhole ( struct sock * sk ,
struct dst_entry * * dst ,
struct flowi * fl ) ;
2006-07-31 07:19:33 +04:00
extern int ip6_sk_dst_lookup ( struct sock * sk ,
struct dst_entry * * dst ,
struct flowi * fl ) ;
2005-04-17 02:20:36 +04:00
/*
* skb processing functions
*/
extern int ip6_output ( struct sk_buff * skb ) ;
extern int ip6_forward ( struct sk_buff * skb ) ;
extern int ip6_input ( struct sk_buff * skb ) ;
extern int ip6_mc_input ( struct sk_buff * skb ) ;
2008-01-12 06:15:08 +03:00
extern int __ip6_local_out ( struct sk_buff * skb ) ;
extern int ip6_local_out ( struct sk_buff * skb ) ;
2005-04-17 02:20:36 +04:00
/*
* Extension header ( options ) processing
*/
extern void ipv6_push_nfrag_opts ( struct sk_buff * skb ,
struct ipv6_txoptions * opt ,
u8 * proto ,
struct in6_addr * * daddr_p ) ;
extern void ipv6_push_frag_opts ( struct sk_buff * skb ,
struct ipv6_txoptions * opt ,
u8 * proto ) ;
extern int ipv6_skip_exthdr ( const struct sk_buff * , int start ,
2005-04-25 07:16:19 +04:00
u8 * nexthdrp ) ;
2005-04-17 02:20:36 +04:00
extern int ipv6_ext_hdr ( u8 nexthdr ) ;
2006-08-24 06:18:35 +04:00
extern int ipv6_find_tlv ( struct sk_buff * skb , int offset , int type ) ;
2005-04-17 02:20:36 +04:00
/*
* socket options ( ipv6_sockglue . c )
*/
extern int ipv6_setsockopt ( struct sock * sk , int level ,
int optname ,
char __user * optval ,
int optlen ) ;
extern int ipv6_getsockopt ( struct sock * sk , int level ,
int optname ,
char __user * optval ,
int __user * optlen ) ;
2006-03-21 09:45:21 +03:00
extern int compat_ipv6_setsockopt ( struct sock * sk ,
int level ,
int optname ,
char __user * optval ,
int optlen ) ;
extern int compat_ipv6_getsockopt ( struct sock * sk ,
int level ,
int optname ,
char __user * optval ,
int __user * optlen ) ;
2005-04-17 02:20:36 +04:00
extern int ip6_datagram_connect ( struct sock * sk ,
struct sockaddr * addr , int addr_len ) ;
extern int ipv6_recv_error ( struct sock * sk , struct msghdr * msg , int len ) ;
2006-11-15 07:56:00 +03:00
extern void ipv6_icmp_error ( struct sock * sk , struct sk_buff * skb , int err , __be16 port ,
2005-04-17 02:20:36 +04:00
u32 info , u8 * payload ) ;
extern void ipv6_local_error ( struct sock * sk , int err , struct flowi * fl , u32 info ) ;
extern int inet6_release ( struct socket * sock ) ;
extern int inet6_bind ( struct socket * sock , struct sockaddr * uaddr ,
int addr_len ) ;
extern int inet6_getname ( struct socket * sock , struct sockaddr * uaddr ,
int * uaddr_len , int peer ) ;
extern int inet6_ioctl ( struct socket * sock , unsigned int cmd ,
unsigned long arg ) ;
2005-12-14 10:25:44 +03:00
extern int inet6_hash_connect ( struct inet_timewait_death_row * death_row ,
struct sock * sk ) ;
2005-04-17 02:20:36 +04:00
/*
* reassembly . c
*/
2005-12-22 23:49:22 +03:00
extern const struct proto_ops inet6_stream_ops ;
extern const struct proto_ops inet6_dgram_ops ;
2005-08-16 09:18:02 +04:00
2005-12-27 07:43:12 +03:00
struct group_source_req ;
struct group_filter ;
2005-08-16 09:18:02 +04:00
extern int ip6_mc_source ( int add , int omode , struct sock * sk ,
struct group_source_req * pgsr ) ;
extern int ip6_mc_msfilter ( struct sock * sk , struct group_filter * gsf ) ;
extern int ip6_mc_msfget ( struct sock * sk , struct group_filter * gsf ,
struct group_filter __user * optval ,
int __user * optlen ) ;
ipv6: almost identical frag hashing funcs combined
$ diff-funcs ip6qhashfn reassembly.c netfilter/nf_conntrack_reasm.c
--- reassembly.c:ip6qhashfn()
+++ netfilter/nf_conntrack_reasm.c:ip6qhashfn()
@@ -1,5 +1,5 @@
-static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
- struct in6_addr *daddr)
+static unsigned int ip6qhashfn(__be32 id, const struct in6_addr *saddr,
+ const struct in6_addr *daddr)
{
u32 a, b, c;
@@ -9,7 +9,7 @@
a += JHASH_GOLDEN_RATIO;
b += JHASH_GOLDEN_RATIO;
- c += ip6_frags.rnd;
+ c += nf_frags.rnd;
__jhash_mix(a, b, c);
a += (__force u32)saddr->s6_addr32[3];
And codiff xx.o.old xx.o.new:
net/ipv6/netfilter/nf_conntrack_reasm.c:
ip6qhashfn | -512
nf_hashfn | +6
nf_ct_frag6_gather | +36
3 functions changed, 42 bytes added, 512 bytes removed, diff: -470
net/ipv6/reassembly.c:
ip6qhashfn | -512
ip6_hashfn | +7
ipv6_frag_rcv | +89
3 functions changed, 96 bytes added, 512 bytes removed, diff: -416
net/ipv6/reassembly.c:
inet6_hash_frag | +510
1 function changed, 510 bytes added, diff: +510
Total: -376
Compile tested.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2008-10-01 13:48:31 +04:00
extern unsigned int inet6_hash_frag ( __be32 id , const struct in6_addr * saddr ,
const struct in6_addr * daddr , u32 rnd ) ;
2005-08-16 09:18:02 +04:00
# ifdef CONFIG_PROC_FS
2008-03-27 02:52:32 +03:00
extern int ac6_proc_init ( struct net * net ) ;
extern void ac6_proc_exit ( struct net * net ) ;
2005-08-16 09:18:02 +04:00
extern int raw6_proc_init ( void ) ;
extern void raw6_proc_exit ( void ) ;
2008-03-21 14:14:45 +03:00
extern int tcp6_proc_init ( struct net * net ) ;
extern void tcp6_proc_exit ( struct net * net ) ;
2008-03-21 14:14:17 +03:00
extern int udp6_proc_init ( struct net * net ) ;
extern void udp6_proc_exit ( struct net * net ) ;
2006-11-27 22:10:57 +03:00
extern int udplite6_proc_init ( void ) ;
extern void udplite6_proc_exit ( void ) ;
2005-08-16 09:18:02 +04:00
extern int ipv6_misc_proc_init ( void ) ;
extern void ipv6_misc_proc_exit ( void ) ;
2007-04-25 08:54:09 +04:00
extern int snmp6_register_dev ( struct inet6_dev * idev ) ;
extern int snmp6_unregister_dev ( struct inet6_dev * idev ) ;
2005-08-16 09:18:02 +04:00
2007-04-25 08:54:09 +04:00
# else
2008-03-27 02:52:32 +03:00
static inline int ac6_proc_init ( struct net * net ) { return 0 ; }
static inline void ac6_proc_exit ( struct net * net ) { }
static inline int snmp6_register_dev ( struct inet6_dev * idev ) { return 0 ; }
static inline int snmp6_unregister_dev ( struct inet6_dev * idev ) { return 0 ; }
2005-08-16 09:18:02 +04:00
# endif
2005-04-17 02:20:36 +04:00
2005-08-16 09:18:02 +04:00
# ifdef CONFIG_SYSCTL
2008-01-10 13:53:43 +03:00
extern ctl_table ipv6_route_table_template [ ] ;
extern ctl_table ipv6_icmp_table_template [ ] ;
2005-04-17 02:20:36 +04:00
2008-02-05 13:57:59 +03:00
extern struct ctl_table * ipv6_icmp_sysctl_init ( struct net * net ) ;
extern struct ctl_table * ipv6_route_sysctl_init ( struct net * net ) ;
2008-01-10 13:47:55 +03:00
extern int ipv6_sysctl_register ( void ) ;
2005-08-16 09:18:02 +04:00
extern void ipv6_sysctl_unregister ( void ) ;
2008-07-27 11:59:33 +04:00
extern int ipv6_static_sysctl_register ( void ) ;
extern void ipv6_static_sysctl_unregister ( void ) ;
2005-08-16 09:18:02 +04:00
# endif
2005-04-17 02:20:36 +04:00
2005-08-16 09:18:02 +04:00
# endif /* __KERNEL__ */
# endif /* _NET_IPV6_H */