aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-02-29 11:06:47 -0500
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-03-04 01:18:22 -0500
commite898d4db2749c6052072e9bc4448e396cbdeb06a (patch)
tree2b8673d85210a23e67d0817b18f401411e8936f3
parentc6aefafb7ec620911d46174eed514f9df639e5a4 (diff)
[UDP]: Allow users to configure UDP-Lite.
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 <yoshfuji@linux-ipv6.org>
-rw-r--r--include/linux/udp.h11
-rw-r--r--include/net/ipv6.h5
-rw-r--r--include/net/transp_v6.h5
-rw-r--r--include/net/udplite.h9
-rw-r--r--net/ipv4/Kconfig10
-rw-r--r--net/ipv4/Makefile3
-rw-r--r--net/ipv4/af_inet.c7
-rw-r--r--net/ipv4/proc.c5
-rw-r--r--net/ipv4/udp.c24
-rw-r--r--net/ipv6/Makefile3
-rw-r--r--net/ipv6/af_inet6.c14
-rw-r--r--net/ipv6/ipv6_sockglue.c6
-rw-r--r--net/ipv6/proc.c6
-rw-r--r--net/ipv6/udp.c16
14 files changed, 99 insertions, 25 deletions
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 8ec703f462da..4144664d69d9 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -70,8 +70,10 @@ struct udp_sock {
70#define UDPLITE_BIT 0x1 /* set by udplite proto init function */ 70#define UDPLITE_BIT 0x1 /* set by udplite proto init function */
71#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */ 71#define UDPLITE_SEND_CC 0x2 /* set via udplite setsockopt */
72#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */ 72#define UDPLITE_RECV_CC 0x4 /* set via udplite setsocktopt */
73#ifdef CONFIG_IP_UDPLITE
73 __u8 pcflag; /* marks socket as UDP-Lite if > 0 */ 74 __u8 pcflag; /* marks socket as UDP-Lite if > 0 */
74 __u8 unused[3]; 75 __u8 unused[3];
76#endif
75 /* 77 /*
76 * For encapsulation sockets. 78 * For encapsulation sockets.
77 */ 79 */
@@ -82,7 +84,16 @@ static inline struct udp_sock *udp_sk(const struct sock *sk)
82{ 84{
83 return (struct udp_sock *)sk; 85 return (struct udp_sock *)sk;
84} 86}
87
88#ifdef CONFIG_IP_UDPLITE
85#define IS_UDPLITE(__sk) (udp_sk(__sk)->pcflag) 89#define IS_UDPLITE(__sk) (udp_sk(__sk)->pcflag)
90#define IS_PROTO_UDPLITE(__proto) ((__proto) == IPPROTO_UDPLITE)
91#define IS_SOL_UDPFAMILY(level) ((level) == SOL_UDP || (level) == SOL_UDPLITE)
92#else
93#define IS_UDPLITE(__sk) 0
94#define IS_PROTO_UDPLITE(__proto) 0
95#define IS_SOL_UDPFAMILY(level) ((level) == SOL_UDP)
96#endif
86 97
87#endif 98#endif
88 99
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8b05c65415cb..96b1763bfcaa 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -603,8 +603,13 @@ extern int tcp6_proc_init(void);
603extern void tcp6_proc_exit(void); 603extern void tcp6_proc_exit(void);
604extern int udp6_proc_init(void); 604extern int udp6_proc_init(void);
605extern void udp6_proc_exit(void); 605extern void udp6_proc_exit(void);
606#ifdef CONFIG_IP_UDPLITE
606extern int udplite6_proc_init(void); 607extern int udplite6_proc_init(void);
607extern void udplite6_proc_exit(void); 608extern void udplite6_proc_exit(void);
609#else
610static inline int udplite6_proc_init(void) { return 0; }
611static inline void udplite6_proc_exit(void) { }
612#endif
608extern int ipv6_misc_proc_init(void); 613extern int ipv6_misc_proc_init(void);
609extern void ipv6_misc_proc_exit(void); 614extern void ipv6_misc_proc_exit(void);
610extern int snmp6_register_dev(struct inet6_dev *idev); 615extern int snmp6_register_dev(struct inet6_dev *idev);
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 27394e0447d8..902e6c6bc793 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -27,8 +27,13 @@ extern int rawv6_init(void);
27extern void rawv6_exit(void); 27extern void rawv6_exit(void);
28extern int udpv6_init(void); 28extern int udpv6_init(void);
29extern void udpv6_exit(void); 29extern void udpv6_exit(void);
30#ifdef CONFIG_IP_UDPLITE
30extern int udplitev6_init(void); 31extern int udplitev6_init(void);
31extern void udplitev6_exit(void); 32extern void udplitev6_exit(void);
33#else
34static inline int udplitev6_init(void) { return 0; }
35static inline void udplitev6_exit(void) { }
36#endif
32extern int tcpv6_init(void); 37extern int tcpv6_init(void);
33extern void tcpv6_exit(void); 38extern void tcpv6_exit(void);
34 39
diff --git a/include/net/udplite.h b/include/net/udplite.h
index b76b2e377af4..01ddb2c20264 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -25,7 +25,9 @@ static __inline__ int udplite_getfrag(void *from, char *to, int offset,
25/* Designate sk as UDP-Lite socket */ 25/* Designate sk as UDP-Lite socket */
26static inline int udplite_sk_init(struct sock *sk) 26static inline int udplite_sk_init(struct sock *sk)
27{ 27{
28#ifdef CONFIG_IP_UDPLITE
28 udp_sk(sk)->pcflag = UDPLITE_BIT; 29 udp_sk(sk)->pcflag = UDPLITE_BIT;
30#endif
29 return 0; 31 return 0;
30} 32}
31 33
@@ -69,7 +71,7 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
69static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh) 71static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh)
70{ 72{
71 int cscov = up->len; 73 int cscov = up->len;
72 74#ifdef CONFIG_IP_UDPLITE
73 /* 75 /*
74 * Sender has set `partial coverage' option on UDP-Lite socket 76 * Sender has set `partial coverage' option on UDP-Lite socket
75 */ 77 */
@@ -93,13 +95,15 @@ static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh)
93 * illegal, we fall back to the defaults here. 95 * illegal, we fall back to the defaults here.
94 */ 96 */
95 } 97 }
98#endif
96 return cscov; 99 return cscov;
97} 100}
98 101
99static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb) 102static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
100{ 103{
101 int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
102 __wsum csum = 0; 104 __wsum csum = 0;
105#ifdef CONFIG_IP_UDPLITE
106 int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
103 107
104 skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */ 108 skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */
105 109
@@ -112,6 +116,7 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
112 if ((cscov -= len) <= 0) 116 if ((cscov -= len) <= 0)
113 break; 117 break;
114 } 118 }
119#endif
115 return csum; 120 return csum;
116} 121}
117 122
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 19880b086e71..efe3832c4ad8 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -632,5 +632,15 @@ config TCP_MD5SIG
632 632
633 If unsure, say N. 633 If unsure, say N.
634 634
635config IP_UDPLITE
636 bool "IP: UDP-Lite Protocol (RFC 3828)"
637 default n
638 ---help---
639 UDP-Lite (RFC 3828) is a UDP-like protocol with variable-length
640 checksum. Read <file:Documentation/networking/udplite.txt> for
641 details.
642
643 If unsure, say N.
644
635source "net/ipv4/ipvs/Kconfig" 645source "net/ipv4/ipvs/Kconfig"
636 646
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index ad40ef3f9ebc..e88cebdf3e30 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -8,7 +8,7 @@ obj-y := route.o inetpeer.o protocol.o \
8 inet_timewait_sock.o inet_connection_sock.o \ 8 inet_timewait_sock.o inet_connection_sock.o \
9 tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ 9 tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
10 tcp_minisocks.o tcp_cong.o \ 10 tcp_minisocks.o tcp_cong.o \
11 datagram.o raw.o udp.o udplite.o \ 11 datagram.o raw.o udp.o \
12 arp.o icmp.o devinet.o af_inet.o igmp.o \ 12 arp.o icmp.o devinet.o af_inet.o igmp.o \
13 fib_frontend.o fib_semantics.o \ 13 fib_frontend.o fib_semantics.o \
14 inet_fragment.o 14 inet_fragment.o
@@ -49,6 +49,7 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
49obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o 49obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
50obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o 50obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
51obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o 51obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
52obj-$(CONFIG_IP_UDPLITE) += udplite.o
52obj-$(CONFIG_NETLABEL) += cipso_ipv4.o 53obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
53 54
54obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \ 55obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 4f539bd48718..67260c0eaaa8 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1317,15 +1317,18 @@ static int __init init_ipv4_mibs(void)
1317 if (snmp_mib_init((void **)udp_statistics, 1317 if (snmp_mib_init((void **)udp_statistics,
1318 sizeof(struct udp_mib)) < 0) 1318 sizeof(struct udp_mib)) < 0)
1319 goto err_udp_mib; 1319 goto err_udp_mib;
1320#ifdef CONFIG_IP_UDPLITE
1320 if (snmp_mib_init((void **)udplite_statistics, 1321 if (snmp_mib_init((void **)udplite_statistics,
1321 sizeof(struct udp_mib)) < 0) 1322 sizeof(struct udp_mib)) < 0)
1322 goto err_udplite_mib; 1323 goto err_udplite_mib;
1323 1324#endif
1324 tcp_mib_init(); 1325 tcp_mib_init();
1325 1326
1326 return 0; 1327 return 0;
1327 1328
1329#ifdef CONFIG_IP_UDPLITE
1328err_udplite_mib: 1330err_udplite_mib:
1331#endif
1329 snmp_mib_free((void **)udp_statistics); 1332 snmp_mib_free((void **)udp_statistics);
1330err_udp_mib: 1333err_udp_mib:
1331 snmp_mib_free((void **)tcp_statistics); 1334 snmp_mib_free((void **)tcp_statistics);
@@ -1423,8 +1426,10 @@ static int __init inet_init(void)
1423 /* Setup UDP memory threshold */ 1426 /* Setup UDP memory threshold */
1424 udp_init(); 1427 udp_init();
1425 1428
1429#ifdef CONFIG_IP_UDPLITE
1426 /* Add UDP-Lite (RFC 3828) */ 1430 /* Add UDP-Lite (RFC 3828) */
1427 udplite4_register(); 1431 udplite4_register();
1432#endif
1428 1433
1429 /* 1434 /*
1430 * Set the ICMP layer up 1435 * Set the ICMP layer up
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index d63474c6b400..d75ddb7fa4b8 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -59,7 +59,9 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
59 atomic_read(&tcp_memory_allocated)); 59 atomic_read(&tcp_memory_allocated));
60 seq_printf(seq, "UDP: inuse %d mem %d\n", sock_prot_inuse_get(&udp_prot), 60 seq_printf(seq, "UDP: inuse %d mem %d\n", sock_prot_inuse_get(&udp_prot),
61 atomic_read(&udp_memory_allocated)); 61 atomic_read(&udp_memory_allocated));
62#ifdef CONFIG_IP_UDPLITE
62 seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(&udplite_prot)); 63 seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(&udplite_prot));
64#endif
63 seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse_get(&raw_prot)); 65 seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse_get(&raw_prot));
64 seq_printf(seq, "FRAG: inuse %d memory %d\n", 66 seq_printf(seq, "FRAG: inuse %d memory %d\n",
65 ip_frag_nqueues(&init_net), ip_frag_mem(&init_net)); 67 ip_frag_nqueues(&init_net), ip_frag_mem(&init_net));
@@ -349,6 +351,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
349 snmp_fold_field((void **)udp_statistics, 351 snmp_fold_field((void **)udp_statistics,
350 snmp4_udp_list[i].entry)); 352 snmp4_udp_list[i].entry));
351 353
354#ifdef CONFIG_IP_UDPLITE
352 /* the UDP and UDP-Lite MIBs are the same */ 355 /* the UDP and UDP-Lite MIBs are the same */
353 seq_puts(seq, "\nUdpLite:"); 356 seq_puts(seq, "\nUdpLite:");
354 for (i = 0; snmp4_udp_list[i].name != NULL; i++) 357 for (i = 0; snmp4_udp_list[i].name != NULL; i++)
@@ -359,7 +362,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
359 seq_printf(seq, " %lu", 362 seq_printf(seq, " %lu",
360 snmp_fold_field((void **)udplite_statistics, 363 snmp_fold_field((void **)udplite_statistics,
361 snmp4_udp_list[i].entry)); 364 snmp4_udp_list[i].entry));
362 365#endif
363 seq_putc(seq, '\n'); 366 seq_putc(seq, '\n');
364 return 0; 367 return 0;
365} 368}
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 7ea1b67b6de1..acc353aa89eb 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1127,7 +1127,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
1127 UDP_SKB_CB(skb)->partial_cov = 0; 1127 UDP_SKB_CB(skb)->partial_cov = 0;
1128 UDP_SKB_CB(skb)->cscov = skb->len; 1128 UDP_SKB_CB(skb)->cscov = skb->len;
1129 1129
1130 if (proto == IPPROTO_UDPLITE) { 1130 if (IS_PROTO_UDPLITE(proto)) {
1131 err = udplite_checksum_init(skb, uh); 1131 err = udplite_checksum_init(skb, uh);
1132 if (err) 1132 if (err)
1133 return err; 1133 return err;
@@ -1175,7 +1175,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1175 if (ulen > skb->len) 1175 if (ulen > skb->len)
1176 goto short_packet; 1176 goto short_packet;
1177 1177
1178 if (proto == IPPROTO_UDP) { 1178 if (IS_PROTO_UDPLITE(proto)) {
1179 /* UDP validates ulen. */ 1179 /* UDP validates ulen. */
1180 if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen)) 1180 if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
1181 goto short_packet; 1181 goto short_packet;
@@ -1217,7 +1217,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1217 if (udp_lib_checksum_complete(skb)) 1217 if (udp_lib_checksum_complete(skb))
1218 goto csum_error; 1218 goto csum_error;
1219 1219
1220 UDP_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); 1220 UDP_INC_STATS_BH(UDP_MIB_NOPORTS, IS_PROTO_UDPLITE(proto));
1221 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 1221 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
1222 1222
1223 /* 1223 /*
@@ -1229,7 +1229,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1229 1229
1230short_packet: 1230short_packet:
1231 LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n", 1231 LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
1232 proto == IPPROTO_UDPLITE ? "-Lite" : "", 1232 IS_PROTO_UDPLITE(proto) ? "-Lite" : "",
1233 NIPQUAD(saddr), 1233 NIPQUAD(saddr),
1234 ntohs(uh->source), 1234 ntohs(uh->source),
1235 ulen, 1235 ulen,
@@ -1244,14 +1244,14 @@ csum_error:
1244 * the network is concerned, anyway) as per 4.1.3.4 (MUST). 1244 * the network is concerned, anyway) as per 4.1.3.4 (MUST).
1245 */ 1245 */
1246 LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n", 1246 LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
1247 proto == IPPROTO_UDPLITE ? "-Lite" : "", 1247 IS_PROTO_UDPLITE(proto) ? "-Lite" : "",
1248 NIPQUAD(saddr), 1248 NIPQUAD(saddr),
1249 ntohs(uh->source), 1249 ntohs(uh->source),
1250 NIPQUAD(daddr), 1250 NIPQUAD(daddr),
1251 ntohs(uh->dest), 1251 ntohs(uh->dest),
1252 ulen); 1252 ulen);
1253drop: 1253drop:
1254 UDP_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); 1254 UDP_INC_STATS_BH(UDP_MIB_INERRORS, IS_PROTO_UDPLITE(proto));
1255 kfree_skb(skb); 1255 kfree_skb(skb);
1256 return 0; 1256 return 0;
1257} 1257}
@@ -1279,7 +1279,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1279 struct udp_sock *up = udp_sk(sk); 1279 struct udp_sock *up = udp_sk(sk);
1280 int val; 1280 int val;
1281 int err = 0; 1281 int err = 0;
1282#ifdef CONFIG_IP_UDPLITE
1282 int is_udplite = IS_UDPLITE(sk); 1283 int is_udplite = IS_UDPLITE(sk);
1284#endif
1283 1285
1284 if (optlen<sizeof(int)) 1286 if (optlen<sizeof(int))
1285 return -EINVAL; 1287 return -EINVAL;
@@ -1315,6 +1317,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1315 } 1317 }
1316 break; 1318 break;
1317 1319
1320#ifdef CONFIG_IP_UDPLITE
1318 /* 1321 /*
1319 * UDP-Lite's partial checksum coverage (RFC 3828). 1322 * UDP-Lite's partial checksum coverage (RFC 3828).
1320 */ 1323 */
@@ -1340,6 +1343,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1340 up->pcrlen = val; 1343 up->pcrlen = val;
1341 up->pcflag |= UDPLITE_RECV_CC; 1344 up->pcflag |= UDPLITE_RECV_CC;
1342 break; 1345 break;
1346#endif
1343 1347
1344 default: 1348 default:
1345 err = -ENOPROTOOPT; 1349 err = -ENOPROTOOPT;
@@ -1352,7 +1356,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1352int udp_setsockopt(struct sock *sk, int level, int optname, 1356int udp_setsockopt(struct sock *sk, int level, int optname,
1353 char __user *optval, int optlen) 1357 char __user *optval, int optlen)
1354{ 1358{
1355 if (level == SOL_UDP || level == SOL_UDPLITE) 1359 if (IS_SOL_UDPFAMILY(level))
1356 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 1360 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
1357 udp_push_pending_frames); 1361 udp_push_pending_frames);
1358 return ip_setsockopt(sk, level, optname, optval, optlen); 1362 return ip_setsockopt(sk, level, optname, optval, optlen);
@@ -1362,7 +1366,7 @@ int udp_setsockopt(struct sock *sk, int level, int optname,
1362int compat_udp_setsockopt(struct sock *sk, int level, int optname, 1366int compat_udp_setsockopt(struct sock *sk, int level, int optname,
1363 char __user *optval, int optlen) 1367 char __user *optval, int optlen)
1364{ 1368{
1365 if (level == SOL_UDP || level == SOL_UDPLITE) 1369 if (IS_SOL_UDPFAMILY(level))
1366 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 1370 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
1367 udp_push_pending_frames); 1371 udp_push_pending_frames);
1368 return compat_ip_setsockopt(sk, level, optname, optval, optlen); 1372 return compat_ip_setsockopt(sk, level, optname, optval, optlen);
@@ -1416,7 +1420,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
1416int udp_getsockopt(struct sock *sk, int level, int optname, 1420int udp_getsockopt(struct sock *sk, int level, int optname,
1417 char __user *optval, int __user *optlen) 1421 char __user *optval, int __user *optlen)
1418{ 1422{
1419 if (level == SOL_UDP || level == SOL_UDPLITE) 1423 if (IS_SOL_UDPFAMILY(level))
1420 return udp_lib_getsockopt(sk, level, optname, optval, optlen); 1424 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
1421 return ip_getsockopt(sk, level, optname, optval, optlen); 1425 return ip_getsockopt(sk, level, optname, optval, optlen);
1422} 1426}
@@ -1425,7 +1429,7 @@ int udp_getsockopt(struct sock *sk, int level, int optname,
1425int compat_udp_getsockopt(struct sock *sk, int level, int optname, 1429int compat_udp_getsockopt(struct sock *sk, int level, int optname,
1426 char __user *optval, int __user *optlen) 1430 char __user *optval, int __user *optlen)
1427{ 1431{
1428 if (level == SOL_UDP || level == SOL_UDPLITE) 1432 if (IS_SOL_UDPFAMILY(level))
1429 return udp_lib_getsockopt(sk, level, optname, optval, optlen); 1433 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
1430 return compat_ip_getsockopt(sk, level, optname, optval, optlen); 1434 return compat_ip_getsockopt(sk, level, optname, optval, optlen);
1431} 1435}
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index ae14617e607f..81969479955f 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_IPV6) += ipv6.o
6 6
7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ 7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
8 addrlabel.o \ 8 addrlabel.o \
9 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \ 9 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o \
10 raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ 10 raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
11 exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o 11 exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o
12 12
@@ -17,6 +17,7 @@ ipv6-$(CONFIG_NETFILTER) += netfilter.o
17ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o 17ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
18ipv6-$(CONFIG_PROC_FS) += proc.o 18ipv6-$(CONFIG_PROC_FS) += proc.o
19ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o 19ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o
20ipv6-$(CONFIG_IP_UDPLITE) += udplite.o
20 21
21ipv6-objs += $(ipv6-y) 22ipv6-objs += $(ipv6-y)
22 23
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 9869f87243cf..243c42a6b80d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -691,12 +691,16 @@ static int __init init_ipv6_mibs(void)
691 goto err_icmpmsg_mib; 691 goto err_icmpmsg_mib;
692 if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0) 692 if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0)
693 goto err_udp_mib; 693 goto err_udp_mib;
694#ifdef CONFIG_IP_UDPLITE
694 if (snmp_mib_init((void **)udplite_stats_in6, 695 if (snmp_mib_init((void **)udplite_stats_in6,
695 sizeof (struct udp_mib)) < 0) 696 sizeof (struct udp_mib)) < 0)
696 goto err_udplite_mib; 697 goto err_udplite_mib;
698#endif
697 return 0; 699 return 0;
698 700
701#ifdef CONFIG_IP_UDPLITE
699err_udplite_mib: 702err_udplite_mib:
703#endif
700 snmp_mib_free((void **)udp_stats_in6); 704 snmp_mib_free((void **)udp_stats_in6);
701err_udp_mib: 705err_udp_mib:
702 snmp_mib_free((void **)icmpv6msg_statistics); 706 snmp_mib_free((void **)icmpv6msg_statistics);
@@ -715,7 +719,9 @@ static void cleanup_ipv6_mibs(void)
715 snmp_mib_free((void **)icmpv6_statistics); 719 snmp_mib_free((void **)icmpv6_statistics);
716 snmp_mib_free((void **)icmpv6msg_statistics); 720 snmp_mib_free((void **)icmpv6msg_statistics);
717 snmp_mib_free((void **)udp_stats_in6); 721 snmp_mib_free((void **)udp_stats_in6);
722#ifdef CONFIG_IP_UDPLITE
718 snmp_mib_free((void **)udplite_stats_in6); 723 snmp_mib_free((void **)udplite_stats_in6);
724#endif
719} 725}
720 726
721static int inet6_net_init(struct net *net) 727static int inet6_net_init(struct net *net)
@@ -760,9 +766,11 @@ static int __init inet6_init(void)
760 if (err) 766 if (err)
761 goto out_unregister_tcp_proto; 767 goto out_unregister_tcp_proto;
762 768
769#ifdef CONFIG_IP_UDPLITE
763 err = proto_register(&udplitev6_prot, 1); 770 err = proto_register(&udplitev6_prot, 1);
764 if (err) 771 if (err)
765 goto out_unregister_udp_proto; 772 goto out_unregister_udp_proto;
773#endif
766 774
767 err = proto_register(&rawv6_prot, 1); 775 err = proto_register(&rawv6_prot, 1);
768 if (err) 776 if (err)
@@ -933,8 +941,10 @@ out_sock_register_fail:
933out_unregister_raw_proto: 941out_unregister_raw_proto:
934 proto_unregister(&rawv6_prot); 942 proto_unregister(&rawv6_prot);
935out_unregister_udplite_proto: 943out_unregister_udplite_proto:
944#ifdef CONFIG_IP_UDPLITE
936 proto_unregister(&udplitev6_prot); 945 proto_unregister(&udplitev6_prot);
937out_unregister_udp_proto: 946out_unregister_udp_proto:
947#endif
938 proto_unregister(&udpv6_prot); 948 proto_unregister(&udpv6_prot);
939out_unregister_tcp_proto: 949out_unregister_tcp_proto:
940 proto_unregister(&tcpv6_prot); 950 proto_unregister(&tcpv6_prot);
@@ -950,7 +960,9 @@ static void __exit inet6_exit(void)
950 rtnl_unregister_all(PF_INET6); 960 rtnl_unregister_all(PF_INET6);
951 961
952 udpv6_exit(); 962 udpv6_exit();
963#ifdef CONFIG_IP_UDPLITE
953 udplitev6_exit(); 964 udplitev6_exit();
965#endif
954 tcpv6_exit(); 966 tcpv6_exit();
955 967
956 /* Cleanup code parts. */ 968 /* Cleanup code parts. */
@@ -982,7 +994,9 @@ static void __exit inet6_exit(void)
982 unregister_pernet_subsys(&inet6_net_ops); 994 unregister_pernet_subsys(&inet6_net_ops);
983 cleanup_ipv6_mibs(); 995 cleanup_ipv6_mibs();
984 proto_unregister(&rawv6_prot); 996 proto_unregister(&rawv6_prot);
997#ifdef CONFIG_IP_UDPLITE
985 proto_unregister(&udplitev6_prot); 998 proto_unregister(&udplitev6_prot);
999#endif
986 proto_unregister(&udpv6_prot); 1000 proto_unregister(&udpv6_prot);
987 proto_unregister(&tcpv6_prot); 1001 proto_unregister(&tcpv6_prot);
988} 1002}
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index bf2a686aa13d..0a18fecb93d1 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -239,7 +239,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
239 struct sk_buff *pktopt; 239 struct sk_buff *pktopt;
240 240
241 if (sk->sk_protocol != IPPROTO_UDP && 241 if (sk->sk_protocol != IPPROTO_UDP &&
242#ifdef CONFIG_IP_UDPLITE
242 sk->sk_protocol != IPPROTO_UDPLITE && 243 sk->sk_protocol != IPPROTO_UDPLITE &&
244#endif
243 sk->sk_protocol != IPPROTO_TCP) 245 sk->sk_protocol != IPPROTO_TCP)
244 break; 246 break;
245 247
@@ -279,7 +281,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
279 } else { 281 } else {
280 struct proto *prot = &udp_prot; 282 struct proto *prot = &udp_prot;
281 283
282 if (sk->sk_protocol == IPPROTO_UDPLITE) 284 if (IS_PROTO_UDPLITE(sk->sk_protocol))
283 prot = &udplite_prot; 285 prot = &udplite_prot;
284 local_bh_disable(); 286 local_bh_disable();
285 sock_prot_inuse_add(sk->sk_prot, -1); 287 sock_prot_inuse_add(sk->sk_prot, -1);
@@ -844,7 +846,9 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
844 switch (optname) { 846 switch (optname) {
845 case IPV6_ADDRFORM: 847 case IPV6_ADDRFORM:
846 if (sk->sk_protocol != IPPROTO_UDP && 848 if (sk->sk_protocol != IPPROTO_UDP &&
849#ifdef CONFIG_IP_UDPLITE
847 sk->sk_protocol != IPPROTO_UDPLITE && 850 sk->sk_protocol != IPPROTO_UDPLITE &&
851#endif
848 sk->sk_protocol != IPPROTO_TCP) 852 sk->sk_protocol != IPPROTO_TCP)
849 return -EINVAL; 853 return -EINVAL;
850 if (sk->sk_state != TCP_ESTABLISHED) 854 if (sk->sk_state != TCP_ESTABLISHED)
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 199ef379e501..5ba7ae849d04 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -39,8 +39,10 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
39 sock_prot_inuse_get(&tcpv6_prot)); 39 sock_prot_inuse_get(&tcpv6_prot));
40 seq_printf(seq, "UDP6: inuse %d\n", 40 seq_printf(seq, "UDP6: inuse %d\n",
41 sock_prot_inuse_get(&udpv6_prot)); 41 sock_prot_inuse_get(&udpv6_prot));
42#ifdef CONFIG_IP_UDPLITE
42 seq_printf(seq, "UDPLITE6: inuse %d\n", 43 seq_printf(seq, "UDPLITE6: inuse %d\n",
43 sock_prot_inuse_get(&udplitev6_prot)); 44 sock_prot_inuse_get(&udplitev6_prot));
45#endif
44 seq_printf(seq, "RAW6: inuse %d\n", 46 seq_printf(seq, "RAW6: inuse %d\n",
45 sock_prot_inuse_get(&rawv6_prot)); 47 sock_prot_inuse_get(&rawv6_prot));
46 seq_printf(seq, "FRAG6: inuse %d memory %d\n", 48 seq_printf(seq, "FRAG6: inuse %d memory %d\n",
@@ -111,6 +113,7 @@ static struct snmp_mib snmp6_udp6_list[] = {
111 SNMP_MIB_SENTINEL 113 SNMP_MIB_SENTINEL
112}; 114};
113 115
116#ifdef CONFIG_IP_UDPLITE
114static struct snmp_mib snmp6_udplite6_list[] = { 117static struct snmp_mib snmp6_udplite6_list[] = {
115 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS), 118 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS),
116 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS), 119 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
@@ -118,6 +121,7 @@ static struct snmp_mib snmp6_udplite6_list[] = {
118 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS), 121 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
119 SNMP_MIB_SENTINEL 122 SNMP_MIB_SENTINEL
120}; 123};
124#endif
121 125
122static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) 126static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib)
123{ 127{
@@ -176,7 +180,9 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
176 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); 180 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
177 snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics); 181 snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
178 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); 182 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
183#ifdef CONFIG_IP_UDPLITE
179 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list); 184 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
185#endif
180 } 186 }
181 return 0; 187 return 0;
182} 188}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 53739de829db..55feac7ba717 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -400,7 +400,7 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
400 UDP_SKB_CB(skb)->partial_cov = 0; 400 UDP_SKB_CB(skb)->partial_cov = 0;
401 UDP_SKB_CB(skb)->cscov = skb->len; 401 UDP_SKB_CB(skb)->cscov = skb->len;
402 402
403 if (proto == IPPROTO_UDPLITE) { 403 if (IS_PROTO_UDPLITE(proto)) {
404 err = udplite_checksum_init(skb, uh); 404 err = udplite_checksum_init(skb, uh);
405 if (err) 405 if (err)
406 return err; 406 return err;
@@ -489,7 +489,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
489 489
490 if (udp_lib_checksum_complete(skb)) 490 if (udp_lib_checksum_complete(skb))
491 goto discard; 491 goto discard;
492 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); 492 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS, IS_PROTO_UDPLITE(proto));
493 493
494 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); 494 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
495 495
@@ -510,11 +510,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
510 510
511short_packet: 511short_packet:
512 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: %d/%u\n", 512 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: %d/%u\n",
513 proto == IPPROTO_UDPLITE ? "-Lite" : "", 513 IS_PROTO_UDPLITE(proto) ? "-Lite" : "",
514 ulen, skb->len); 514 ulen, skb->len);
515 515
516discard: 516discard:
517 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); 517 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, IS_PROTO_UDPLITE(proto));
518 kfree_skb(skb); 518 kfree_skb(skb);
519 return 0; 519 return 0;
520} 520}
@@ -890,7 +890,7 @@ int udpv6_destroy_sock(struct sock *sk)
890int udpv6_setsockopt(struct sock *sk, int level, int optname, 890int udpv6_setsockopt(struct sock *sk, int level, int optname,
891 char __user *optval, int optlen) 891 char __user *optval, int optlen)
892{ 892{
893 if (level == SOL_UDP || level == SOL_UDPLITE) 893 if (IS_SOL_UDPFAMILY(level))
894 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 894 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
895 udp_v6_push_pending_frames); 895 udp_v6_push_pending_frames);
896 return ipv6_setsockopt(sk, level, optname, optval, optlen); 896 return ipv6_setsockopt(sk, level, optname, optval, optlen);
@@ -900,7 +900,7 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname,
900int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, 900int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
901 char __user *optval, int optlen) 901 char __user *optval, int optlen)
902{ 902{
903 if (level == SOL_UDP || level == SOL_UDPLITE) 903 if (IS_SOL_UDPFAMILY(level))
904 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 904 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
905 udp_v6_push_pending_frames); 905 udp_v6_push_pending_frames);
906 return compat_ipv6_setsockopt(sk, level, optname, optval, optlen); 906 return compat_ipv6_setsockopt(sk, level, optname, optval, optlen);
@@ -910,7 +910,7 @@ int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
910int udpv6_getsockopt(struct sock *sk, int level, int optname, 910int udpv6_getsockopt(struct sock *sk, int level, int optname,
911 char __user *optval, int __user *optlen) 911 char __user *optval, int __user *optlen)
912{ 912{
913 if (level == SOL_UDP || level == SOL_UDPLITE) 913 if (IS_SOL_UDPFAMILY(level))
914 return udp_lib_getsockopt(sk, level, optname, optval, optlen); 914 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
915 return ipv6_getsockopt(sk, level, optname, optval, optlen); 915 return ipv6_getsockopt(sk, level, optname, optval, optlen);
916} 916}
@@ -919,7 +919,7 @@ int udpv6_getsockopt(struct sock *sk, int level, int optname,
919int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, 919int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
920 char __user *optval, int __user *optlen) 920 char __user *optval, int __user *optlen)
921{ 921{
922 if (level == SOL_UDP || level == SOL_UDPLITE) 922 if (IS_SOL_UDPFAMILY(level))
923 return udp_lib_getsockopt(sk, level, optname, optval, optlen); 923 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
924 return compat_ipv6_getsockopt(sk, level, optname, optval, optlen); 924 return compat_ipv6_getsockopt(sk, level, optname, optval, optlen);
925} 925}