aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_output.c12
-rw-r--r--net/ipv4/udp.c7
-rw-r--r--net/ipv6/ip6_output.c67
-rw-r--r--net/ipv6/ip6mr.c1
-rw-r--r--net/packet/af_packet.c17
-rw-r--r--net/sunrpc/Kconfig2
6 files changed, 74 insertions, 32 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 557fe16cbfb0..dda42f0bd7a3 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -663,14 +663,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
663 th->urg_ptr = 0; 663 th->urg_ptr = 0;
664 664
665 /* The urg_mode check is necessary during a below snd_una win probe */ 665 /* The urg_mode check is necessary during a below snd_una win probe */
666 if (unlikely(tcp_urg_mode(tp))) { 666 if (unlikely(tcp_urg_mode(tp) &&
667 if (between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF)) { 667 between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) {
668 th->urg_ptr = htons(tp->snd_up - tcb->seq); 668 th->urg_ptr = htons(tp->snd_up - tcb->seq);
669 th->urg = 1; 669 th->urg = 1;
670 } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) {
671 th->urg_ptr = 0xFFFF;
672 th->urg = 1;
673 }
674 } 670 }
675 671
676 tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); 672 tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index b7faffe5c029..cc3a0a06c004 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1015,9 +1015,11 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1015 1015
1016 if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) { 1016 if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
1017 /* Note that an ENOMEM error is charged twice */ 1017 /* Note that an ENOMEM error is charged twice */
1018 if (rc == -ENOMEM) 1018 if (rc == -ENOMEM) {
1019 UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS, 1019 UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
1020 is_udplite); 1020 is_udplite);
1021 atomic_inc(&sk->sk_drops);
1022 }
1021 goto drop; 1023 goto drop;
1022 } 1024 }
1023 1025
@@ -1229,7 +1231,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
1229 int proto) 1231 int proto)
1230{ 1232{
1231 struct sock *sk; 1233 struct sock *sk;
1232 struct udphdr *uh = udp_hdr(skb); 1234 struct udphdr *uh;
1233 unsigned short ulen; 1235 unsigned short ulen;
1234 struct rtable *rt = (struct rtable*)skb->dst; 1236 struct rtable *rt = (struct rtable*)skb->dst;
1235 __be32 saddr = ip_hdr(skb)->saddr; 1237 __be32 saddr = ip_hdr(skb)->saddr;
@@ -1242,6 +1244,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
1242 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 1244 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
1243 goto drop; /* No space for header. */ 1245 goto drop; /* No space for header. */
1244 1246
1247 uh = udp_hdr(skb);
1245 ulen = ntohs(uh->len); 1248 ulen = ntohs(uh->len);
1246 if (ulen > skb->len) 1249 if (ulen > skb->len)
1247 goto short_packet; 1250 goto short_packet;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4b15938bef4d..9fb49c3b518a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1105,6 +1105,18 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1105 return err; 1105 return err;
1106} 1106}
1107 1107
1108static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
1109 gfp_t gfp)
1110{
1111 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
1112}
1113
1114static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
1115 gfp_t gfp)
1116{
1117 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
1118}
1119
1108int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, 1120int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1109 int offset, int len, int odd, struct sk_buff *skb), 1121 int offset, int len, int odd, struct sk_buff *skb),
1110 void *from, int length, int transhdrlen, 1122 void *from, int length, int transhdrlen,
@@ -1130,17 +1142,37 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1130 * setup for corking 1142 * setup for corking
1131 */ 1143 */
1132 if (opt) { 1144 if (opt) {
1133 if (np->cork.opt == NULL) { 1145 if (WARN_ON(np->cork.opt))
1134 np->cork.opt = kmalloc(opt->tot_len,
1135 sk->sk_allocation);
1136 if (unlikely(np->cork.opt == NULL))
1137 return -ENOBUFS;
1138 } else if (np->cork.opt->tot_len < opt->tot_len) {
1139 printk(KERN_DEBUG "ip6_append_data: invalid option length\n");
1140 return -EINVAL; 1146 return -EINVAL;
1141 } 1147
1142 memcpy(np->cork.opt, opt, opt->tot_len); 1148 np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation);
1143 inet->cork.flags |= IPCORK_OPT; 1149 if (unlikely(np->cork.opt == NULL))
1150 return -ENOBUFS;
1151
1152 np->cork.opt->tot_len = opt->tot_len;
1153 np->cork.opt->opt_flen = opt->opt_flen;
1154 np->cork.opt->opt_nflen = opt->opt_nflen;
1155
1156 np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt,
1157 sk->sk_allocation);
1158 if (opt->dst0opt && !np->cork.opt->dst0opt)
1159 return -ENOBUFS;
1160
1161 np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt,
1162 sk->sk_allocation);
1163 if (opt->dst1opt && !np->cork.opt->dst1opt)
1164 return -ENOBUFS;
1165
1166 np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt,
1167 sk->sk_allocation);
1168 if (opt->hopopt && !np->cork.opt->hopopt)
1169 return -ENOBUFS;
1170
1171 np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt,
1172 sk->sk_allocation);
1173 if (opt->srcrt && !np->cork.opt->srcrt)
1174 return -ENOBUFS;
1175
1144 /* need source address above miyazawa*/ 1176 /* need source address above miyazawa*/
1145 } 1177 }
1146 dst_hold(&rt->u.dst); 1178 dst_hold(&rt->u.dst);
@@ -1167,8 +1199,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1167 } else { 1199 } else {
1168 rt = (struct rt6_info *)inet->cork.dst; 1200 rt = (struct rt6_info *)inet->cork.dst;
1169 fl = &inet->cork.fl; 1201 fl = &inet->cork.fl;
1170 if (inet->cork.flags & IPCORK_OPT) 1202 opt = np->cork.opt;
1171 opt = np->cork.opt;
1172 transhdrlen = 0; 1203 transhdrlen = 0;
1173 exthdrlen = 0; 1204 exthdrlen = 0;
1174 mtu = inet->cork.fragsize; 1205 mtu = inet->cork.fragsize;
@@ -1407,9 +1438,15 @@ error:
1407 1438
1408static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) 1439static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
1409{ 1440{
1410 inet->cork.flags &= ~IPCORK_OPT; 1441 if (np->cork.opt) {
1411 kfree(np->cork.opt); 1442 kfree(np->cork.opt->dst0opt);
1412 np->cork.opt = NULL; 1443 kfree(np->cork.opt->dst1opt);
1444 kfree(np->cork.opt->hopopt);
1445 kfree(np->cork.opt->srcrt);
1446 kfree(np->cork.opt);
1447 np->cork.opt = NULL;
1448 }
1449
1413 if (inet->cork.dst) { 1450 if (inet->cork.dst) {
1414 dst_release(inet->cork.dst); 1451 dst_release(inet->cork.dst);
1415 inet->cork.dst = NULL; 1452 inet->cork.dst = NULL;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index d19a84b79503..228be551e9c1 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -48,6 +48,7 @@
48#include <linux/pim.h> 48#include <linux/pim.h>
49#include <net/addrconf.h> 49#include <net/addrconf.h>
50#include <linux/netfilter_ipv6.h> 50#include <linux/netfilter_ipv6.h>
51#include <net/ip6_checksum.h>
51 52
52/* Big lock, protecting vif table, mrt cache and mroute socket state. 53/* Big lock, protecting vif table, mrt cache and mroute socket state.
53 Note that the changes are semaphored via rtnl_lock. 54 Note that the changes are semaphored via rtnl_lock.
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 5f94db2f3e9e..1fc4a7885c41 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -77,6 +77,7 @@
77#include <linux/poll.h> 77#include <linux/poll.h>
78#include <linux/module.h> 78#include <linux/module.h>
79#include <linux/init.h> 79#include <linux/init.h>
80#include <linux/mutex.h>
80 81
81#ifdef CONFIG_INET 82#ifdef CONFIG_INET
82#include <net/inet_common.h> 83#include <net/inet_common.h>
@@ -175,6 +176,7 @@ struct packet_sock {
175#endif 176#endif
176 struct packet_type prot_hook; 177 struct packet_type prot_hook;
177 spinlock_t bind_lock; 178 spinlock_t bind_lock;
179 struct mutex pg_vec_lock;
178 unsigned int running:1, /* prot_hook is attached*/ 180 unsigned int running:1, /* prot_hook is attached*/
179 auxdata:1, 181 auxdata:1,
180 origdev:1; 182 origdev:1;
@@ -220,13 +222,13 @@ static void *packet_lookup_frame(struct packet_sock *po, unsigned int position,
220 h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size); 222 h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
221 switch (po->tp_version) { 223 switch (po->tp_version) {
222 case TPACKET_V1: 224 case TPACKET_V1:
223 if (status != h.h1->tp_status ? TP_STATUS_USER : 225 if (status != (h.h1->tp_status ? TP_STATUS_USER :
224 TP_STATUS_KERNEL) 226 TP_STATUS_KERNEL))
225 return NULL; 227 return NULL;
226 break; 228 break;
227 case TPACKET_V2: 229 case TPACKET_V2:
228 if (status != h.h2->tp_status ? TP_STATUS_USER : 230 if (status != (h.h2->tp_status ? TP_STATUS_USER :
229 TP_STATUS_KERNEL) 231 TP_STATUS_KERNEL))
230 return NULL; 232 return NULL;
231 break; 233 break;
232 } 234 }
@@ -1069,6 +1071,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
1069 */ 1071 */
1070 1072
1071 spin_lock_init(&po->bind_lock); 1073 spin_lock_init(&po->bind_lock);
1074 mutex_init(&po->pg_vec_lock);
1072 po->prot_hook.func = packet_rcv; 1075 po->prot_hook.func = packet_rcv;
1073 1076
1074 if (sock->type == SOCK_PACKET) 1077 if (sock->type == SOCK_PACKET)
@@ -1865,6 +1868,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
1865 synchronize_net(); 1868 synchronize_net();
1866 1869
1867 err = -EBUSY; 1870 err = -EBUSY;
1871 mutex_lock(&po->pg_vec_lock);
1868 if (closing || atomic_read(&po->mapped) == 0) { 1872 if (closing || atomic_read(&po->mapped) == 0) {
1869 err = 0; 1873 err = 0;
1870#define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; }) 1874#define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
@@ -1886,6 +1890,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
1886 if (atomic_read(&po->mapped)) 1890 if (atomic_read(&po->mapped))
1887 printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped)); 1891 printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped));
1888 } 1892 }
1893 mutex_unlock(&po->pg_vec_lock);
1889 1894
1890 spin_lock(&po->bind_lock); 1895 spin_lock(&po->bind_lock);
1891 if (was_running && !po->running) { 1896 if (was_running && !po->running) {
@@ -1918,7 +1923,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
1918 1923
1919 size = vma->vm_end - vma->vm_start; 1924 size = vma->vm_end - vma->vm_start;
1920 1925
1921 lock_sock(sk); 1926 mutex_lock(&po->pg_vec_lock);
1922 if (po->pg_vec == NULL) 1927 if (po->pg_vec == NULL)
1923 goto out; 1928 goto out;
1924 if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE) 1929 if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
@@ -1941,7 +1946,7 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
1941 err = 0; 1946 err = 0;
1942 1947
1943out: 1948out:
1944 release_sock(sk); 1949 mutex_unlock(&po->pg_vec_lock);
1945 return err; 1950 return err;
1946} 1951}
1947#endif 1952#endif
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index dcef600d0bf5..5592883e1e4a 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -6,7 +6,7 @@ config SUNRPC_GSS
6 6
7config SUNRPC_XPRT_RDMA 7config SUNRPC_XPRT_RDMA
8 tristate 8 tristate
9 depends on SUNRPC && INFINIBAND && EXPERIMENTAL 9 depends on SUNRPC && INFINIBAND && INFINIBAND_ADDR_TRANS && EXPERIMENTAL
10 default SUNRPC && INFINIBAND 10 default SUNRPC && INFINIBAND
11 help 11 help
12 This option allows the NFS client and server to support 12 This option allows the NFS client and server to support