* Re: [PATCH 11/36] ixgbe, rcu: convert call_rcu(ring_free_rcu) to kfree_rcu()
From: David Miller @ 2011-03-18 19:36 UTC (permalink / raw)
To: laijs
Cc: e1000-devel, bruce.w.allan, jesse.brandeburg, linux-kernel,
john.ronciak, netdev, mingo, paulmck
In-Reply-To: <4D82D821.1070101@cn.fujitsu.com>
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Fri, 18 Mar 2011 11:57:21 +0800
>
>
> The rcu callback ring_free_rcu() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(ring_free_rcu).
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: David S. Miller <davem@davemloft.net>
------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: [PATCH 09/36] net, rcu: convert call_rcu(ip_mc_socklist_reclaim) to kfree_rcu()
From: David Miller @ 2011-03-18 19:36 UTC (permalink / raw)
To: laijs-BthXqXjhjHXQFUHtdCDX3A
Cc: axboe-tSWWG44O7X1aa/9Udqfwiw, pekkas-UjJjq++bwZ7HOG6cAo2yLw,
nhorman-2XuSBdqkA4R54TAoqtyWWQ, yoshfuji-VfPWfsRibaP+Ru+s062T9g,
netdev-u79uwXL29TY76Z2rM5mHXA, shemminger-ZtmgI6mnKB3QT0dZR+AlfA,
jmorris-gx6/JNMH7DfYtjvyW6yDsg,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-scsi-u79uwXL29TY76Z2rM5mHXA, James.Bottomley-l3A5Bk7waGM,
devel-s9riP+hp16TNLxjTenLetw, eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
tj-DgEjT+Ai2ygdnm+yROfE0A, kuznet-v/Mj1YrvjDBInbfyfbPRSQ,
mingo-X9Un+BFzKDI, paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
kaber-dcUjhNyLwpNeoWH0uzbU5w, jarkao2-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <4D82D544.6090509-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
From: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Date: Fri, 18 Mar 2011 11:45:08 +0800
>
>
> The rcu callback ip_mc_socklist_reclaim() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(ip_mc_socklist_reclaim).
>
> Signed-off-by: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Acked-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
^ permalink raw reply
* Re: [PATCH 18/36] net,rcu: convert call_rcu(xps_dev_maps_release) to kfree_rcu()
From: David Miller @ 2011-03-18 19:36 UTC (permalink / raw)
To: laijs
Cc: paulmck, mingo, eric.dumazet, therbert, ebiederm, gregkh, netdev,
linux-kernel
In-Reply-To: <4D82D967.7090408@cn.fujitsu.com>
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Fri, 18 Mar 2011 12:02:47 +0800
>
>
> The rcu callback xps_dev_maps_release() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(xps_dev_maps_release).
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH 08/36] net,rcu: convert call_rcu(ip_sf_socklist_reclaim) to kfree_rcu()
From: David Miller @ 2011-03-18 19:35 UTC (permalink / raw)
To: laijs
Cc: paulmck, mingo, axboe, robert.w.love, James.Bottomley, nhorman,
kuznet, pekkas, jmorris, yoshfuji, kaber, eric.dumazet,
shemminger, tj, jarkao2, linux-kernel, devel, linux-scsi, netdev
In-Reply-To: <4D82D52E.1010501@cn.fujitsu.com>
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Fri, 18 Mar 2011 11:44:46 +0800
>
>
> The rcu callback ip_sf_socklist_reclaim() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(ip_sf_socklist_reclaim).
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH 07/36] net, rcu: convert call_rcu(ip_mc_list_reclaim) to kfree_rcu()
From: David Miller @ 2011-03-18 19:35 UTC (permalink / raw)
To: laijs-BthXqXjhjHXQFUHtdCDX3A
Cc: axboe-tSWWG44O7X1aa/9Udqfwiw, pekkas-UjJjq++bwZ7HOG6cAo2yLw,
nhorman-2XuSBdqkA4R54TAoqtyWWQ, yoshfuji-VfPWfsRibaP+Ru+s062T9g,
netdev-u79uwXL29TY76Z2rM5mHXA, shemminger-ZtmgI6mnKB3QT0dZR+AlfA,
jmorris-gx6/JNMH7DfYtjvyW6yDsg,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-scsi-u79uwXL29TY76Z2rM5mHXA, James.Bottomley-l3A5Bk7waGM,
devel-s9riP+hp16TNLxjTenLetw, eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
tj-DgEjT+Ai2ygdnm+yROfE0A, kuznet-v/Mj1YrvjDBInbfyfbPRSQ,
mingo-X9Un+BFzKDI, paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
kaber-dcUjhNyLwpNeoWH0uzbU5w, jarkao2-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <4D82D508.5080901-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
From: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Date: Fri, 18 Mar 2011 11:44:08 +0800
>
>
> The rcu callback ip_mc_list_reclaim() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(ip_mc_list_reclaim).
>
> Signed-off-by: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Acked-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
^ permalink raw reply
* Re: [PATCH 06/36] net,rcu: convert call_rcu(__gen_kill_estimator) to kfree_rcu()
From: David Miller @ 2011-03-18 19:35 UTC (permalink / raw)
To: laijs
Cc: paulmck, mingo, axboe, robert.w.love, James.Bottomley, nhorman,
kuznet, pekkas, jmorris, yoshfuji, kaber, eric.dumazet,
shemminger, tj, jarkao2, linux-kernel, devel, linux-scsi, netdev
In-Reply-To: <4D82D4DE.60105@cn.fujitsu.com>
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Fri, 18 Mar 2011 11:43:26 +0800
>
>
> The rcu callback __gen_kill_estimator() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(__gen_kill_estimator).
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH 15/36] net,rcu: convert call_rcu(ipv6_mc_socklist_reclaim) to kfree_rcu()
From: David Miller @ 2011-03-18 19:36 UTC (permalink / raw)
To: laijs
Cc: paulmck, mingo, kuznet, pekkas, jmorris, yoshfuji, kaber, netdev,
linux-kernel
In-Reply-To: <4D82D8F2.5020208@cn.fujitsu.com>
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Fri, 18 Mar 2011 12:00:50 +0800
>
>
> The rcu callback ipv6_mc_socklist_reclaim() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(ipv6_mc_socklist_reclaim).
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH 04/36] net, rcu: convert call_rcu(__leaf_info_free_rcu) to kfree_rcu()
From: David Miller @ 2011-03-18 19:35 UTC (permalink / raw)
To: laijs-BthXqXjhjHXQFUHtdCDX3A
Cc: axboe-tSWWG44O7X1aa/9Udqfwiw, pekkas-UjJjq++bwZ7HOG6cAo2yLw,
nhorman-2XuSBdqkA4R54TAoqtyWWQ, yoshfuji-VfPWfsRibaP+Ru+s062T9g,
netdev-u79uwXL29TY76Z2rM5mHXA, shemminger-ZtmgI6mnKB3QT0dZR+AlfA,
jmorris-gx6/JNMH7DfYtjvyW6yDsg,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-scsi-u79uwXL29TY76Z2rM5mHXA, James.Bottomley-l3A5Bk7waGM,
devel-s9riP+hp16TNLxjTenLetw, eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
tj-DgEjT+Ai2ygdnm+yROfE0A, kuznet-v/Mj1YrvjDBInbfyfbPRSQ,
mingo-X9Un+BFzKDI, paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
kaber-dcUjhNyLwpNeoWH0uzbU5w, jarkao2-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <4D82D4AA.2080601-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
From: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Date: Fri, 18 Mar 2011 11:42:34 +0800
>
>
> The rcu callback __leaf_info_free_rcu() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(__leaf_info_free_rcu).
>
> Signed-off-by: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Acked-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
^ permalink raw reply
* Re: [PATCH 03/36] net,rcu: convert call_rcu(fc_rport_free_rcu) to kfree_rcu()
From: David Miller @ 2011-03-18 19:35 UTC (permalink / raw)
To: laijs
Cc: paulmck, mingo, axboe, robert.w.love, James.Bottomley, nhorman,
kuznet, pekkas, jmorris, yoshfuji, kaber, eric.dumazet,
shemminger, tj, jarkao2, linux-kernel, devel, linux-scsi, netdev
In-Reply-To: <4D82D493.3080504@cn.fujitsu.com>
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Fri, 18 Mar 2011 11:42:11 +0800
>
>
> The rcu callback fc_rport_free_rcu() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(fc_rport_free_rcu).
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [PATCH 01/36] net,rcu: convert call_rcu(free_dm_hw_stat) to kfree_rcu()
From: David Miller @ 2011-03-18 19:35 UTC (permalink / raw)
To: laijs
Cc: paulmck, mingo, axboe, robert.w.love, James.Bottomley, nhorman,
kuznet, pekkas, jmorris, yoshfuji, kaber, eric.dumazet,
shemminger, tj, jarkao2, linux-kernel, devel, linux-scsi, netdev
In-Reply-To: <4D82D3FF.2080303@cn.fujitsu.com>
From: Lai Jiangshan <laijs@cn.fujitsu.com>
Date: Fri, 18 Mar 2011 11:39:43 +0800
>
>
> The rcu callback free_dm_hw_stat() just calls a kfree(),
> so we use kfree_rcu() instead of the call_rcu(free_dm_hw_stat).
>
> Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: VLAN over GRE segfault
From: Herbert Xu @ 2011-03-18 19:28 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Diddi Oscarsson, David Miller, netdev, Patrick McHardy
In-Reply-To: <1300444047.2888.18.camel@edumazet-laptop>
On Fri, Mar 18, 2011 at 11:27:27AM +0100, Eric Dumazet wrote:
>
> This uncover a bug in vlan code.
>
> We should make sure vlan devices take into account their
> real_dev->needed_headroom or we risk a crash in ipgre_header(), because
> we dont have enough room to push IP header in skb.
>
> Reported-by: Diddi Oscarsson <diddi@diddi.se>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH] headers: use __aligned_xx types for userspace
From: Mike Frysinger @ 2011-03-18 18:50 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, netdev, David S. Miller
Now that we finally have __aligned_xx exported to userspace, convert
the headers that get exported over to the proper type.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
include/linux/if_ppp.h | 16 ++++++++--------
include/linux/netfilter/nfnetlink_log.h | 4 ++--
include/linux/netfilter/nfnetlink_queue.h | 4 ++--
include/linux/netfilter/xt_connbytes.h | 4 ++--
include/linux/netfilter/xt_quota.h | 2 +-
5 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/include/linux/if_ppp.h b/include/linux/if_ppp.h
index fcef103..c9ad383 100644
--- a/include/linux/if_ppp.h
+++ b/include/linux/if_ppp.h
@@ -114,14 +114,14 @@ struct pppol2tp_ioc_stats {
__u16 tunnel_id; /* redundant */
__u16 session_id; /* if zero, get tunnel stats */
__u32 using_ipsec:1; /* valid only for session_id == 0 */
- aligned_u64 tx_packets;
- aligned_u64 tx_bytes;
- aligned_u64 tx_errors;
- aligned_u64 rx_packets;
- aligned_u64 rx_bytes;
- aligned_u64 rx_seq_discards;
- aligned_u64 rx_oos_packets;
- aligned_u64 rx_errors;
+ __aligned_u64 tx_packets;
+ __aligned_u64 tx_bytes;
+ __aligned_u64 tx_errors;
+ __aligned_u64 rx_packets;
+ __aligned_u64 rx_bytes;
+ __aligned_u64 rx_seq_discards;
+ __aligned_u64 rx_oos_packets;
+ __aligned_u64 rx_errors;
};
#define ifr__name b.ifr_ifrn.ifrn_name
diff --git a/include/linux/netfilter/nfnetlink_log.h b/include/linux/netfilter/nfnetlink_log.h
index ea9b8d3..90c2c95 100644
--- a/include/linux/netfilter/nfnetlink_log.h
+++ b/include/linux/netfilter/nfnetlink_log.h
@@ -28,8 +28,8 @@ struct nfulnl_msg_packet_hw {
};
struct nfulnl_msg_packet_timestamp {
- aligned_be64 sec;
- aligned_be64 usec;
+ __aligned_be64 sec;
+ __aligned_be64 usec;
};
enum nfulnl_attr_type {
diff --git a/include/linux/netfilter/nfnetlink_queue.h b/include/linux/netfilter/nfnetlink_queue.h
index 2455fe5..af94e00 100644
--- a/include/linux/netfilter/nfnetlink_queue.h
+++ b/include/linux/netfilter/nfnetlink_queue.h
@@ -25,8 +25,8 @@ struct nfqnl_msg_packet_hw {
};
struct nfqnl_msg_packet_timestamp {
- aligned_be64 sec;
- aligned_be64 usec;
+ __aligned_be64 sec;
+ __aligned_be64 usec;
};
enum nfqnl_attr_type {
diff --git a/include/linux/netfilter/xt_connbytes.h b/include/linux/netfilter/xt_connbytes.h
index 92fcbb0..f1d6c15 100644
--- a/include/linux/netfilter/xt_connbytes.h
+++ b/include/linux/netfilter/xt_connbytes.h
@@ -17,8 +17,8 @@ enum xt_connbytes_direction {
struct xt_connbytes_info {
struct {
- aligned_u64 from; /* count to be matched */
- aligned_u64 to; /* count to be matched */
+ __aligned_u64 from; /* count to be matched */
+ __aligned_u64 to; /* count to be matched */
} count;
__u8 what; /* ipt_connbytes_what */
__u8 direction; /* ipt_connbytes_direction */
diff --git a/include/linux/netfilter/xt_quota.h b/include/linux/netfilter/xt_quota.h
index b0d28c6..468c4e9 100644
--- a/include/linux/netfilter/xt_quota.h
+++ b/include/linux/netfilter/xt_quota.h
@@ -11,7 +11,7 @@ struct xt_quota_priv;
struct xt_quota_info {
u_int32_t flags;
u_int32_t pad;
- aligned_u64 quota;
+ __aligned_u64 quota;
/* Used internally by the kernel */
struct xt_quota_priv *master;
--
1.7.4.1
^ permalink raw reply related
* patch for format issues and header bug in net/ipv4/icmp.c
From: Jeffrin Jose @ 2011-03-18 18:35 UTC (permalink / raw)
To: David S. Miller, Alexey Kuznetsov; +Cc: linux-kernel, netdev
[-- Attachment #1: Type: text/plain, Size: 277 bytes --]
hello ,
I have created a patch for net/ipv4/icmp.c
using checkpatch.pl script to fix several warnings
and an error.
I have attached the patch along with this mail.
/Thanks
--
software engineer.
department of computer science
rajagiri school of engineering and technology.
[-- Attachment #2: 0001-net-Fixed-format-issues-and-header-bug-in-net-ipv4-i.patch --]
[-- Type: text/x-diff, Size: 4317 bytes --]
>From 01861eb7151d397d10e1e8be58ac79252b04e254 Mon Sep 17 00:00:00 2001
From: Jeffrin Jose <ahiliation@yahoo.co.in>
Date: Fri, 18 Mar 2011 23:20:24 +0530
Subject: [PATCH] net : Fixed format issues and header bug in net/ipv4/icmp.c
This is a patch to net/ipv4/icmp.c file that fixes several
line limit and several format ones and also a header path
issue found by the checkpatch.pl tool.
Author: Jeffrin Jose <ahiliation@yahoo.co.in>
Signed-off-by: Jeffrin Jose
---
net/ipv4/icmp.c | 30 +++++++++++++++++-------------
1 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index a91dc16..348cc17 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -53,7 +53,7 @@
* - ICMP header length was not accounted
* at all.
* Tristan Greaves : Added sysctl option to ignore bogus
- * broadcast responses from broken routers.
+ * broadcast responses from broken routers.
*
* To Fix:
*
@@ -89,7 +89,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <net/checksum.h>
#include <net/xfrm.h>
#include <net/inet_common.h>
@@ -113,7 +113,8 @@ struct icmp_bxm {
};
/* An array of errno for error messages from dest unreach. */
-/* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */
+/* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST
+be considered 'transient errs'. */
const struct icmp_err icmp_err_convert[] = {
{
@@ -303,7 +304,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param,
ipc, rt, MSG_DONTWAIT) < 0) {
ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_OUTERRORS);
ip_flush_pending_frames(sk);
- } else if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
+ } else if ((skb == skb_peek(&sk->sk_write_queue)) != NULL) {
struct icmphdr *icmph = icmp_hdr(skb);
__wsum csum = 0;
struct sk_buff *skb1;
@@ -411,7 +412,8 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in,
} else
return rt;
- err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4), AF_INET);
+ err = xfrm_decode_session_reverse(skb_in, \
+ flowi4_to_flowi(&fl4), AF_INET);
if (err)
goto relookup_failed;
@@ -648,7 +650,7 @@ static void icmp_unreach(struct sk_buff *skb)
/*
* Incomplete header ?
- * Only checks for the IP header, there should be an
+ * Only checks for the IP header, there should be an
* additional check for longer headers in upper levels.
*/
@@ -670,18 +672,20 @@ static void icmp_unreach(struct sk_buff *skb)
break;
case ICMP_FRAG_NEEDED:
if (ipv4_config.no_pmtu_disc) {
- LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: fragmentation needed and DF set.\n",
+ LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: \
+ fragmentation needed and DF set.\n",
&iph->daddr);
} else {
info = ip_rt_frag_needed(net, iph,
- ntohs(icmph->un.frag.mtu),
+ ntohs(icmph->un.frag.mtu),
skb->dev);
if (!info)
goto out;
}
break;
case ICMP_SR_FAILED:
- LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: Source Route Failed.\n",
+ LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: \
+ Source Route Failed.\n",
&iph->daddr);
break;
default:
@@ -875,7 +879,7 @@ out_err:
*
* RFC1812 (4.3.3.9). A router MUST implement it.
* A router SHOULD have switch turning it on/off.
- * This switch MUST be ON by default.
+ * This switch MUST be ON by default.
*
* Gratuitous replies, zero-source replies are not implemented,
* that complies with RFC. DO NOT implement them!!! All the idea
@@ -1163,7 +1167,7 @@ static int __net_init icmp_sk_init(struct net *net)
net->ipv4.sysctl_icmp_ignore_bogus_error_responses = 1;
/*
- * Configurable global rate limit.
+ * Configurable global rate limit.
*
* ratelimit defines tokens/packet consumed for dst->rate_token
* bucket ratemask defines which icmp types are ratelimited by
@@ -1188,8 +1192,8 @@ fail:
}
static struct pernet_operations __net_initdata icmp_sk_ops = {
- .init = icmp_sk_init,
- .exit = icmp_sk_exit,
+ .init = icmp_sk_init,
+ .exit = icmp_sk_exit,
};
int __init icmp_init(void)
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] net: implement dev_disable_lro() hw_features compatibility
From: Ben Hutchings @ 2011-03-18 18:13 UTC (permalink / raw)
To: Michał Mirosław; +Cc: netdev, David S. Miller
In-Reply-To: <37d3c96bc52c87fcd4cdd39c9c852b1d2bbc249d.1300466356.git.mirq-linux@rere.qmqm.pl>
On Fri, 2011-03-18 at 18:42 +0100, Michał Mirosław wrote:
> Implement compatibility with new hw_features for dev_disable_lro().
Good point, but...
> This is a transition path - dev_disable_lro() should be later
> integrated into netdev_fix_features() after all drivers are converted.
>
> There's no point in exporting __ethtool_set_flags() as it and dev_disable_lro()
> are always built-in.
>
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---
>
> Patch is build-tested only, as I don't have any LRO-capable hardware.
> It might be prettier to move dev_disable_lro() to ethtool.c.
It *looks* right.
> net/core/dev.c | 20 ++++++++++++--------
> net/core/ethtool.c | 2 +-
> 2 files changed, 13 insertions(+), 9 deletions(-)
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 0b88eba..105e082 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1353,14 +1353,18 @@ EXPORT_SYMBOL(dev_close);
> */
> void dev_disable_lro(struct net_device *dev)
> {
> - if (dev->ethtool_ops && dev->ethtool_ops->get_flags &&
> - dev->ethtool_ops->set_flags) {
> - u32 flags = dev->ethtool_ops->get_flags(dev);
> - if (flags & ETH_FLAG_LRO) {
> - flags &= ~ETH_FLAG_LRO;
> - dev->ethtool_ops->set_flags(dev, flags);
> - }
> - }
> + extern int __ethtool_set_flags(struct net_device *, u32);
[...]
Local function declarations are a very bad idea, as they are not checked
against the function definition. Please declare the function in
<linux/ethtool.h>; that does not oblige us to export it.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH] net: ipv4: add IPPROTO_ICMP socket kind
From: Vasiliy Kulikov @ 2011-03-18 18:00 UTC (permalink / raw)
To: linux-kernel
Cc: netdev, Pavel Kankovsky, Solar Designer, Kees Cook, Dan Rosenberg,
Eugene Teo, Nelson Elhage, David S. Miller, Alexey Kuznetsov,
Pekka Savola, James Morris, Hideaki YOSHIFUJI, Patrick McHardy
This patch adds IPPROTO_ICMP socket kind. It makes it possible to send
ICMP_ECHO messages and receive the corresponding ICMP_ECHOREPLY messages
without any special privileges. In other words, the patch makes it
possible to implement setuid-less and CAP_NET_RAW-less /bin/ping. In
order not to increase the kernel's attack surface (in case of
vulnerabilities in the newly added code), the new functionality is
disabled by default, but is enabled at bootup by supporting Linux
distributions, optionally with restriction to a group or a group range
(see below).
Similar functionality is implemented in Mac OS X:
http://www.manpagez.com/man/4/icmp/
A new ping socket is created with
socket(PF_INET, SOCK_DGRAM, PROT_ICMP)
Message identifiers (octets 4-5 of ICMP header) are interpreted as local
ports. Addresses are stored in struct sockaddr_in. No port numbers are
reserved for privileged processes, port 0 is reserved for API ("let the
kernel pick a free number"). There is no notion of remote ports, remote
port numbers provided by the user (e.g. in connect()) are ignored.
Data sent and received include ICMP headers. This is deliberate to:
1) Avoid the need to transport headers values like sequence numbers by
other means
2) Make it easier to port existing programs using raw sockets.
ICMP headers given to send() are checked and sanitized. The type must be
ICMP_ECHO and the code must be zero (future extensions might relax this,
see below). The id is set to the number (local port) of the socket, the
checksum is always recomputed.
ICMP reply packets received from the network are demultiplexed according
to their id's, and are returned by recv() without any modifications.
IP header information and ICMP errors of those packets may be obtained
via ancillary data (IP_RECVTTL, IP_RETOPTS, and IP_RECVERR). ICMP source
quenches and redirects are reported as fake errors via the error queue
(IP_RECVERR); the next hop address for redirects is saved to ee_info (in
network order).
socket(2) is restricted to the group range specified in
"/proc/sys/net/ipv4/ping_group_range". It is "1 0" by default, meaning
that nobody (not even root) may create ping sockets. Setting it to "100
100" would grant permissions to the single group, "0 65535" would enable
it for the world.
The existing code might be (in the unlikely case anyone needs it)
extended rather easily to handle other similar pairs of ICMP messages
(Timestamp/Reply, Information Request/Reply, Address Mask Request/Reply
etc.).
Userspace ping util & patch for it:
http://openwall.info/wiki/segoon/ping
A revision of this patch (for RHEL5/OpenVZ kernels) is in use in
Owl-current, such as in the 2011/03/12 LiveCD ISOs:
http://mirrors.kernel.org/openwall/Owl/current/iso/
For Openwall GNU/*/Linux it is the last step on the road to the
setuid-less distro.
Initially this functionality was written by Pavel Kankovsky (CC'ed him)
for linux 2.4.32, but unfortunately it was never made public.
Reference to the previous discussion:
http://lwn.net/Articles/420801/
All ping options (-b, -p, -Q, -R, -s, -t, -T, -M, -I), are tested with
the patch.
Changes since RFCv2:
- fixed checksumming bug.
- CAP_NET_RAW may not create icmp sockets anymore.
Changes since RFCv1:
- minor cleanups.
- introduced sysctl'able group range to restrict socket(2).
Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
---
include/net/netns/ipv4.h | 2 +
include/net/ping.h | 69 ++++
net/ipv4/Kconfig | 21 +
net/ipv4/Makefile | 1 +
net/ipv4/af_inet.c | 36 ++
net/ipv4/icmp.c | 14 +-
net/ipv4/ping.c | 933 ++++++++++++++++++++++++++++++++++++++++++++
net/ipv4/sysctl_net_ipv4.c | 90 +++++
8 files changed, 1165 insertions(+), 1 deletions(-)
create mode 100644 include/net/ping.h
create mode 100644 net/ipv4/ping.c
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index d68c3f1..ff3bb61 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -55,6 +55,8 @@ struct netns_ipv4 {
int sysctl_rt_cache_rebuild_count;
int current_rt_cache_rebuild_count;
+ unsigned int sysctl_ping_group_range[2];
+
atomic_t rt_genid;
#ifdef CONFIG_IP_MROUTE
diff --git a/include/net/ping.h b/include/net/ping.h
new file mode 100644
index 0000000..32ad20a
--- /dev/null
+++ b/include/net/ping.h
@@ -0,0 +1,69 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Definitions for the "ping" module.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _PING_H
+#define _PING_H
+
+#include <net/netns/hash.h>
+
+#ifdef CONFIG_IP_PING_DEBUG
+#define ping_debug(fmt, x...) printk(KERN_INFO fmt, ## x)
+#else
+#define ping_debug(fmt, x...) do {} while (0)
+#endif
+
+/* PING_HTABLE_SIZE must be power of 2 */
+#define PING_HTABLE_SIZE 64
+#define PING_HTABLE_MASK (PING_HTABLE_SIZE-1)
+
+#define ping_portaddr_for_each_entry(__sk, node, list) \
+ hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
+
+/*
+ * gid_t is either uint or ushort. We want to pass it to
+ * proc_dointvec_minmax(), so it must not be larger than INT_MAX
+ */
+#define GID_T_MAX (((gid_t)~0U) >> 1)
+
+struct ping_table {
+ struct hlist_nulls_head hash[PING_HTABLE_SIZE];
+ rwlock_t lock;
+};
+
+struct ping_iter_state {
+ struct seq_net_private p;
+ int bucket;
+};
+
+extern struct proto ping_prot;
+
+
+#ifdef CONFIG_IP_PING
+#define icmp_echoreply ping_rcv
+#else
+#define icmp_echoreply icmp_discard
+#endif
+
+extern void ping_rcv(struct sk_buff *);
+extern void ping_err(struct sk_buff *, u32 info);
+
+extern void inet_get_ping_group_range_net(struct net *net, unsigned int *low, unsigned int *high);
+
+#ifdef CONFIG_PROC_FS
+extern int __init ping_proc_init(void);
+extern void ping_proc_exit(void);
+#endif
+
+void __init ping_init(void);
+
+
+#endif /* _PING_H */
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index a5a1050..cf64f35 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -14,6 +14,27 @@ config IP_MULTICAST
<file:Documentation/networking/multicast.txt>. For most people, it's
safe to say N.
+config IP_PING
+ bool "IP: ping socket"
+ depends on EXPERIMENTAL
+ help
+ This option introduces a new kind of sockets - "ping sockets".
+
+ A ping socket makes it possible to send ICMP Echo messages and receive
+ corresponding ICMP Echo Reply messages without any special privileges.
+ In other words, it makes is possible to implement setuid-less /bin/ping.
+
+ A new ping socket is created with socket(PF_INET, SOCK_DGRAM, PROT_ICMP).
+
+config IP_PING_DEBUG
+ bool "IP: ping socket debug output"
+ depends on IP_PING
+ default n
+ help
+ Enable the inclusion of debug code in the ICMP ping sockets.
+ Be aware that doing this will impact performance.
+ If unsure say N.
+
config IP_ADVANCED_ROUTER
bool "IP: advanced router"
---help---
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 4978d22..3a37479 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
obj-$(CONFIG_IP_MROUTE) += ipmr.o
+obj-$(CONFIG_IP_PING) += ping.o
obj-$(CONFIG_NET_IPIP) += ipip.o
obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
obj-$(CONFIG_NET_IPGRE) += ip_gre.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 45b89d7..a707d3e 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -105,6 +105,7 @@
#include <net/tcp.h>
#include <net/udp.h>
#include <net/udplite.h>
+#include <net/ping.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/raw.h>
@@ -1008,6 +1009,16 @@ static struct inet_protosw inetsw_array[] =
.flags = INET_PROTOSW_PERMANENT,
},
+#ifdef CONFIG_IP_PING
+ {
+ .type = SOCK_DGRAM,
+ .protocol = IPPROTO_ICMP,
+ .prot = &ping_prot,
+ .ops = &inet_dgram_ops,
+ .no_check = UDP_CSUM_DEFAULT,
+ .flags = INET_PROTOSW_REUSE,
+ },
+#endif
{
.type = SOCK_RAW,
@@ -1528,6 +1539,9 @@ static const struct net_protocol udp_protocol = {
static const struct net_protocol icmp_protocol = {
.handler = icmp_rcv,
+#ifdef CONFIG_IP_PING
+ .err_handler = ping_err,
+#endif
.no_policy = 1,
.netns_ok = 1,
};
@@ -1643,6 +1657,12 @@ static int __init inet_init(void)
if (rc)
goto out_unregister_udp_proto;
+#ifdef CONFIG_IP_PING
+ rc = proto_register(&ping_prot, 1);
+ if (rc)
+ goto out_unregister_raw_proto;
+#endif
+
/*
* Tell SOCKET that we are alive...
*/
@@ -1698,6 +1718,10 @@ static int __init inet_init(void)
/* Add UDP-Lite (RFC 3828) */
udplite4_register();
+#ifdef CONFIG_IP_PING
+ ping_init();
+#endif
+
/*
* Set the ICMP layer up
*/
@@ -1728,6 +1752,10 @@ static int __init inet_init(void)
rc = 0;
out:
return rc;
+#ifdef CONFIG_IP_PING
+out_unregister_raw_proto:
+ proto_unregister(&raw_prot);
+#endif
out_unregister_udp_proto:
proto_unregister(&udp_prot);
out_unregister_tcp_proto:
@@ -1752,11 +1780,19 @@ static int __init ipv4_proc_init(void)
goto out_tcp;
if (udp4_proc_init())
goto out_udp;
+#ifdef CONFIG_IP_PING
+ if (ping_proc_init())
+ goto out_ping;
+#endif
if (ip_misc_proc_init())
goto out_misc;
out:
return rc;
out_misc:
+#ifdef CONFIG_IP_PING
+ ping_proc_exit();
+out_ping:
+#endif
udp4_proc_exit();
out_udp:
tcp4_proc_exit();
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 4aa1b7f..7a52374 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -83,6 +83,7 @@
#include <net/tcp.h>
#include <net/udp.h>
#include <net/raw.h>
+#include <net/ping.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/errno.h>
@@ -798,6 +799,17 @@ static void icmp_redirect(struct sk_buff *skb)
iph->saddr, skb->dev);
break;
}
+
+#ifdef CONFIG_IP_PING
+ /* Ping wants to see redirects.
+ * Let's pretend they are errors of sorts... */
+ if (iph->protocol == IPPROTO_ICMP &&
+ iph->ihl >= 5 &&
+ pskb_may_pull(skb, (iph->ihl<<2)+8)) {
+ ping_err(skb, icmp_hdr(skb)->un.gateway);
+ }
+#endif
+
out:
return;
out_err:
@@ -1058,7 +1070,7 @@ error:
*/
static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
[ICMP_ECHOREPLY] = {
- .handler = icmp_discard,
+ .handler = icmp_echoreply,
},
[1] = {
.handler = icmp_discard,
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
new file mode 100644
index 0000000..16a4683
--- /dev/null
+++ b/net/ipv4/ping.c
@@ -0,0 +1,933 @@
+/*
+ * INET An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * "Ping" sockets
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Based on ipv4/udp.c code.
+ *
+ * Authors: Vasiliy Kulikov / Openwall (for Linux 2.6),
+ * Pavel Kankovsky (for Linux 2.4.32)
+ *
+ * Pavel gave all rights to bugs to Vasiliy,
+ * none of the bugs are Pavel's now.
+ *
+ */
+
+#include <asm/system.h>
+#include <linux/uaccess.h>
+#include <asm/ioctls.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <net/snmp.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/icmp.h>
+#include <net/protocol.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <net/sock.h>
+#include <net/ping.h>
+#include <net/icmp.h>
+#include <net/udp.h>
+#include <net/route.h>
+#include <net/inet_common.h>
+#include <net/checksum.h>
+
+
+struct ping_table ping_table __read_mostly;
+
+u16 ping_port_rover;
+
+static inline int ping_hashfn(struct net *net, unsigned num, unsigned mask)
+{
+ int res = (num + net_hash_mix(net)) & mask;
+ ping_debug("hash(%d) = %d\n", num, res);
+ return res;
+}
+
+static inline struct hlist_nulls_head *ping_hashslot(struct ping_table *table,
+ struct net *net, unsigned num)
+{
+ return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)];
+}
+
+static int ping_v4_get_port(struct sock *sk, unsigned short ident)
+{
+ struct hlist_nulls_node *node;
+ struct hlist_nulls_head *hlist;
+ struct inet_sock *isk, *isk2;
+ struct sock *sk2 = NULL;
+
+ isk = inet_sk(sk);
+ write_lock_bh(&ping_table.lock);
+ if (ident == 0) {
+ u32 i;
+ u16 result = ping_port_rover + 1;
+
+ for (i = 0; i < (1L << 16); i++, result++) {
+ if (!result)
+ result++; /* avoid zero */
+ hlist = ping_hashslot(&ping_table, sock_net(sk),
+ result);
+ ping_portaddr_for_each_entry(sk2, node, hlist) {
+ isk2 = inet_sk(sk2);
+
+ if (isk2->inet_num == result)
+ goto next_port;
+ }
+
+ /* found */
+ ping_port_rover = ident = result;
+ break;
+next_port:
+ ;
+ }
+ if (i >= (1L << 16))
+ goto fail;
+ } else {
+ hlist = ping_hashslot(&ping_table, sock_net(sk), ident);
+ ping_portaddr_for_each_entry(sk2, node, hlist) {
+ isk2 = inet_sk(sk2);
+
+ if ((isk2->inet_num == ident) &&
+ (sk2 != sk) &&
+ (!sk2->sk_reuse || !sk->sk_reuse))
+ goto fail;
+ }
+ }
+
+ ping_debug("found port/ident = %d\n", ident);
+ isk->inet_num = ident;
+ if (sk_unhashed(sk)) {
+ ping_debug("was not hashed\n");
+ sock_hold(sk);
+ hlist_nulls_add_head(&sk->sk_nulls_node, hlist);
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+ }
+ write_unlock_bh(&ping_table.lock);
+ return 0;
+
+fail:
+ write_unlock_bh(&ping_table.lock);
+ return 1;
+}
+
+static void ping_v4_hash(struct sock *sk)
+{
+ ping_debug("ping_v4_hash(sk->port=%u)\n", inet_sk(sk)->inet_num);
+ BUG(); /* "Please do not press this button again." */
+}
+
+static void ping_v4_unhash(struct sock *sk)
+{
+ struct inet_sock *isk = inet_sk(sk);
+ ping_debug("ping_v4_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ if (sk_hashed(sk)) {
+ struct hlist_nulls_head *hslot;
+
+ hslot = ping_hashslot(&ping_table, sock_net(sk), isk->inet_num);
+ write_lock_bh(&ping_table.lock);
+ hlist_nulls_del(&sk->sk_nulls_node);
+ sock_put(sk);
+ isk->inet_num = isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ write_unlock_bh(&ping_table.lock);
+ }
+}
+
+struct sock *ping_v4_lookup(struct net *net, u32 saddr, u32 daddr,
+ u16 ident, int dif)
+{
+ struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident);
+ struct sock *sk = NULL;
+ struct inet_sock *isk;
+ struct hlist_nulls_node *hnode;
+
+ ping_debug("try to find: num = %d, daddr = %ld, dif = %d\n",
+ (int)ident, (unsigned long)daddr, dif);
+ read_lock_bh(&ping_table.lock);
+
+ ping_portaddr_for_each_entry(sk, hnode, hslot) {
+ isk = inet_sk(sk);
+
+ ping_debug("found: %p: num = %d, daddr = %ld, dif = %d\n", sk,
+ (int)isk->inet_num, (unsigned long)isk->inet_rcv_saddr,
+ sk->sk_bound_dev_if);
+
+ ping_debug("iterate\n");
+ if (isk->inet_num != ident)
+ continue;
+ if (isk->inet_rcv_saddr && isk->inet_rcv_saddr != daddr)
+ continue;
+ if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
+ continue;
+
+ sock_hold(sk);
+ goto exit;
+ }
+
+ sk = NULL;
+exit:
+ read_unlock_bh(&ping_table.lock);
+
+ return sk;
+}
+
+static int ping_init_sock(struct sock *sk)
+{
+ struct net *net = sock_net(sk);
+ gid_t group = current_egid();
+ gid_t range[2];
+ struct group_info *group_info = get_current_groups();
+ int i, j, count = group_info->ngroups;
+
+ inet_get_ping_group_range_net(net, range, range+1);
+ if (range[0] <= group && group <= range[1])
+ return 0;
+
+ for (i = 0; i < group_info->nblocks; i++) {
+ int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
+
+ for (j = 0; j < cp_count; j++) {
+ group = group_info->blocks[i][j];
+ if (range[0] <= group && group <= range[1])
+ return 0;
+ }
+
+ count -= cp_count;
+ }
+
+ return -EACCES;
+}
+
+static void ping_close(struct sock *sk, long timeout)
+{
+ ping_debug("ping_close(sk=%p,sk->num=%u)\n",
+ inet_sk(sk), inet_sk(sk)->inet_num);
+ ping_debug("isk->refcnt = %d\n", sk->sk_refcnt.counter);
+
+ sk_common_release(sk);
+}
+
+/*
+ * We need our own bind because there are no privileged id's == local ports.
+ * Moreover, we don't allow binding to multi- and broadcast addresses.
+ */
+
+static int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+{
+ struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
+ struct inet_sock *isk = inet_sk(sk);
+ unsigned short snum;
+ int chk_addr_ret;
+ int err;
+
+ if (addr_len < sizeof(struct sockaddr_in))
+ return -EINVAL;
+
+ ping_debug("ping_v4_bind(sk=%p,sa_addr=%08x,sa_port=%d)\n",
+ sk, addr->sin_addr.s_addr, ntohs(addr->sin_port));
+
+ chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
+ if (addr->sin_addr.s_addr == INADDR_ANY)
+ chk_addr_ret = RTN_LOCAL;
+
+ if ((sysctl_ip_nonlocal_bind == 0 &&
+ isk->freebind == 0 && isk->transparent == 0 &&
+ chk_addr_ret != RTN_LOCAL) ||
+ chk_addr_ret == RTN_MULTICAST ||
+ chk_addr_ret == RTN_BROADCAST)
+ return -EADDRNOTAVAIL;
+
+ lock_sock(sk);
+
+ err = -EINVAL;
+ if (isk->inet_num != 0)
+ goto out;
+
+ err = -EADDRINUSE;
+ isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
+ snum = ntohs(addr->sin_port);
+ if (ping_v4_get_port(sk, snum) != 0) {
+ isk->inet_saddr = isk->inet_rcv_saddr = 0;
+ goto out;
+ }
+
+ ping_debug("after bind(): num = %d, daddr = %ld, dif = %d\n",
+ (int)isk->inet_num,
+ (unsigned long) isk->inet_rcv_saddr,
+ (int)sk->sk_bound_dev_if);
+
+ err = 0;
+ if (isk->inet_rcv_saddr)
+ sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
+ if (snum)
+ sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
+ isk->inet_sport = htons(isk->inet_num);
+ isk->inet_daddr = 0;
+ isk->inet_dport = 0;
+ sk_dst_reset(sk);
+out:
+ release_sock(sk);
+ ping_debug("ping_v4_bind -> %d\n", err);
+ return err;
+}
+
+/*
+ * Is this a supported type of ICMP message?
+ */
+
+static inline int ping_supported(int type, int code)
+{
+ if (type == ICMP_ECHO && code == 0)
+ return 1;
+ return 0;
+}
+
+/*
+ * This routine is called by the ICMP module when it gets some
+ * sort of error condition.
+ */
+
+static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
+
+void ping_err(struct sk_buff *skb, u32 info)
+{
+ struct iphdr *iph = (struct iphdr *)skb->data;
+ struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
+ struct inet_sock *inet_sock;
+ int type = icmph->type;
+ int code = icmph->code;
+ struct net *net = dev_net(skb->dev);
+ struct sock *sk;
+ int harderr;
+ int err;
+
+ /* We assume the packet has already been checked by icmp_unreach */
+
+ if (!ping_supported(icmph->type, icmph->code))
+ return;
+
+ ping_debug("ping_err(type=%04x,code=%04x,id=%04x,seq=%04x)\n", type,
+ code, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence));
+
+ sk = ping_v4_lookup(net, iph->daddr, iph->saddr,
+ ntohs(icmph->un.echo.id), skb->dev->ifindex);
+ if (sk == NULL) {
+ ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
+ ping_debug("no socket, dropping\n");
+ return; /* No socket for error */
+ }
+ ping_debug("err on socket %p\n", sk);
+
+ err = 0;
+ harderr = 0;
+ inet_sock = inet_sk(sk);
+
+ switch (type) {
+ default:
+ case ICMP_TIME_EXCEEDED:
+ err = EHOSTUNREACH;
+ break;
+ case ICMP_SOURCE_QUENCH:
+ /* This is not a real error but ping wants to see it.
+ * Report it with some fake errno. */
+ err = EREMOTEIO;
+ break;
+ case ICMP_PARAMETERPROB:
+ err = EPROTO;
+ harderr = 1;
+ break;
+ case ICMP_DEST_UNREACH:
+ if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
+ if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) {
+ err = EMSGSIZE;
+ harderr = 1;
+ break;
+ }
+ goto out;
+ }
+ err = EHOSTUNREACH;
+ if (code <= NR_ICMP_UNREACH) {
+ harderr = icmp_err_convert[code].fatal;
+ err = icmp_err_convert[code].errno;
+ }
+ break;
+ case ICMP_REDIRECT:
+ /* See ICMP_SOURCE_QUENCH */
+ err = EREMOTEIO;
+ break;
+ }
+
+ /*
+ * RFC1122: OK. Passes ICMP errors back to application, as per
+ * 4.1.3.3.
+ */
+ if (!inet_sock->recverr) {
+ if (!harderr || sk->sk_state != TCP_ESTABLISHED)
+ goto out;
+ } else {
+ ip_icmp_error(sk, skb, err, 0 /* no remote port */,
+ info, (u8 *)icmph);
+ }
+ sk->sk_err = err;
+ sk->sk_error_report(sk);
+out:
+ sock_put(sk);
+}
+
+/*
+ * Copy and checksum an ICMP Echo packet from user space into a buffer.
+ */
+
+struct pingfakehdr {
+ struct icmphdr icmph;
+ struct iovec *iov;
+ u32 wcheck;
+};
+
+static int ping_getfrag(void *from, char * to,
+ int offset, int fraglen, int odd, struct sk_buff *skb)
+{
+ struct pingfakehdr *pfh = (struct pingfakehdr *)from;
+
+ if (offset == 0) {
+ if (fraglen < sizeof(struct icmphdr))
+ BUG();
+ if (csum_partial_copy_fromiovecend(to + sizeof(struct icmphdr),
+ pfh->iov, 0, fraglen - sizeof(struct icmphdr),
+ &pfh->wcheck))
+ return -EFAULT;
+
+ return 0;
+ }
+ if (offset < sizeof(struct icmphdr))
+ BUG();
+ if (csum_partial_copy_fromiovecend
+ (to, pfh->iov, offset - sizeof(struct icmphdr),
+ fraglen, &pfh->wcheck))
+ return -EFAULT;
+ return 0;
+}
+
+static int ping_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh)
+{
+ struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
+
+ pfh->wcheck = csum_partial((char *)&pfh->icmph,
+ sizeof(struct icmphdr), pfh->wcheck);
+ pfh->icmph.checksum = csum_fold(pfh->wcheck);
+ memcpy(icmp_hdr(skb), &pfh->icmph, sizeof(struct icmphdr));
+ skb->ip_summed = CHECKSUM_NONE;
+ return ip_push_pending_frames(sk);
+}
+
+int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len)
+{
+ struct inet_sock *isk = inet_sk(sk);
+ struct ipcm_cookie ipc;
+ struct icmphdr user_icmph;
+ struct pingfakehdr pfh;
+ struct rtable *rt = NULL;
+ int free = 0;
+ u32 saddr, daddr;
+ u8 tos;
+ int err;
+
+ ping_debug("ping_sendmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
+
+
+ if (len > 0xFFFF)
+ return -EMSGSIZE;
+
+ /*
+ * Check the flags.
+ */
+
+ /* Mirror BSD error message compatibility */
+ if (msg->msg_flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+ /*
+ * Fetch the ICMP header provided by the userland.
+ * iovec is modified!
+ */
+
+ if (memcpy_fromiovec((u8 *)&user_icmph, msg->msg_iov,
+ sizeof(struct icmphdr)))
+ return -EFAULT;
+ if (!ping_supported(user_icmph.type, user_icmph.code))
+ return -EINVAL;
+
+ /*
+ * Get and verify the address.
+ */
+
+ if (msg->msg_name) {
+ struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name;
+ if (msg->msg_namelen < sizeof(*usin))
+ return -EINVAL;
+ if (usin->sin_family != AF_INET)
+ return -EINVAL;
+ daddr = usin->sin_addr.s_addr;
+ /* no remote port */
+ } else {
+ if (sk->sk_state != TCP_ESTABLISHED)
+ return -EDESTADDRREQ;
+ daddr = isk->inet_daddr;
+ /* no remote port */
+ }
+
+ ipc.addr = isk->inet_saddr;
+ ipc.opt = NULL;
+ ipc.oif = sk->sk_bound_dev_if;
+
+ if (msg->msg_controllen) {
+ err = ip_cmsg_send(sock_net(sk), msg, &ipc);
+ if (err)
+ return err;
+ if (ipc.opt)
+ free = 1;
+ }
+ if (!ipc.opt)
+ ipc.opt = isk->opt;
+
+ saddr = ipc.addr;
+ ipc.addr = daddr;
+
+ if (ipc.opt && ipc.opt->srr) {
+ if (!daddr)
+ return -EINVAL;
+ daddr = ipc.opt->faddr;
+ }
+ tos = RT_TOS(isk->tos);
+ if (sock_flag(sk, SOCK_LOCALROUTE) ||
+ (msg->msg_flags&MSG_DONTROUTE) ||
+ (ipc.opt && ipc.opt->is_strictroute)) {
+ tos |= RTO_ONLINK;
+ }
+
+ if (ipv4_is_multicast(daddr)) {
+ if (!ipc.oif)
+ ipc.oif = isk->mc_index;
+ if (!saddr)
+ saddr = isk->mc_addr;
+ }
+
+ {
+ struct flowi fl = { .oif = ipc.oif,
+ .mark = sk->sk_mark,
+ .nl_u = { .ip4_u = {
+ .daddr = daddr,
+ .saddr = saddr,
+ .tos = tos } },
+ .proto = IPPROTO_ICMP,
+ .flags = inet_sk_flowi_flags(sk),
+ };
+
+ struct net *net = sock_net(sk);
+
+ security_sk_classify_flow(sk, &fl);
+ err = ip_route_output_flow(net, &rt, &fl, sk, 1);
+ if (err) {
+ if (err == -ENETUNREACH)
+ IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
+ goto out;
+ }
+
+ err = -EACCES;
+ if ((rt->rt_flags & RTCF_BROADCAST) &&
+ !sock_flag(sk, SOCK_BROADCAST))
+ goto out;
+ }
+
+ if (msg->msg_flags & MSG_CONFIRM)
+ goto do_confirm;
+back_from_confirm:
+
+ if (!ipc.addr)
+ ipc.addr = rt->rt_dst;
+
+ lock_sock(sk);
+
+ pfh.icmph.type = user_icmph.type; /* already checked */
+ pfh.icmph.code = user_icmph.code; /* dtto */
+ pfh.icmph.checksum = 0;
+ pfh.icmph.un.echo.id = isk->inet_sport;
+ pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
+ pfh.iov = msg->msg_iov;
+ pfh.wcheck = 0;
+
+ err = ip_append_data(sk, ping_getfrag, &pfh, len,
+ 0, &ipc, &rt,
+ msg->msg_flags);
+ if (err)
+ ip_flush_pending_frames(sk);
+ else
+ err = ping_push_pending_frames(sk, &pfh);
+ release_sock(sk);
+
+out:
+ ip_rt_put(rt);
+ if (free)
+ kfree(ipc.opt);
+ if (!err) {
+ icmp_out_count(sock_net(sk), user_icmph.type);
+ return len;
+ }
+ return err;
+
+do_confirm:
+ dst_confirm(&rt->dst);
+ if (!(msg->msg_flags & MSG_PROBE) || len)
+ goto back_from_confirm;
+ err = 0;
+ goto out;
+}
+
+/*
+ * IOCTL requests applicable to the UDP^H^H^HICMP protocol
+ */
+
+int ping_ioctl(struct sock *sk, int cmd, unsigned long arg)
+{
+ ping_debug("ping_ioctl(sk=%p,sk->num=%u,cmd=%d,arg=%lu)\n",
+ inet_sk(sk), inet_sk(sk)->inet_num, cmd, arg);
+ switch (cmd) {
+ case SIOCOUTQ:
+ case SIOCINQ:
+ return udp_ioctl(sk, cmd, arg);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+ size_t len, int noblock, int flags, int *addr_len)
+{
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
+ struct sk_buff *skb;
+ int copied, err;
+
+ ping_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
+
+ if (flags & MSG_OOB)
+ goto out;
+
+ if (addr_len)
+ *addr_len = sizeof(*sin);
+
+ if (flags & MSG_ERRQUEUE)
+ return ip_recv_error(sk, msg, len);
+
+ skb = skb_recv_datagram(sk, flags, noblock, &err);
+ if (!skb)
+ goto out;
+
+ copied = skb->len;
+ if (copied > len) {
+ msg->msg_flags |= MSG_TRUNC;
+ copied = len;
+ }
+
+ /* Don't bother checking the checksum */
+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+ if (err)
+ goto done;
+
+ sock_recv_timestamp(msg, sk, skb);
+
+ /* Copy the address. */
+ if (sin) {
+ sin->sin_family = AF_INET;
+ sin->sin_port = 0 /* skb->h.uh->source */;
+ sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+ }
+ if (isk->cmsg_flags)
+ ip_cmsg_recv(msg, skb);
+ err = copied;
+
+done:
+ skb_free_datagram(sk, skb);
+out:
+ ping_debug("ping_recvmsg -> %d\n", err);
+ return err;
+}
+
+static int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+ ping_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
+ inet_sk(sk), inet_sk(sk)->inet_num, skb);
+ if (sock_queue_rcv_skb(sk, skb) < 0) {
+ ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_INERRORS);
+ kfree_skb(skb);
+ ping_debug("ping_queue_rcv_skb -> failed\n");
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * All we need to do is get the socket.
+ */
+
+void ping_rcv(struct sk_buff *skb)
+{
+ struct sock *sk;
+ struct net *net = dev_net(skb->dev);
+ struct iphdr *iph = ip_hdr(skb);
+ struct icmphdr *icmph = icmp_hdr(skb);
+ u32 saddr = iph->saddr;
+ u32 daddr = iph->daddr;
+
+ /* We assume the packet has already been checked by icmp_rcv */
+
+ ping_debug("ping_rcv(skb=%p,id=%04x,seq=%04x)\n",
+ skb, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence));
+
+ /* Push ICMP header back */
+ skb_push(skb, skb->data - (u8 *)icmph);
+
+ sk = ping_v4_lookup(net, saddr, daddr, ntohs(icmph->un.echo.id),
+ skb->dev->ifindex);
+ if (sk != NULL) {
+ ping_debug("rcv on socket %p\n", sk);
+ ping_queue_rcv_skb(sk, skb_get(skb));
+ sock_put(sk);
+ return;
+ }
+ ping_debug("no socket, dropping\n");
+
+ /* We're called from icmp_rcv(). kfree_skb() is done there. */
+}
+
+struct proto ping_prot = {
+ .name = "PING",
+ .owner = THIS_MODULE,
+ .init = ping_init_sock,
+ .close = ping_close,
+ .connect = ip4_datagram_connect,
+ .disconnect = udp_disconnect,
+ .ioctl = ping_ioctl,
+ .setsockopt = ip_setsockopt,
+ .getsockopt = ip_getsockopt,
+ .sendmsg = ping_sendmsg,
+ .recvmsg = ping_recvmsg,
+ .bind = ping_bind,
+ .backlog_rcv = ping_queue_rcv_skb,
+ .hash = ping_v4_hash,
+ .unhash = ping_v4_unhash,
+ .get_port = ping_v4_get_port,
+ .obj_size = sizeof(struct inet_sock),
+};
+EXPORT_SYMBOL(ping_prot);
+
+#ifdef CONFIG_PROC_FS
+
+static struct sock *ping_get_first(struct seq_file *seq, int start)
+{
+ struct sock *sk;
+ struct ping_iter_state *state = seq->private;
+ struct net *net = seq_file_net(seq);
+
+ for (state->bucket = start; state->bucket < PING_HTABLE_SIZE;
+ ++state->bucket) {
+ struct hlist_nulls_node *node;
+ struct hlist_nulls_head *hslot = &ping_table.hash[state->bucket];
+
+ if (hlist_nulls_empty(hslot))
+ continue;
+
+ sk_nulls_for_each(sk, node, hslot) {
+ if (net_eq(sock_net(sk), net))
+ goto found;
+ }
+ }
+ sk = NULL;
+found:
+ return sk;
+}
+
+static struct sock *ping_get_next(struct seq_file *seq, struct sock *sk)
+{
+ struct ping_iter_state *state = seq->private;
+ struct net *net = seq_file_net(seq);
+
+ do {
+ sk = sk_nulls_next(sk);
+ } while (sk && (!net_eq(sock_net(sk), net)));
+
+ if (!sk)
+ return ping_get_first(seq, state->bucket + 1);
+ return sk;
+}
+
+static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct sock *sk = ping_get_first(seq, 0);
+
+ if (sk)
+ while (pos && (sk = ping_get_next(seq, sk)) != NULL)
+ --pos;
+ return pos ? NULL : sk;
+}
+
+static void *ping_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ struct ping_iter_state *state = seq->private;
+ state->bucket = 0;
+
+ read_lock_bh(&ping_table.lock);
+
+ return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
+}
+
+static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock *sk;
+
+ if (v == SEQ_START_TOKEN)
+ sk = ping_get_idx(seq, 0);
+ else
+ sk = ping_get_next(seq, v);
+
+ ++*pos;
+ return sk;
+}
+
+static void ping_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock_bh(&ping_table.lock);
+}
+
+static void ping_format_sock(struct sock *sp, struct seq_file *f,
+ int bucket, int *len)
+{
+ struct inet_sock *inet = inet_sk(sp);
+ __be32 dest = inet->inet_daddr;
+ __be32 src = inet->inet_rcv_saddr;
+ __u16 destp = ntohs(inet->inet_dport);
+ __u16 srcp = ntohs(inet->inet_sport);
+
+ seq_printf(f, "%5d: %08X:%04X %08X:%04X"
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n",
+ bucket, src, srcp, dest, destp, sp->sk_state,
+ sk_wmem_alloc_get(sp),
+ sk_rmem_alloc_get(sp),
+ 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
+ atomic_read(&sp->sk_refcnt), sp,
+ atomic_read(&sp->sk_drops), len);
+}
+
+static int ping_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN)
+ seq_printf(seq, "%-127s\n",
+ " sl local_address rem_address st tx_queue "
+ "rx_queue tr tm->when retrnsmt uid timeout "
+ "inode ref pointer drops");
+ else {
+ struct ping_iter_state *state = seq->private;
+ int len;
+
+ ping_format_sock(v, seq, state->bucket, &len);
+ seq_printf(seq, "%*s\n", 127 - len, "");
+ }
+ return 0;
+}
+
+static const struct seq_operations ping_seq_ops = {
+ .show = ping_seq_show,
+ .start = ping_seq_start,
+ .next = ping_seq_next,
+ .stop = ping_seq_stop,
+};
+
+static int ping_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open_net(inode, file, &ping_seq_ops,
+ sizeof(struct ping_iter_state));
+}
+
+static const struct file_operations ping_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = ping_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_net,
+};
+
+static const char ping_proc_name[] = "icmp";
+
+static int ping_proc_register(struct net *net)
+{
+ struct proc_dir_entry *p;
+ int rc = 0;
+
+ p = proc_create_data(ping_proc_name, S_IRUGO, net->proc_net,
+ &ping_seq_fops, NULL);
+ if (!p)
+ rc = -ENOMEM;
+ return rc;
+}
+
+static void ping_proc_unregister(struct net *net)
+{
+ proc_net_remove(net, ping_proc_name);
+}
+
+
+static int __net_init ping_proc_init_net(struct net *net)
+{
+ return ping_proc_register(net);
+}
+
+static void __net_exit ping_proc_exit_net(struct net *net)
+{
+ ping_proc_unregister(net);
+}
+
+static struct pernet_operations ping_net_ops = {
+ .init = ping_proc_init_net,
+ .exit = ping_proc_exit_net,
+};
+
+int __init ping_proc_init(void)
+{
+ return register_pernet_subsys(&ping_net_ops);
+}
+
+void ping_proc_exit(void)
+{
+ unregister_pernet_subsys(&ping_net_ops);
+}
+
+#endif
+
+void __init ping_init(void)
+{
+ int i;
+
+ for (i = 0; i < PING_HTABLE_SIZE; i++)
+ INIT_HLIST_NULLS_HEAD(&ping_table.hash[i], i);
+ rwlock_init(&ping_table.lock);
+}
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 1a45665..9b406d7 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -13,6 +13,7 @@
#include <linux/seqlock.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/nsproxy.h>
#include <net/snmp.h>
#include <net/icmp.h>
#include <net/ip.h>
@@ -21,6 +22,7 @@
#include <net/udp.h>
#include <net/cipso_ipv4.h>
#include <net/inet_frag.h>
+#include <net/ping.h>
static int zero;
static int tcp_retr1_max = 255;
@@ -30,6 +32,10 @@ static int tcp_adv_win_scale_min = -31;
static int tcp_adv_win_scale_max = 31;
static int ip_ttl_min = 1;
static int ip_ttl_max = 255;
+#ifdef CONFIG_IP_PING
+static int ip_ping_group_range_min[] = { 0, 0 };
+static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX };
+#endif
/* Update system visible IP port range */
static void set_local_port_range(int range[2])
@@ -68,6 +74,67 @@ static int ipv4_local_port_range(ctl_table *table, int write,
return ret;
}
+#ifdef CONFIG_IP_PING
+
+void inet_get_ping_group_range_net(struct net *net, gid_t *low, gid_t *high)
+{
+ gid_t *data = net->ipv4.sysctl_ping_group_range;
+ unsigned seq;
+ do {
+ seq = read_seqbegin(&sysctl_local_ports.lock);
+
+ *low = data[0];
+ *high = data[1];
+ } while (read_seqretry(&sysctl_local_ports.lock, seq));
+}
+
+void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high)
+{
+ gid_t *data = table->data;
+ unsigned seq;
+ do {
+ seq = read_seqbegin(&sysctl_local_ports.lock);
+
+ *low = data[0];
+ *high = data[1];
+ } while (read_seqretry(&sysctl_local_ports.lock, seq));
+}
+
+/* Update system visible IP port range */
+static void set_ping_group_range(struct ctl_table *table, int range[2])
+{
+ gid_t *data = table->data;
+ write_seqlock(&sysctl_local_ports.lock);
+ data[0] = range[0];
+ data[1] = range[1];
+ write_sequnlock(&sysctl_local_ports.lock);
+}
+
+/* Validate changes from /proc interface. */
+static int ipv4_ping_group_range(ctl_table *table, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret;
+ gid_t range[2];
+ ctl_table tmp = {
+ .data = &range,
+ .maxlen = sizeof(range),
+ .mode = table->mode,
+ .extra1 = &ip_ping_group_range_min,
+ .extra2 = &ip_ping_group_range_max,
+ };
+
+ inet_get_ping_group_range_table(table, range, range + 1);
+ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+ if (write && ret == 0)
+ set_ping_group_range(table, range);
+
+ return ret;
+}
+#endif
+
static int proc_tcp_congestion_control(ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -680,6 +747,15 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec
},
+#ifdef CONFIG_IP_PING
+ {
+ .procname = "ping_group_range",
+ .data = &init_net.ipv4.sysctl_ping_group_range,
+ .maxlen = sizeof(init_net.ipv4.sysctl_ping_group_range),
+ .mode = 0644,
+ .proc_handler = ipv4_ping_group_range,
+ },
+#endif
{ }
};
@@ -714,8 +790,22 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
&net->ipv4.sysctl_icmp_ratemask;
table[6].data =
&net->ipv4.sysctl_rt_cache_rebuild_count;
+#ifdef CONFIG_IP_PING
+ table[7].data =
+ &net->ipv4.sysctl_ping_group_range;
+#endif
+
}
+#ifdef CONFIG_IP_PING
+ /*
+ * Sane defaults - nobody may create ping sockets.
+ * Boot scripts should set this to disto-specific group.
+ */
+ net->ipv4.sysctl_ping_group_range[0] = 1;
+ net->ipv4.sysctl_ping_group_range[1] = 0;
+#endif
+
net->ipv4.sysctl_rt_cache_rebuild_count = 4;
net->ipv4.ipv4_hdr = register_net_sysctl_table(net,
--
1.7.0.4
^ permalink raw reply related
* [PATCH] net: implement dev_disable_lro() hw_features compatibility
From: Michał Mirosław @ 2011-03-18 17:42 UTC (permalink / raw)
To: netdev; +Cc: Ben Hutchings, David S. Miller
Implement compatibility with new hw_features for dev_disable_lro().
This is a transition path - dev_disable_lro() should be later
integrated into netdev_fix_features() after all drivers are converted.
There's no point in exporting __ethtool_set_flags() as it and dev_disable_lro()
are always built-in.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
Patch is build-tested only, as I don't have any LRO-capable hardware.
It might be prettier to move dev_disable_lro() to ethtool.c.
net/core/dev.c | 20 ++++++++++++--------
net/core/ethtool.c | 2 +-
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 0b88eba..105e082 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1353,14 +1353,18 @@ EXPORT_SYMBOL(dev_close);
*/
void dev_disable_lro(struct net_device *dev)
{
- if (dev->ethtool_ops && dev->ethtool_ops->get_flags &&
- dev->ethtool_ops->set_flags) {
- u32 flags = dev->ethtool_ops->get_flags(dev);
- if (flags & ETH_FLAG_LRO) {
- flags &= ~ETH_FLAG_LRO;
- dev->ethtool_ops->set_flags(dev, flags);
- }
- }
+ extern int __ethtool_set_flags(struct net_device *, u32);
+ u32 flags;
+
+ if (dev->ethtool_ops && dev->ethtool_ops->get_flags)
+ flags = dev->ethtool_ops->get_flags(dev);
+ else
+ flags = ethtool_op_get_flags(dev);
+
+ if (!(flags & ETH_FLAG_LRO))
+ return;
+
+ __ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO);
WARN_ON(dev->features & NETIF_F_LRO);
}
EXPORT_SYMBOL(dev_disable_lro);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index c1a71bb..7371177 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -513,7 +513,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
}
}
-static int __ethtool_set_flags(struct net_device *dev, u32 data)
+int __ethtool_set_flags(struct net_device *dev, u32 data)
{
u32 changed;
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/2] netfilter: get rid of atomic ops in fast path
From: Eric Dumazet @ 2011-03-18 17:07 UTC (permalink / raw)
To: Patrick McHardy, David Miller
Cc: Netfilter Development Mailinglist, netdev, Jan Engelhardt
We currently use a percpu spinlock to 'protect' rule bytes/packets
counters, after various attempts to use RCU instead.
Lately we added a seqlock so that get_counters() can run without
blocking BH or 'writers'. But we really use the seqcount in it.
Spinlock itself is only locked by the current/owner cpu, so we can
remove it completely.
This cleanups api, using correct 'writer' vs 'reader' semantic.
At replace time, the get_counters() call makes sure all cpus are done
using the old table.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Jan Engelhardt <jengelh@medozas.de>
Cc: Patrick McHardy <kaber@trash.net>
---
include/linux/netfilter/x_tables.h | 96 +++++++++++----------------
net/ipv4/netfilter/arp_tables.c | 18 +++--
net/ipv4/netfilter/ip_tables.c | 28 +++----
net/ipv6/netfilter/ip6_tables.c | 19 +++--
net/netfilter/x_tables.c | 9 --
5 files changed, 80 insertions(+), 90 deletions(-)
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 3721952..32cddf7 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -456,72 +456,60 @@ extern void xt_proto_fini(struct net *net, u_int8_t af);
extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
extern void xt_free_table_info(struct xt_table_info *info);
-/*
- * Per-CPU spinlock associated with per-cpu table entries, and
- * with a counter for the "reading" side that allows a recursive
- * reader to avoid taking the lock and deadlocking.
- *
- * "reading" is used by ip/arp/ip6 tables rule processing which runs per-cpu.
- * It needs to ensure that the rules are not being changed while the packet
- * is being processed. In some cases, the read lock will be acquired
- * twice on the same CPU; this is okay because of the count.
- *
- * "writing" is used when reading counters.
- * During replace any readers that are using the old tables have to complete
- * before freeing the old table. This is handled by the write locking
- * necessary for reading the counters.
+/**
+ * xt_recseq - recursive seqcount for netfilter use
+ *
+ * Packet processing changes the seqcount only if no recursion happened
+ * get_counters() can use read_seqcount_begin()/read_seqcount_retry(),
+ * because we use the normal seqcount convention :
+ * Low order bit set to 1 if a writer is active.
*/
-struct xt_info_lock {
- seqlock_t lock;
- unsigned char readers;
-};
-DECLARE_PER_CPU(struct xt_info_lock, xt_info_locks);
+DECLARE_PER_CPU(seqcount_t, xt_recseq);
-/*
- * Note: we need to ensure that preemption is disabled before acquiring
- * the per-cpu-variable, so we do it as a two step process rather than
- * using "spin_lock_bh()".
- *
- * We _also_ need to disable bottom half processing before updating our
- * nesting count, to make sure that the only kind of re-entrancy is this
- * code being called by itself: since the count+lock is not an atomic
- * operation, we can allow no races.
+/**
+ * xt_write_recseq_begin - start of a write section
*
- * _Only_ that special combination of being per-cpu and never getting
- * re-entered asynchronously means that the count is safe.
+ * Begin packet processing : all readers must wait the end
+ * 1) Must be called with preemption disabled
+ * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add())
+ * Returns :
+ * 1 if no recursion on this cpu
+ * 0 if recursion detected
*/
-static inline void xt_info_rdlock_bh(void)
+static inline unsigned int xt_write_recseq_begin(void)
{
- struct xt_info_lock *lock;
+ unsigned int addend;
- local_bh_disable();
- lock = &__get_cpu_var(xt_info_locks);
- if (likely(!lock->readers++))
- write_seqlock(&lock->lock);
-}
+ /*
+ * Low order bit of sequence is set if we already
+ * called xt_write_recseq_begin().
+ */
+ addend = (__this_cpu_read(xt_recseq.sequence) + 1) & 1;
-static inline void xt_info_rdunlock_bh(void)
-{
- struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks);
+ /*
+ * This is kind of a write_seqcount_begin(), but addend is 0 or 1
+ * We dont check addend value to avoid a test and conditional jump,
+ * since addend is most likely 1
+ */
+ __this_cpu_add(xt_recseq.sequence, addend);
+ smp_wmb();
- if (likely(!--lock->readers))
- write_sequnlock(&lock->lock);
- local_bh_enable();
+ return addend;
}
-/*
- * The "writer" side needs to get exclusive access to the lock,
- * regardless of readers. This must be called with bottom half
- * processing (and thus also preemption) disabled.
+/**
+ * xt_write_recseq_end - end of a write section
+ * @addend: return value from previous xt_write_recseq_begin()
+ *
+ * End packet processing : all readers can proceed
+ * 1) Must be called with preemption disabled
+ * 2) softirqs must be disabled too (or we should use irqsafe_cpu_add())
*/
-static inline void xt_info_wrlock(unsigned int cpu)
-{
- write_seqlock(&per_cpu(xt_info_locks, cpu).lock);
-}
-
-static inline void xt_info_wrunlock(unsigned int cpu)
+static inline void xt_write_recseq_end(unsigned int addend)
{
- write_sequnlock(&per_cpu(xt_info_locks, cpu).lock);
+ /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */
+ smp_wmb();
+ __this_cpu_add(xt_recseq.sequence, addend);
}
/*
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 4b5d457..2ea7433 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -260,6 +260,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
void *table_base;
const struct xt_table_info *private;
struct xt_action_param acpar;
+ unsigned int addend;
if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
return NF_DROP;
@@ -267,7 +268,8 @@ unsigned int arpt_do_table(struct sk_buff *skb,
indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname;
- xt_info_rdlock_bh();
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
private = table->private;
table_base = private->entries[smp_processor_id()];
@@ -338,7 +340,8 @@ unsigned int arpt_do_table(struct sk_buff *skb,
/* Verdict */
break;
} while (!acpar.hotdrop);
- xt_info_rdunlock_bh();
+ xt_write_recseq_end(addend);
+ local_bh_enable();
if (acpar.hotdrop)
return NF_DROP;
@@ -712,7 +715,7 @@ static void get_counters(const struct xt_table_info *t,
unsigned int i;
for_each_possible_cpu(cpu) {
- seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
+ seqcount_t *s = &per_cpu(xt_recseq, cpu);
i = 0;
xt_entry_foreach(iter, t->entries[cpu], t->size) {
@@ -720,10 +723,10 @@ static void get_counters(const struct xt_table_info *t,
unsigned int start;
do {
- start = read_seqbegin(lock);
+ start = read_seqcount_begin(s);
bcnt = iter->counters.bcnt;
pcnt = iter->counters.pcnt;
- } while (read_seqretry(lock, start));
+ } while (read_seqcount_retry(s, start));
ADD_COUNTER(counters[i], bcnt, pcnt);
++i;
@@ -1115,6 +1118,7 @@ static int do_add_counters(struct net *net, const void __user *user,
int ret = 0;
void *loc_cpu_entry;
struct arpt_entry *iter;
+ unsigned int addend;
#ifdef CONFIG_COMPAT
struct compat_xt_counters_info compat_tmp;
@@ -1171,12 +1175,12 @@ static int do_add_counters(struct net *net, const void __user *user,
/* Choose the copy that is on our node */
curcpu = smp_processor_id();
loc_cpu_entry = private->entries[curcpu];
- xt_info_wrlock(curcpu);
+ addend = xt_write_recseq_begin();
xt_entry_foreach(iter, loc_cpu_entry, private->size) {
ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
++i;
}
- xt_info_wrunlock(curcpu);
+ xt_write_recseq_end(addend);
unlock_up_free:
local_bh_enable();
xt_table_unlock(t);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index ffcea0d..2b6b700 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -68,15 +68,6 @@ void *ipt_alloc_initial_table(const struct xt_table *info)
}
EXPORT_SYMBOL_GPL(ipt_alloc_initial_table);
-/*
- We keep a set of rules for each CPU, so we can avoid write-locking
- them in the softirq when updating the counters and therefore
- only need to read-lock in the softirq; doing a write_lock_bh() in user
- context stops packets coming through and allows user context to read
- the counters or update the rules.
-
- Hence the start of any table is given by get_table() below. */
-
/* Returns whether matches rule or not. */
/* Performance critical - called for every packet */
static inline bool
@@ -311,6 +302,7 @@ ipt_do_table(struct sk_buff *skb,
unsigned int *stackptr, origptr, cpu;
const struct xt_table_info *private;
struct xt_action_param acpar;
+ unsigned int addend;
/* Initialization */
ip = ip_hdr(skb);
@@ -331,7 +323,8 @@ ipt_do_table(struct sk_buff *skb,
acpar.hooknum = hook;
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
- xt_info_rdlock_bh();
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
private = table->private;
cpu = smp_processor_id();
table_base = private->entries[cpu];
@@ -430,7 +423,9 @@ ipt_do_table(struct sk_buff *skb,
pr_debug("Exiting %s; resetting sp from %u to %u\n",
__func__, *stackptr, origptr);
*stackptr = origptr;
- xt_info_rdunlock_bh();
+ xt_write_recseq_end(addend);
+ local_bh_enable();
+
#ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT;
#else
@@ -886,7 +881,7 @@ get_counters(const struct xt_table_info *t,
unsigned int i;
for_each_possible_cpu(cpu) {
- seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
+ seqcount_t *s = &per_cpu(xt_recseq, cpu);
i = 0;
xt_entry_foreach(iter, t->entries[cpu], t->size) {
@@ -894,10 +889,10 @@ get_counters(const struct xt_table_info *t,
unsigned int start;
do {
- start = read_seqbegin(lock);
+ start = read_seqcount_begin(s);
bcnt = iter->counters.bcnt;
pcnt = iter->counters.pcnt;
- } while (read_seqretry(lock, start));
+ } while (read_seqcount_retry(s, start));
ADD_COUNTER(counters[i], bcnt, pcnt);
++i; /* macro does multi eval of i */
@@ -1312,6 +1307,7 @@ do_add_counters(struct net *net, const void __user *user,
int ret = 0;
void *loc_cpu_entry;
struct ipt_entry *iter;
+ unsigned int addend;
#ifdef CONFIG_COMPAT
struct compat_xt_counters_info compat_tmp;
@@ -1368,12 +1364,12 @@ do_add_counters(struct net *net, const void __user *user,
/* Choose the copy that is on our node */
curcpu = smp_processor_id();
loc_cpu_entry = private->entries[curcpu];
- xt_info_wrlock(curcpu);
+ addend = xt_write_recseq_begin();
xt_entry_foreach(iter, loc_cpu_entry, private->size) {
ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
++i;
}
- xt_info_wrunlock(curcpu);
+ xt_write_recseq_end(addend);
unlock_up_free:
local_bh_enable();
xt_table_unlock(t);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 0b2af9b..ec7cf57 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -340,6 +340,7 @@ ip6t_do_table(struct sk_buff *skb,
unsigned int *stackptr, origptr, cpu;
const struct xt_table_info *private;
struct xt_action_param acpar;
+ unsigned int addend;
/* Initialization */
indev = in ? in->name : nulldevname;
@@ -358,7 +359,8 @@ ip6t_do_table(struct sk_buff *skb,
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
- xt_info_rdlock_bh();
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
private = table->private;
cpu = smp_processor_id();
table_base = private->entries[cpu];
@@ -442,7 +444,9 @@ ip6t_do_table(struct sk_buff *skb,
} while (!acpar.hotdrop);
*stackptr = origptr;
- xt_info_rdunlock_bh();
+
+ xt_write_recseq_end(addend);
+ local_bh_enable();
#ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT;
@@ -899,7 +903,7 @@ get_counters(const struct xt_table_info *t,
unsigned int i;
for_each_possible_cpu(cpu) {
- seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock;
+ seqcount_t *s = &per_cpu(xt_recseq, cpu);
i = 0;
xt_entry_foreach(iter, t->entries[cpu], t->size) {
@@ -907,10 +911,10 @@ get_counters(const struct xt_table_info *t,
unsigned int start;
do {
- start = read_seqbegin(lock);
+ start = read_seqcount_begin(s);
bcnt = iter->counters.bcnt;
pcnt = iter->counters.pcnt;
- } while (read_seqretry(lock, start));
+ } while (read_seqcount_retry(s, start));
ADD_COUNTER(counters[i], bcnt, pcnt);
++i;
@@ -1325,6 +1329,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
int ret = 0;
const void *loc_cpu_entry;
struct ip6t_entry *iter;
+ unsigned int addend;
#ifdef CONFIG_COMPAT
struct compat_xt_counters_info compat_tmp;
@@ -1381,13 +1386,13 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
i = 0;
/* Choose the copy that is on our node */
curcpu = smp_processor_id();
- xt_info_wrlock(curcpu);
+ addend = xt_write_recseq_begin();
loc_cpu_entry = private->entries[curcpu];
xt_entry_foreach(iter, loc_cpu_entry, private->size) {
ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
++i;
}
- xt_info_wrunlock(curcpu);
+ xt_write_recseq_end(addend);
unlock_up_free:
local_bh_enable();
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index a9adf4c..52959ef 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -762,8 +762,8 @@ void xt_compat_unlock(u_int8_t af)
EXPORT_SYMBOL_GPL(xt_compat_unlock);
#endif
-DEFINE_PER_CPU(struct xt_info_lock, xt_info_locks);
-EXPORT_PER_CPU_SYMBOL_GPL(xt_info_locks);
+DEFINE_PER_CPU(seqcount_t, xt_recseq);
+EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
static int xt_jumpstack_alloc(struct xt_table_info *i)
{
@@ -1362,10 +1362,7 @@ static int __init xt_init(void)
int rv;
for_each_possible_cpu(i) {
- struct xt_info_lock *lock = &per_cpu(xt_info_locks, i);
-
- seqlock_init(&lock->lock);
- lock->readers = 0;
+ seqcount_init(&per_cpu(xt_recseq, i));
}
xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL);
^ permalink raw reply related
* [PATCH 1/2] netfilter: xtables: fix reentrancy
From: Eric Dumazet @ 2011-03-18 17:05 UTC (permalink / raw)
To: Patrick McHardy, David Miller
Cc: Netfilter Development Mailinglist, netdev, Jan Engelhardt
commit f3c5c1bfd4308 (make ip_tables reentrant) introduced a race in
handling the stackptr restore, at the end of ipt_do_table()
We should do it before the call to xt_info_rdunlock_bh(), or we allow
cpu preemption and another cpu overwrites stackptr of original one.
A second fix is to change the underflow test to check the origptr value
instead of 0 to detect underflow, or else we allow a jump from different
hooks.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Jan Engelhardt <jengelh@medozas.de>
Cc: Patrick McHardy <kaber@trash.net>
---
net/ipv4/netfilter/ip_tables.c | 4 ++--
net/ipv6/netfilter/ip6_tables.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index b09ed0d..ffcea0d 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -387,7 +387,7 @@ ipt_do_table(struct sk_buff *skb,
verdict = (unsigned)(-v) - 1;
break;
}
- if (*stackptr == 0) {
+ if (*stackptr <= origptr) {
e = get_entry(table_base,
private->underflow[hook]);
pr_debug("Underflow (this is normal) "
@@ -427,10 +427,10 @@ ipt_do_table(struct sk_buff *skb,
/* Verdict */
break;
} while (!acpar.hotdrop);
- xt_info_rdunlock_bh();
pr_debug("Exiting %s; resetting sp from %u to %u\n",
__func__, *stackptr, origptr);
*stackptr = origptr;
+ xt_info_rdunlock_bh();
#ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT;
#else
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index c9598a9..0b2af9b 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -410,7 +410,7 @@ ip6t_do_table(struct sk_buff *skb,
verdict = (unsigned)(-v) - 1;
break;
}
- if (*stackptr == 0)
+ if (*stackptr <= origptr)
e = get_entry(table_base,
private->underflow[hook]);
else
@@ -441,8 +441,8 @@ ip6t_do_table(struct sk_buff *skb,
break;
} while (!acpar.hotdrop);
- xt_info_rdunlock_bh();
*stackptr = origptr;
+ xt_info_rdunlock_bh();
#ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT;
^ permalink raw reply related
* Re: [PATCH 2/2] virtio_net: remove send completion interrupts and avoid TX queue overrun through packet drop
From: Shirley Ma @ 2011-03-18 16:54 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: Rusty Russell, David Miller, kvm, netdev, Herbert Xu
In-Reply-To: <20110318131558.GC4221@redhat.com>
On Fri, 2011-03-18 at 15:15 +0200, Michael S. Tsirkin wrote:
> Is this the local or remote throughput?
> With UDP_STREAM you are mostly interested in
> remote throughput, local one can be pretty high
> while most packets get dropped.
This is local throughput. Remote is called recv(netserver) data. With
default wmem/rmem, there are so many recv errors. I haven't tuned the
results yet.
Thanks
Shirley
^ permalink raw reply
* Re: LRO disable warnings on kernel 2.6.38
From: Alexander Duyck @ 2011-03-18 16:18 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: netdev, Eric Dumazet, Neil Horman
In-Reply-To: <1300446743.11985.317.camel@firesoul.comx.local>
On 3/18/2011 4:12 AM, Jesper Dangaard Brouer wrote:
> Hi
>
> I'm seeing the LRO disable warnings using kernel 2.6.38:
>
> [ 8.664759] NET: Registered protocol family 10
> [ 8.838148] ADDRCONF(NETDEV_UP): eth71: link is not ready
> [ 8.872639] ------------[ cut here ]------------
> [ 8.872645] WARNING: at net/core/dev.c:1363 dev_disable_lro+0x7b/0x80()
> [ 8.872647] Hardware name: ProLiant DL370 G6
> [ 8.872648] Modules linked in: ipv6 nf_conntrack ip_tables loop i7core_edac edac_core ipmi_si ipmi_msghandler joydev hpilo pcspkr sg hpsa igb ata_piix netxen_nic dca [last unloaded: scsi_wait_scan]
> [ 8.872660] Pid: 2221, comm: sysctl Not tainted 2.6.38-comx04 #2
> [ 8.872662] Call Trace:
> [ 8.872671] [<ffffffff81056e1f>] ? warn_slowpath_common+0x7f/0xc0
> [ 8.872675] [<ffffffff81056e7a>] ? warn_slowpath_null+0x1a/0x20
> [ 8.872680] [<ffffffff8140c0ab>] ? dev_disable_lro+0x7b/0x80
> [ 8.872686] [<ffffffff81474f27>] ? devinet_sysctl_forward+0x147/0x180
> [ 8.872691] [<ffffffff811872f7>] ? proc_sys_call_handler+0x97/0xd0
> [ 8.872700] [<ffffffff81187344>] ? proc_sys_write+0x14/0x20
> [ 8.872704] [<ffffffff81124148>] ? vfs_write+0xc8/0x180
> [ 8.872707] [<ffffffff81124301>] ? sys_write+0x51/0x90
> [ 8.872712] [<ffffffff8100b8c2>] ? system_call_fastpath+0x16/0x1b
> [ 8.872714] ---[ end trace 6245283cb8d484cc ]---
>
> The strange part is that I didn't see this warning on my testlab and
> pre-prod servers. The warning is from the first production server,
> which got kernel 2.6.38 deployed this morning.
>
> The NIC driver is igb.
>
> The only difference in hardware between the production and
> pre-production server (which didn't show the warning), is the
> prod-server have an extra dual-port original Intel NIC, dev-named
> "eth71". And its just after the init of eth71, the warning occurs.
>
> We usually use a 6 port NIC from Hotlava, which is based on the same
> chip 82576 and also uses the same igb driver.
>
> Intel orig NIC eth71
> albpd4:~# ethtool -i eth71
> driver: igb
> version: 2.1.0-k2
> firmware-version: 1.2-1
> bus-info: 0000:21:00.0
>
> Hotlava Intel chip based NIC eth51:
> albpd4:~# ethtool -i eth51
> driver: igb
> version: 2.1.0-k2
> firmware-version: 1.2-1
> bus-info: 0000:1d:00.1
>
> I don't understand why I don't see the warning on my pre-prod server,
> which only have the Hotlava NIC?!?
>
The error doesn't make any sense for igb to be triggering since it
doesn't support setting the NETIF_F_LRO flag in the 2.6.38 kernel.
By any chance are there any ixgbe or other interfaces in the system? I
would suspect the error to come from a driver that at least contains the
NETIF_F_LRO flag.
Thanks,
Alex
^ permalink raw reply
* Re: [Bug 16572] random panics in bridging on 2.6.34+
From: Stephen Hemminger @ 2011-03-18 16:03 UTC (permalink / raw)
To: Herbert Xu; +Cc: David S. Miller, netdev, bugzilla-daemon
In-Reply-To: <20110318152728.GA22053@gondor.apana.org.au>
On Fri, 18 Mar 2011 10:27:28 -0500
Herbert Xu <herbert@gondor.hengli.com.au> wrote:
> On Fri, Mar 18, 2011 at 08:10:52AM -0700, Stephen Hemminger wrote:
> > On Fri, 18 Mar 2011 13:49:03 GMT
> > bugzilla-daemon@bugzilla.kernel.org wrote:
> >
> > > https://bugzilla.kernel.org/show_bug.cgi?id=16572
> >
> > Herbert hasn't submitted the patch upstream.
>
> Oops! Thanks for reminding me.
>
> bridge: Reset IPCB when entering IP stack on NF_FORWARD
>
> Whenever we enter the IP stack proper from bridge netfilter we
> need to ensure that the skb is in a form the IP stack expects
> it to be in.
>
> The entry point on NF_FORWARD did not meet the requirements of
> the IP stack, therefore leading to potential crashes/panics.
>
> This patch fixes the problem.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
^ permalink raw reply
* Re: [PATCHv2 3/9] macb: unify at91 and avr32 platform data
From: Russell King - ARM Linux @ 2011-03-18 15:54 UTC (permalink / raw)
To: Jamie Iles
Cc: Peter Korsgaard, avictor.za@gmail.com, plagnioj, linux-arm-kernel,
nicolas.ferre, netdev
In-Reply-To: <20110318154839.GB3393@pulham.picochip.com>
On Fri, Mar 18, 2011 at 03:48:39PM +0000, Jamie Iles wrote:
> On Fri, Mar 18, 2011 at 03:41:18PM +0000, Russell King - ARM Linux wrote:
> > On Thu, Mar 17, 2011 at 09:51:01PM +0000, Jamie Iles wrote:
> > > On Thu, Mar 17, 2011 at 09:34:03AM +0000, Jamie Iles wrote:
> > > > Ok, I'll rename to macb_platform_data and update at91_ether to use
> > > > that with a comment describing that we're sharing the platform data
> > > > with macb. At least that gets rid of the preprocessor stuff in
> > > > board.h for at91 too.
> > >
> > > So here's the updated patch with changes to the at91_ether driver to
> > > share the data with macb.
> > >
> > > Russell, are you happy to take this series? If so, how would you prefer
> > > it, in the patch system or as a git pull?
> >
> > As Nicolas Ferre is listed in MAINTAINERS as being responsible for the
> > MACB driver, I think he should at last Ack these patches first.
>
> OK, that's absolutely fine with me.
>
> > I'm also concious of the fact that Linus complains if my tree contains
> > changes for drivers/ stuff as well as ARM stuff, so I'm nervous about
> > taking it as-is. So, I'd rather see drivers stuff separated as much
> > as possible from the arch updates.
>
> I happy to split the driver and arch updates, but I'm not sure that it
> can be done in such a way that platforms would build between the arch
> and driver merges.
>
> > I'm also concious that this has become ready for potentially merging
> > during the merge window, and therefore hasn't had previous exposure
> > in linux-next, and so should wait until the next merge window. I do
> > feel that I'm going to be yelled at for saying that... but I'm sure
> > I'll also be yelled at if I did take it.
>
> I don't have any problem with waiting until the next merge window, and
> to be honest I'd like see these patches have some time in next as I
> can't test them on devices with a MACB.
Okay, that sounds like a very good reason to wait until Nicolas can
review them and provide an ack.
^ permalink raw reply
* Re: [PATCHv2 3/9] macb: unify at91 and avr32 platform data
From: Jamie Iles @ 2011-03-18 15:48 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Jamie Iles, Peter Korsgaard, avictor.za@gmail.com, plagnioj,
linux-arm-kernel, nicolas.ferre, netdev
In-Reply-To: <20110318154118.GQ29758@n2100.arm.linux.org.uk>
On Fri, Mar 18, 2011 at 03:41:18PM +0000, Russell King - ARM Linux wrote:
> On Thu, Mar 17, 2011 at 09:51:01PM +0000, Jamie Iles wrote:
> > On Thu, Mar 17, 2011 at 09:34:03AM +0000, Jamie Iles wrote:
> > > Ok, I'll rename to macb_platform_data and update at91_ether to use
> > > that with a comment describing that we're sharing the platform data
> > > with macb. At least that gets rid of the preprocessor stuff in
> > > board.h for at91 too.
> >
> > So here's the updated patch with changes to the at91_ether driver to
> > share the data with macb.
> >
> > Russell, are you happy to take this series? If so, how would you prefer
> > it, in the patch system or as a git pull?
>
> As Nicolas Ferre is listed in MAINTAINERS as being responsible for the
> MACB driver, I think he should at last Ack these patches first.
OK, that's absolutely fine with me.
> I'm also concious of the fact that Linus complains if my tree contains
> changes for drivers/ stuff as well as ARM stuff, so I'm nervous about
> taking it as-is. So, I'd rather see drivers stuff separated as much
> as possible from the arch updates.
I happy to split the driver and arch updates, but I'm not sure that it
can be done in such a way that platforms would build between the arch
and driver merges.
> I'm also concious that this has become ready for potentially merging
> during the merge window, and therefore hasn't had previous exposure
> in linux-next, and so should wait until the next merge window. I do
> feel that I'm going to be yelled at for saying that... but I'm sure
> I'll also be yelled at if I did take it.
I don't have any problem with waiting until the next merge window, and
to be honest I'd like see these patches have some time in next as I
can't test them on devices with a MACB.
Jamie
^ permalink raw reply
* Re: [PATCHv2 3/9] macb: unify at91 and avr32 platform data
From: Russell King - ARM Linux @ 2011-03-18 15:41 UTC (permalink / raw)
To: Jamie Iles
Cc: Peter Korsgaard, avictor.za@gmail.com, plagnioj, linux-arm-kernel,
nicolas.ferre, netdev
In-Reply-To: <20110317215101.GC2927@pulham.picochip.com>
On Thu, Mar 17, 2011 at 09:51:01PM +0000, Jamie Iles wrote:
> On Thu, Mar 17, 2011 at 09:34:03AM +0000, Jamie Iles wrote:
> > Ok, I'll rename to macb_platform_data and update at91_ether to use
> > that with a comment describing that we're sharing the platform data
> > with macb. At least that gets rid of the preprocessor stuff in
> > board.h for at91 too.
>
> So here's the updated patch with changes to the at91_ether driver to
> share the data with macb.
>
> Russell, are you happy to take this series? If so, how would you prefer
> it, in the patch system or as a git pull?
As Nicolas Ferre is listed in MAINTAINERS as being responsible for the
MACB driver, I think he should at last Ack these patches first.
I'm also concious of the fact that Linus complains if my tree contains
changes for drivers/ stuff as well as ARM stuff, so I'm nervous about
taking it as-is. So, I'd rather see drivers stuff separated as much
as possible from the arch updates.
I'm also concious that this has become ready for potentially merging
during the merge window, and therefore hasn't had previous exposure
in linux-next, and so should wait until the next merge window. I do
feel that I'm going to be yelled at for saying that... but I'm sure
I'll also be yelled at if I did take it.
^ permalink raw reply
* Re: LRO disable warnings on kernel 2.6.38
From: Ben Hutchings @ 2011-03-18 15:40 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: netdev, Eric Dumazet, Neil Horman, Alexander Duyck
In-Reply-To: <1300446743.11985.317.camel@firesoul.comx.local>
On Fri, 2011-03-18 at 12:12 +0100, Jesper Dangaard Brouer wrote:
> Hi
>
> I'm seeing the LRO disable warnings using kernel 2.6.38:
>
> [ 8.664759] NET: Registered protocol family 10
> [ 8.838148] ADDRCONF(NETDEV_UP): eth71: link is not ready
> [ 8.872639] ------------[ cut here ]------------
> [ 8.872645] WARNING: at net/core/dev.c:1363 dev_disable_lro+0x7b/0x80()
> [ 8.872647] Hardware name: ProLiant DL370 G6
> [ 8.872648] Modules linked in: ipv6 nf_conntrack ip_tables loop i7core_edac edac_core ipmi_si ipmi_msghandler joydev hpilo pcspkr sg hpsa igb ata_piix netxen_nic dca [last unloaded: scsi_wait_scan]
> [ 8.872660] Pid: 2221, comm: sysctl Not tainted 2.6.38-comx04 #2
> [ 8.872662] Call Trace:
> [ 8.872671] [<ffffffff81056e1f>] ? warn_slowpath_common+0x7f/0xc0
> [ 8.872675] [<ffffffff81056e7a>] ? warn_slowpath_null+0x1a/0x20
> [ 8.872680] [<ffffffff8140c0ab>] ? dev_disable_lro+0x7b/0x80
> [ 8.872686] [<ffffffff81474f27>] ? devinet_sysctl_forward+0x147/0x180
> [ 8.872691] [<ffffffff811872f7>] ? proc_sys_call_handler+0x97/0xd0
> [ 8.872700] [<ffffffff81187344>] ? proc_sys_write+0x14/0x20
> [ 8.872704] [<ffffffff81124148>] ? vfs_write+0xc8/0x180
> [ 8.872707] [<ffffffff81124301>] ? sys_write+0x51/0x90
> [ 8.872712] [<ffffffff8100b8c2>] ? system_call_fastpath+0x16/0x1b
> [ 8.872714] ---[ end trace 6245283cb8d484cc ]---
>
> The strange part is that I didn't see this warning on my testlab and
> pre-prod servers. The warning is from the first production server,
> which got kernel 2.6.38 deployed this morning.
>
> The NIC driver is igb.
>
> The only difference in hardware between the production and
> pre-production server (which didn't show the warning), is the
> prod-server have an extra dual-port original Intel NIC, dev-named
> "eth71". And its just after the init of eth71, the warning occurs.
The warning is triggered if you enable forwarding or bridging on a
device without LRO, and the driver fails to disable LRO when requested.
You can see from the call chain that this is being triggered by a sysctl
write, not during registration.
> We usually use a 6 port NIC from Hotlava, which is based on the same
> chip 82576 and also uses the same igb driver.
>
> Intel orig NIC eth71
> albpd4:~# ethtool -i eth71
> driver: igb
> version: 2.1.0-k2
[...]
This appears to be the in-tree version of igb, which never enables LRO.
So I can't see how it could trigger this warning.
Are any other drivers being used for other interfaces?
And I'm sorry I forgot to include device & driver in this warning!
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox