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 .
*
* Definitions for the UDP module .
*
* Version : @ ( # ) udp . h 1.0 .2 05 / 07 / 93
*
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 : Turned on udp checksums . I don ' t want to
* chase ' memory corruption ' bugs that aren ' t !
*
* 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 _UDP_H
# define _UDP_H
# include <linux/list.h>
2005-12-27 07:43:12 +03:00
# include <net/inet_sock.h>
2005-04-17 02:20:36 +04:00
# include <net/sock.h>
# include <net/snmp.h>
2006-11-27 22:10:57 +03:00
# include <net/ip.h>
# include <linux/ipv6.h>
2005-04-17 02:20:36 +04:00
# include <linux/seq_file.h>
2006-10-20 01:23:57 +04:00
# include <linux/poll.h>
2005-04-17 02:20:36 +04:00
2006-11-27 22:10:57 +03:00
/**
* struct udp_skb_cb - UDP ( - Lite ) private variables
*
* @ header : private variables used by IPv4 / IPv6
* @ cscov : checksum coverage length ( UDP - Lite only )
* @ partial_cov : if set indicates partial csum coverage
*/
struct udp_skb_cb {
union {
struct inet_skb_parm h4 ;
# if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct inet6_skb_parm h6 ;
# endif
} header ;
__u16 cscov ;
__u8 partial_cov ;
} ;
# define UDP_SKB_CB(__skb) ((struct udp_skb_cb *)((__skb)->cb))
2005-04-17 02:20:36 +04:00
extern struct hlist_head udp_hash [ UDP_HTABLE_SIZE ] ;
extern rwlock_t udp_hash_lock ;
/* Note: this must match 'valbool' in sock_setsockopt */
# define UDP_CSUM_NOXMIT 1
/* Used by SunRPC/xprt layer. */
# define UDP_CSUM_NORCV 2
/* Default, as per the RFC, is to always do csums. */
# define UDP_CSUM_DEFAULT 0
extern struct proto udp_prot ;
2007-12-31 11:29:24 +03:00
extern atomic_t udp_memory_allocated ;
/* sysctl variables for udp */
extern int sysctl_udp_mem [ 3 ] ;
extern int sysctl_udp_rmem_min ;
extern int sysctl_udp_wmem_min ;
2005-12-27 07:43:12 +03:00
struct sk_buff ;
2005-04-17 02:20:36 +04:00
2006-11-27 22:10:57 +03:00
/*
* Generic checksumming routines for UDP ( - Lite ) v4 and v6
*/
2006-11-15 08:40:42 +03:00
static inline __sum16 __udp_lib_checksum_complete ( struct sk_buff * skb )
2006-11-27 22:10:57 +03:00
{
2007-03-26 07:10:56 +04:00
return __skb_checksum_complete_head ( skb , UDP_SKB_CB ( skb ) - > cscov ) ;
2006-11-27 22:10:57 +03:00
}
2006-11-21 05:06:37 +03:00
static inline int udp_lib_checksum_complete ( struct sk_buff * skb )
2006-11-27 22:10:57 +03:00
{
2007-04-09 22:59:39 +04:00
return ! skb_csum_unnecessary ( skb ) & &
2006-11-27 22:10:57 +03:00
__udp_lib_checksum_complete ( skb ) ;
}
/**
* udp_csum_outgoing - compute UDPv4 / v6 checksum over fragments
* @ sk : socket we are writing to
* @ skb : sk_buff containing the filled - in UDP header
* ( checksum field must be zeroed out )
*/
2006-11-15 08:35:48 +03:00
static inline __wsum udp_csum_outgoing ( struct sock * sk , struct sk_buff * skb )
2006-11-27 22:10:57 +03:00
{
2007-04-26 05:04:18 +04:00
__wsum csum = csum_partial ( skb_transport_header ( skb ) ,
sizeof ( struct udphdr ) , 0 ) ;
2006-11-27 22:10:57 +03:00
skb_queue_walk ( & sk - > sk_write_queue , skb ) {
csum = csum_add ( csum , skb - > csum ) ;
}
return csum ;
}
/* hash routines shared between UDPv4/6 and UDP-Litev4/6 */
static inline void udp_lib_hash ( struct sock * sk )
{
BUG ( ) ;
}
static inline void udp_lib_unhash ( struct sock * sk )
{
write_lock_bh ( & udp_hash_lock ) ;
if ( sk_del_node_init ( sk ) ) {
inet_sk ( sk ) - > num = 0 ;
sock_prot_dec_use ( sk - > sk_prot ) ;
}
write_unlock_bh ( & udp_hash_lock ) ;
}
static inline void udp_lib_close ( struct sock * sk , long timeout )
{
sk_common_release ( sk ) ;
}
/* net/ipv4/udp.c */
2006-08-27 07:06:05 +04:00
extern int udp_get_port ( struct sock * sk , unsigned short snum ,
2007-06-06 02:18:43 +04:00
int ( * saddr_cmp ) ( const struct sock * , const struct sock * ) ) ;
2005-04-17 02:20:36 +04:00
extern void udp_err ( struct sk_buff * , u32 ) ;
extern int udp_sendmsg ( struct kiocb * iocb , struct sock * sk ,
struct msghdr * msg , size_t len ) ;
extern int udp_rcv ( struct sk_buff * skb ) ;
extern int udp_ioctl ( struct sock * sk , int cmd , unsigned long arg ) ;
extern int udp_disconnect ( struct sock * sk , int flags ) ;
extern unsigned int udp_poll ( struct file * file , struct socket * sock ,
poll_table * wait ) ;
2006-11-27 20:29:59 +03:00
extern int udp_lib_getsockopt ( struct sock * sk , int level , int optname ,
char __user * optval , int __user * optlen ) ;
extern int udp_lib_setsockopt ( struct sock * sk , int level , int optname ,
char __user * optval , int optlen ,
int ( * push_pending_frames ) ( struct sock * ) ) ;
2005-04-17 02:20:36 +04:00
DECLARE_SNMP_STAT ( struct udp_mib , udp_statistics ) ;
2007-12-11 22:30:32 +03:00
DECLARE_SNMP_STAT ( struct udp_mib , udp_stats_in6 ) ;
/* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
DECLARE_SNMP_STAT ( struct udp_mib , udplite_statistics ) ;
DECLARE_SNMP_STAT ( struct udp_mib , udplite_stats_in6 ) ;
2006-11-27 22:10:57 +03:00
/*
* SNMP statistics for UDP and UDP - Lite
*/
# define UDP_INC_STATS_USER(field, is_udplite) do { \
if ( is_udplite ) SNMP_INC_STATS_USER ( udplite_statistics , field ) ; \
else SNMP_INC_STATS_USER ( udp_statistics , field ) ; } while ( 0 )
# define UDP_INC_STATS_BH(field, is_udplite) do { \
if ( is_udplite ) SNMP_INC_STATS_BH ( udplite_statistics , field ) ; \
else SNMP_INC_STATS_BH ( udp_statistics , field ) ; } while ( 0 )
2005-04-17 02:20:36 +04:00
2007-12-11 22:30:32 +03:00
# define UDP6_INC_STATS_BH(field, is_udplite) do { \
if ( is_udplite ) SNMP_INC_STATS_BH ( udplite_stats_in6 , field ) ; \
else SNMP_INC_STATS_BH ( udp_stats_in6 , field ) ; } while ( 0 )
# define UDP6_INC_STATS_USER(field, is_udplite) do { \
if ( is_udplite ) SNMP_INC_STATS_USER ( udplite_stats_in6 , field ) ; \
else SNMP_INC_STATS_USER ( udp_stats_in6 , field ) ; } while ( 0 )
# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
# define UDPX_INC_STATS_BH(sk, field) \
do { \
if ( ( sk ) - > sk_family = = AF_INET ) \
UDP_INC_STATS_BH ( field , 0 ) ; \
else \
UDP6_INC_STATS_BH ( field , 0 ) ; \
} while ( 0 ) ;
# else
# define UDPX_INC_STATS_BH(sk, field) UDP_INC_STATS_BH(field, 0)
# endif
2005-04-17 02:20:36 +04:00
/* /proc */
struct udp_seq_afinfo {
struct module * owner ;
char * name ;
sa_family_t family ;
2006-11-27 22:10:57 +03:00
struct hlist_head * hashtable ;
2005-04-17 02:20:36 +04:00
int ( * seq_show ) ( struct seq_file * m , void * v ) ;
struct file_operations * seq_fops ;
} ;
struct udp_iter_state {
sa_family_t family ;
2006-11-27 22:10:57 +03:00
struct hlist_head * hashtable ;
2005-04-17 02:20:36 +04:00
int bucket ;
struct seq_operations seq_ops ;
} ;
2005-08-16 09:18:02 +04:00
# ifdef CONFIG_PROC_FS
2005-04-17 02:20:36 +04:00
extern int udp_proc_register ( struct udp_seq_afinfo * afinfo ) ;
extern void udp_proc_unregister ( struct udp_seq_afinfo * afinfo ) ;
2005-08-16 09:18:02 +04:00
extern int udp4_proc_init ( void ) ;
extern void udp4_proc_exit ( void ) ;
# endif
2007-12-31 11:29:24 +03:00
extern void udp_init ( void ) ;
2005-04-17 02:20:36 +04:00
# endif /* _UDP_H */