Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH REPOST net-next-2.6 3/4] bonding: Fix useless test: int > INT_MAX
From: David Miller @ 2009-08-28 22:49 UTC (permalink / raw)
  To: fubar; +Cc: netdev, nicolas.2p.debian
In-Reply-To: <1251497115-16234-4-git-send-email-fubar@us.ibm.com>

From: Jay Vosburgh <fubar@us.ibm.com>
Date: Fri, 28 Aug 2009 15:05:14 -0700

> From: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
> 
> max_bonds is of type int and cannot be greater than INT_MAX.
> 
> Signed-off-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>

It seems you use two different encodings here for Nicolas's
last name, and thus the two-dotted 'u' comes out corrupted
in the From: field.

This causes patchwork to not be able to parse the patch
and thus put it properly into the queue.  So all that's
in there are patches #1, #2 and #4.


^ permalink raw reply

* Re: [PATCH 1/2] lsm: Add hooks to the TUN driver
From: David Miller @ 2009-08-28 22:46 UTC (permalink / raw)
  Cc: netdev, linux-security-module, selinux
In-Reply-To: <20090828221243.3900.15668.stgit@flek.lan>

From: Paul Moore <paul.moore@hp.com>
Date: Fri, 28 Aug 2009 18:12:43 -0400

> The TUN driver lacks any LSM hooks which makes it difficult for LSM modules,
> such as SELinux, to enforce access controls on network traffic generated by
> TUN users; this is particularly problematic for virtualization apps such as
> QEMU and KVM.  This patch adds three new LSM hooks designed to control the
> creation and attachment of TUN devices, the hooks are:
> 
>  * security_tun_dev_create()
>    Provides access control for the creation of new TUN devices
> 
>  * security_tun_dev_post_create()
>    Provides the ability to create the necessary socket LSM state for newly
>    created TUN devices
> 
>  * security_tun_dev_attach()
>    Provides access control for attaching to existing, persistent TUN devices
>    and the ability to update the TUN device's socket LSM state as necessary
> 
> Signed-off-by: Paul Moore <paul.moore@hp.com>
> Acked-by: Eric Paris <eparis@parisplace.org>
> Acked-by: Serge Hallyn <serue@us.ibm.com>

I'm happy if you guys merge this via the security tree,
feel free to add:

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply

* Re: [PATCH 1/9] task_struct: add PF_NONOTIFY for fanotify to use
From: Eric Paris @ 2009-08-28 22:39 UTC (permalink / raw)
  To: Evgeniy Polyakov
  Cc: linux-kernel, linux-fsdevel, netdev, davem, viro, alan, hch
In-Reply-To: <20090828223626.GA8283@ioremap.net>

On Sat, 2009-08-29 at 02:36 +0400, Evgeniy Polyakov wrote:
> Hi.
> 
> On Fri, Aug 28, 2009 at 02:55:42PM -0400, Eric Paris (eparis@redhat.com) wrote:
> > Since fanotify opens file descriptors inside the kernel for it's listeners
> > it needs a way to make sure that 2 fanotify listeners, both which listen to
> > open events do not continuously see each others open events (and get into a
> > livelock reporting on each other's activity).  This fix is to create a new
> > tast_struct flags called PF_NONOTIFY.  If this flag is set in a task no
> > fanotify events will be generated for that task.   fanotify will set the
> > flag before and open call and will clear it immediately after.
> 
> Is there a way to get old-school notifications with the object
> information instead of opened file desriptor, which may suffer rlimit
> problems and scalability issues with too many opened/closed descriptors?

Use inotify.

-Eric


^ permalink raw reply

* Re: [PATCH 1/9] task_struct: add PF_NONOTIFY for fanotify to use
From: Evgeniy Polyakov @ 2009-08-28 22:36 UTC (permalink / raw)
  To: Eric Paris; +Cc: linux-kernel, linux-fsdevel, netdev, davem, viro, alan, hch
In-Reply-To: <20090828185542.8014.22791.stgit@paris.rdu.redhat.com>

Hi.

On Fri, Aug 28, 2009 at 02:55:42PM -0400, Eric Paris (eparis@redhat.com) wrote:
> Since fanotify opens file descriptors inside the kernel for it's listeners
> it needs a way to make sure that 2 fanotify listeners, both which listen to
> open events do not continuously see each others open events (and get into a
> livelock reporting on each other's activity).  This fix is to create a new
> tast_struct flags called PF_NONOTIFY.  If this flag is set in a task no
> fanotify events will be generated for that task.   fanotify will set the
> flag before and open call and will clear it immediately after.

Is there a way to get old-school notifications with the object
information instead of opened file desriptor, which may suffer rlimit
problems and scalability issues with too many opened/closed descriptors?

-- 
	Evgeniy Polyakov

^ permalink raw reply

* [PATCH 2/2] selinux: Support for the new TUN LSM hooks
From: Paul Moore @ 2009-08-28 22:12 UTC (permalink / raw)
  To: netdev, linux-security-module, selinux
In-Reply-To: <20090828220400.3900.64377.stgit@flek.lan>

Add support for the new TUN LSM hooks: security_tun_dev_create(),
security_tun_dev_post_create() and security_tun_dev_attach().  This includes
the addition of a new object class, tun_socket, which represents the socks
associated with TUN devices.  The _tun_dev_create() and _tun_dev_post_create()
hooks are fairly similar to the standard socket functions but _tun_dev_attach()
is a bit special.  The _tun_dev_attach() is unique because it involves a
domain attaching to an existing TUN device and its associated tun_socket
object, an operation which does not exist with standard sockets and most
closely resembles a relabel operation.

Signed-off-by: Paul Moore <paul.moore@hp.com>
Acked-by: Eric Paris <eparis@parisplace.org>
---

 security/selinux/hooks.c                   |   60 +++++++++++++++++++++++++++-
 security/selinux/include/av_inherit.h      |    1 
 security/selinux/include/av_permissions.h  |   22 ++++++++++
 security/selinux/include/class_to_string.h |    1 
 security/selinux/include/flask.h           |    1 
 5 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8d8b69c..8ee6b07 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -13,8 +13,8 @@
  *					   Eric Paris <eparis@redhat.com>
  *  Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  *			    <dgoeddel@trustedcs.com>
- *  Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
- *		Paul Moore <paul.moore@hp.com>
+ *  Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P.
+ *	Paul Moore <paul.moore@hp.com>
  *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
  *		       Yuichi Nakamura <ynakam@hitachisoft.jp>
  *
@@ -4309,6 +4309,59 @@ static void selinux_req_classify_flow(const struct request_sock *req,
 	fl->secid = req->secid;
 }
 
+static int selinux_tun_dev_create(void)
+{
+	u32 sid = current_sid();
+
+	/* we aren't taking into account the "sockcreate" SID since the socket
+	 * that is being created here is not a socket in the traditional sense,
+	 * instead it is a private sock, accessible only to the kernel, and
+	 * representing a wide range of network traffic spanning multiple
+	 * connections unlike traditional sockets - check the TUN driver to
+	 * get a better understanding of why this socket is special */
+
+	return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
+			    NULL);
+}
+
+static void selinux_tun_dev_post_create(struct sock *sk)
+{
+	struct sk_security_struct *sksec = sk->sk_security;
+
+	/* we don't currently perform any NetLabel based labeling here and it
+	 * isn't clear that we would want to do so anyway; while we could apply
+	 * labeling without the support of the TUN user the resulting labeled
+	 * traffic from the other end of the connection would almost certainly
+	 * cause confusion to the TUN user that had no idea network labeling
+	 * protocols were being used */
+
+	/* see the comments in selinux_tun_dev_create() about why we don't use
+	 * the sockcreate SID here */
+
+	sksec->sid = current_sid();
+	sksec->sclass = SECCLASS_TUN_SOCKET;
+}
+
+static int selinux_tun_dev_attach(struct sock *sk)
+{
+	struct sk_security_struct *sksec = sk->sk_security;
+	u32 sid = current_sid();
+	int err;
+
+	err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET,
+			   TUN_SOCKET__RELABELFROM, NULL);
+	if (err)
+		return err;
+	err = avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET,
+			   TUN_SOCKET__RELABELTO, NULL);
+	if (err)
+		return err;
+
+	sksec->sid = sid;
+
+	return 0;
+}
+
 static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
 {
 	int err = 0;
@@ -5477,6 +5530,9 @@ static struct security_operations selinux_ops = {
 	.inet_csk_clone =		selinux_inet_csk_clone,
 	.inet_conn_established =	selinux_inet_conn_established,
 	.req_classify_flow =		selinux_req_classify_flow,
+	.tun_dev_create =		selinux_tun_dev_create,
+	.tun_dev_post_create = 		selinux_tun_dev_post_create,
+	.tun_dev_attach =		selinux_tun_dev_attach,
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	.xfrm_policy_alloc_security =	selinux_xfrm_policy_alloc,
diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h
index 8377a4b..abedcd7 100644
--- a/security/selinux/include/av_inherit.h
+++ b/security/selinux/include/av_inherit.h
@@ -15,6 +15,7 @@
    S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL)
    S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL)
    S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL)
+   S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL)
    S_(SECCLASS_IPC, ipc, 0x00000200UL)
    S_(SECCLASS_SEM, ipc, 0x00000200UL)
    S_(SECCLASS_MSGQ, ipc, 0x00000200UL)
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index d645192..0b41ad5 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -423,6 +423,28 @@
 #define UNIX_DGRAM_SOCKET__RECV_MSG               0x00080000UL
 #define UNIX_DGRAM_SOCKET__SEND_MSG               0x00100000UL
 #define UNIX_DGRAM_SOCKET__NAME_BIND              0x00200000UL
+#define TUN_SOCKET__IOCTL                         0x00000001UL
+#define TUN_SOCKET__READ                          0x00000002UL
+#define TUN_SOCKET__WRITE                         0x00000004UL
+#define TUN_SOCKET__CREATE                        0x00000008UL
+#define TUN_SOCKET__GETATTR                       0x00000010UL
+#define TUN_SOCKET__SETATTR                       0x00000020UL
+#define TUN_SOCKET__LOCK                          0x00000040UL
+#define TUN_SOCKET__RELABELFROM                   0x00000080UL
+#define TUN_SOCKET__RELABELTO                     0x00000100UL
+#define TUN_SOCKET__APPEND                        0x00000200UL
+#define TUN_SOCKET__BIND                          0x00000400UL
+#define TUN_SOCKET__CONNECT                       0x00000800UL
+#define TUN_SOCKET__LISTEN                        0x00001000UL
+#define TUN_SOCKET__ACCEPT                        0x00002000UL
+#define TUN_SOCKET__GETOPT                        0x00004000UL
+#define TUN_SOCKET__SETOPT                        0x00008000UL
+#define TUN_SOCKET__SHUTDOWN                      0x00010000UL
+#define TUN_SOCKET__RECVFROM                      0x00020000UL
+#define TUN_SOCKET__SENDTO                        0x00040000UL
+#define TUN_SOCKET__RECV_MSG                      0x00080000UL
+#define TUN_SOCKET__SEND_MSG                      0x00100000UL
+#define TUN_SOCKET__NAME_BIND                     0x00200000UL
 #define PROCESS__FORK                             0x00000001UL
 #define PROCESS__TRANSITION                       0x00000002UL
 #define PROCESS__SIGCHLD                          0x00000004UL
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
index 21ec786..7ab9299 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -77,3 +77,4 @@
     S_(NULL)
     S_(NULL)
     S_("kernel_service")
+    S_("tun_socket")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index 882f27d..f248500 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -53,6 +53,7 @@
 #define SECCLASS_PEER                                    68
 #define SECCLASS_CAPABILITY2                             69
 #define SECCLASS_KERNEL_SERVICE                          74
