Skip to content

Commit

Permalink
[UDP]: Allow users to configure UDP-Lite.
Browse files Browse the repository at this point in the history
Let's give users an option for disabling UDP-Lite (~4K).

old:
|    text	   data	    bss	    dec	    hex	filename
|  286498	  12432	   6072	 305002	  4a76a	net/ipv4/built-in.o
|  193830	   8192	   3204	 205226	  321aa	net/ipv6/ipv6.o

new (without UDP-Lite):
|    text	   data	    bss	    dec	    hex	filename
|  284086	  12136	   5432	 301654	  49a56	net/ipv4/built-in.o
|  191835	   7832	   3076	 202743	  317f7	net/ipv6/ipv6.o

Signed-off-by: YOSHIFUJI Hideaki <[email protected]>
  • Loading branch information
yoshfuji committed Mar 4, 2008
1 parent c6aefaf commit e898d4d
Show file tree
Hide file tree
Showing 14 changed files with 99 additions and 25 deletions.
11 changes: 11 additions & 0 deletions include/linux/udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ struct udp_sock {
#define UDPLITE_BIT 0x1 /* set by udplite proto init function */
#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */
#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */
#ifdef CONFIG_IP_UDPLITE
__u8 pcflag; /* marks socket as UDP-Lite if > 0 */
__u8 unused[3];
#endif
/*
* For encapsulation sockets.
*/
Expand All @@ -82,7 +84,16 @@ static inline struct udp_sock *udp_sk(const struct sock *sk)
{
return (struct udp_sock *)sk;
}

#ifdef CONFIG_IP_UDPLITE
#define IS_UDPLITE(__sk) (udp_sk(__sk)->pcflag)
#define IS_PROTO_UDPLITE(__proto) ((__proto) == IPPROTO_UDPLITE)
#define IS_SOL_UDPFAMILY(level) ((level) == SOL_UDP || (level) == SOL_UDPLITE)
#else
#define IS_UDPLITE(__sk) 0
#define IS_PROTO_UDPLITE(__proto) 0
#define IS_SOL_UDPFAMILY(level) ((level) == SOL_UDP)
#endif

#endif

Expand Down
5 changes: 5 additions & 0 deletions include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,13 @@ extern int tcp6_proc_init(void);
extern void tcp6_proc_exit(void);
extern int udp6_proc_init(void);
extern void udp6_proc_exit(void);
#ifdef CONFIG_IP_UDPLITE
extern int udplite6_proc_init(void);
extern void udplite6_proc_exit(void);
#else
static inline int udplite6_proc_init(void) { return 0; }
static inline void udplite6_proc_exit(void) { }
#endif
extern int ipv6_misc_proc_init(void);
extern void ipv6_misc_proc_exit(void);
extern int snmp6_register_dev(struct inet6_dev *idev);
Expand Down
5 changes: 5 additions & 0 deletions include/net/transp_v6.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ extern int rawv6_init(void);
extern void rawv6_exit(void);
extern int udpv6_init(void);
extern void udpv6_exit(void);
#ifdef CONFIG_IP_UDPLITE
extern int udplitev6_init(void);
extern void udplitev6_exit(void);
#else
static inline int udplitev6_init(void) { return 0; }
static inline void udplitev6_exit(void) { }
#endif
extern int tcpv6_init(void);
extern void tcpv6_exit(void);

Expand Down
9 changes: 7 additions & 2 deletions include/net/udplite.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ static __inline__ int udplite_getfrag(void *from, char *to, int offset,
/* Designate sk as UDP-Lite socket */
static inline int udplite_sk_init(struct sock *sk)
{
#ifdef CONFIG_IP_UDPLITE
udp_sk(sk)->pcflag = UDPLITE_BIT;
#endif
return 0;
}

Expand Down Expand Up @@ -69,7 +71,7 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh)
{
int cscov = up->len;

#ifdef CONFIG_IP_UDPLITE
/*
* Sender has set `partial coverage' option on UDP-Lite socket
*/
Expand All @@ -93,13 +95,15 @@ static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh)
* illegal, we fall back to the defaults here.
*/
}
#endif
return cscov;
}

static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
{
int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
__wsum csum = 0;
#ifdef CONFIG_IP_UDPLITE
int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));

skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */

Expand All @@ -112,6 +116,7 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
if ((cscov -= len) <= 0)
break;
}
#endif
return csum;
}

Expand Down
10 changes: 10 additions & 0 deletions net/ipv4/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -632,5 +632,15 @@ config TCP_MD5SIG

If unsure, say N.

config IP_UDPLITE
bool "IP: UDP-Lite Protocol (RFC 3828)"
default n
---help---
UDP-Lite (RFC 3828) is a UDP-like protocol with variable-length
checksum. Read <file:Documentation/networking/udplite.txt> for
details.

If unsure, say N.

source "net/ipv4/ipvs/Kconfig"

3 changes: 2 additions & 1 deletion net/ipv4/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ obj-y := route.o inetpeer.o protocol.o \
inet_timewait_sock.o inet_connection_sock.o \
tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
tcp_minisocks.o tcp_cong.o \
datagram.o raw.o udp.o udplite.o \
datagram.o raw.o udp.o \
arp.o icmp.o devinet.o af_inet.o igmp.o \
fib_frontend.o fib_semantics.o \
inet_fragment.o
Expand Down Expand Up @@ -49,6 +49,7 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
obj-$(CONFIG_IP_UDPLITE) += udplite.o
obj-$(CONFIG_NETLABEL) += cipso_ipv4.o

obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
Expand Down
7 changes: 6 additions & 1 deletion net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,15 +1317,18 @@ static int __init init_ipv4_mibs(void)
if (snmp_mib_init((void **)udp_statistics,
sizeof(struct udp_mib)) < 0)
goto err_udp_mib;
#ifdef CONFIG_IP_UDPLITE
if (snmp_mib_init((void **)udplite_statistics,
sizeof(struct udp_mib)) < 0)
goto err_udplite_mib;

#endif
tcp_mib_init();

return 0;

#ifdef CONFIG_IP_UDPLITE
err_udplite_mib:
#endif
snmp_mib_free((void **)udp_statistics);
err_udp_mib:
snmp_mib_free((void **)tcp_statistics);
Expand Down Expand Up @@ -1423,8 +1426,10 @@ static int __init inet_init(void)
/* Setup UDP memory threshold */
udp_init();

#ifdef CONFIG_IP_UDPLITE
/* Add UDP-Lite (RFC 3828) */
udplite4_register();
#endif

/*
* Set the ICMP layer up
Expand Down
5 changes: 4 additions & 1 deletion net/ipv4/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
atomic_read(&tcp_memory_allocated));
seq_printf(seq, "UDP: inuse %d mem %d\n", sock_prot_inuse_get(&udp_prot),
atomic_read(&udp_memory_allocated));
#ifdef CONFIG_IP_UDPLITE
seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(&udplite_prot));
#endif
seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse_get(&raw_prot));
seq_printf(seq, "FRAG: inuse %d memory %d\n",
ip_frag_nqueues(&init_net), ip_frag_mem(&init_net));
Expand Down Expand Up @@ -349,6 +351,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
snmp_fold_field((void **)udp_statistics,
snmp4_udp_list[i].entry));

#ifdef CONFIG_IP_UDPLITE
/* the UDP and UDP-Lite MIBs are the same */
seq_puts(seq, "\nUdpLite:");
for (i = 0; snmp4_udp_list[i].name != NULL; i++)
Expand All @@ -359,7 +362,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " %lu",
snmp_fold_field((void **)udplite_statistics,
snmp4_udp_list[i].entry));

#endif
seq_putc(seq, '\n');
return 0;
}
Expand Down
24 changes: 14 additions & 10 deletions net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
UDP_SKB_CB(skb)->partial_cov = 0;
UDP_SKB_CB(skb)->cscov = skb->len;

if (proto == IPPROTO_UDPLITE) {
if (IS_PROTO_UDPLITE(proto)) {
err = udplite_checksum_init(skb, uh);
if (err)
return err;
Expand Down Expand Up @@ -1175,7 +1175,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
if (ulen > skb->len)
goto short_packet;

if (proto == IPPROTO_UDP) {
if (IS_PROTO_UDPLITE(proto)) {
/* UDP validates ulen. */
if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
goto short_packet;
Expand Down Expand Up @@ -1217,7 +1217,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
if (udp_lib_checksum_complete(skb))
goto csum_error;

UDP_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
UDP_INC_STATS_BH(UDP_MIB_NOPORTS, IS_PROTO_UDPLITE(proto));
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);

/*
Expand All @@ -1229,7 +1229,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],

short_packet:
LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
proto == IPPROTO_UDPLITE ? "-Lite" : "",
IS_PROTO_UDPLITE(proto) ? "-Lite" : "",
NIPQUAD(saddr),
ntohs(uh->source),
ulen,
Expand All @@ -1244,14 +1244,14 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
* the network is concerned, anyway) as per 4.1.3.4 (MUST).
*/
LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
proto == IPPROTO_UDPLITE ? "-Lite" : "",
IS_PROTO_UDPLITE(proto) ? "-Lite" : "",
NIPQUAD(saddr),
ntohs(uh->source),
NIPQUAD(daddr),
ntohs(uh->dest),
ulen);
drop:
UDP_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
UDP_INC_STATS_BH(UDP_MIB_INERRORS, IS_PROTO_UDPLITE(proto));
kfree_skb(skb);
return 0;
}
Expand Down Expand Up @@ -1279,7 +1279,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
struct udp_sock *up = udp_sk(sk);
int val;
int err = 0;
#ifdef CONFIG_IP_UDPLITE
int is_udplite = IS_UDPLITE(sk);
#endif

if (optlen<sizeof(int))
return -EINVAL;
Expand Down Expand Up @@ -1315,6 +1317,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
}
break;

