diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2010-10-12 10:41:22 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2010-10-12 10:41:26 -0400 |
| commit | 7c5f13519a67aa7ba3a99155f128d4bdef87d087 (patch) | |
| tree | e4d0537092930a53a85932de83a7861990c58607 /net/ipv4 | |
| parent | 5e62feabcc3e4127a084701ec54ffe891985b7e8 (diff) | |
| parent | 021989622810b02aab4b24f91e1f5ada2b654579 (diff) | |
Merge branch 'x86/urgent' of into irq/sparseirq
Reason: Pull in the latest io_apic bugfixes
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/ip_gre.c | 8 | ||||
| -rw-r--r-- | net/ipv4/ip_output.c | 19 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ipt_REJECT.c | 1 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_defrag_ipv4.c | 4 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_nat_snmp_basic.c | 6 | ||||
| -rw-r--r-- | net/ipv4/route.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 9 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 5 | ||||
| -rw-r--r-- | net/ipv4/xfrm4_policy.c | 2 | ||||
| -rw-r--r-- | net/ipv4/xfrm4_state.c | 33 |
10 files changed, 56 insertions, 33 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 945b20a5ad50..35c93e8b6a46 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -45,7 +45,7 @@ | |||
| 45 | #include <net/netns/generic.h> | 45 | #include <net/netns/generic.h> |
| 46 | #include <net/rtnetlink.h> | 46 | #include <net/rtnetlink.h> |
| 47 | 47 | ||
| 48 | #ifdef CONFIG_IPV6 | 48 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 49 | #include <net/ipv6.h> | 49 | #include <net/ipv6.h> |
| 50 | #include <net/ip6_fib.h> | 50 | #include <net/ip6_fib.h> |
| 51 | #include <net/ip6_route.h> | 51 | #include <net/ip6_route.h> |
| @@ -699,7 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 699 | if ((dst = rt->rt_gateway) == 0) | 699 | if ((dst = rt->rt_gateway) == 0) |
| 700 | goto tx_error_icmp; | 700 | goto tx_error_icmp; |
| 701 | } | 701 | } |
| 702 | #ifdef CONFIG_IPV6 | 702 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 703 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 703 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
| 704 | struct in6_addr *addr6; | 704 | struct in6_addr *addr6; |
| 705 | int addr_type; | 705 | int addr_type; |
| @@ -774,7 +774,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 774 | goto tx_error; | 774 | goto tx_error; |
| 775 | } | 775 | } |
| 776 | } | 776 | } |
| 777 | #ifdef CONFIG_IPV6 | 777 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 778 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 778 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
| 779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); | 779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); |
| 780 | 780 | ||
| @@ -850,7 +850,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
| 850 | if ((iph->ttl = tiph->ttl) == 0) { | 850 | if ((iph->ttl = tiph->ttl) == 0) { |
| 851 | if (skb->protocol == htons(ETH_P_IP)) | 851 | if (skb->protocol == htons(ETH_P_IP)) |
| 852 | iph->ttl = old_iph->ttl; | 852 | iph->ttl = old_iph->ttl; |
| 853 | #ifdef CONFIG_IPV6 | 853 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 854 | else if (skb->protocol == htons(ETH_P_IPV6)) | 854 | else if (skb->protocol == htons(ETH_P_IPV6)) |
| 855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; | 855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; |
| 856 | #endif | 856 | #endif |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 04b69896df5f..7649d7750075 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -488,9 +488,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
| 488 | * we can switch to copy when see the first bad fragment. | 488 | * we can switch to copy when see the first bad fragment. |
| 489 | */ | 489 | */ |
| 490 | if (skb_has_frags(skb)) { | 490 | if (skb_has_frags(skb)) { |
| 491 | struct sk_buff *frag; | 491 | struct sk_buff *frag, *frag2; |
| 492 | int first_len = skb_pagelen(skb); | 492 | int first_len = skb_pagelen(skb); |
| 493 | int truesizes = 0; | ||
| 494 | 493 | ||
| 495 | if (first_len - hlen > mtu || | 494 | if (first_len - hlen > mtu || |
| 496 | ((first_len - hlen) & 7) || | 495 | ((first_len - hlen) & 7) || |
| @@ -503,18 +502,18 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
| 503 | if (frag->len > mtu || | 502 | if (frag->len > mtu || |
| 504 | ((frag->len & 7) && frag->next) || | 503 | ((frag->len & 7) && frag->next) || |
| 505 | skb_headroom(frag) < hlen) | 504 | skb_headroom(frag) < hlen) |
| 506 | goto slow_path; | 505 | goto slow_path_clean; |
| 507 | 506 | ||
| 508 | /* Partially cloned skb? */ | 507 | /* Partially cloned skb? */ |
| 509 | if (skb_shared(frag)) | 508 | if (skb_shared(frag)) |
| 510 | goto slow_path; | 509 | goto slow_path_clean; |
| 511 | 510 | ||
| 512 | BUG_ON(frag->sk); | 511 | BUG_ON(frag->sk); |
| 513 | if (skb->sk) { | 512 | if (skb->sk) { |
| 514 | frag->sk = skb->sk; | 513 | frag->sk = skb->sk; |
| 515 | frag->destructor = sock_wfree; | 514 | frag->destructor = sock_wfree; |
| 516 | } | 515 | } |
| 517 | truesizes += frag->truesize; | 516 | skb->truesize -= frag->truesize; |
| 518 | } | 517 | } |
| 519 | 518 | ||
| 520 | /* Everything is OK. Generate! */ | 519 | /* Everything is OK. Generate! */ |
| @@ -524,7 +523,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
| 524 | frag = skb_shinfo(skb)->frag_list; | 523 | frag = skb_shinfo(skb)->frag_list; |
| 525 | skb_frag_list_init(skb); | 524 | skb_frag_list_init(skb); |
| 526 | skb->data_len = first_len - skb_headlen(skb); | 525 | skb->data_len = first_len - skb_headlen(skb); |
| 527 | skb->truesize -= truesizes; | ||
| 528 | skb->len = first_len; | 526 | skb->len = first_len; |
| 529 | iph->tot_len = htons(first_len); | 527 | iph->tot_len = htons(first_len); |
| 530 | iph->frag_off = htons(IP_MF); | 528 | iph->frag_off = htons(IP_MF); |
| @@ -576,6 +574,15 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
| 576 | } | 574 | } |
| 577 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); | 575 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
| 578 | return err; | 576 | return err; |
| 577 | |||
| 578 | slow_path_clean: | ||
| 579 | skb_walk_frags(skb, frag2) { | ||
| 580 | if (frag2 == frag) | ||
| 581 | break; | ||
| 582 | frag2->sk = NULL; | ||
| 583 | frag2->destructor = NULL; | ||
| 584 | skb->truesize += frag2->truesize; | ||
| 585 | } | ||
| 579 | } | 586 | } |
| 580 | 587 | ||
| 581 | slow_path: | 588 | slow_path: |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index b254dafaf429..43eec80c0e7c 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
| @@ -112,6 +112,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
| 112 | /* ip_route_me_harder expects skb->dst to be set */ | 112 | /* ip_route_me_harder expects skb->dst to be set */ |
| 113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); | 113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); |
| 114 | 114 | ||
| 115 | nskb->protocol = htons(ETH_P_IP); | ||
| 115 | if (ip_route_me_harder(nskb, addr_type)) | 116 | if (ip_route_me_harder(nskb, addr_type)) |
| 116 | goto free_nskb; | 117 | goto free_nskb; |
| 117 | 118 | ||
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index eab8de32f200..f3a9b42b16c6 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
| @@ -66,9 +66,11 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | |||
| 66 | const struct net_device *out, | 66 | const struct net_device *out, |
| 67 | int (*okfn)(struct sk_buff *)) | 67 | int (*okfn)(struct sk_buff *)) |
| 68 | { | 68 | { |
| 69 | struct sock *sk = skb->sk; | ||
| 69 | struct inet_sock *inet = inet_sk(skb->sk); | 70 | struct inet_sock *inet = inet_sk(skb->sk); |
| 70 | 71 | ||
| 71 | if (inet && inet->nodefrag) | 72 | if (sk && (sk->sk_family == PF_INET) && |
| 73 | inet->nodefrag) | ||
| 72 | return NF_ACCEPT; | 74 | return NF_ACCEPT; |
| 73 | 75 | ||
| 74 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 76 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 1679e2c0963d..ee5f419d0a56 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
| @@ -893,13 +893,15 @@ static void fast_csum(__sum16 *csum, | |||
| 893 | unsigned char s[4]; | 893 | unsigned char s[4]; |
| 894 | 894 | ||
| 895 | if (offset & 1) { | 895 | if (offset & 1) { |
| 896 | s[0] = s[2] = 0; | 896 | s[0] = ~0; |
| 897 | s[1] = ~*optr; | 897 | s[1] = ~*optr; |
| 898 | s[2] = 0; | ||
| 898 | s[3] = *nptr; | 899 | s[3] = *nptr; |
| 899 | } else { | 900 | } else { |
| 900 | s[1] = s[3] = 0; | ||
| 901 | s[0] = ~*optr; | 901 | s[0] = ~*optr; |
| 902 | s[1] = ~0; | ||
| 902 | s[2] = *nptr; | 903 | s[2] = *nptr; |
| 904 | s[3] = 0; | ||
| 903 | } | 905 | } |
| 904 | 906 | ||
| 905 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); | 907 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6298f75d5e93..ac6559cb54f9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1231,7 +1231,7 @@ restart: | |||
| 1231 | } | 1231 | } |
| 1232 | 1232 | ||
| 1233 | if (net_ratelimit()) | 1233 | if (net_ratelimit()) |
| 1234 | printk(KERN_WARNING "Neighbour table overflow.\n"); | 1234 | printk(KERN_WARNING "ipv4: Neighbour table overflow.\n"); |
| 1235 | rt_drop(rt); | 1235 | rt_drop(rt); |
| 1236 | return -ENOBUFS; | 1236 | return -ENOBUFS; |
| 1237 | } | 1237 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3fb1428e526e..f115ea68a4ef 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -386,8 +386,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 386 | */ | 386 | */ |
| 387 | 387 | ||
| 388 | mask = 0; | 388 | mask = 0; |
| 389 | if (sk->sk_err) | ||
| 390 | mask = POLLERR; | ||
| 391 | 389 | ||
| 392 | /* | 390 | /* |
| 393 | * POLLHUP is certainly not done right. But poll() doesn't | 391 | * POLLHUP is certainly not done right. But poll() doesn't |
| @@ -457,6 +455,11 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 457 | if (tp->urg_data & TCP_URG_VALID) | 455 | if (tp->urg_data & TCP_URG_VALID) |
| 458 | mask |= POLLPRI; | 456 | mask |= POLLPRI; |
| 459 | } | 457 | } |
| 458 | /* This barrier is coupled with smp_wmb() in tcp_reset() */ | ||
| 459 | smp_rmb(); | ||
| 460 | if (sk->sk_err) | ||
| 461 | mask |= POLLERR; | ||
| 462 | |||
| 460 | return mask; | 463 | return mask; |
| 461 | } | 464 | } |
| 462 | EXPORT_SYMBOL(tcp_poll); | 465 | EXPORT_SYMBOL(tcp_poll); |
| @@ -940,7 +943,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 940 | sg = sk->sk_route_caps & NETIF_F_SG; | 943 | sg = sk->sk_route_caps & NETIF_F_SG; |
| 941 | 944 | ||
| 942 | while (--iovlen >= 0) { | 945 | while (--iovlen >= 0) { |
| 943 | int seglen = iov->iov_len; | 946 | size_t seglen = iov->iov_len; |
| 944 | unsigned char __user *from = iov->iov_base; | 947 | unsigned char __user *from = iov->iov_base; |
| 945 | 948 | ||
| 946 | iov++; | 949 | iov++; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e663b78a2ef6..b55f60f6fcbe 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -2545,7 +2545,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
| 2545 | cnt += tcp_skb_pcount(skb); | 2545 | cnt += tcp_skb_pcount(skb); |
| 2546 | 2546 | ||
| 2547 | if (cnt > packets) { | 2547 | if (cnt > packets) { |
| 2548 | if (tcp_is_sack(tp) || (oldcnt >= packets)) | 2548 | if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) || |
| 2549 | (oldcnt >= packets)) | ||
| 2549 | break; | 2550 | break; |
| 2550 | 2551 | ||
| 2551 | mss = skb_shinfo(skb)->gso_size; | 2552 | mss = skb_shinfo(skb)->gso_size; |
| @@ -4048,6 +4049,8 @@ static void tcp_reset(struct sock *sk) | |||
| 4048 | default: | 4049 | default: |
| 4049 | sk->sk_err = ECONNRESET; | 4050 | sk->sk_err = ECONNRESET; |
| 4050 | } | 4051 | } |
| 4052 | /* This barrier is coupled with smp_rmb() in tcp_poll() */ | ||
| 4053 | smp_wmb(); | ||
| 4051 | 4054 | ||
| 4052 | if (!sock_flag(sk, SOCK_DEAD)) | 4055 | if (!sock_flag(sk, SOCK_DEAD)) |
| 4053 | sk->sk_error_report(sk); | 4056 | sk->sk_error_report(sk); |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 869078d4eeb9..a580349f0b8a 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -61,7 +61,7 @@ static int xfrm4_get_saddr(struct net *net, | |||
| 61 | 61 | ||
| 62 | static int xfrm4_get_tos(struct flowi *fl) | 62 | static int xfrm4_get_tos(struct flowi *fl) |
| 63 | { | 63 | { |
| 64 | return fl->fl4_tos; | 64 | return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */ |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, | 67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 1ef1366a0a03..47947624eccc 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
| @@ -21,21 +21,25 @@ static int xfrm4_init_flags(struct xfrm_state *x) | |||
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | static void | 23 | static void |
| 24 | __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 24 | __xfrm4_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
| 25 | struct xfrm_tmpl *tmpl, | 25 | { |
| 26 | xfrm_address_t *daddr, xfrm_address_t *saddr) | 26 | sel->daddr.a4 = fl->fl4_dst; |
| 27 | sel->saddr.a4 = fl->fl4_src; | ||
| 28 | sel->dport = xfrm_flowi_dport(fl); | ||
| 29 | sel->dport_mask = htons(0xffff); | ||
| 30 | sel->sport = xfrm_flowi_sport(fl); | ||
| 31 | sel->sport_mask = htons(0xffff); | ||
| 32 | sel->family = AF_INET; | ||
| 33 | sel->prefixlen_d = 32; | ||
| 34 | sel->prefixlen_s = 32; | ||
| 35 | sel->proto = fl->proto; | ||
| 36 | sel->ifindex = fl->oif; | ||
| 37 | } | ||
| 38 | |||
| 39 | static void | ||
| 40 | xfrm4_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
| 41 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
| 27 | { | 42 | { |
| 28 | x->sel.daddr.a4 = fl->fl4_dst; | ||
| 29 | x->sel.saddr.a4 = fl->fl4_src; | ||
| 30 | x->sel.dport = xfrm_flowi_dport(fl); | ||
| 31 | x->sel.dport_mask = htons(0xffff); | ||
| 32 | x->sel.sport = xfrm_flowi_sport(fl); | ||
| 33 | x->sel.sport_mask = htons(0xffff); | ||
| 34 | x->sel.family = AF_INET; | ||
| 35 | x->sel.prefixlen_d = 32; | ||
| 36 | x->sel.prefixlen_s = 32; | ||
| 37 | x->sel.proto = fl->proto; | ||
| 38 | x->sel.ifindex = fl->oif; | ||
| 39 | x->id = tmpl->id; | 43 | x->id = tmpl->id; |
| 40 | if (x->id.daddr.a4 == 0) | 44 | if (x->id.daddr.a4 == 0) |
| 41 | x->id.daddr.a4 = daddr->a4; | 45 | x->id.daddr.a4 = daddr->a4; |
| @@ -70,6 +74,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = { | |||
| 70 | .owner = THIS_MODULE, | 74 | .owner = THIS_MODULE, |
| 71 | .init_flags = xfrm4_init_flags, | 75 | .init_flags = xfrm4_init_flags, |
| 72 | .init_tempsel = __xfrm4_init_tempsel, | 76 | .init_tempsel = __xfrm4_init_tempsel, |
| 77 | .init_temprop = xfrm4_init_temprop, | ||
| 73 | .output = xfrm4_output, | 78 | .output = xfrm4_output, |
| 74 | .extract_input = xfrm4_extract_input, | 79 | .extract_input = xfrm4_extract_input, |
| 75 | .extract_output = xfrm4_extract_output, | 80 | .extract_output = xfrm4_extract_output, |