+#define SECCLASS_TUN_SOCKET                              75
 
 /*
  * Security identifier indices for initial entities


^ permalink raw reply related

* [PATCH 1/2] lsm: Add hooks to the TUN driver
From: Paul Moore @ 2009-08-28 22:12 UTC (permalink / raw)
  To: netdev, linux-security-module, selinux
In-Reply-To: <20090828220400.3900.64377.stgit@flek.lan>

The TUN driver lacks any LSM hooks which makes it difficult for LSM modules,
such as SELinux, to enforce access controls on network traffic generated by
TUN users; this is particularly problematic for virtualization apps such as
QEMU and KVM.  This patch adds three new LSM hooks designed to control the
creation and attachment of TUN devices, the hooks are:

 * security_tun_dev_create()
   Provides access control for the creation of new TUN devices

 * security_tun_dev_post_create()
   Provides the ability to create the necessary socket LSM state for newly
   created TUN devices

 * security_tun_dev_attach()
   Provides access control for attaching to existing, persistent TUN devices
   and the ability to update the TUN device's socket LSM state as necessary

Signed-off-by: Paul Moore <paul.moore@hp.com>
Acked-by: Eric Paris <eparis@parisplace.org>
Acked-by: Serge Hallyn <serue@us.ibm.com>
---

 drivers/net/tun.c        |   22 +++++++++++++++-------
 include/linux/security.h |   31 +++++++++++++++++++++++++++++++
 security/capability.c    |   19 +++++++++++++++++++
 security/security.c      |   18 ++++++++++++++++++
 4 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 42b6c63..87214a2 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -130,17 +130,10 @@ static inline struct tun_sock *tun_sk(struct sock *sk)
 static int tun_attach(struct tun_struct *tun, struct file *file)
 {
 	struct tun_file *tfile = file->private_data;
-	const struct cred *cred = current_cred();
 	int err;
 
 	ASSERT_RTNL();
 
-	/* Check permissions */
-	if (((tun->owner != -1 && cred->euid != tun->owner) ||
-	     (tun->group != -1 && !in_egroup_p(tun->group))) &&
-		!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
 	netif_tx_lock_bh(tun->dev);
 
 	err = -EINVAL;
@@ -926,6 +919,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
 	dev = __dev_get_by_name(net, ifr->ifr_name);
 	if (dev) {
+		const struct cred *cred = current_cred();
+
 		if (ifr->ifr_flags & IFF_TUN_EXCL)
 			return -EBUSY;
 		if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
@@ -935,6 +930,14 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		else
 			return -EINVAL;
 
+		if (((tun->owner != -1 && cred->euid != tun->owner) ||
+		     (tun->group != -1 && !in_egroup_p(tun->group))) &&
+		    !capable(CAP_NET_ADMIN))
+			return -EPERM;
+		err = security_tun_dev_attach(tun->sk);
+		if (err < 0)
+			return err;
+
 		err = tun_attach(tun, file);
 		if (err < 0)
 			return err;
@@ -947,6 +950,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
+		err = security_tun_dev_create();
+		if (err < 0)
+			return err;
 
 		/* Set dev type */
 		if (ifr->ifr_flags & IFF_TUN) {
@@ -989,6 +995,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		tun->sk = sk;
 		container_of(sk, struct tun_sock, sk)->tun = tun;
 
+		security_tun_dev_post_create(sk);
+
 		tun_net_init(dev);
 
 		if (strchr(dev->name, '%')) {
diff --git a/include/linux/security.h b/include/linux/security.h
index 1f16eea..d0e7d4a 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -994,6 +994,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *	Sets the connection's peersid to the secmark on skb.
  * @req_classify_flow:
  *	Sets the flow's sid to the openreq sid.
+ * @tun_dev_create:
+ *	Check permissions prior to creating a new TUN device.
+ * @tun_dev_post_create:
+ *	This hook allows a module to update or allocate a per-socket security
+ *	structure.
+ *	@sk contains the newly created sock structure.
+ * @tun_dev_attach:
+ *	Check permissions prior to attaching to a persistent TUN device.  This
+ *	hook can also be used by the module to update any security state
+ *	associated with the TUN device's sock structure.
+ *	@sk contains the existing sock structure.
  *
  * Security hooks for XFRM operations.
  *
@@ -1592,6 +1603,9 @@ struct security_operations {
 	void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req);
 	void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb);
 	void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
+	int (*tun_dev_create)(void);
+	void (*tun_dev_post_create)(struct sock *sk);
+	int (*tun_dev_attach)(struct sock *sk);
 #endif	/* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2575,6 +2589,9 @@ void security_inet_csk_clone(struct sock *newsk,
 			const struct request_sock *req);
 void security_inet_conn_established(struct sock *sk,
 			struct sk_buff *skb);
+int security_tun_dev_create(void);
+void security_tun_dev_post_create(struct sock *sk);
+int security_tun_dev_attach(struct sock *sk);
 
 #else	/* CONFIG_SECURITY_NETWORK */
 static inline int security_unix_stream_connect(struct socket *sock,
@@ -2725,6 +2742,20 @@ static inline void security_inet_conn_established(struct sock *sk,
 			struct sk_buff *skb)
 {
 }
+
+static inline int security_tun_dev_create(void)
+{
+	return 0;
+}
+
+static inline void security_tun_dev_post_create(struct sock *sk)
+{
+}
+
+static inline int security_tun_dev_attach(struct sock *sk)
+{
+	return 0;
+}
 #endif	/* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
diff --git a/security/capability.c b/security/capability.c
index 88f752e..8cb75b6 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -701,10 +701,26 @@ static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb)
 {
 }
 
+
+
 static void cap_req_classify_flow(const struct request_sock *req,
 				  struct flowi *fl)
 {
 }
+
+static int cap_tun_dev_create(void)
+{
+	return 0;
+}
+
+static void cap_tun_dev_post_create(struct sock *sk)
+{
+}
+
+static int cap_tun_dev_attach(struct sock *sk)
+{
+	return 0;
+}
 #endif	/* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1020,6 +1036,9 @@ void security_fixup_ops(struct security_operations *ops)
 	set_to_cap_if_null(ops, inet_csk_clone);
 	set_to_cap_if_null(ops, inet_conn_established);
 	set_to_cap_if_null(ops, req_classify_flow);
+	set_to_cap_if_null(ops, tun_dev_create);
+	set_to_cap_if_null(ops, tun_dev_post_create);
+	set_to_cap_if_null(ops, tun_dev_attach);
 #endif	/* CONFIG_SECURITY_NETWORK */
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	set_to_cap_if_null(ops, xfrm_policy_alloc_security);
diff --git a/security/security.c b/security/security.c
index dc7674f..dc6953c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1112,6 +1112,24 @@ void security_inet_conn_established(struct sock *sk,
 	security_ops->inet_conn_established(sk, skb);
 }
 
+int security_tun_dev_create(void)
+{
+	return security_ops->tun_dev_create();
+}
+EXPORT_SYMBOL(security_tun_dev_create);
+
+void security_tun_dev_post_create(struct sock *sk)
+{
+	return security_ops->tun_dev_post_create(sk);
+}
+EXPORT_SYMBOL(security_tun_dev_post_create);
+
+int security_tun_dev_attach(struct sock *sk)
+{
+	return security_ops->tun_dev_attach(sk);
+}
+EXPORT_SYMBOL(security_tun_dev_attach);
+
 #endif	/* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM


^ permalink raw reply related

* [PATCH 0/2] New LSM hooks for the TUN driver
From: Paul Moore @ 2009-08-28 22:12 UTC (permalink / raw)
  To: netdev, linux-security-module, selinux

This is the third, and hopefully final, version of the new LSM TUN hooks.  This
version incorporates all outstanding feedback as well as my sign-off and ACKs
from both Eric and Serge (see patches).  However, the patches are still missing
an ACK from netdev - I haven't heard any objections but I'm not certain anyone
from netdev has really taken a look yet.

Dave and James - these patches once again straddle that line between networking
and security; while James has usually ushered these types of patches upstream
in the past I'll let you two fight it out again for the honors (assuming you
are both okay with the patches).

The patches can also be found in git form here:

 * git://git.infradead.org/users/pcmoore/lblnet-2.6_next

Thanks.

---

Paul Moore (2):
      selinux: Support for the new TUN LSM hooks
      lsm: Add hooks to the TUN driver


 drivers/net/tun.c                          |   22 +++++++---
 include/linux/security.h                   |   31 ++++++++++++++
 security/capability.c                      |   19 +++++++++
 security/security.c                        |   18 ++++++++
 security/selinux/hooks.c                   |   60 +++++++++++++++++++++++++++-
 security/selinux/include/av_inherit.h      |    1 
 security/selinux/include/av_permissions.h  |   22 ++++++++++
 security/selinux/include/class_to_string.h |    1 
 security/selinux/include/flask.h           |    1 
 9 files changed, 166 insertions(+), 9 deletions(-)

^ permalink raw reply

* [PATCH REPOST net-next-2.6 3/4] bonding: Fix useless test: int > INT_MAX
From: Jay Vosburgh @ 2009-08-28 22:05 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Nicolas de Pesloüan
In-Reply-To: <1251497115-16234-3-git-send-email-fubar@us.ibm.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 887 bytes --]

From: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>

max_bonds is of type int and cannot be greater than INT_MAX.

Signed-off-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ed00ba9..6b9f15b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4759,7 +4759,7 @@ static int bond_check_params(struct bond_params *params)
 		params->ad_select = BOND_AD_STABLE;
 	}
 
-	if (max_bonds < 0 || max_bonds > INT_MAX) {
+	if (max_bonds < 0) {
 		pr_warning(DRV_NAME
 		       ": Warning: max_bonds (%d) not in range %d-%d, so it "
 		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH REPOST net-next-2.6 4/4] bonding: Have bond_check_dev_link examine netif_running
From: Jay Vosburgh @ 2009-08-28 22:05 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Petri Gynther
In-Reply-To: <1251497115-16234-4-git-send-email-fubar@us.ibm.com>

From: Petri Gynther <pgynther@google.com>

bonding: Have bond_check_dev_link examine netif_running

	Some network devices do not call netif_carrier_off when they
are set administratively down.  Have the bonding link check function
also inspect the netif_running state.  Ignore netif_running if the
bond_check_dev_link function is called with "reporting" set, as in that
case it's inspecting the capabilities of the non-netif_carrier device
driver.

Signed-off-by: Petri Gynther <pgynther@google.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6b9f15b..7c0e0bd 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -695,6 +695,9 @@ static int bond_check_dev_link(struct bonding *bond,
 	struct ifreq ifr;
 	struct mii_ioctl_data *mii;
 
+	if (!reporting && !netif_running(slave_dev))
+		return 0;
+
 	if (bond->params.use_carrier)
 		return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
 
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH REPOST net-next-2.6 2/4] bonding: use compare_ether_addr
From: Jay Vosburgh @ 2009-08-28 22:05 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Stephen Hemminger
In-Reply-To: <1251497115-16234-2-git-send-email-fubar@us.ibm.com>

From: Stephen Hemminger <shemminger@vyatta.com>

Bonding can use compare_ether_addr() in bond_release.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1aeb36c..ed00ba9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1796,7 +1796,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave, *oldcurrent;
 	struct sockaddr addr;
-	int mac_addr_differ;
 
 	/* slave is not a slave or master is not master of this slave */
 	if (!(slave_dev->flags & IFF_SLAVE) ||
@@ -1820,9 +1819,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	}
 
 	if (!bond->params.fail_over_mac) {
-		mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
-					 ETH_ALEN);
-		if (!mac_addr_differ && (bond->slave_cnt > 1))
+		if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr)
+		    && bond->slave_cnt > 1)
 			pr_warning(DRV_NAME
 			       ": %s: Warning: the permanent HWaddr of %s - "
 			       "%pM - is still in use by %s. "
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH REPOST net-next 1/4] bonding: propogate vlan_features to bonding master
From: Jay Vosburgh @ 2009-08-28 22:05 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Or Gerlitz
In-Reply-To: <1251497115-16234-1-git-send-email-fubar@us.ibm.com>

Propogate the vlan_features of the slave devices to the bonding
master device, using the same logic as for regular features.

	Tested by Or Gerlitz <ogerlitz@voltaire.com>, who also removed
the debug logic from the original test patch.

Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 4798d30..1aeb36c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1331,6 +1331,7 @@ static int bond_compute_features(struct bonding *bond)
 	struct slave *slave;
 	struct net_device *bond_dev = bond->dev;
 	unsigned long features = bond_dev->features;
+	unsigned long vlan_features = 0;
 	unsigned short max_hard_header_len = max((u16)ETH_HLEN,
 						bond_dev->hard_header_len);
 	int i;
@@ -1343,10 +1344,14 @@ static int bond_compute_features(struct bonding *bond)
 
 	features &= ~NETIF_F_ONE_FOR_ALL;
 
+	vlan_features = bond->first_slave->dev->vlan_features;
 	bond_for_each_slave(bond, slave, i) {
 		features = netdev_increment_features(features,
 						     slave->dev->features,
 						     NETIF_F_ONE_FOR_ALL);
+		vlan_features = netdev_increment_features(vlan_features,
+							slave->dev->vlan_features,
+							NETIF_F_ONE_FOR_ALL);
 		if (slave->dev->hard_header_len > max_hard_header_len)
 			max_hard_header_len = slave->dev->hard_header_len;
 	}
@@ -1354,6 +1359,7 @@ static int bond_compute_features(struct bonding *bond)
 done:
 	features |= (bond_dev->features & BOND_VLAN_FEATURES);
 	bond_dev->features = netdev_fix_features(features, NULL);
+	bond_dev->vlan_features = netdev_fix_features(vlan_features, NULL);
 	bond_dev->hard_header_len = max_hard_header_len;
 
 	return 0;
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH REPOST net-next-2.6 0/4] bonding: Four patches
From: Jay Vosburgh @ 2009-08-28 22:05 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

	Reposting after I screwed up the Subject lines

	Four patches for bonding:

	Patch 1 adds the propogation of vlan_features from the slaves
to the master device.

	Patch 2 replaces a cumbersome manual MAC address comparison with
compare_ether_addr.

	Patch 3 removes a useless test against INT_MAX

	Patch 4 modifies bond_check_dev_link to handle devices that leave
carrier up even when adminstratively down.

	Due to lab machine adventures on my end, I was only able to compile
test patches 2 - 4.

	Please apply for net-next-2.6.

	-J

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply

* [PATCH] From: Petri Gynther <pgynther@google.com>
From: Jay Vosburgh @ 2009-08-28 21:57 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Petri Gynther
In-Reply-To: <1251496672-14498-4-git-send-email-fubar@us.ibm.com>

From: Petri Gynther <pgynther@google.com>

bonding: Have bond_check_dev_link examine netif_running

	Some network devices do not call netif_carrier_off when they
are set administratively down.  Have the bonding link check function
also inspect the netif_running state.  Ignore netif_running if the
bond_check_dev_link function is called with "reporting" set, as in that
case it's inspecting the capabilities of the non-netif_carrier device
driver.

Signed-off-by: Petri Gynther <pgynther@google.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6b9f15b..7c0e0bd 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -695,6 +695,9 @@ static int bond_check_dev_link(struct bonding *bond,
 	struct ifreq ifr;
 	struct mii_ioctl_data *mii;
 
+	if (!reporting && !netif_running(slave_dev))
+		return 0;
+
 	if (bond->params.use_carrier)
 		return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
 
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH net-next-2.6 0/4] bonding: Four patches
From: Jay Vosburgh @ 2009-08-28 21:57 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

	Four patches for bonding:

	Patch 1 adds the propogation of vlan_features from the slaves
to the master device.

	Patch 2 replaces a cumbersome manual MAC address comparison with
compare_ether_addr.

	Patch 3 removes a useless test against INT_MAX.

	Patch 4 modifies bond_check_dev_link to handle devices that leave
carrier up even when adminstratively down.

	Due to lab machine adventures on my end, I was only able to compile
test patches 2 - 4.

	Please apply for net-next-2.6.

	-J

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply

* [PATCH] Fix useless test: int > INT_MAX
From: Jay Vosburgh @ 2009-08-28 21:57 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Nicolas de Pesloüan
In-Reply-To: <1251496672-14498-3-git-send-email-fubar@us.ibm.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 887 bytes --]

From: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>

max_bonds is of type int and cannot be greater than INT_MAX.

Signed-off-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ed00ba9..6b9f15b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4759,7 +4759,7 @@ static int bond_check_params(struct bond_params *params)
 		params->ad_select = BOND_AD_STABLE;
 	}
 
-	if (max_bonds < 0 || max_bonds > INT_MAX) {
+	if (max_bonds < 0) {
 		pr_warning(DRV_NAME
 		       ": Warning: max_bonds (%d) not in range %d-%d, so it "
 		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH] bonding: use compare_ether_addr
From: Jay Vosburgh @ 2009-08-28 21:57 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Stephen Hemminger
In-Reply-To: <1251496672-14498-2-git-send-email-fubar@us.ibm.com>

From: Stephen Hemminger <shemminger@vyatta.com>

Bonding can use compare_ether_addr() in bond_release.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1aeb36c..ed00ba9 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1796,7 +1796,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave, *oldcurrent;
 	struct sockaddr addr;
-	int mac_addr_differ;
 
 	/* slave is not a slave or master is not master of this slave */
 	if (!(slave_dev->flags & IFF_SLAVE) ||
@@ -1820,9 +1819,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	}
 
 	if (!bond->params.fail_over_mac) {
-		mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
-					 ETH_ALEN);
-		if (!mac_addr_differ && (bond->slave_cnt > 1))
+		if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr)
+		    && bond->slave_cnt > 1)
 			pr_warning(DRV_NAME
 			       ": %s: Warning: the permanent HWaddr of %s - "
 			       "%pM - is still in use by %s. "
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH] bonding: propogate vlan_features to bonding master
From: Jay Vosburgh @ 2009-08-28 21:57 UTC (permalink / raw)
  To: netdev; +Cc: David Miller, Or Gerlitz
