Please apply the following patches to 3.0.x, 3.2.x, 3.4.x, and
3.6.x -stable, respectively.

Thanks!
>From 668130e8b7bb303d058d8b5af873e6c67b63856a Mon Sep 17 00:00:00 2001
From: Xi Wang <[email protected]>
Date: Sun, 11 Nov 2012 11:20:01 +0000
Subject: [PATCH 1/4] ipv4: avoid undefined behavior in do_ip_setsockopt()

[ Upstream commit 0c9f79be295c99ac7e4b569ca493d75fdcc19e4e ]

(1<<optname) is undefined behavior in C with a negative optname or
optname larger than 31.  In those cases the result of the shift is
not necessarily zero (e.g., on x86).

This patch simplifies the code with a switch statement on optname.
It also allows the compiler to generate better code (e.g., using a
64-bit mask).

Signed-off-by: Xi Wang <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv4/ip_sockglue.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index ab0c9ef..ee02ab9 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -467,18 +467,27 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        struct inet_sock *inet = inet_sk(sk);
        int val = 0, err;
 
-       if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
-                            (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
-                            (1<<IP_RETOPTS) | (1<<IP_TOS) |
-                            (1<<IP_TTL) | (1<<IP_HDRINCL) |
-                            (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
-                            (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
-                            (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
-           optname == IP_MULTICAST_TTL ||
-           optname == IP_MULTICAST_ALL ||
-           optname == IP_MULTICAST_LOOP ||
-           optname == IP_RECVORIGDSTADDR) {
+       switch (optname) {
+       case IP_PKTINFO:
+       case IP_RECVTTL:
+       case IP_RECVOPTS:
+       case IP_RECVTOS:
+       case IP_RETOPTS:
+       case IP_TOS:
+       case IP_TTL:
+       case IP_HDRINCL:
+       case IP_MTU_DISCOVER:
+       case IP_RECVERR:
+       case IP_ROUTER_ALERT:
+       case IP_FREEBIND:
+       case IP_PASSSEC:
+       case IP_TRANSPARENT:
+       case IP_MINTTL:
+       case IP_NODEFRAG:
+       case IP_MULTICAST_TTL:
+       case IP_MULTICAST_ALL:
+       case IP_MULTICAST_LOOP:
+       case IP_RECVORIGDSTADDR:
                if (optlen >= sizeof(int)) {
                        if (get_user(val, (int __user *) optval))
                                return -EFAULT;
-- 
1.7.11.7


>From 0a3fff76600507e757ae3d9d38f0f0b9332072ce Mon Sep 17 00:00:00 2001
From: Hannes Frederic Sowa <[email protected]>
Date: Sat, 10 Nov 2012 19:52:34 +0000
Subject: [PATCH 2/4] ipv6: setsockopt(IPIPPROTO_IPV6, IPV6_MINHOPCOUNT)
 forgot to set return value

[ Upstream commit d4596bad2a713fcd0def492b1960e6d899d5baa8 ]

Cc: Stephen Hemminger <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv6/ipv6_sockglue.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 147ede38..3223eb9 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -798,6 +798,7 @@ pref_skip_coa:
                if (val < 0 || val > 255)
                        goto e_inval;
                np->min_hopcount = val;
+               retv = 0;
                break;
        case IPV6_DONTFRAG:
                np->dontfrag = valbool;
-- 
1.7.11.7


>From 4fce25c3e4188b58572ad661a425f0606a73bc9f Mon Sep 17 00:00:00 2001
From: Jiri Pirko <[email protected]>
Date: Wed, 14 Nov 2012 02:51:04 +0000
Subject: [PATCH 3/4] net: correct check in dev_addr_del()

[ Upstream commit a652208e0b52c190e57f2a075ffb5e897fe31c3b ]

Check (ha->addr == dev->dev_addr) is always true because dev_addr_init()
sets this. Correct the check to behave properly on addr removal.

Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev_addr_lists.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index e2e6693..c776af5 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -307,7 +307,8 @@ int dev_addr_del(struct net_device *dev, unsigned char 
*addr,
         */
        ha = list_first_entry(&dev->dev_addrs.list,
                              struct netdev_hw_addr, list);
-       if (ha->addr == dev->dev_addr && ha->refcount == 1)
+       if (!memcmp(ha->addr, addr, dev->addr_len) &&
+           ha->type == addr_type && ha->refcount == 1)
                return -ENOENT;
 
        err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
-- 
1.7.11.7


>From 04bf57cf63408af7f9e5bf1151f541ac08d0bff8 Mon Sep 17 00:00:00 2001
From: Tom Herbert <[email protected]>
Date: Fri, 16 Nov 2012 09:04:15 +0000
Subject: [PATCH 4/4] net-rps: Fix brokeness causing OOO packets

[ Upstream commit baefa31db2f2b13a05d1b81bdf2d20d487f58b0a ]

In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU
selected for RFS is not set correctly when CPU is changing.
This is causing OOO packets and probably other issues.

Signed-off-by: Tom Herbert <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Acked-by: Ben Hutchings <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 5b84eaf..465f1f6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2706,8 +2706,10 @@ static int get_rps_cpu(struct net_device *dev, struct 
sk_buff *skb,
                if (unlikely(tcpu != next_cpu) &&
                    (tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||
                     ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
-                     rflow->last_qtail)) >= 0))
+                     rflow->last_qtail)) >= 0)) {
+                       tcpu = next_cpu;
                        rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
+               }
 
                if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
                        *rflowp = rflow;
-- 
1.7.11.7

>From bb43e44b242d13c9e4753bc9786151ef4df60c99 Mon Sep 17 00:00:00 2001
From: Xi Wang <[email protected]>
Date: Sun, 11 Nov 2012 11:20:01 +0000
Subject: [PATCH 1/4] ipv4: avoid undefined behavior in do_ip_setsockopt()

[ Upstream commit 0c9f79be295c99ac7e4b569ca493d75fdcc19e4e ]

(1<<optname) is undefined behavior in C with a negative optname or
optname larger than 31.  In those cases the result of the shift is
not necessarily zero (e.g., on x86).

This patch simplifies the code with a switch statement on optname.
It also allows the compiler to generate better code (e.g., using a
64-bit mask).

Signed-off-by: Xi Wang <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv4/ip_sockglue.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 09ff51b..0106d25 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -468,18 +468,27 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        struct inet_sock *inet = inet_sk(sk);
        int val = 0, err;
 
-       if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
-                            (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
-                            (1<<IP_RETOPTS) | (1<<IP_TOS) |
-                            (1<<IP_TTL) | (1<<IP_HDRINCL) |
-                            (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
-                            (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
-                            (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
-           optname == IP_MULTICAST_TTL ||
-           optname == IP_MULTICAST_ALL ||
-           optname == IP_MULTICAST_LOOP ||
-           optname == IP_RECVORIGDSTADDR) {
+       switch (optname) {
+       case IP_PKTINFO:
+       case IP_RECVTTL:
+       case IP_RECVOPTS:
+       case IP_RECVTOS:
+       case IP_RETOPTS:
+       case IP_TOS:
+       case IP_TTL:
+       case IP_HDRINCL:
+       case IP_MTU_DISCOVER:
+       case IP_RECVERR:
+       case IP_ROUTER_ALERT:
+       case IP_FREEBIND:
+       case IP_PASSSEC:
+       case IP_TRANSPARENT:
+       case IP_MINTTL:
+       case IP_NODEFRAG:
+       case IP_MULTICAST_TTL:
+       case IP_MULTICAST_ALL:
+       case IP_MULTICAST_LOOP:
+       case IP_RECVORIGDSTADDR:
                if (optlen >= sizeof(int)) {
                        if (get_user(val, (int __user *) optval))
                                return -EFAULT;
-- 
1.7.11.7


>From 4bc72175ded95c3d68f62545fc1c610507831eee Mon Sep 17 00:00:00 2001
From: Hannes Frederic Sowa <[email protected]>
Date: Sat, 10 Nov 2012 19:52:34 +0000
Subject: [PATCH 2/4] ipv6: setsockopt(IPIPPROTO_IPV6, IPV6_MINHOPCOUNT)
 forgot to set return value

[ Upstream commit d4596bad2a713fcd0def492b1960e6d899d5baa8 ]

Cc: Stephen Hemminger <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv6/ipv6_sockglue.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 26cb08c..b204df8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -798,6 +798,7 @@ pref_skip_coa:
                if (val < 0 || val > 255)
                        goto e_inval;
                np->min_hopcount = val;
+               retv = 0;
                break;
        case IPV6_DONTFRAG:
                np->dontfrag = valbool;
-- 
1.7.11.7


>From 86eb2195dafea146706a114f748935a76d38297a Mon Sep 17 00:00:00 2001
From: Jiri Pirko <[email protected]>
Date: Wed, 14 Nov 2012 02:51:04 +0000
Subject: [PATCH 3/4] net: correct check in dev_addr_del()

[ Upstream commit a652208e0b52c190e57f2a075ffb5e897fe31c3b ]

Check (ha->addr == dev->dev_addr) is always true because dev_addr_init()
sets this. Correct the check to behave properly on addr removal.

Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev_addr_lists.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 277faef..0387da0 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -308,7 +308,8 @@ int dev_addr_del(struct net_device *dev, unsigned char 
*addr,
         */
        ha = list_first_entry(&dev->dev_addrs.list,
                              struct netdev_hw_addr, list);
-       if (ha->addr == dev->dev_addr && ha->refcount == 1)
+       if (!memcmp(ha->addr, addr, dev->addr_len) &&
+           ha->type == addr_type && ha->refcount == 1)
                return -ENOENT;
 
        err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
-- 
1.7.11.7


>From 689e5e60ef224f3407573aa6ee503c306a99f25d Mon Sep 17 00:00:00 2001
From: Tom Herbert <[email protected]>
Date: Fri, 16 Nov 2012 09:04:15 +0000
Subject: [PATCH 4/4] net-rps: Fix brokeness causing OOO packets

[ Upstream commit baefa31db2f2b13a05d1b81bdf2d20d487f58b0a ]

In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU
selected for RFS is not set correctly when CPU is changing.
This is causing OOO packets and probably other issues.

Signed-off-by: Tom Herbert <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Acked-by: Ben Hutchings <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 480be72..2aac4ec 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2829,8 +2829,10 @@ static int get_rps_cpu(struct net_device *dev, struct 
sk_buff *skb,
                if (unlikely(tcpu != next_cpu) &&
                    (tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||
                     ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
-                     rflow->last_qtail)) >= 0))
+                     rflow->last_qtail)) >= 0)) {
+                       tcpu = next_cpu;
                        rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
+               }
 
                if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
                        *rflowp = rflow;
-- 
1.7.11.7

>From 41bf39d3ea484be927cebc02bab4513bc278d6b0 Mon Sep 17 00:00:00 2001
From: Xi Wang <[email protected]>
Date: Sun, 11 Nov 2012 11:20:01 +0000
Subject: [PATCH 1/5] ipv4: avoid undefined behavior in do_ip_setsockopt()

[ Upstream commit 0c9f79be295c99ac7e4b569ca493d75fdcc19e4e ]

(1<<optname) is undefined behavior in C with a negative optname or
optname larger than 31.  In those cases the result of the shift is
not necessarily zero (e.g., on x86).

This patch simplifies the code with a switch statement on optname.
It also allows the compiler to generate better code (e.g., using a
64-bit mask).

Signed-off-by: Xi Wang <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv4/ip_sockglue.c | 35 ++++++++++++++++++++++-------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 2fd0fba..59ef40a 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -456,19 +456,28 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        struct inet_sock *inet = inet_sk(sk);
        int val = 0, err;
 
-       if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
-                            (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
-                            (1<<IP_RETOPTS) | (1<<IP_TOS) |
-                            (1<<IP_TTL) | (1<<IP_HDRINCL) |
-                            (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
-                            (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
-                            (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
-           optname == IP_UNICAST_IF ||
-           optname == IP_MULTICAST_TTL ||
-           optname == IP_MULTICAST_ALL ||
-           optname == IP_MULTICAST_LOOP ||
-           optname == IP_RECVORIGDSTADDR) {
+       switch (optname) {
+       case IP_PKTINFO:
+       case IP_RECVTTL:
+       case IP_RECVOPTS:
+       case IP_RECVTOS:
+       case IP_RETOPTS:
+       case IP_TOS:
+       case IP_TTL:
+       case IP_HDRINCL:
+       case IP_MTU_DISCOVER:
+       case IP_RECVERR:
+       case IP_ROUTER_ALERT:
+       case IP_FREEBIND:
+       case IP_PASSSEC:
+       case IP_TRANSPARENT:
+       case IP_MINTTL:
+       case IP_NODEFRAG:
+       case IP_UNICAST_IF:
+       case IP_MULTICAST_TTL:
+       case IP_MULTICAST_ALL:
+       case IP_MULTICAST_LOOP:
+       case IP_RECVORIGDSTADDR:
                if (optlen >= sizeof(int)) {
                        if (get_user(val, (int __user *) optval))
                                return -EFAULT;
-- 
1.7.11.7


>From 63950c29d47e5334b985def26fca4345fc91e75c Mon Sep 17 00:00:00 2001
From: Hannes Frederic Sowa <[email protected]>
Date: Sat, 10 Nov 2012 19:52:34 +0000
Subject: [PATCH 2/5] ipv6: setsockopt(IPIPPROTO_IPV6, IPV6_MINHOPCOUNT)
 forgot to set return value

[ Upstream commit d4596bad2a713fcd0def492b1960e6d899d5baa8 ]

Cc: Stephen Hemminger <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv6/ipv6_sockglue.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 63dd1f8..34c1109 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -828,6 +828,7 @@ pref_skip_coa:
                if (val < 0 || val > 255)
                        goto e_inval;
                np->min_hopcount = val;
+               retv = 0;
                break;
        case IPV6_DONTFRAG:
                np->dontfrag = valbool;
-- 
1.7.11.7


>From d1f6864ea9a9ab2f8a8e9322c94ed073bd6c41e2 Mon Sep 17 00:00:00 2001
From: Jiri Pirko <[email protected]>
Date: Wed, 14 Nov 2012 02:51:04 +0000
Subject: [PATCH 3/5] net: correct check in dev_addr_del()

[ Upstream commit a652208e0b52c190e57f2a075ffb5e897fe31c3b ]

Check (ha->addr == dev->dev_addr) is always true because dev_addr_init()
sets this. Correct the check to behave properly on addr removal.

Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev_addr_lists.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 626698f..76f6d0b 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -308,7 +308,8 @@ int dev_addr_del(struct net_device *dev, unsigned char 
*addr,
         */
        ha = list_first_entry(&dev->dev_addrs.list,
                              struct netdev_hw_addr, list);
-       if (ha->addr == dev->dev_addr && ha->refcount == 1)
+       if (!memcmp(ha->addr, addr, dev->addr_len) &&
+           ha->type == addr_type && ha->refcount == 1)
                return -ENOENT;
 
        err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
-- 
1.7.11.7


>From d661003efcb9c8d8883eca743bf4fc448aa47f9f Mon Sep 17 00:00:00 2001
From: Tom Herbert <[email protected]>
Date: Fri, 16 Nov 2012 09:04:15 +0000
Subject: [PATCH 4/5] net-rps: Fix brokeness causing OOO packets

[ Upstream commit baefa31db2f2b13a05d1b81bdf2d20d487f58b0a ]

In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU
selected for RFS is not set correctly when CPU is changing.
This is causing OOO packets and probably other issues.

Signed-off-by: Tom Herbert <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Acked-by: Ben Hutchings <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 24a21f3..eb858dc 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2763,8 +2763,10 @@ static int get_rps_cpu(struct net_device *dev, struct 
sk_buff *skb,
                if (unlikely(tcpu != next_cpu) &&
                    (tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||
                     ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
-                     rflow->last_qtail)) >= 0))
+                     rflow->last_qtail)) >= 0)) {
+                       tcpu = next_cpu;
                        rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
+               }
 
                if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
                        *rflowp = rflow;
-- 
1.7.11.7


>From 2a7ee5c346a18a46f119a455e0f3116bd7d8a476 Mon Sep 17 00:00:00 2001
From: Xi Wang <[email protected]>
Date: Sun, 11 Nov 2012 11:20:01 +0000
Subject: [PATCH 1/8] ipv4: avoid undefined behavior in do_ip_setsockopt()

[ Upstream commit 0c9f79be295c99ac7e4b569ca493d75fdcc19e4e ]

(1<<optname) is undefined behavior in C with a negative optname or
optname larger than 31.  In those cases the result of the shift is
not necessarily zero (e.g., on x86).

This patch simplifies the code with a switch statement on optname.
It also allows the compiler to generate better code (e.g., using a
64-bit mask).

Signed-off-by: Xi Wang <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv4/ip_sockglue.c | 35 ++++++++++++++++++++++-------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5eea4a8..14bbfcf 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        struct inet_sock *inet = inet_sk(sk);
        int val = 0, err;
 
-       if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
-                            (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
-                            (1<<IP_RETOPTS) | (1<<IP_TOS) |
-                            (1<<IP_TTL) | (1<<IP_HDRINCL) |
-                            (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
-                            (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
-                            (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
-           optname == IP_UNICAST_IF ||
-           optname == IP_MULTICAST_TTL ||
-           optname == IP_MULTICAST_ALL ||
-           optname == IP_MULTICAST_LOOP ||
-           optname == IP_RECVORIGDSTADDR) {
+       switch (optname) {
+       case IP_PKTINFO:
+       case IP_RECVTTL:
+       case IP_RECVOPTS:
+       case IP_RECVTOS:
+       case IP_RETOPTS:
+       case IP_TOS:
+       case IP_TTL:
+       case IP_HDRINCL:
+       case IP_MTU_DISCOVER:
+       case IP_RECVERR:
+       case IP_ROUTER_ALERT:
+       case IP_FREEBIND:
+       case IP_PASSSEC:
+       case IP_TRANSPARENT:
+       case IP_MINTTL:
+       case IP_NODEFRAG:
+       case IP_UNICAST_IF:
+       case IP_MULTICAST_TTL:
+       case IP_MULTICAST_ALL:
+       case IP_MULTICAST_LOOP:
+       case IP_RECVORIGDSTADDR:
                if (optlen >= sizeof(int)) {
                        if (get_user(val, (int __user *) optval))
                                return -EFAULT;
-- 
1.7.11.7


>From e031b84387a863855999d681f922fd7094c76009 Mon Sep 17 00:00:00 2001
From: Saurabh Mohan <[email protected]>
Date: Wed, 14 Nov 2012 18:08:15 -0800
Subject: [PATCH 2/8] ipv4/ip_vti.c: VTI fix post-decryption forwarding

[ Upstream commit b2942004fb5c9f3304b77e187b8a1977b3626c9b ]

With the latest kernel there are two things that must be done post decryption
 so that the packet are forwarded.
 1. Remove the mark from the packet. This will cause the packet to not match
 the ipsec-policy again. However doing this causes the post-decryption check to
 fail also and the packet will get dropped. (cat /proc/net/xfrm_stat).
 2. Remove the sp association in the skbuff so that no policy check is done on
 the packet for VTI tunnels.

Due to #2 above we must now do a security-policy check in the vti rcv path
prior to resetting the mark in the skbuff.

Signed-off-by: Saurabh Mohan <[email protected]>
Reported-by: Ruben Herold <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv4/ip_vti.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 3511ffb..bf89b21 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -341,12 +341,17 @@ static int vti_rcv(struct sk_buff *skb)
        if (tunnel != NULL) {
                struct pcpu_tstats *tstats;
 
+               if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+                       return -1;
+
                tstats = this_cpu_ptr(tunnel->dev->tstats);
                u64_stats_update_begin(&tstats->syncp);
                tstats->rx_packets++;
                tstats->rx_bytes += skb->len;
                u64_stats_update_end(&tstats->syncp);
 
+               skb->mark = 0;
+               secpath_reset(skb);
                skb->dev = tunnel->dev;
                rcu_read_unlock();
                return 1;
-- 
1.7.11.7


>From 513a4430184bb9f058832c9b462037737d9c33b9 Mon Sep 17 00:00:00 2001
From: Hannes Frederic Sowa <[email protected]>
Date: Sat, 10 Nov 2012 19:52:34 +0000
Subject: [PATCH 3/8] ipv6: setsockopt(IPIPPROTO_IPV6, IPV6_MINHOPCOUNT)
 forgot to set return value

[ Upstream commit d4596bad2a713fcd0def492b1960e6d899d5baa8 ]

Cc: Stephen Hemminger <[email protected]>
Signed-off-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv6/ipv6_sockglue.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ba6d13d..e02faed 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -827,6 +827,7 @@ pref_skip_coa:
                if (val < 0 || val > 255)
                        goto e_inval;
                np->min_hopcount = val;
+               retv = 0;
                break;
        case IPV6_DONTFRAG:
                np->dontfrag = valbool;
-- 
1.7.11.7


>From 3e168a2aebeef824b7de16af9914a41bb43a7a7e Mon Sep 17 00:00:00 2001
From: Jiri Pirko <[email protected]>
Date: Wed, 14 Nov 2012 02:51:04 +0000
Subject: [PATCH 4/8] net: correct check in dev_addr_del()

[ Upstream commit a652208e0b52c190e57f2a075ffb5e897fe31c3b ]

Check (ha->addr == dev->dev_addr) is always true because dev_addr_init()
sets this. Correct the check to behave properly on addr removal.

Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev_addr_lists.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index c4cc2bc..716f363 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -317,7 +317,8 @@ int dev_addr_del(struct net_device *dev, unsigned char 
*addr,
         */
        ha = list_first_entry(&dev->dev_addrs.list,
                              struct netdev_hw_addr, list);
-       if (ha->addr == dev->dev_addr && ha->refcount == 1)
+       if (!memcmp(ha->addr, addr, dev->addr_len) &&
+           ha->type == addr_type && ha->refcount == 1)
                return -ENOENT;
 
        err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
-- 
1.7.11.7


>From 5e26fb0e61c630f44d4cdd09e5c190647e4aa0f3 Mon Sep 17 00:00:00 2001
From: Tom Herbert <[email protected]>
Date: Fri, 16 Nov 2012 09:04:15 +0000
Subject: [PATCH 5/8] net-rps: Fix brokeness causing OOO packets

[ Upstream commit baefa31db2f2b13a05d1b81bdf2d20d487f58b0a ]

In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU
selected for RFS is not set correctly when CPU is changing.
This is causing OOO packets and probably other issues.

Signed-off-by: Tom Herbert <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Acked-by: Ben Hutchings <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/core/dev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index aed87a4..1dce5b5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2793,8 +2793,10 @@ static int get_rps_cpu(struct net_device *dev, struct 
sk_buff *skb,
                if (unlikely(tcpu != next_cpu) &&
                    (tcpu == RPS_NO_CPU || !cpu_online(tcpu) ||
                     ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
-                     rflow->last_qtail)) >= 0))
+                     rflow->last_qtail)) >= 0)) {
+                       tcpu = next_cpu;
                        rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
+               }
 
                if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
                        *rflowp = rflow;
-- 
1.7.11.7


>From 92732269096b1737ebb14b5cd98c1721fd5cbc15 Mon Sep 17 00:00:00 2001
From: Tommi Rantala <[email protected]>
Date: Thu, 15 Nov 2012 03:49:05 +0000
Subject: [PATCH 6/8] sctp: fix /proc/net/sctp/ memory leak

[ Upstream commit 0da9a0c2638c8476b4a5021841912f249e3187dc ]

Commit 13d782f ("sctp: Make the proc files per network namespace.")
changed the /proc/net/sctp/ struct file_operations opener functions to
use single_open_net() and seq_open_net().

Avoid leaking memory by using single_release_net() and seq_release_net()
as the release functions.

Discovered with Trinity (the syscall fuzzer).

Signed-off-by: Tommi Rantala <[email protected]>
Acked-by: Neil Horman <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/sctp/proc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 1e2eee8..13969b2 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -101,7 +101,7 @@ static const struct file_operations sctp_snmp_seq_fops = {
        .open    = sctp_snmp_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = single_release,
+       .release = single_release_net,
 };
 
 /* Set up the proc fs entry for 'snmp' object. */
@@ -245,7 +245,7 @@ static const struct file_operations sctp_eps_seq_fops = {
        .open    = sctp_eps_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release,
+       .release = seq_release_net,
 };
 
 /* Set up the proc fs entry for 'eps' object. */
@@ -361,7 +361,7 @@ static const struct file_operations sctp_assocs_seq_fops = {
        .open    = sctp_assocs_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release,
+       .release = seq_release_net,
 };
 
 /* Set up the proc fs entry for 'assocs' object. */
@@ -503,7 +503,7 @@ static const struct file_operations sctp_remaddr_seq_fops = 
{
        .open = sctp_remaddr_seq_open,
        .read = seq_read,
        .llseek = seq_lseek,
-       .release = seq_release,
+       .release = seq_release_net,
 };
 
 int __init sctp_remaddr_proc_init(void)
-- 
1.7.11.7


>From 9e6a7cc684ebf922e7e402c4972e6f8ea1dfa0aa Mon Sep 17 00:00:00 2001
From: Andrew Vagin <[email protected]>
Date: Thu, 15 Nov 2012 04:03:17 +0000
Subject: [PATCH 7/8] tcp: fix retransmission in repair mode

[ Upstream commit ec34232575083fd0f43d3a101e8ebb041b203761 ]

Currently if a socket was repaired with a few packet in a write queue,
a kernel bug may be triggered:

kernel BUG at net/ipv4/tcp_output.c:2330!
RIP: 0010:[<ffffffff8155784f>] tcp_retransmit_skb+0x5ff/0x610

According to the initial realization v3.4-rc2-963-gc0e88ff,
all skb-s should look like already posted. This patch fixes code
according with this sentence.

Here are three points, which were not done in the initial patch:
1. A tcp send head should not be changed
2. Initialize TSO state of a skb
3. Reset the retransmission time

This patch moves logic from tcp_sendmsg to tcp_write_xmit. A packet
passes the ussual way, but isn't sent to network. This patch solves
all described problems and handles tcp_sendpages.

Cc: Pavel Emelyanov <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Alexey Kuznetsov <[email protected]>
Cc: James Morris <[email protected]>
Cc: Hideaki YOSHIFUJI <[email protected]>
Cc: Patrick McHardy <[email protected]>
Signed-off-by: Andrey Vagin <[email protected]>
Acked-by: Pavel Emelyanov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv4/tcp.c        | 4 ++--
 net/ipv4/tcp_output.c | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 49dd993..b0b39f6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1236,7 +1236,7 @@ new_segment:
 wait_for_sndbuf:
                        set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 wait_for_memory:
-                       if (copied && likely(!tp->repair))
+                       if (copied)
                                tcp_push(sk, flags & ~MSG_MORE, mss_now, 
TCP_NAGLE_PUSH);
 
                        if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
@@ -1247,7 +1247,7 @@ wait_for_memory:
        }
 
 out:
-       if (copied && likely(!tp->repair))
+       if (copied)
                tcp_push(sk, flags, mss_now, tp->nonagle);
        release_sock(sk);
        return copied + copied_syn;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index d046326..6735bea 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1977,6 +1977,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int 
mss_now, int nonagle,
                tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
                BUG_ON(!tso_segs);
 
+               if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE)
+                       goto repair; /* Skip network transmission */
+
                cwnd_quota = tcp_cwnd_test(tp, skb);
                if (!cwnd_quota)
                        break;
@@ -2017,6 +2020,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int 
mss_now, int nonagle,
                if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
                        break;
 
+repair:
                /* Advance the send_head.  This one is sent out.
                 * This call will increment packets_out.
                 */
-- 
1.7.11.7


>From e7510275aa8b8ff6bda0ff3cd9461a7bf461aa3d Mon Sep 17 00:00:00 2001
From: Eric Dumazet <[email protected]>
Date: Fri, 16 Nov 2012 05:31:53 +0000
Subject: [PATCH 8/8] tcp: handle tcp_net_metrics_init() order-5 memory
 allocation failures

[ Upstream commit 976a702ac9eeacea09e588456ab165dc06f9ee83 ]

order-5 allocations can fail with current kernels, we should
try vmalloc() as well.

Reported-by: Julien Tinnes <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 net/ipv4/tcp_metrics.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 0abe67b..2efd1a5 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -1,13 +1,13 @@
 #include <linux/rcupdate.h>
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
-#include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/tcp.h>
 #include <linux/hash.h>
+#include <linux/vmalloc.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/net_namespace.h>
@@ -722,7 +722,10 @@ static int __net_init tcp_net_metrics_init(struct net *net)
        net->ipv4.tcp_metrics_hash_log = order_base_2(slots);
        size = sizeof(struct tcpm_hash_bucket) << 
net->ipv4.tcp_metrics_hash_log;
 
-       net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL);
+       net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
+       if (!net->ipv4.tcp_metrics_hash)
+               net->ipv4.tcp_metrics_hash = vzalloc(size);
+
        if (!net->ipv4.tcp_metrics_hash)
                return -ENOMEM;
 
@@ -743,7 +746,10 @@ static void __net_exit tcp_net_metrics_exit(struct net 
*net)
                        tm = next;
                }
        }
-       kfree(net->ipv4.tcp_metrics_hash);
+       if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash))
+               vfree(net->ipv4.tcp_metrics_hash);
+       else
+               kfree(net->ipv4.tcp_metrics_hash);
 }
 
 static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
-- 
1.7.11.7

Reply via email to