#ifdef CONFIG_IP_UDPLITE
/*
* UDP-Lite's partial checksum coverage (RFC 3828).
*/
Expand All @@ -1340,6 +1343,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
up->pcrlen = val;
up->pcflag |= UDPLITE_RECV_CC;
break;
#endif

default:
err = -ENOPROTOOPT;
Expand All @@ -1352,7 +1356,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
int udp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
if (IS_SOL_UDPFAMILY(level))
return udp_lib_setsockopt(sk, level, optname, optval, optlen,
udp_push_pending_frames);
return ip_setsockopt(sk, level, optname, optval, optlen);
Expand All @@ -1362,7 +1366,7 @@ int udp_setsockopt(struct sock *sk, int level, int optname,
int compat_udp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
if (IS_SOL_UDPFAMILY(level))
return udp_lib_setsockopt(sk, level, optname, optval, optlen,
udp_push_pending_frames);
return compat_ip_setsockopt(sk, level, optname, optval, optlen);
Expand Down Expand Up @@ -1416,7 +1420,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
int udp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
if (IS_SOL_UDPFAMILY(level))
return udp_lib_getsockopt(sk, level, optname, optval, optlen);
return ip_getsockopt(sk, level, optname, optval, optlen);
}
Expand All @@ -1425,7 +1429,7 @@ int udp_getsockopt(struct sock *sk, int level, int optname,
int compat_udp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
if (IS_SOL_UDPFAMILY(level))
return udp_lib_getsockopt(sk, level, optname, optval, optlen);
return compat_ip_getsockopt(sk, level, optname, optval, optlen);
}
Expand Down
3 changes: 2 additions & 1 deletion net/ipv6/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ obj-$(CONFIG_IPV6) += ipv6.o

ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
addrlabel.o \
route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o \
raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o

Expand All @@ -17,6 +17,7 @@ ipv6-$(CONFIG_NETFILTER) += netfilter.o
ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
ipv6-$(CONFIG_PROC_FS) += proc.o
ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o
ipv6-$(CONFIG_IP_UDPLITE) += udplite.o

ipv6-objs += $(ipv6-y)

Expand Down
14 changes: 14 additions & 0 deletions net/ipv6/af_inet6.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,12 +691,16 @@ static int __init init_ipv6_mibs(void)
goto err_icmpmsg_mib;
if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0)
goto err_udp_mib;
#ifdef CONFIG_IP_UDPLITE
if (snmp_mib_init((void **)udplite_stats_in6,
sizeof (struct udp_mib)) < 0)
goto err_udplite_mib;
#endif
return 0;

#ifdef CONFIG_IP_UDPLITE
err_udplite_mib:
#endif
snmp_mib_free((void **)udp_stats_in6);
err_udp_mib:
snmp_mib_free((void **)icmpv6msg_statistics);
Expand All @@ -715,7 +719,9 @@ static void cleanup_ipv6_mibs(void)
snmp_mib_free((void **)icmpv6_statistics);
snmp_mib_free((void **)icmpv6msg_statistics);
snmp_mib_free((void **)udp_stats_in6);
#ifdef CONFIG_IP_UDPLITE
snmp_mib_free((void **)udplite_stats_in6);
#endif
}

static int inet6_net_init(struct net *net)
Expand Down Expand Up @@ -760,9 +766,11 @@ static int __init inet6_init(void)
if (err)
goto out_unregister_tcp_proto;

#ifdef CONFIG_IP_UDPLITE
err = proto_register(&udplitev6_prot, 1);
if (err)
goto out_unregister_udp_proto;
#endif

err = proto_register(&rawv6_prot, 1);
if (err)
Expand Down Expand Up @@ -933,8 +941,10 @@ static int __init inet6_init(void)
out_unregister_raw_proto:
proto_unregister(&rawv6_prot);
out_unregister_udplite_proto:
#ifdef CONFIG_IP_UDPLITE
proto_unregister(&udplitev6_prot);
out_unregister_udp_proto:
#endif
proto_unregister(&udpv6_prot);
out_unregister_tcp_proto:
proto_unregister(&tcpv6_prot);
Expand All @@ -950,7 +960,9 @@ static void __exit inet6_exit(void)
rtnl_unregister_all(PF_INET6);

udpv6_exit();
#ifdef CONFIG_IP_UDPLITE
udplitev6_exit();
#endif
tcpv6_exit();

/* Cleanup code parts. */
Expand Down Expand Up @@ -982,7 +994,9 @@ static void __exit inet6_exit(void)
unregister_pernet_subsys(&inet6_net_ops);
cleanup_ipv6_mibs();
proto_unregister(&rawv6_prot);
#ifdef CONFIG_IP_UDPLITE
proto_unregister(&udplitev6_prot);
#endif
proto_unregister(&udpv6_prot);
proto_unregister(&tcpv6_prot);
}
Expand Down
Loading

0 comments on commit e898d4d

Please sign in to comment.