In-Reply-To: <1251496672-14498-1-git-send-email-fubar@us.ibm.com>

Propogate the vlan_features of the slave devices to the bonding
master device, using the same logic as for regular features.

	Tested by Or Gerlitz <ogerlitz@voltaire.com>, who also removed
the debug logic from the original test patch.

Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 4798d30..1aeb36c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1331,6 +1331,7 @@ static int bond_compute_features(struct bonding *bond)
 	struct slave *slave;
 	struct net_device *bond_dev = bond->dev;
 	unsigned long features = bond_dev->features;
+	unsigned long vlan_features = 0;
 	unsigned short max_hard_header_len = max((u16)ETH_HLEN,
 						bond_dev->hard_header_len);
 	int i;
@@ -1343,10 +1344,14 @@ static int bond_compute_features(struct bonding *bond)
 
 	features &= ~NETIF_F_ONE_FOR_ALL;
 
+	vlan_features = bond->first_slave->dev->vlan_features;
 	bond_for_each_slave(bond, slave, i) {
 		features = netdev_increment_features(features,
 						     slave->dev->features,
 						     NETIF_F_ONE_FOR_ALL);
+		vlan_features = netdev_increment_features(vlan_features,
+							slave->dev->vlan_features,
+							NETIF_F_ONE_FOR_ALL);
 		if (slave->dev->hard_header_len > max_hard_header_len)
 			max_hard_header_len = slave->dev->hard_header_len;
 	}
@@ -1354,6 +1359,7 @@ static int bond_compute_features(struct bonding *bond)
 done:
 	features |= (bond_dev->features & BOND_VLAN_FEATURES);
 	bond_dev->features = netdev_fix_features(features, NULL);
+	bond_dev->vlan_features = netdev_fix_features(vlan_features, NULL);
 	bond_dev->hard_header_len = max_hard_header_len;
 
 	return 0;
-- 
1.6.0.2


^ permalink raw reply related

* Re: [PATCH] skb: Augment skb_copy_datagram_iovec TRACE_EVENT to dump more info
From: Steven Rostedt @ 2009-08-28 20:50 UTC (permalink / raw)
  To: Neil Horman; +Cc: netdev, davem, mingo
In-Reply-To: <20090828203314.GA30417@hmsreliant.think-freely.org>


On Fri, 28 Aug 2009, Neil Horman wrote:

> Hey all-
> 	As promised in our previous discussion, I've augmented the
> skb_copy_datagram_iovec TRACE_EVENT to dump out the info I was previously
> gathering in the ftrace module thats been removed.  This patch gives me
> everything I need.  Tested and working by me
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>

Much better :-)

> 
> Neil
> 
> 
>  skb.h |   26 +++++++++++++++++++++++---
>  1 file changed, 23 insertions(+), 3 deletions(-)
> 
> 
> diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
> index 4b2be6d..45b9a3f 100644
> --- a/include/trace/events/skb.h
> +++ b/include/trace/events/skb.h
> @@ -7,6 +7,7 @@
>  #include <linux/skbuff.h>
>  #include <linux/netdevice.h>
>  #include <linux/tracepoint.h>
> +#include <net/sock.h>
>  
>  /*
>   * Tracepoint for free an sk_buff:
> @@ -42,16 +43,35 @@ TRACE_EVENT(skb_copy_datagram_iovec,
>  	TP_ARGS(skb, len),
>  
>  	TP_STRUCT__entry(
> -		__field(	const void *,		skbaddr		)
> +		__field(	const struct sk_buff *,	skb		)
>  		__field(	int,			len		)
> +		__field(	int,			anid		)
> +		__field(	int,			cnid		)
> +		__field(	int,			rx_queue	)
> +		__dynamic_array(char,		name,	IFNAMSIZ	)

For string fields we have a __string macro:

		__string(	char,			name		)

>  	),
>  
>  	TP_fast_assign(
> -		__entry->skbaddr = skb;
> +		struct net_device *dev = NULL;
> +		__entry->skb = skb;
>  		__entry->len = len;
> +		__entry->anid = page_to_nid(virt_to_page(skb->data));
> +		__entry->cnid = cpu_to_node(smp_processor_id());
> +		__entry->rx_queue = skb->queue_mapping;
> +		if (skb->sk) {
> +			dev = dev_get_by_index(sock_net(skb->sk), skb->iif);
> +		}

Nitpick, but this should still use normal Linux styling:

		if (skb->sk)
			dev = dev_get_by_index(sock_net(skb->sk), skb->iif);


> +		if (dev) {
> +			__assign_str(name, dev->name);
> +			dev_put(dev);
> +		} else {
> +			__assign_str(name, "Unknown");
> +		}

And remove the extra braces here too.

>  	),
>  
> -	TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len)
> +	TP_printk("skb=%p anid=%d cnid=%d len=%d rx_queue=%d name=%s",
> +			__entry->skb, __entry->anid, __entry->cnid,
> +			__entry->len, __entry->rx_queue, __get_str(name))
>  );
>  
>  #endif /* _TRACE_SKB_H */
> 

Other than that, this looks good.

Acked-by: Steven Rostedt <rostedt@goodmis.org>

-- Steve



^ permalink raw reply

* [PATCH] skb: Augment skb_copy_datagram_iovec TRACE_EVENT to dump more info
From: Neil Horman @ 2009-08-28 20:33 UTC (permalink / raw)
  To: netdev; +Cc: davem, mingo, rostedt, nhorman

Hey all-
	As promised in our previous discussion, I've augmented the
skb_copy_datagram_iovec TRACE_EVENT to dump out the info I was previously
gathering in the ftrace module thats been removed.  This patch gives me
everything I need.  Tested and working by me

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>

Neil


 skb.h |   26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)


diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index 4b2be6d..45b9a3f 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -7,6 +7,7 @@
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/tracepoint.h>
+#include <net/sock.h>
 
 /*
  * Tracepoint for free an sk_buff:
@@ -42,16 +43,35 @@ TRACE_EVENT(skb_copy_datagram_iovec,
 	TP_ARGS(skb, len),
 
 	TP_STRUCT__entry(
-		__field(	const void *,		skbaddr		)
+		__field(	const struct sk_buff *,	skb		)
 		__field(	int,			len		)
+		__field(	int,			anid		)
+		__field(	int,			cnid		)
+		__field(	int,			rx_queue	)
+		__dynamic_array(char,		name,	IFNAMSIZ	)
 	),
 
 	TP_fast_assign(
-		__entry->skbaddr = skb;
+		struct net_device *dev = NULL;
+		__entry->skb = skb;
 		__entry->len = len;
+		__entry->anid = page_to_nid(virt_to_page(skb->data));
+		__entry->cnid = cpu_to_node(smp_processor_id());
+		__entry->rx_queue = skb->queue_mapping;
+		if (skb->sk) {
+			dev = dev_get_by_index(sock_net(skb->sk), skb->iif);
+		}
+		if (dev) {
+			__assign_str(name, dev->name);
+			dev_put(dev);
+		} else {
+			__assign_str(name, "Unknown");
+		}
 	),
 
-	TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len)
+	TP_printk("skb=%p anid=%d cnid=%d len=%d rx_queue=%d name=%s",
+			__entry->skb, __entry->anid, __entry->cnid,
+			__entry->len, __entry->rx_queue, __get_str(name))
 );
 
 #endif /* _TRACE_SKB_H */

