aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c5
-rw-r--r--net/ipv4/inet_diag.c14
-rw-r--r--net/ipv4/ip_output.c25
-rw-r--r--net/ipv4/netfilter.c60
-rw-r--r--net/ipv4/netfilter/ip_queue.c6
-rw-r--r--net/ipv4/netfilter/ip_tables.c2
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c6
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c2
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c14
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c7
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c4
-rw-r--r--net/ipv4/ping.c1
-rw-r--r--net/ipv4/route.c82
-rw-r--r--net/ipv4/tcp.c10
-rw-r--r--net/ipv4/tcp_ipv4.c1
-rw-r--r--net/ipv4/udp.c13
-rw-r--r--net/ipv4/xfrm4_output.c7
22 files changed, 128 insertions, 145 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 9c1926027a26..ef1528af7abf 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -465,8 +465,10 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
465 if (addr_len < sizeof(struct sockaddr_in)) 465 if (addr_len < sizeof(struct sockaddr_in))
466 goto out; 466 goto out;
467 467
468 if (addr->sin_family != AF_INET) 468 if (addr->sin_family != AF_INET) {
469 err = -EAFNOSUPPORT;
469 goto out; 470 goto out;
471 }
470 472
471 chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); 473 chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
472 474
@@ -676,6 +678,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags)
676 678
677 lock_sock(sk2); 679 lock_sock(sk2);
678 680
681 sock_rps_record_flow(sk2);
679 WARN_ON(!((1 << sk2->sk_state) & 682 WARN_ON(!((1 << sk2->sk_state) &
680 (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); 683 (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE)));
681 684
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 6ffe94ca5bc9..3267d3898437 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -437,7 +437,7 @@ static int valid_cc(const void *bc, int len, int cc)
437 return 0; 437 return 0;
438 if (cc == len) 438 if (cc == len)
439 return 1; 439 return 1;
440 if (op->yes < 4) 440 if (op->yes < 4 || op->yes & 3)
441 return 0; 441 return 0;
442 len -= op->yes; 442 len -= op->yes;
443 bc += op->yes; 443 bc += op->yes;
@@ -447,11 +447,11 @@ static int valid_cc(const void *bc, int len, int cc)
447 447
448static int inet_diag_bc_audit(const void *bytecode, int bytecode_len) 448static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
449{ 449{
450 const unsigned char *bc = bytecode; 450 const void *bc = bytecode;
451 int len = bytecode_len; 451 int len = bytecode_len;
452 452
453 while (len > 0) { 453 while (len > 0) {
454 struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)bc; 454 const struct inet_diag_bc_op *op = bc;
455 455
456//printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len); 456//printk("BC: %d %d %d {%d} / %d\n", op->code, op->yes, op->no, op[1].no, len);
457 switch (op->code) { 457 switch (op->code) {
@@ -462,22 +462,20 @@ static int inet_diag_bc_audit(const void *bytecode, int bytecode_len)
462 case INET_DIAG_BC_S_LE: 462 case INET_DIAG_BC_S_LE:
463 case INET_DIAG_BC_D_GE: 463 case INET_DIAG_BC_D_GE:
464 case INET_DIAG_BC_D_LE: 464 case INET_DIAG_BC_D_LE:
465 if (op->yes < 4 || op->yes > len + 4)
466 return -EINVAL;
467 case INET_DIAG_BC_JMP: 465 case INET_DIAG_BC_JMP:
468 if (op->no < 4 || op->no > len + 4) 466 if (op->no < 4 || op->no > len + 4 || op->no & 3)
469 return -EINVAL; 467 return -EINVAL;
470 if (op->no < len && 468 if (op->no < len &&
471 !valid_cc(bytecode, bytecode_len, len - op->no)) 469 !valid_cc(bytecode, bytecode_len, len - op->no))
472 return -EINVAL; 470 return -EINVAL;
473 break; 471 break;
474 case INET_DIAG_BC_NOP: 472 case INET_DIAG_BC_NOP:
475 if (op->yes < 4 || op->yes > len + 4)
476 return -EINVAL;
477 break; 473 break;
478 default: 474 default:
479 return -EINVAL; 475 return -EINVAL;
480 } 476 }
477 if (op->yes < 4 || op->yes > len + 4 || op->yes & 3)
478 return -EINVAL;
481 bc += op->yes; 479 bc += op->yes;
482 len -= op->yes; 480 len -= op->yes;
483 } 481 }
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 98af3697c718..84f26e8e6c60 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -799,9 +799,9 @@ static int __ip_append_data(struct sock *sk,
799 int csummode = CHECKSUM_NONE; 799 int csummode = CHECKSUM_NONE;
800 struct rtable *rt = (struct rtable *)cork->dst; 800 struct rtable *rt = (struct rtable *)cork->dst;
801 801
802 exthdrlen = transhdrlen ? rt->dst.header_len : 0; 802 skb = skb_peek_tail(queue);
803 length += exthdrlen; 803
804 transhdrlen += exthdrlen; 804 exthdrlen = !skb ? rt->dst.header_len : 0;
805 mtu = cork->fragsize; 805 mtu = cork->fragsize;
806 806
807 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 807 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
@@ -825,12 +825,10 @@ static int __ip_append_data(struct sock *sk,
825 !exthdrlen) 825 !exthdrlen)
826 csummode = CHECKSUM_PARTIAL; 826 csummode = CHECKSUM_PARTIAL;
827 827
828 skb = skb_peek_tail(queue);
829
830 cork->length += length; 828 cork->length += length;
831 if (((length > mtu) || (skb && skb_is_gso(skb))) && 829 if (((length > mtu) || (skb && skb_is_gso(skb))) &&
832 (sk->sk_protocol == IPPROTO_UDP) && 830 (sk->sk_protocol == IPPROTO_UDP) &&
833 (rt->dst.dev->features & NETIF_F_UFO)) { 831 (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
834 err = ip_ufo_append_data(sk, queue, getfrag, from, length, 832 err = ip_ufo_append_data(sk, queue, getfrag, from, length,
835 hh_len, fragheaderlen, transhdrlen, 833 hh_len, fragheaderlen, transhdrlen,
836 mtu, flags); 834 mtu, flags);
@@ -883,17 +881,16 @@ alloc_new_skb:
883 else 881 else
884 alloclen = fraglen; 882 alloclen = fraglen;
885 883
884 alloclen += exthdrlen;
885
886 /* The last fragment gets additional space at tail. 886 /* The last fragment gets additional space at tail.
887 * Note, with MSG_MORE we overallocate on fragments, 887 * Note, with MSG_MORE we overallocate on fragments,
888 * because we have no idea what fragment will be 888 * because we have no idea what fragment will be
889 * the last. 889 * the last.
890 */ 890 */
891 if (datalen == length + fraggap) { 891 if (datalen == length + fraggap)
892 alloclen += rt->dst.trailer_len; 892 alloclen += rt->dst.trailer_len;
893 /* make sure mtu is not reached */ 893
894 if (datalen > mtu - fragheaderlen - rt->dst.trailer_len)
895 datalen -= ALIGN(rt->dst.trailer_len, 8);
896 }
897 if (transhdrlen) { 894 if (transhdrlen) {
898 skb = sock_alloc_send_skb(sk, 895 skb = sock_alloc_send_skb(sk,
899 alloclen + hh_len + 15, 896 alloclen + hh_len + 15,
@@ -926,11 +923,11 @@ alloc_new_skb:
926 /* 923 /*
927 * Find where to start putting bytes. 924 * Find where to start putting bytes.
928 */ 925 */
929 data = skb_put(skb, fraglen); 926 data = skb_put(skb, fraglen + exthdrlen);
930 skb_set_network_header(skb, exthdrlen); 927 skb_set_network_header(skb, exthdrlen);
931 skb->transport_header = (skb->network_header + 928 skb->transport_header = (skb->network_header +
932 fragheaderlen); 929 fragheaderlen);
933 data += fragheaderlen; 930 data += fragheaderlen + exthdrlen;
934 931
935 if (fraggap) { 932 if (fraggap) {
936 skb->csum = skb_copy_and_csum_bits( 933 skb->csum = skb_copy_and_csum_bits(
@@ -1064,7 +1061,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
1064 */ 1061 */
1065 *rtp = NULL; 1062 *rtp = NULL;
1066 cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ? 1063 cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ?
1067 rt->dst.dev->mtu : dst_mtu(rt->dst.path); 1064 rt->dst.dev->mtu : dst_mtu(&rt->dst);
1068 cork->dst = &rt->dst; 1065 cork->dst = &rt->dst;
1069 cork->length = 0; 1066 cork->length = 0;
1070 cork->tx_flags = ipc->tx_flags; 1067 cork->tx_flags = ipc->tx_flags;
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 4614babdc45f..2e97e3ec1eb7 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -17,51 +17,35 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
17 const struct iphdr *iph = ip_hdr(skb); 17 const struct iphdr *iph = ip_hdr(skb);
18 struct rtable *rt; 18 struct rtable *rt;
19 struct flowi4 fl4 = {}; 19 struct flowi4 fl4 = {};
20 unsigned long orefdst; 20 __be32 saddr = iph->saddr;
21 __u8 flags = 0;
21 unsigned int hh_len; 22 unsigned int hh_len;
22 unsigned int type;
23 23
24 type = inet_addr_type(net, iph->saddr); 24 if (!skb->sk && addr_type != RTN_LOCAL) {
25 if (skb->sk && inet_sk(skb->sk)->transparent) 25 if (addr_type == RTN_UNSPEC)
26 type = RTN_LOCAL; 26 addr_type = inet_addr_type(net, saddr);
27 if (addr_type == RTN_UNSPEC) 27 if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
28 addr_type = type; 28 flags |= FLOWI_FLAG_ANYSRC;
29 else
30 saddr = 0;
31 }
29 32
30 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause 33 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
31 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. 34 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
32 */ 35 */
33 if (addr_type == RTN_LOCAL) { 36 fl4.daddr = iph->daddr;
34 fl4.daddr = iph->daddr; 37 fl4.saddr = saddr;
35 if (type == RTN_LOCAL) 38 fl4.flowi4_tos = RT_TOS(iph->tos);
36 fl4.saddr = iph->saddr; 39 fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
37 fl4.flowi4_tos = RT_TOS(iph->tos); 40 fl4.flowi4_mark = skb->mark;
38 fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; 41 fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags;
39 fl4.flowi4_mark = skb->mark; 42 rt = ip_route_output_key(net, &fl4);
40 fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; 43 if (IS_ERR(rt))
41 rt = ip_route_output_key(net, &fl4); 44 return -1;
42 if (IS_ERR(rt))
43 return -1;
44
45 /* Drop old route. */
46 skb_dst_drop(skb);
47 skb_dst_set(skb, &rt->dst);
48 } else {
49 /* non-local src, find valid iif to satisfy
50 * rp-filter when calling ip_route_input. */
51 fl4.daddr = iph->saddr;
52 rt = ip_route_output_key(net, &fl4);
53 if (IS_ERR(rt))
54 return -1;
55 45
56 orefdst = skb->_skb_refdst; 46 /* Drop old route. */
57 if (ip_route_input(skb, iph->daddr, iph->saddr, 47 skb_dst_drop(skb);
58 RT_TOS(iph->tos), rt->dst.dev) != 0) { 48 skb_dst_set(skb, &rt->dst);
59 dst_release(&rt->dst);
60 return -1;
61 }
62 dst_release(&rt->dst);
63 refdst_drop(orefdst);
64 }
65 49
66 if (skb_dst(skb)->error) 50 if (skb_dst(skb)->error)
67 return -1; 51 return -1;
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index d2c1311cb28d..5c9b9d963918 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -203,7 +203,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
203 else 203 else
204 pmsg->outdev_name[0] = '\0'; 204 pmsg->outdev_name[0] = '\0';
205 205
206 if (entry->indev && entry->skb->dev) { 206 if (entry->indev && entry->skb->dev &&
207 entry->skb->mac_header != entry->skb->network_header) {
207 pmsg->hw_type = entry->skb->dev->type; 208 pmsg->hw_type = entry->skb->dev->type;
208 pmsg->hw_addrlen = dev_parse_header(entry->skb, 209 pmsg->hw_addrlen = dev_parse_header(entry->skb,
209 pmsg->hw_addr); 210 pmsg->hw_addr);
@@ -402,7 +403,8 @@ ipq_dev_drop(int ifindex)
402static inline void 403static inline void
403__ipq_rcv_skb(struct sk_buff *skb) 404__ipq_rcv_skb(struct sk_buff *skb)
404{ 405{
405 int status, type, pid, flags, nlmsglen, skblen; 406 int status, type, pid, flags;
407 unsigned int nlmsglen, skblen;
406 struct nlmsghdr *nlh; 408 struct nlmsghdr *nlh;
407 409
408 skblen = skb->len; 410 skblen = skb->len;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 764743843503..24e556e83a3b 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -566,7 +566,7 @@ check_entry(const struct ipt_entry *e, const char *name)
566 const struct xt_entry_target *t; 566 const struct xt_entry_target *t;
567 567
568 if (!ip_checkentry(&e->ip)) { 568 if (!ip_checkentry(&e->ip)) {
569 duprintf("ip check failed %p %s.\n", e, par->match->name); 569 duprintf("ip check failed %p %s.\n", e, name);
570 return -EINVAL; 570 return -EINVAL;
571 } 571 }
572 572
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index d609ac3cb9a4..5c9e97c79017 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -307,7 +307,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
307 * error messages (RELATED) and information requests (see below) */ 307 * error messages (RELATED) and information requests (see below) */
308 if (ip_hdr(skb)->protocol == IPPROTO_ICMP && 308 if (ip_hdr(skb)->protocol == IPPROTO_ICMP &&
309 (ctinfo == IP_CT_RELATED || 309 (ctinfo == IP_CT_RELATED ||
310 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)) 310 ctinfo == IP_CT_RELATED_REPLY))
311 return XT_CONTINUE; 311 return XT_CONTINUE;
312 312
313 /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, 313 /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO,
@@ -321,12 +321,12 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
321 ct->mark = hash; 321 ct->mark = hash;
322 break; 322 break;
323 case IP_CT_RELATED: 323 case IP_CT_RELATED:
324 case IP_CT_RELATED+IP_CT_IS_REPLY: 324 case IP_CT_RELATED_REPLY:
325 /* FIXME: we don't handle expectations at the 325 /* FIXME: we don't handle expectations at the
326 * moment. they can arrive on a different node than 326 * moment. they can arrive on a different node than
327 * the master connection (e.g. FTP passive mode) */ 327 * the master connection (e.g. FTP passive mode) */
328 case IP_CT_ESTABLISHED: 328 case IP_CT_ESTABLISHED:
329 case IP_CT_ESTABLISHED+IP_CT_IS_REPLY: 329 case IP_CT_ESTABLISHED_REPLY:
330 break; 330 break;
331 default: 331 default:
332 break; 332 break;
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index d2ed9dc74ebc..9931152a78b5 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -60,7 +60,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par)
60 nat = nfct_nat(ct); 60 nat = nfct_nat(ct);
61 61
62 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || 62 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
63 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); 63 ctinfo == IP_CT_RELATED_REPLY));
64 64
65 /* Source address is 0.0.0.0 - locally generated packet that is 65 /* Source address is 0.0.0.0 - locally generated packet that is
66 * probably not supposed to be masqueraded. 66 * probably not supposed to be masqueraded.
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 1ff79e557f96..51f13f8ec724 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -40,7 +40,6 @@ static void send_reset(struct sk_buff *oldskb, int hook)
40 struct iphdr *niph; 40 struct iphdr *niph;
41 const struct tcphdr *oth; 41 const struct tcphdr *oth;
42 struct tcphdr _otcph, *tcph; 42 struct tcphdr _otcph, *tcph;
43 unsigned int addr_type;
44 43
45 /* IP header checks: fragment. */ 44 /* IP header checks: fragment. */
46 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) 45 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))
@@ -55,6 +54,9 @@ static void send_reset(struct sk_buff *oldskb, int hook)
55 if (oth->rst) 54 if (oth->rst)
56 return; 55 return;
57 56
57 if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
58 return;
59
58 /* Check checksum */ 60 /* Check checksum */
59 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP)) 61 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
60 return; 62 return;
@@ -101,19 +103,11 @@ static void send_reset(struct sk_buff *oldskb, int hook)
101 nskb->csum_start = (unsigned char *)tcph - nskb->head; 103 nskb->csum_start = (unsigned char *)tcph - nskb->head;
102 nskb->csum_offset = offsetof(struct tcphdr, check); 104 nskb->csum_offset = offsetof(struct tcphdr, check);
103 105
104 addr_type = RTN_UNSPEC;
105 if (hook != NF_INET_FORWARD
106#ifdef CONFIG_BRIDGE_NETFILTER
107 || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
108#endif
109 )
110 addr_type = RTN_LOCAL;
111
112 /* ip_route_me_harder expects skb->dst to be set */ 106 /* ip_route_me_harder expects skb->dst to be set */
113 skb_dst_set_noref(nskb, skb_dst(oldskb)); 107 skb_dst_set_noref(nskb, skb_dst(oldskb));
114 108
115 nskb->protocol = htons(ETH_P_IP); 109 nskb->protocol = htons(ETH_P_IP);
116 if (ip_route_me_harder(nskb, addr_type)) 110 if (ip_route_me_harder(nskb, RTN_UNSPEC))
117 goto free_nskb; 111 goto free_nskb;
118 112
119 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb)); 113 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
index af6e9c778345..2b57e52c746c 100644
--- a/net/ipv4/netfilter/ipt_ecn.c
+++ b/net/ipv4/netfilter/ipt_ecn.c
@@ -25,7 +25,8 @@ MODULE_LICENSE("GPL");
25static inline bool match_ip(const struct sk_buff *skb, 25static inline bool match_ip(const struct sk_buff *skb,
26 const struct ipt_ecn_info *einfo) 26 const struct ipt_ecn_info *einfo)
27{ 27{
28 return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect; 28 return ((ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect) ^
29 !!(einfo->invert & IPT_ECN_OP_MATCH_IP);
29} 30}
30 31
31static inline bool match_tcp(const struct sk_buff *skb, 32static inline bool match_tcp(const struct sk_buff *skb,
@@ -76,8 +77,6 @@ static bool ecn_mt(const struct sk_buff *skb, struct xt_action_param *par)
76 return false; 77 return false;
77 78
78 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { 79 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
79 if (ip_hdr(skb)->protocol != IPPROTO_TCP)
80 return false;
81 if (!match_tcp(skb, info, &par->hotdrop)) 80 if (!match_tcp(skb, info, &par->hotdrop))
82 return false; 81 return false;
83 } 82 }
@@ -97,7 +96,7 @@ static int ecn_mt_check(const struct xt_mtchk_param *par)
97 return -EINVAL; 96 return -EINVAL;
98 97
99 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && 98 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) &&
100 ip->proto != IPPROTO_TCP) { 99 (ip->proto != IPPROTO_TCP || ip->invflags & IPT_INV_PROTO)) {
101 pr_info("cannot match TCP bits in rule for non-tcp packets\n"); 100 pr_info("cannot match TCP bits in rule for non-tcp packets\n");
102 return -EINVAL; 101 return -EINVAL;
103 } 102 }
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 5a03c02af999..de9da21113a1 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -101,7 +101,7 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
101 101
102 /* This is where we call the helper: as the packet goes out. */ 102 /* This is where we call the helper: as the packet goes out. */
103 ct = nf_ct_get(skb, &ctinfo); 103 ct = nf_ct_get(skb, &ctinfo);
104 if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) 104 if (!ct || ctinfo == IP_CT_RELATED_REPLY)
105 goto out; 105 goto out;
106 106
107 help = nfct_help(ct); 107 help = nfct_help(ct);
@@ -121,7 +121,9 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
121 return ret; 121 return ret;
122 } 122 }
123 123
124 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { 124 /* adjust seqs for loopback traffic only in outgoing direction */
125 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
126 !nf_is_loopback_packet(skb)) {
125 typeof(nf_nat_seq_adjust_hook) seq_adjust; 127 typeof(nf_nat_seq_adjust_hook) seq_adjust;
126 128
127 seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); 129 seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook);
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 7404bde95994..ab5b27a2916f 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -160,7 +160,7 @@ icmp_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
160 /* Update skb to refer to this connection */ 160 /* Update skb to refer to this connection */
161 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; 161 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
162 skb->nfctinfo = *ctinfo; 162 skb->nfctinfo = *ctinfo;
163 return -NF_ACCEPT; 163 return NF_ACCEPT;
164} 164}
165 165
166/* Small and modified version of icmp_rcv */ 166/* Small and modified version of icmp_rcv */
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 9c71b2755ce3..3346de5d94d0 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -433,7 +433,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
433 433
434 /* Must be RELATED */ 434 /* Must be RELATED */
435 NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED || 435 NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED ||
436 skb->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY); 436 skb->nfctinfo == IP_CT_RELATED_REPLY);
437 437
438 /* Redirects on non-null nats must be dropped, else they'll 438 /* Redirects on non-null nats must be dropped, else they'll
439 start talking to each other without our translation, and be 439 start talking to each other without our translation, and be
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 99cfa28b6d38..ebc5f8894f99 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -160,7 +160,7 @@ static void nf_nat_csum(struct sk_buff *skb, const struct iphdr *iph, void *data
160 160
161 if (skb->ip_summed != CHECKSUM_PARTIAL) { 161 if (skb->ip_summed != CHECKSUM_PARTIAL) {
162 if (!(rt->rt_flags & RTCF_LOCAL) && 162 if (!(rt->rt_flags & RTCF_LOCAL) &&
163 skb->dev->features & NETIF_F_V4_CSUM) { 163 (!skb->dev || skb->dev->features & NETIF_F_V4_CSUM)) {
164 skb->ip_summed = CHECKSUM_PARTIAL; 164 skb->ip_summed = CHECKSUM_PARTIAL;
165 skb->csum_start = skb_headroom(skb) + 165 skb->csum_start = skb_headroom(skb) +
166 skb_network_offset(skb) + 166 skb_network_offset(skb) +
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 21c30426480b..733c9abc1cbd 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -53,7 +53,7 @@ ipt_snat_target(struct sk_buff *skb, const struct xt_action_param *par)
53 53
54 /* Connection must be valid and new. */ 54 /* Connection must be valid and new. */
55 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || 55 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
56 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); 56 ctinfo == IP_CT_RELATED_REPLY));
57 NF_CT_ASSERT(par->out != NULL); 57 NF_CT_ASSERT(par->out != NULL);
58 58
59 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); 59 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 7317bdf1d457..483b76d042da 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -116,7 +116,7 @@ nf_nat_fn(unsigned int hooknum,
116 116
117 switch (ctinfo) { 117 switch (ctinfo) {
118 case IP_CT_RELATED: 118 case IP_CT_RELATED:
119 case IP_CT_RELATED+IP_CT_IS_REPLY: 119 case IP_CT_RELATED_REPLY:
120 if (ip_hdr(skb)->protocol == IPPROTO_ICMP) { 120 if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
121 if (!nf_nat_icmp_reply_translation(ct, ctinfo, 121 if (!nf_nat_icmp_reply_translation(ct, ctinfo,
122 hooknum, skb)) 122 hooknum, skb))
@@ -144,7 +144,7 @@ nf_nat_fn(unsigned int hooknum,
144 default: 144 default:
145 /* ESTABLISHED */ 145 /* ESTABLISHED */
146 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || 146 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
147 ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY)); 147 ctinfo == IP_CT_ESTABLISHED_REPLY);
148 } 148 }
149 149
150 return nf_nat_packet(ct, ctinfo, hooknum, skb); 150 return nf_nat_packet(ct, ctinfo, hooknum, skb);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 9aaa67165f42..39b403f854c6 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -41,7 +41,6 @@
41#include <linux/proc_fs.h> 41#include <linux/proc_fs.h>
42#include <net/sock.h> 42#include <net/sock.h>
43#include <net/ping.h> 43#include <net/ping.h>
44#include <net/icmp.h>
45#include <net/udp.h> 44#include <net/udp.h>
46#include <net/route.h> 45#include <net/route.h>
47#include <net/inet_common.h> 46#include <net/inet_common.h>
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 52b0b956508b..aa13ef105110 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1316,6 +1316,23 @@ reject_redirect:
1316 ; 1316 ;
1317} 1317}
1318 1318
1319static bool peer_pmtu_expired(struct inet_peer *peer)
1320{
1321 unsigned long orig = ACCESS_ONCE(peer->pmtu_expires);
1322
1323 return orig &&
1324 time_after_eq(jiffies, orig) &&
1325 cmpxchg(&peer->pmtu_expires, orig, 0) == orig;
1326}
1327
1328static bool peer_pmtu_cleaned(struct inet_peer *peer)
1329{
1330 unsigned long orig = ACCESS_ONCE(peer->pmtu_expires);
1331
1332 return orig &&
1333 cmpxchg(&peer->pmtu_expires, orig, 0) == orig;
1334}
1335
1319static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) 1336static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
1320{ 1337{
1321 struct rtable *rt = (struct rtable *)dst; 1338 struct rtable *rt = (struct rtable *)dst;
@@ -1331,14 +1348,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
1331 rt_genid(dev_net(dst->dev))); 1348 rt_genid(dev_net(dst->dev)));
1332 rt_del(hash, rt); 1349 rt_del(hash, rt);
1333 ret = NULL; 1350 ret = NULL;
1334 } else if (rt->peer && 1351 } else if (rt->peer && peer_pmtu_expired(rt->peer)) {
1335 rt->peer->pmtu_expires && 1352 dst_metric_set(dst, RTAX_MTU, rt->peer->pmtu_orig);
1336 time_after_eq(jiffies, rt->peer->pmtu_expires)) {
1337 unsigned long orig = rt->peer->pmtu_expires;
1338
1339 if (cmpxchg(&rt->peer->pmtu_expires, orig, 0) == orig)
1340 dst_metric_set(dst, RTAX_MTU,
1341 rt->peer->pmtu_orig);
1342 } 1353 }
1343 } 1354 }
1344 return ret; 1355 return ret;
@@ -1531,8 +1542,10 @@ unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
1531 1542
1532static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer) 1543static void check_peer_pmtu(struct dst_entry *dst, struct inet_peer *peer)
1533{ 1544{
1534 unsigned long expires = peer->pmtu_expires; 1545 unsigned long expires = ACCESS_ONCE(peer->pmtu_expires);
1535 1546
1547 if (!expires)
1548 return;
1536 if (time_before(jiffies, expires)) { 1549 if (time_before(jiffies, expires)) {
1537 u32 orig_dst_mtu = dst_mtu(dst); 1550 u32 orig_dst_mtu = dst_mtu(dst);
1538 if (peer->pmtu_learned < orig_dst_mtu) { 1551 if (peer->pmtu_learned < orig_dst_mtu) {
@@ -1555,10 +1568,11 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
1555 rt_bind_peer(rt, rt->rt_dst, 1); 1568 rt_bind_peer(rt, rt->rt_dst, 1);
1556 peer = rt->peer; 1569 peer = rt->peer;
1557 if (peer) { 1570 if (peer) {
1571 unsigned long pmtu_expires = ACCESS_ONCE(peer->pmtu_expires);
1572
1558 if (mtu < ip_rt_min_pmtu) 1573 if (mtu < ip_rt_min_pmtu)
1559 mtu = ip_rt_min_pmtu; 1574 mtu = ip_rt_min_pmtu;
1560 if (!peer->pmtu_expires || mtu < peer->pmtu_learned) { 1575 if (!pmtu_expires || mtu < peer->pmtu_learned) {
1561 unsigned long pmtu_expires;
1562 1576
1563 pmtu_expires = jiffies + ip_rt_mtu_expires; 1577 pmtu_expires = jiffies + ip_rt_mtu_expires;
1564 if (!pmtu_expires) 1578 if (!pmtu_expires)
@@ -1612,13 +1626,14 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
1612 rt_bind_peer(rt, rt->rt_dst, 0); 1626 rt_bind_peer(rt, rt->rt_dst, 0);
1613 1627
1614 peer = rt->peer; 1628 peer = rt->peer;
1615 if (peer && peer->pmtu_expires) 1629 if (peer) {
1616 check_peer_pmtu(dst, peer); 1630 check_peer_pmtu(dst, peer);
1617 1631
1618 if (peer && peer->redirect_learned.a4 && 1632 if (peer->redirect_learned.a4 &&
1619 peer->redirect_learned.a4 != rt->rt_gateway) { 1633 peer->redirect_learned.a4 != rt->rt_gateway) {
1620 if (check_peer_redir(dst, peer)) 1634 if (check_peer_redir(dst, peer))
1621 return NULL; 1635 return NULL;
1636 }
1622 } 1637 }
1623 1638
1624 rt->rt_peer_genid = rt_peer_genid(); 1639 rt->rt_peer_genid = rt_peer_genid();
@@ -1649,14 +1664,8 @@ static void ipv4_link_failure(struct sk_buff *skb)
1649 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); 1664 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
1650 1665
1651 rt = skb_rtable(skb); 1666 rt = skb_rtable(skb);
1652 if (rt && 1667 if (rt && rt->peer && peer_pmtu_cleaned(rt->peer))
1653 rt->peer && 1668 dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig);
1654 rt->peer->pmtu_expires) {
1655 unsigned long orig = rt->peer->pmtu_expires;
1656
1657 if (cmpxchg(&rt->peer->pmtu_expires, orig, 0) == orig)
1658 dst_metric_set(&rt->dst, RTAX_MTU, rt->peer->pmtu_orig);
1659 }
1660} 1669}
1661 1670
1662static int ip_rt_bug(struct sk_buff *skb) 1671static int ip_rt_bug(struct sk_buff *skb)
@@ -1770,8 +1779,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
1770 sizeof(u32) * RTAX_MAX); 1779 sizeof(u32) * RTAX_MAX);
1771 dst_init_metrics(&rt->dst, peer->metrics, false); 1780 dst_init_metrics(&rt->dst, peer->metrics, false);
1772 1781
1773 if (peer->pmtu_expires) 1782 check_peer_pmtu(&rt->dst, peer);
1774 check_peer_pmtu(&rt->dst, peer);
1775 if (peer->redirect_learned.a4 && 1783 if (peer->redirect_learned.a4 &&
1776 peer->redirect_learned.a4 != rt->rt_gateway) { 1784 peer->redirect_learned.a4 != rt->rt_gateway) {
1777 rt->rt_gateway = peer->redirect_learned.a4; 1785 rt->rt_gateway = peer->redirect_learned.a4;
@@ -1894,9 +1902,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1894 1902
1895 hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); 1903 hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
1896 rth = rt_intern_hash(hash, rth, skb, dev->ifindex); 1904 rth = rt_intern_hash(hash, rth, skb, dev->ifindex);
1897 err = 0; 1905 return IS_ERR(rth) ? PTR_ERR(rth) : 0;
1898 if (IS_ERR(rth))
1899 err = PTR_ERR(rth);
1900 1906
1901e_nobufs: 1907e_nobufs:
1902 return -ENOBUFS; 1908 return -ENOBUFS;
@@ -2775,7 +2781,8 @@ static int rt_fill_info(struct net *net,
2775 struct rtable *rt = skb_rtable(skb); 2781 struct rtable *rt = skb_rtable(skb);
2776 struct rtmsg *r; 2782 struct rtmsg *r;
2777 struct nlmsghdr *nlh; 2783 struct nlmsghdr *nlh;
2778 long expires; 2784 long expires = 0;
2785 const struct inet_peer *peer = rt->peer;
2779 u32 id = 0, ts = 0, tsage = 0, error; 2786 u32 id = 0, ts = 0, tsage = 0, error;
2780 2787
2781 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); 2788 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
@@ -2823,15 +2830,16 @@ static int rt_fill_info(struct net *net,
2823 NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark); 2830 NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark);
2824 2831
2825 error = rt->dst.error; 2832 error = rt->dst.error;
2826 expires = (rt->peer && rt->peer->pmtu_expires) ? 2833 if (peer) {
2827 rt->peer->pmtu_expires - jiffies : 0;
2828 if (rt->peer) {
2829 inet_peer_refcheck(rt->peer); 2834 inet_peer_refcheck(rt->peer);
2830 id = atomic_read(&rt->peer->ip_id_count) & 0xffff; 2835 id = atomic_read(&peer->ip_id_count) & 0xffff;
2831 if (rt->peer->tcp_ts_stamp) { 2836 if (peer->tcp_ts_stamp) {
2832 ts = rt->peer->tcp_ts; 2837 ts = peer->tcp_ts;
2833 tsage = get_seconds() - rt->peer->tcp_ts_stamp; 2838 tsage = get_seconds() - peer->tcp_ts_stamp;
2834 } 2839 }
2840 expires = ACCESS_ONCE(peer->pmtu_expires);
2841 if (expires)
2842 expires -= jiffies;
2835 } 2843 }
2836 2844
2837 if (rt_is_input_route(rt)) { 2845 if (rt_is_input_route(rt)) {
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 054a59d21eb0..46febcacb729 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3220,7 +3220,7 @@ __setup("thash_entries=", set_thash_entries);
3220void __init tcp_init(void) 3220void __init tcp_init(void)
3221{ 3221{
3222 struct sk_buff *skb = NULL; 3222 struct sk_buff *skb = NULL;
3223 unsigned long nr_pages, limit; 3223 unsigned long limit;
3224 int i, max_share, cnt; 3224 int i, max_share, cnt;
3225 unsigned long jiffy = jiffies; 3225 unsigned long jiffy = jiffies;
3226 3226
@@ -3277,13 +3277,7 @@ void __init tcp_init(void)
3277 sysctl_tcp_max_orphans = cnt / 2; 3277 sysctl_tcp_max_orphans = cnt / 2;
3278 sysctl_max_syn_backlog = max(128, cnt / 256); 3278 sysctl_max_syn_backlog = max(128, cnt / 256);
3279 3279
3280 /* Set the pressure threshold to be a fraction of global memory that 3280 limit = nr_free_buffer_pages() / 8;
3281 * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
3282 * memory, with a floor of 128 pages.
3283 */
3284 nr_pages = totalram_pages - totalhigh_pages;
3285 limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
3286 limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
3287 limit = max(limit, 128UL); 3281 limit = max(limit, 128UL);
3288 sysctl_tcp_mem[0] = limit / 4 * 3; 3282 sysctl_tcp_mem[0] = limit / 4 * 3;
3289 sysctl_tcp_mem[1] = limit; 3283 sysctl_tcp_mem[1] = limit;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a7d6671e33b8..708dc203b034 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1589,6 +1589,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1589 goto discard; 1589 goto discard;
1590 1590
1591 if (nsk != sk) { 1591 if (nsk != sk) {
1592 sock_rps_save_rxhash(nsk, skb->rxhash);
1592 if (tcp_child_process(sk, nsk, skb)) { 1593 if (tcp_child_process(sk, nsk, skb)) {
1593 rsk = nsk; 1594 rsk = nsk;
1594 goto reset; 1595 goto reset;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index abca870d8ff6..198f75b7bdd3 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1249,6 +1249,9 @@ csum_copy_err:
1249 1249
1250 if (noblock) 1250 if (noblock)
1251 return -EAGAIN; 1251 return -EAGAIN;
1252
1253 /* starting over for a new packet */
1254 msg->msg_flags &= ~MSG_TRUNC;
1252 goto try_again; 1255 goto try_again;
1253} 1256}
1254 1257
@@ -2206,16 +2209,10 @@ void __init udp_table_init(struct udp_table *table, const char *name)
2206 2209
2207void __init udp_init(void) 2210void __init udp_init(void)
2208{ 2211{
2209 unsigned long nr_pages, limit; 2212 unsigned long limit;
2210 2213
2211 udp_table_init(&udp_table, "UDP"); 2214 udp_table_init(&udp_table, "UDP");
2212 /* Set the pressure threshold up by the same strategy of TCP. It is a 2215 limit = nr_free_buffer_pages() / 8;
2213 * fraction of global memory that is up to 1/2 at 256 MB, decreasing
2214 * toward zero with the amount of memory, with a floor of 128 pages.
2215 */
2216 nr_pages = totalram_pages - totalhigh_pages;
2217 limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
2218 limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
2219 limit = max(limit, 128UL); 2216 limit = max(limit, 128UL);
2220 sysctl_udp_mem[0] = limit / 4 * 3; 2217 sysctl_udp_mem[0] = limit / 4 * 3;
2221 sysctl_udp_mem[1] = limit; 2218 sysctl_udp_mem[1] = limit;
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 2d51840e53a1..327a617d594c 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -32,7 +32,12 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
32 dst = skb_dst(skb); 32 dst = skb_dst(skb);
33 mtu = dst_mtu(dst); 33 mtu = dst_mtu(dst);
34 if (skb->len > mtu) { 34 if (skb->len > mtu) {
35 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); 35 if (skb->sk)
36 ip_local_error(skb->sk, EMSGSIZE, ip_hdr(skb)->daddr,
37 inet_sk(skb->sk)->inet_dport, mtu);
38 else
39 icmp_send(skb, ICMP_DEST_UNREACH,
40 ICMP_FRAG_NEEDED, htonl(mtu));
36 ret = -EMSGSIZE; 41 ret = -EMSGSIZE;
37 } 42 }
38out: 43out: