I missed a couple patches in yesterday's submission, please queue the following patches up for 2.6.39-stable, thanks!
>From b3ba2c0af575db43e42688e7aaa6cb31e3a2d27b Mon Sep 17 00:00:00 2001 From: Eric Dumazet <eric.duma...@gmail.com> Date: Sat, 18 Jun 2011 11:59:18 -0700 Subject: [PATCH 1/4] ipv4: fix multicast losses
[ Upstream commit 9aa3c94ce59066f545521033007abb6441706068 ] Knut Tidemann found that first packet of a multicast flow was not correctly received, and bisected the regression to commit b23dd4fe42b4 (Make output route lookup return rtable directly.) Special thanks to Knut, who provided a very nice bug report, including sample programs to demonstrate the bug. Reported-and-bisectedby: Knut Tidemann <knut.andre.tidem...@jotron.com> Signed-off-by: Eric Dumazet <eric.duma...@gmail.com> Signed-off-by: David S. Miller <da...@davemloft.net> --- net/ipv4/route.c | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 99e6e4b..b8b5c3f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1914,9 +1914,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); rth = rt_intern_hash(hash, rth, skb, dev->ifindex); - err = 0; - if (IS_ERR(rth)) - err = PTR_ERR(rth); + return IS_ERR(rth) ? PTR_ERR(rth) : 0; e_nobufs: return -ENOBUFS; -- 1.7.5.4 >From 80d1dd9b4283f16ded80aec0e9f8382dcbb10b63 Mon Sep 17 00:00:00 2001 From: Julian Anastasov <j...@ssi.bg> Date: Sat, 18 Jun 2011 07:53:59 +0000 Subject: [PATCH 2/4] netfilter: Fix ip_route_me_harder triggering ip_rt_bug [ Upstream commit ed6e4ef836d425bc35e33bf20fcec95e68203afa ] Avoid creating input routes with ip_route_me_harder. It does not work for locally generated packets. Instead, restrict sockets to provide valid saddr for output route (or unicast saddr for transparent proxy). For other traffic allow saddr to be unicast or local but if callers forget to check saddr type use 0 for the output route. The resulting handling should be: - REJECT TCP: - in INPUT we can provide addr_type = RTN_LOCAL but better allow rejecting traffic delivered with local route (no IP address => use RTN_UNSPEC to allow also RTN_UNICAST). - FORWARD: RTN_UNSPEC => allow RTN_LOCAL/RTN_UNICAST saddr, add fix to ignore RTN_BROADCAST and RTN_MULTICAST - OUTPUT: RTN_UNSPEC - NAT, mangle, ip_queue, nf_ip_reroute: RTN_UNSPEC in LOCAL_OUT - IPVS: - use RTN_LOCAL in LOCAL_OUT and FORWARD after SNAT to restrict saddr to be local Signed-off-by: Julian Anastasov <j...@ssi.bg> Signed-off-by: David S. Miller <da...@davemloft.net> --- net/ipv4/netfilter.c | 60 ++++++++++++++------------------------ net/ipv4/netfilter/ipt_REJECT.c | 14 ++------ 2 files changed, 26 insertions(+), 48 deletions(-) diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 4614bab..2e97e3e 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) const struct iphdr *iph = ip_hdr(skb); struct rtable *rt; struct flowi4 fl4 = {}; - unsigned long orefdst; + __be32 saddr = iph->saddr; + __u8 flags = 0; unsigned int hh_len; - unsigned int type; - type = inet_addr_type(net, iph->saddr); - if (skb->sk && inet_sk(skb->sk)->transparent) - type = RTN_LOCAL; - if (addr_type == RTN_UNSPEC) - addr_type = type; + if (!skb->sk && addr_type != RTN_LOCAL) { + if (addr_type == RTN_UNSPEC) + addr_type = inet_addr_type(net, saddr); + if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) + flags |= FLOWI_FLAG_ANYSRC; + else + saddr = 0; + } /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. */ - if (addr_type == RTN_LOCAL) { - fl4.daddr = iph->daddr; - if (type == RTN_LOCAL) - fl4.saddr = iph->saddr; - fl4.flowi4_tos = RT_TOS(iph->tos); - fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; - fl4.flowi4_mark = skb->mark; - fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; - rt = ip_route_output_key(net, &fl4); - if (IS_ERR(rt)) - return -1; - - /* Drop old route. */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - } else { - /* non-local src, find valid iif to satisfy - * rp-filter when calling ip_route_input. */ - fl4.daddr = iph->saddr; - rt = ip_route_output_key(net, &fl4); - if (IS_ERR(rt)) - return -1; + fl4.daddr = iph->daddr; + fl4.saddr = saddr; + fl4.flowi4_tos = RT_TOS(iph->tos); + fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; + fl4.flowi4_mark = skb->mark; + fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; + rt = ip_route_output_key(net, &fl4); + if (IS_ERR(rt)) + return -1; - orefdst = skb->_skb_refdst; - if (ip_route_input(skb, iph->daddr, iph->saddr, - RT_TOS(iph->tos), rt->dst.dev) != 0) { - dst_release(&rt->dst); - return -1; - } - dst_release(&rt->dst); - refdst_drop(orefdst); - } + /* Drop old route. */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); if (skb_dst(skb)->error) return -1; diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 1ff79e5..51f13f8 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) struct iphdr *niph; const struct tcphdr *oth; struct tcphdr _otcph, *tcph; - unsigned int addr_type; /* IP header checks: fragment. */ if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) @@ -55,6 +54,9 @@ static void send_reset(struct sk_buff *oldskb, int hook) if (oth->rst) return; + if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) + return; + /* Check checksum */ if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP)) return; @@ -101,19 +103,11 @@ static void send_reset(struct sk_buff *oldskb, int hook) nskb->csum_start = (unsigned char *)tcph - nskb->head; nskb->csum_offset = offsetof(struct tcphdr, check); - addr_type = RTN_UNSPEC; - if (hook != NF_INET_FORWARD -#ifdef CONFIG_BRIDGE_NETFILTER - || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED) -#endif - ) - addr_type = RTN_LOCAL; - /* ip_route_me_harder expects skb->dst to be set */ skb_dst_set_noref(nskb, skb_dst(oldskb)); nskb->protocol = htons(ETH_P_IP); - if (ip_route_me_harder(nskb, addr_type)) + if (ip_route_me_harder(nskb, RTN_UNSPEC)) goto free_nskb; niph->ttl = ip4_dst_hoplimit(skb_dst(nskb)); -- 1.7.5.4 >From 59ac3e37bdc0bf24b81f946727a01204dbd6344d Mon Sep 17 00:00:00 2001 From: Wei Yongjun <yj...@cn.fujitsu.com> Date: Tue, 31 May 2011 22:53:19 +0000 Subject: [PATCH 3/4] vlan: fix typo in vlan_dev_hard_start_xmit() [ Upstream commit 307f73df2b9829ee5a261d1ed432ff683c426cdf ] commit 4af429d29b341bb1735f04c2fb960178ed5d52e7 (vlan: lockless transmit path) have a typo in vlan_dev_hard_start_xmit(), using u64_stats_update_begin() to end the stat update, it should be u64_stats_update_end(). Signed-off-by: Wei Yongjun <yj...@cn.fujitsu.com> Reviewed-by: WANG Cong <xiyou.wangc...@gmail.com> Acked-by: Eric Dumazet <eric.duma...@gmail.com> Signed-off-by: David S. Miller <da...@davemloft.net> --- net/8021q/vlan_dev.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b2ff6c8..f11e61e 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -338,7 +338,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, u64_stats_update_begin(&stats->syncp); stats->tx_packets++; stats->tx_bytes += len; - u64_stats_update_begin(&stats->syncp); + u64_stats_update_end(&stats->syncp); } else { this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); } -- 1.7.5.4 >From 989d4bc59dbb997b5a17ff252eb3d1014c47102b Mon Sep 17 00:00:00 2001 From: Steffen Klassert <steffen.klass...@secunet.com> Date: Sun, 5 Jun 2011 20:46:03 +0000 Subject: [PATCH 4/4] xfrm: Fix off by one in the replay advance functions [ Upstream commit e756682c8baa47da1648c0c016e9f48ed66bc32d ] We may write 4 byte too much when we reinitialize the anti replay window in the replay advance functions. This patch fixes this by adjusting the last index of the initialization loop. Signed-off-by: Steffen Klassert <steffen.klass...@secunet.com> Signed-off-by: David S. Miller <da...@davemloft.net> --- net/xfrm/xfrm_replay.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 47f1b86..b11ea69 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c @@ -265,7 +265,7 @@ static void xfrm_replay_advance_bmp(struct xfrm_state *x, __be32 net_seq) bitnr = bitnr & 0x1F; replay_esn->bmp[nr] |= (1U << bitnr); } else { - nr = replay_esn->replay_window >> 5; + nr = (replay_esn->replay_window - 1) >> 5; for (i = 0; i <= nr; i++) replay_esn->bmp[i] = 0; @@ -471,7 +471,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq) bitnr = bitnr & 0x1F; replay_esn->bmp[nr] |= (1U << bitnr); } else { - nr = replay_esn->replay_window >> 5; + nr = (replay_esn->replay_window - 1) >> 5; for (i = 0; i <= nr; i++) replay_esn->bmp[i] = 0; -- 1.7.5.4
_______________________________________________ stable mailing list stable@linux.kernel.org http://linux.kernel.org/mailman/listinfo/stable