^ permalink raw reply related

* Re: UDP multicast packet loss not reported if TX ring overrun?
From: Christoph Lameter @ 2009-08-28 19:53 UTC (permalink / raw)
  To: David Miller; +Cc: sri, dlstevens, eric.dumazet, netdev, niv
In-Reply-To: <20090828.122459.245170385.davem@davemloft.net>

On Fri, 28 Aug 2009, David Miller wrote:

> From: Christoph Lameter <cl@linux-foundation.org>
> Date: Fri, 28 Aug 2009 09:53:40 -0400 (EDT)
>
> > Seems though that the qdisc drop count does not flow into the tx_dropped
> > counter for the interface.
>
> And it should not.
>
> The qdisc drops the packet due to flow control, not the hardware
> device.
>
> Device drops are for things like transmission errors on the wire.
>
> If you start incrementing tx_dropped here, people won't be able
> to tell they have a deteriorating cable or bad switch or similar.

?? The patch does not do that. That was extra stuff not covered by the
patch.


^ permalink raw reply

* Re: UDP multicast packet loss not reported if TX ring overrun?
From: Christoph Lameter @ 2009-08-28 20:09 UTC (permalink / raw)
  To: David Miller; +Cc: sri, dlstevens, eric.dumazet, netdev, niv
In-Reply-To: <20090828.130309.225603635.davem@davemloft.net>

On Fri, 28 Aug 2009, David Miller wrote:

> From: Christoph Lameter <cl@linux-foundation.org>
> Date: Fri, 28 Aug 2009 15:53:42 -0400 (EDT)
>
> > On Fri, 28 Aug 2009, David Miller wrote:
> >
> >> If you start incrementing tx_dropped here, people won't be able
> >> to tell they have a deteriorating cable or bad switch or similar.
> >
> > ?? The patch does not do that. That was extra stuff not covered by the
> > patch.
>
> Yes you did, you put a device tx_dropped counter bump into
> qdisc_drop().

Yes I did to that to test if I could propagate the counter somehow to the
device struct. But that did not work and showed that the qdisc structure
displayed by tc is different from the qdisc in use for the device. There
must be some other bug that causes the use of data from a different qdisc
to be displayed. Maybe device specific.

The patch definitely was never intended to be submitted for inclusion.
Just to show what the nature of the bug is.


^ permalink raw reply

* Re: UDP multicast packet loss not reported if TX ring overrun?
From: Christoph Lameter @ 2009-08-28 20:00 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, sri, dlstevens, netdev, niv
In-Reply-To: <20090828.122658.188210079.davem@davemloft.net>

On Fri, 28 Aug 2009, David Miller wrote:

> I'm not accepting changes like the patch you propose here, it's not
> the correct thing to do.
>
> The device never saw the packet, it never dropped it.
>
> The qdisc saw it, the qdisc dropped it, and therefore that's where we
> account for it.

udp send currently drops packets without any error message and without
incrementing any counters.

That occurs only if the socket option IP_RECVERR is not set.

If you set IP_RECVERR then statistics are kept about dropped packets and
they are displayed as drops at the IP and UDP layer.

Are you saying that this behavior is okay? It is desired behavior that a
socket option changes the way how global network counters are handled?



^ permalink raw reply

* Re: UDP multicast packet loss not reported if TX ring overrun?
From: David Miller @ 2009-08-28 20:04 UTC (permalink / raw)
  To: cl; +Cc: eric.dumazet, sri, dlstevens, netdev, niv
In-Reply-To: <alpine.DEB.1.10.0908281556480.17784@gentwo.org>

From: Christoph Lameter <cl@linux-foundation.org>
Date: Fri, 28 Aug 2009 16:00:24 -0400 (EDT)

> Are you saying that this behavior is okay? It is desired behavior that a
> socket option changes the way how global network counters are handled?

I'm saying that bumping the per-device tx_dropped counter in
the qdisc layer is wrong, nothing more.

^ permalink raw reply

* Re: UDP multicast packet loss not reported if TX ring overrun?
From: David Miller @ 2009-08-28 20:03 UTC (permalink / raw)
  To: cl; +Cc: sri, dlstevens, eric.dumazet, netdev, niv
In-Reply-To: <alpine.DEB.1.10.0908281553190.17784@gentwo.org>

From: Christoph Lameter <cl@linux-foundation.org>
Date: Fri, 28 Aug 2009 15:53:42 -0400 (EDT)

> On Fri, 28 Aug 2009, David Miller wrote:
> 
>> If you start incrementing tx_dropped here, people won't be able
>> to tell they have a deteriorating cable or bad switch or similar.
> 
> ?? The patch does not do that. That was extra stuff not covered by the
> patch.

Yes you did, you put a device tx_dropped counter bump into
qdisc_drop().

^ permalink raw reply

* [PATCH] can: switch to seq_file
From: Alexey Dobriyan @ 2009-08-28 19:57 UTC (permalink / raw)
  To: urs.thuermann, oliver.hartkopp; +Cc: netdev

create_proc_read_entry() is going to be removed soon.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---

 net/can/bcm.c  |   85 +++++++----------
 net/can/proc.c |  281 ++++++++++++++++++++++++++-------------------------------
 2 files changed, 167 insertions(+), 199 deletions(-)

--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -46,6 +46,7 @@
 #include <linux/hrtimer.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/uio.h>
 #include <linux/net.h>
 #include <linux/netdevice.h>
@@ -146,23 +147,18 @@ static char *bcm_proc_getifname(int ifindex)
 	return "???";
 }
 
-static int bcm_read_proc(char *page, char **start, off_t off,
-			 int count, int *eof, void *data)
+static int bcm_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
-	struct sock *sk = (struct sock *)data;
+	struct sock *sk = (struct sock *)m->private;
 	struct bcm_sock *bo = bcm_sk(sk);
 	struct bcm_op *op;
 
