aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ipconfig.c6
-rw-r--r--net/ipv4/netfilter/iptable_filter.c7
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c6
-rw-r--r--net/ipv4/netfilter/iptable_raw.c6
-rw-r--r--net/ipv4/netfilter/iptable_security.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c5
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c2
-rw-r--r--net/ipv4/tcp.c25
-rw-r--r--net/ipv4/udp.c55
9 files changed, 65 insertions, 53 deletions
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 42a0f3dd3fd6..d722013c1cae 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1268,6 +1268,9 @@ __be32 __init root_nfs_parse_addr(char *name)
1268static int __init ip_auto_config(void) 1268static int __init ip_auto_config(void)
1269{ 1269{
1270 __be32 addr; 1270 __be32 addr;
1271#ifdef IPCONFIG_DYNAMIC
1272 int retries = CONF_OPEN_RETRIES;
1273#endif
1271 1274
1272#ifdef CONFIG_PROC_FS 1275#ifdef CONFIG_PROC_FS
1273 proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); 1276 proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
@@ -1304,9 +1307,6 @@ static int __init ip_auto_config(void)
1304#endif 1307#endif
1305 ic_first_dev->next) { 1308 ic_first_dev->next) {
1306#ifdef IPCONFIG_DYNAMIC 1309#ifdef IPCONFIG_DYNAMIC
1307
1308 int retries = CONF_OPEN_RETRIES;
1309
1310 if (ic_dynamic() < 0) { 1310 if (ic_dynamic() < 0) {
1311 ic_close_devs(); 1311 ic_close_devs();
1312 1312
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index c9224310ebae..52cb6939d093 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -93,13 +93,8 @@ ipt_local_out_hook(unsigned int hook,
93{ 93{
94 /* root is playing with raw sockets. */ 94 /* root is playing with raw sockets. */
95 if (skb->len < sizeof(struct iphdr) || 95 if (skb->len < sizeof(struct iphdr) ||
96 ip_hdrlen(skb) < sizeof(struct iphdr)) { 96 ip_hdrlen(skb) < sizeof(struct iphdr))
97 if (net_ratelimit())
98 printk("iptable_filter: ignoring short SOCK_RAW "
99 "packet.\n");
100 return NF_ACCEPT; 97 return NF_ACCEPT;
101 }
102
103 return ipt_do_table(skb, hook, in, out, 98 return ipt_do_table(skb, hook, in, out,
104 dev_net(out)->ipv4.iptable_filter); 99 dev_net(out)->ipv4.iptable_filter);
105} 100}
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 69f2c4287146..3929d20b9e45 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -132,12 +132,8 @@ ipt_local_hook(unsigned int hook,
132 132
133 /* root is playing with raw sockets. */ 133 /* root is playing with raw sockets. */
134 if (skb->len < sizeof(struct iphdr) 134 if (skb->len < sizeof(struct iphdr)
135 || ip_hdrlen(skb) < sizeof(struct iphdr)) { 135 || ip_hdrlen(skb) < sizeof(struct iphdr))
136 if (net_ratelimit())
137 printk("iptable_mangle: ignoring short SOCK_RAW "
138 "packet.\n");
139 return NF_ACCEPT; 136 return NF_ACCEPT;
140 }
141 137
142 /* Save things which could affect route */ 138 /* Save things which could affect route */
143 mark = skb->mark; 139 mark = skb->mark;
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 8faebfe638f1..7f65d18333e3 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -65,12 +65,8 @@ ipt_local_hook(unsigned int hook,
65{ 65{
66 /* root is playing with raw sockets. */ 66 /* root is playing with raw sockets. */
67 if (skb->len < sizeof(struct iphdr) || 67 if (skb->len < sizeof(struct iphdr) ||
68 ip_hdrlen(skb) < sizeof(struct iphdr)) { 68 ip_hdrlen(skb) < sizeof(struct iphdr))
69 if (net_ratelimit())
70 printk("iptable_raw: ignoring short SOCK_RAW "
71 "packet.\n");
72 return NF_ACCEPT; 69 return NF_ACCEPT;
73 }
74 return ipt_do_table(skb, hook, in, out, 70 return ipt_do_table(skb, hook, in, out,
75 dev_net(out)->ipv4.iptable_raw); 71 dev_net(out)->ipv4.iptable_raw);
76} 72}
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index 36f3be3cc428..a52a35f4a584 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -96,12 +96,8 @@ ipt_local_out_hook(unsigned int hook,
96{ 96{
97 /* Somebody is playing with raw sockets. */ 97 /* Somebody is playing with raw sockets. */
98 if (skb->len < sizeof(struct iphdr) 98 if (skb->len < sizeof(struct iphdr)
99 || ip_hdrlen(skb) < sizeof(struct iphdr)) { 99 || ip_hdrlen(skb) < sizeof(struct iphdr))
100 if (net_ratelimit())
101 printk(KERN_INFO "iptable_security: ignoring short "
102 "SOCK_RAW packet.\n");
103 return NF_ACCEPT; 100 return NF_ACCEPT;
104 }
105 return ipt_do_table(skb, hook, in, out, 101 return ipt_do_table(skb, hook, in, out,
106 dev_net(out)->ipv4.iptable_security); 102 dev_net(out)->ipv4.iptable_security);
107} 103}
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index b2141e11575e..4beb04fac588 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -145,11 +145,8 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
145{ 145{
146 /* root is playing with raw sockets. */ 146 /* root is playing with raw sockets. */
147 if (skb->len < sizeof(struct iphdr) || 147 if (skb->len < sizeof(struct iphdr) ||
148 ip_hdrlen(skb) < sizeof(struct iphdr)) { 148 ip_hdrlen(skb) < sizeof(struct iphdr))
149 if (net_ratelimit())
150 printk("ipt_hook: happy cracking.\n");
151 return NF_ACCEPT; 149 return NF_ACCEPT;
152 }
153 return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb); 150 return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb);
154} 151}
155 152
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 1fd3ef7718b6..2a8bee26f43d 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -20,7 +20,7 @@
20#include <net/netfilter/nf_conntrack_core.h> 20#include <net/netfilter/nf_conntrack_core.h>
21#include <net/netfilter/nf_log.h> 21#include <net/netfilter/nf_log.h>
22 22
23static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; 23static unsigned int nf_ct_icmp_timeout __read_mostly = 30*HZ;
24 24
25static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 25static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
26 struct nf_conntrack_tuple *tuple) 26 struct nf_conntrack_tuple *tuple)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index ce572f9dff02..76b148bcb0dc 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -522,8 +522,13 @@ static int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
522 unsigned int offset, size_t len) 522 unsigned int offset, size_t len)
523{ 523{
524 struct tcp_splice_state *tss = rd_desc->arg.data; 524 struct tcp_splice_state *tss = rd_desc->arg.data;
525 int ret;
525 526
526 return skb_splice_bits(skb, offset, tss->pipe, tss->len, tss->flags); 527 ret = skb_splice_bits(skb, offset, tss->pipe, min(rd_desc->count, len),
528 tss->flags);
529 if (ret > 0)
530 rd_desc->count -= ret;
531 return ret;
527} 532}
528 533
529static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss) 534static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss)
@@ -531,6 +536,7 @@ static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss)
531 /* Store TCP splice context information in read_descriptor_t. */ 536 /* Store TCP splice context information in read_descriptor_t. */
532 read_descriptor_t rd_desc = { 537 read_descriptor_t rd_desc = {
533 .arg.data = tss, 538 .arg.data = tss,
539 .count = tss->len,
534 }; 540 };
535 541
536 return tcp_read_sock(sk, &rd_desc, tcp_splice_data_recv); 542 return tcp_read_sock(sk, &rd_desc, tcp_splice_data_recv);
@@ -611,11 +617,13 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
611 tss.len -= ret; 617 tss.len -= ret;
612 spliced += ret; 618 spliced += ret;
613 619
620 if (!timeo)
621 break;
614 release_sock(sk); 622 release_sock(sk);
615 lock_sock(sk); 623 lock_sock(sk);
616 624
617 if (sk->sk_err || sk->sk_state == TCP_CLOSE || 625 if (sk->sk_err || sk->sk_state == TCP_CLOSE ||
618 (sk->sk_shutdown & RCV_SHUTDOWN) || !timeo || 626 (sk->sk_shutdown & RCV_SHUTDOWN) ||
619 signal_pending(current)) 627 signal_pending(current))
620 break; 628 break;
621 } 629 }
@@ -2382,7 +2390,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2382 unsigned int seq; 2390 unsigned int seq;
2383 __be32 delta; 2391 __be32 delta;
2384 unsigned int oldlen; 2392 unsigned int oldlen;
2385 unsigned int len; 2393 unsigned int mss;
2386 2394
2387 if (!pskb_may_pull(skb, sizeof(*th))) 2395 if (!pskb_may_pull(skb, sizeof(*th)))
2388 goto out; 2396 goto out;
@@ -2398,10 +2406,13 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2398 oldlen = (u16)~skb->len; 2406 oldlen = (u16)~skb->len;
2399 __skb_pull(skb, thlen); 2407 __skb_pull(skb, thlen);
2400 2408
2409 mss = skb_shinfo(skb)->gso_size;
2410 if (unlikely(skb->len <= mss))
2411 goto out;
2412
2401 if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { 2413 if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
2402 /* Packet is from an untrusted source, reset gso_segs. */ 2414 /* Packet is from an untrusted source, reset gso_segs. */
2403 int type = skb_shinfo(skb)->gso_type; 2415 int type = skb_shinfo(skb)->gso_type;
2404 int mss;
2405 2416
2406 if (unlikely(type & 2417 if (unlikely(type &
2407 ~(SKB_GSO_TCPV4 | 2418 ~(SKB_GSO_TCPV4 |
@@ -2412,7 +2423,6 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2412 !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))) 2423 !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
2413 goto out; 2424 goto out;
2414 2425
2415 mss = skb_shinfo(skb)->gso_size;
2416 skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss); 2426 skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
2417 2427
2418 segs = NULL; 2428 segs = NULL;
@@ -2423,8 +2433,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2423 if (IS_ERR(segs)) 2433 if (IS_ERR(segs))
2424 goto out; 2434 goto out;
2425 2435
2426 len = skb_shinfo(skb)->gso_size; 2436 delta = htonl(oldlen + (thlen + mss));
2427 delta = htonl(oldlen + (thlen + len));
2428 2437
2429 skb = segs; 2438 skb = segs;
2430 th = tcp_hdr(skb); 2439 th = tcp_hdr(skb);
@@ -2440,7 +2449,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2440 csum_fold(csum_partial(skb_transport_header(skb), 2449 csum_fold(csum_partial(skb_transport_header(skb),
2441 thlen, skb->csum)); 2450 thlen, skb->csum));
2442 2451
2443 seq += len; 2452 seq += mss;
2444 skb = skb->next; 2453 skb = skb->next;
2445 th = tcp_hdr(skb); 2454 th = tcp_hdr(skb);
2446 2455
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index cf5ab0581eba..b7faffe5c029 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -120,8 +120,11 @@ EXPORT_SYMBOL(sysctl_udp_wmem_min);
120atomic_t udp_memory_allocated; 120atomic_t udp_memory_allocated;
121EXPORT_SYMBOL(udp_memory_allocated); 121EXPORT_SYMBOL(udp_memory_allocated);
122 122
123#define PORTS_PER_CHAIN (65536 / UDP_HTABLE_SIZE)
124
123static int udp_lib_lport_inuse(struct net *net, __u16 num, 125static int udp_lib_lport_inuse(struct net *net, __u16 num,
124 const struct udp_hslot *hslot, 126 const struct udp_hslot *hslot,
127 unsigned long *bitmap,
125 struct sock *sk, 128 struct sock *sk,
126 int (*saddr_comp)(const struct sock *sk1, 129 int (*saddr_comp)(const struct sock *sk1,
127 const struct sock *sk2)) 130 const struct sock *sk2))
@@ -132,12 +135,17 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
132 sk_nulls_for_each(sk2, node, &hslot->head) 135 sk_nulls_for_each(sk2, node, &hslot->head)
133 if (net_eq(sock_net(sk2), net) && 136 if (net_eq(sock_net(sk2), net) &&
134 sk2 != sk && 137 sk2 != sk &&
135 sk2->sk_hash == num && 138 (bitmap || sk2->sk_hash == num) &&
136 (!sk2->sk_reuse || !sk->sk_reuse) && 139 (!sk2->sk_reuse || !sk->sk_reuse) &&
137 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if 140 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
138 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && 141 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
139 (*saddr_comp)(sk, sk2)) 142 (*saddr_comp)(sk, sk2)) {
140 return 1; 143 if (bitmap)
144 __set_bit(sk2->sk_hash / UDP_HTABLE_SIZE,
145 bitmap);
146 else
147 return 1;
148 }
141 return 0; 149 return 0;
142} 150}
143 151
@@ -160,32 +168,47 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
160 if (!snum) { 168 if (!snum) {
161 int low, high, remaining; 169 int low, high, remaining;
162 unsigned rand; 170 unsigned rand;
163 unsigned short first; 171 unsigned short first, last;
172 DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
164 173
165 inet_get_local_port_range(&low, &high); 174 inet_get_local_port_range(&low, &high);
166 remaining = (high - low) + 1; 175 remaining = (high - low) + 1;
167 176
168 rand = net_random(); 177 rand = net_random();
169 snum = first = rand % remaining + low; 178 first = (((u64)rand * remaining) >> 32) + low;
170 rand |= 1; 179 /*
171 for (;;) { 180 * force rand to be an odd multiple of UDP_HTABLE_SIZE
172 hslot = &udptable->hash[udp_hashfn(net, snum)]; 181 */
182 rand = (rand | 1) * UDP_HTABLE_SIZE;
183 for (last = first + UDP_HTABLE_SIZE; first != last; first++) {
184 hslot = &udptable->hash[udp_hashfn(net, first)];
185 bitmap_zero(bitmap, PORTS_PER_CHAIN);
173 spin_lock_bh(&hslot->lock); 186 spin_lock_bh(&hslot->lock);
174 if (!udp_lib_lport_inuse(net, snum, hslot, sk, saddr_comp)) 187 udp_lib_lport_inuse(net, snum, hslot, bitmap, sk,
175 break; 188 saddr_comp);
176 spin_unlock_bh(&hslot->lock); 189
190 snum = first;
191 /*
192 * Iterate on all possible values of snum for this hash.
193 * Using steps of an odd multiple of UDP_HTABLE_SIZE
194 * give us randomization and full range coverage.
195 */
177 do { 196 do {
178 snum = snum + rand; 197 if (low <= snum && snum <= high &&
179 } while (snum < low || snum > high); 198 !test_bit(snum / UDP_HTABLE_SIZE, bitmap))
180 if (snum == first) 199 goto found;
181 goto fail; 200 snum += rand;
201 } while (snum != first);
202 spin_unlock_bh(&hslot->lock);
182 } 203 }
204 goto fail;
183 } else { 205 } else {
184 hslot = &udptable->hash[udp_hashfn(net, snum)]; 206 hslot = &udptable->hash[udp_hashfn(net, snum)];
185 spin_lock_bh(&hslot->lock); 207 spin_lock_bh(&hslot->lock);
186 if (udp_lib_lport_inuse(net, snum, hslot, sk, saddr_comp)) 208 if (udp_lib_lport_inuse(net, snum, hslot, NULL, sk, saddr_comp))
187 goto fail_unlock; 209 goto fail_unlock;
188 } 210 }
211found:
189 inet_sk(sk)->num = snum; 212 inet_sk(sk)->num = snum;
190 sk->sk_hash = snum; 213 sk->sk_hash = snum;
191 if (sk_unhashed(sk)) { 214 if (sk_unhashed(sk)) {