-	len += snprintf(page + len, PAGE_SIZE - len, ">>> socket %p",
-			sk->sk_socket);
-	len += snprintf(page + len, PAGE_SIZE - len, " / sk %p", sk);
-	len += snprintf(page + len, PAGE_SIZE - len, " / bo %p", bo);
-	len += snprintf(page + len, PAGE_SIZE - len, " / dropped %lu",
-			bo->dropped_usr_msgs);
-	len += snprintf(page + len, PAGE_SIZE - len, " / bound %s",
-			bcm_proc_getifname(bo->ifindex));
-	len += snprintf(page + len, PAGE_SIZE - len, " <<<\n");
+	seq_printf(m, ">>> socket %p", sk->sk_socket);
+	seq_printf(m, " / sk %p", sk);
+	seq_printf(m, " / bo %p", bo);
+	seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs);
+	seq_printf(m, " / bound %s", bcm_proc_getifname(bo->ifindex));
+	seq_printf(m, " <<<\n");
 
 	list_for_each_entry(op, &bo->rx_ops, list) {
 
@@ -172,71 +168,62 @@ static int bcm_read_proc(char *page, char **start, off_t off,
 		if (!op->frames_abs)
 			continue;
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"rx_op: %03X %-5s ",
+		seq_printf(m, "rx_op: %03X %-5s ",
 				op->can_id, bcm_proc_getifname(op->ifindex));
-		len += snprintf(page + len, PAGE_SIZE - len, "[%d]%c ",
-				op->nframes,
+		seq_printf(m, "[%d]%c ", op->nframes,
 				(op->flags & RX_CHECK_DLC)?'d':' ');
 		if (op->kt_ival1.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"timeo=%lld ",
+			seq_printf(m, "timeo=%lld ",
 					(long long)
 					ktime_to_us(op->kt_ival1));
 
 		if (op->kt_ival2.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"thr=%lld ",
+			seq_printf(m, "thr=%lld ",
 					(long long)
 					ktime_to_us(op->kt_ival2));
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"# recv %ld (%ld) => reduction: ",
+		seq_printf(m, "# recv %ld (%ld) => reduction: ",
 				op->frames_filtered, op->frames_abs);
 
 		reduction = 100 - (op->frames_filtered * 100) / op->frames_abs;
 
-		len += snprintf(page + len, PAGE_SIZE - len, "%s%ld%%\n",
+		seq_printf(m, "%s%ld%%\n",
 				(reduction == 100)?"near ":"", reduction);
-
-		if (len > PAGE_SIZE - 200) {
-			/* mark output cut off */
-			len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
-			break;
-		}
 	}
 
 	list_for_each_entry(op, &bo->tx_ops, list) {
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"tx_op: %03X %s [%d] ",
+		seq_printf(m, "tx_op: %03X %s [%d] ",
 				op->can_id, bcm_proc_getifname(op->ifindex),
 				op->nframes);
 
 		if (op->kt_ival1.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len, "t1=%lld ",
+			seq_printf(m, "t1=%lld ",
 					(long long) ktime_to_us(op->kt_ival1));
 
 		if (op->kt_ival2.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len, "t2=%lld ",
+			seq_printf(m, "t2=%lld ",
 					(long long) ktime_to_us(op->kt_ival2));
 
-		len += snprintf(page + len, PAGE_SIZE - len, "# sent %ld\n",
-				op->frames_abs);
-
-		if (len > PAGE_SIZE - 100) {
-			/* mark output cut off */
-			len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
-			break;
-		}
+		seq_printf(m, "# sent %ld\n", op->frames_abs);
 	}
+	seq_putc(m, '\n');
+	return 0;
+}
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
-
-	*eof = 1;
-	return len;
+static int bcm_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, bcm_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations bcm_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= bcm_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
  *              of the given bcm tx op
@@ -1515,9 +1502,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
 	if (proc_dir) {
 		/* unique socket address as filename */
 		sprintf(bo->procname, "%p", sock);
-		bo->bcm_proc_read = create_proc_read_entry(bo->procname, 0644,
-							   proc_dir,
-							   bcm_read_proc, sk);
+		bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
+						     proc_dir,
+						     &bcm_proc_fops, sk);
 	}
 
 	return 0;
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -196,8 +196,8 @@ void can_stat_update(unsigned long data)
  *
  */
 
-static int can_print_rcvlist(char *page, int len, struct hlist_head *rx_list,
-			     struct net_device *dev)
+static void can_print_rcvlist(struct seq_file *m, struct hlist_head *rx_list,
+			      struct net_device *dev)
 {
 	struct receiver *r;
 	struct hlist_node *n;
@@ -208,199 +208,188 @@ static int can_print_rcvlist(char *page, int len, struct hlist_head *rx_list,
 			"   %-5s  %08X  %08x  %08x  %08x  %8ld  %s\n" :
 			"   %-5s     %03X    %08x  %08lx  %08lx  %8ld  %s\n";
 
-		len += snprintf(page + len, PAGE_SIZE - len, fmt,
-				DNAME(dev), r->can_id, r->mask,
+		seq_printf(m, fmt, DNAME(dev), r->can_id, r->mask,
 				(unsigned long)r->func, (unsigned long)r->data,
 				r->matches, r->ident);
-
-		/* does a typical line fit into the current buffer? */
-
-		/* 100 Bytes before end of buffer */
-		if (len > PAGE_SIZE - 100) {
-			/* mark output cut off */
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"   (..)\n");
-			break;
-		}
 	}
 	rcu_read_unlock();
-
-	return len;
 }
 
-static int can_print_recv_banner(char *page, int len)
+static void can_print_recv_banner(struct seq_file *m)
 {
 	/*
 	 *                  can1.  00000000  00000000  00000000
 	 *                 .......          0  tp20
 	 */
-	len += snprintf(page + len, PAGE_SIZE - len,
-			"  device   can_id   can_mask  function"
+	seq_puts(m, "  device   can_id   can_mask  function"
 			"  userdata   matches  ident\n");
-
-	return len;
 }
 
-static int can_proc_read_stats(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int can_stats_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
+	seq_putc(m, '\n');
+	seq_printf(m, " %8ld transmitted frames (TXF)\n", can_stats.tx_frames);
+	seq_printf(m, " %8ld received frames (RXF)\n", can_stats.rx_frames);
+	seq_printf(m, " %8ld matched frames (RXMF)\n", can_stats.matches);
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld transmitted frames (TXF)\n",
-			can_stats.tx_frames);
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld received frames (RXF)\n", can_stats.rx_frames);
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld matched frames (RXMF)\n", can_stats.matches);
-
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
+	seq_putc(m, '\n');
 
 	if (can_stattimer.function == can_stat_update) {
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld %% total match ratio (RXMR)\n",
+		seq_printf(m, " %8ld %% total match ratio (RXMR)\n",
 				can_stats.total_rx_match_ratio);
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s total tx rate (TXR)\n",
+		seq_printf(m, " %8ld frames/s total tx rate (TXR)\n",
 				can_stats.total_tx_rate);
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s total rx rate (RXR)\n",
+		seq_printf(m, " %8ld frames/s total rx rate (RXR)\n",
 				can_stats.total_rx_rate);
 
-		len += snprintf(page + len, PAGE_SIZE - len, "\n");
+		seq_putc(m, '\n');
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld %% current match ratio (CRXMR)\n",
+		seq_printf(m, " %8ld %% current match ratio (CRXMR)\n",
 				can_stats.current_rx_match_ratio);
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s current tx rate (CTXR)\n",
+		seq_printf(m, " %8ld frames/s current tx rate (CTXR)\n",
 				can_stats.current_tx_rate);
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s current rx rate (CRXR)\n",
+		seq_printf(m, " %8ld frames/s current rx rate (CRXR)\n",
 				can_stats.current_rx_rate);
 
-		len += snprintf(page + len, PAGE_SIZE - len, "\n");
+		seq_putc(m, '\n');
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld %% max match ratio (MRXMR)\n",
+		seq_printf(m, " %8ld %% max match ratio (MRXMR)\n",
 				can_stats.max_rx_match_ratio);
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s max tx rate (MTXR)\n",
+		seq_printf(m, " %8ld frames/s max tx rate (MTXR)\n",
 				can_stats.max_tx_rate);
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s max rx rate (MRXR)\n",
+		seq_printf(m, " %8ld frames/s max rx rate (MRXR)\n",
 				can_stats.max_rx_rate);
 
-		len += snprintf(page + len, PAGE_SIZE - len, "\n");
+		seq_putc(m, '\n');
 	}
 
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld current receive list entries (CRCV)\n",
+	seq_printf(m, " %8ld current receive list entries (CRCV)\n",
 			can_pstats.rcv_entries);
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld maximum receive list entries (MRCV)\n",
+	seq_printf(m, " %8ld maximum receive list entries (MRCV)\n",
 			can_pstats.rcv_entries_max);
 
 	if (can_pstats.stats_reset)
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"\n %8ld statistic resets (STR)\n",
+		seq_printf(m, "\n %8ld statistic resets (STR)\n",
 				can_pstats.stats_reset);
 
 	if (can_pstats.user_reset)
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld user statistic resets (USTR)\n",
+		seq_printf(m, " %8ld user statistic resets (USTR)\n",
 				can_pstats.user_reset);
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
-
-	*eof = 1;
-	return len;
+	seq_putc(m, '\n');
+	return 0;
 }
 
-static int can_proc_read_reset_stats(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static int can_stats_proc_open(struct inode *inode, struct file *file)
 {
-	int len = 0;
+	return single_open(file, can_stats_proc_show, NULL);
+}
+
+static const struct file_operations can_stats_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_stats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
+static int can_reset_stats_proc_show(struct seq_file *m, void *v)
+{
 	user_reset = 1;
 
 	if (can_stattimer.function == can_stat_update) {
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"Scheduled statistic reset #%ld.\n",
+		seq_printf(m, "Scheduled statistic reset #%ld.\n",
 				can_pstats.stats_reset + 1);
 
 	} else {
 		if (can_stats.jiffies_init != jiffies)
 			can_init_stats();
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"Performed statistic reset #%ld.\n",
+		seq_printf(m, "Performed statistic reset #%ld.\n",
 				can_pstats.stats_reset);
 	}
+	return 0;
+}
 
-	*eof = 1;
-	return len;
+static int can_reset_stats_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_reset_stats_proc_show, NULL);
 }
 
-static int can_proc_read_version(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static const struct file_operations can_reset_stats_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_reset_stats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int can_version_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
+	seq_printf(m, "%s\n", CAN_VERSION_STRING);
+	return 0;
+}
 
-	len += snprintf(page + len, PAGE_SIZE - len, "%s\n",
-			CAN_VERSION_STRING);
-	*eof = 1;
-	return len;
+static int can_version_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_version_proc_show, NULL);
 }
 
-static int can_proc_read_rcvlist(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static const struct file_operations can_version_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_version_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int can_rcvlist_proc_show(struct seq_file *m, void *v)
 {
 	/* double cast to prevent GCC warning */
-	int idx = (int)(long)data;
-	int len = 0;
+	int idx = (int)(long)m->private;
 	struct dev_rcv_lists *d;
 	struct hlist_node *n;
 
-	len += snprintf(page + len, PAGE_SIZE - len,
-			"\nreceive list '%s':\n", rx_list_name[idx]);
+	seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]);
 
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) {
 
 		if (!hlist_empty(&d->rx[idx])) {
-			len = can_print_recv_banner(page, len);
-			len = can_print_rcvlist(page, len, &d->rx[idx], d->dev);
+			can_print_recv_banner(m);
+			can_print_rcvlist(m, &d->rx[idx], d->dev);
 		} else
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"  (%s: no entry)\n", DNAME(d->dev));
-
-		/* exit on end of buffer? */
-		if (len > PAGE_SIZE - 100)
-			break;
+			seq_printf(m, "  (%s: no entry)\n", DNAME(d->dev));
 	}
 	rcu_read_unlock();
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
+	seq_putc(m, '\n');
+	return 0;
+}
 
-	*eof = 1;
-	return len;
+static int can_rcvlist_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_rcvlist_proc_show, PDE(inode)->data);
 }
 
-static int can_proc_read_rcvlist_sff(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static const struct file_operations can_rcvlist_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_rcvlist_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
 	struct dev_rcv_lists *d;
 	struct hlist_node *n;
 
 	/* RX_SFF */
-	len += snprintf(page + len, PAGE_SIZE - len,
-			"\nreceive list 'rx_sff':\n");
+	seq_puts(m, "\nreceive list 'rx_sff':\n");
 
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) {
@@ -413,46 +402,38 @@ static int can_proc_read_rcvlist_sff(char *page, char **start, off_t off,
 			}
 
 		if (!all_empty) {
-			len = can_print_recv_banner(page, len);
+			can_print_recv_banner(m);
 			for (i = 0; i < 0x800; i++) {
-				if (!hlist_empty(&d->rx_sff[i]) &&
-				    len < PAGE_SIZE - 100)
-					len = can_print_rcvlist(page, len,
-								&d->rx_sff[i],
-								d->dev);
+				if (!hlist_empty(&d->rx_sff[i]))
+					can_print_rcvlist(m, &d->rx_sff[i],
+							  d->dev);
 			}
 		} else
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"  (%s: no entry)\n", DNAME(d->dev));
-
-		/* exit on end of buffer? */
-		if (len > PAGE_SIZE - 100)
-			break;
+			seq_printf(m, "  (%s: no entry)\n", DNAME(d->dev));
 	}
 	rcu_read_unlock();
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
+	seq_putc(m, '\n');
+	return 0;
+}
 
-	*eof = 1;
-	return len;
+static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_rcvlist_sff_proc_show, NULL);
 }
 
+static const struct file_operations can_rcvlist_sff_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_rcvlist_sff_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * proc utility functions
  */
 
-static struct proc_dir_entry *can_create_proc_readentry(const char *name,
-							mode_t mode,
-							read_proc_t *read_proc,
-							void *data)
-{
-	if (can_dir)
-		return create_proc_read_entry(name, mode, can_dir, read_proc,
-					      data);
-	else
-		return NULL;
-}
-
 static void can_remove_proc_readentry(const char *name)
 {
 	if (can_dir)
@@ -474,24 +455,24 @@ void can_init_proc(void)
 	}
 
 	/* own procfs entries from the AF_CAN core */
-	pde_version     = can_create_proc_readentry(CAN_PROC_VERSION, 0644,
-					can_proc_read_version, NULL);
-	pde_stats       = can_create_proc_readentry(CAN_PROC_STATS, 0644,
-					can_proc_read_stats, NULL);
-	pde_reset_stats = can_create_proc_readentry(CAN_PROC_RESET_STATS, 0644,
-					can_proc_read_reset_stats, NULL);
-	pde_rcvlist_err = can_create_proc_readentry(CAN_PROC_RCVLIST_ERR, 0644,
-					can_proc_read_rcvlist, (void *)RX_ERR);
-	pde_rcvlist_all = can_create_proc_readentry(CAN_PROC_RCVLIST_ALL, 0644,
-					can_proc_read_rcvlist, (void *)RX_ALL);
-	pde_rcvlist_fil = can_create_proc_readentry(CAN_PROC_RCVLIST_FIL, 0644,
-					can_proc_read_rcvlist, (void *)RX_FIL);
-	pde_rcvlist_inv = can_create_proc_readentry(CAN_PROC_RCVLIST_INV, 0644,
-					can_proc_read_rcvlist, (void *)RX_INV);
-	pde_rcvlist_eff = can_create_proc_readentry(CAN_PROC_RCVLIST_EFF, 0644,
-					can_proc_read_rcvlist, (void *)RX_EFF);
-	pde_rcvlist_sff = can_create_proc_readentry(CAN_PROC_RCVLIST_SFF, 0644,
-					can_proc_read_rcvlist_sff, NULL);
+	pde_version     = proc_create(CAN_PROC_VERSION, 0644, can_dir,
+				      &can_version_proc_fops);
+	pde_stats       = proc_create(CAN_PROC_STATS, 0644, can_dir,
+				      &can_stats_proc_fops);
+	pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644, can_dir,
+				      &can_reset_stats_proc_fops);
+	pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_ERR);
+	pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_ALL);
+	pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_FIL);
+	pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_INV);
+	pde_rcvlist_eff = proc_create_data(CAN_PROC_RCVLIST_EFF, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_EFF);
+	pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644, can_dir,
+				      &can_rcvlist_sff_proc_fops);
 }
 
 /*

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox