Netdev List
 help / color / mirror / Atom feed
* [PATCH 3/13] inet_diag: Export inet diag cookie checking routine
From: Pavel Emelyanov @ 2011-12-09 16:21 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

The netlink diag susbsys stores sk address bits in the nl message
as a "cookie" and uses one when dumps details about particular
socket.

The same will be required for udp diag module, so introduce a heler
in inet_diag module

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 include/linux/inet_diag.h |    2 ++
 net/ipv4/inet_diag.c      |   19 ++++++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index 851feff..5036747 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -144,6 +144,8 @@ struct inet_diag_handler {
 	__u16                   idiag_type;
 };
 
+int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req);
+
 extern int  inet_diag_register(const struct inet_diag_handler *handler);
 extern void inet_diag_unregister(const struct inet_diag_handler *handler);
 #endif /* __KERNEL__ */
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index bd3f661..ba3ae1f 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -246,6 +246,18 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
 	return inet_csk_diag_fill(sk, skb, r, pid, seq, nlmsg_flags, unlh);
 }
 
+int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req)
+{
+	if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE ||
+	     req->id.idiag_cookie[1] != INET_DIAG_NOCOOKIE) &&
+	    ((u32)(unsigned long)sk != req->id.idiag_cookie[0] ||
+	     (u32)((((unsigned long)sk) >> 31) >> 1) != req->id.idiag_cookie[1]))
+		return -ESTALE;
+	else
+		return 0;
+}
+EXPORT_SYMBOL_GPL(inet_diag_check_cookie);
+
 static int inet_diag_get_exact(struct sk_buff *in_skb,
 			       const struct nlmsghdr *nlh,
 			       struct inet_diag_req *req)
@@ -288,11 +300,8 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
 	if (sk == NULL)
 		goto unlock;
 
-	err = -ESTALE;
-	if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE ||
-	     req->id.idiag_cookie[1] != INET_DIAG_NOCOOKIE) &&
-	    ((u32)(unsigned long)sk != req->id.idiag_cookie[0] ||
-	     (u32)((((unsigned long)sk) >> 31) >> 1) != req->id.idiag_cookie[1]))
+	err = inet_diag_check_cookie(sk, req);
+	if (err)
 		goto out;
 
 	err = -ENOMEM;
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 4/13] inet_diag: Split inet_diag_get_exact into parts
From: Pavel Emelyanov @ 2011-12-09 16:22 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

The 1st part locks the inet handler and the 2nd one dump the
inet connection sock.

In the next patches the 1st part will be generalized to call
the socket dumping routine indirectly (i.e. TCP/UDP/DCCP) and
the 2nd part will be used by TCP and DCCP handlers.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 net/ipv4/inet_diag.c |   38 ++++++++++++++++++++++----------------
 1 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index ba3ae1f..64abe47 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -258,25 +258,14 @@ int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req)
 }
 EXPORT_SYMBOL_GPL(inet_diag_check_cookie);
 
-static int inet_diag_get_exact(struct sk_buff *in_skb,
-			       const struct nlmsghdr *nlh,
-			       struct inet_diag_req *req)
+static int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
+		const struct nlmsghdr *nlh, struct inet_diag_req *req)
 {
 	int err;
 	struct sock *sk;
 	struct sk_buff *rep;
-	struct inet_hashinfo *hashinfo;
-	const struct inet_diag_handler *handler;
 
-	handler = inet_diag_lock_handler(req->sdiag_protocol);
-	if (IS_ERR(handler)) {
-		err = PTR_ERR(handler);
-		goto unlock;
-	}
-
-	hashinfo = handler->idiag_hashinfo;
 	err = -EINVAL;
-
 	if (req->sdiag_family == AF_INET) {
 		sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0],
 				 req->id.idiag_dport, req->id.idiag_src[0],
@@ -293,12 +282,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
 	}
 #endif
 	else {
-		goto unlock;
+		goto out_nosk;
 	}
 
 	err = -ENOENT;
 	if (sk == NULL)
-		goto unlock;
+		goto out_nosk;
 
 	err = inet_diag_check_cookie(sk, req);
 	if (err)
@@ -332,8 +321,25 @@ out:
 		else
 			sock_put(sk);
 	}
-unlock:
+out_nosk:
+	return err;
+}
+
+static int inet_diag_get_exact(struct sk_buff *in_skb,
+			       const struct nlmsghdr *nlh,
+			       struct inet_diag_req *req)
+{
+	const struct inet_diag_handler *handler;
+	int err;
+
+	handler = inet_diag_lock_handler(req->sdiag_protocol);
+	if (IS_ERR(handler))
+		err = PTR_ERR(handler);
+	else
+		err = inet_diag_dump_one_icsk(handler->idiag_hashinfo,
+				in_skb, nlh, req);
 	inet_diag_unlock_handler(handler);
+
 	return err;
 }
 
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 5/13] inet_diag: Split inet_diag_get_exact into parts
From: Pavel Emelyanov @ 2011-12-09 16:22 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

Similar to previous patch: the 1st part locks the inet handler
and will get generalized and the 2nd one dumps icsk-s and will
be used by TCP and DCCP handlers.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 net/ipv4/inet_diag.c |   28 ++++++++++++++++------------
 1 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 64abe47..f50df2e 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -709,19 +709,11 @@ out:
 	return err;
 }
 
-static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
-		struct inet_diag_req *r, struct nlattr *bc)
+static void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
+		struct netlink_callback *cb, struct inet_diag_req *r, struct nlattr *bc)
 {
 	int i, num;
 	int s_i, s_num;
-	const struct inet_diag_handler *handler;
-	struct inet_hashinfo *hashinfo;
-
-	handler = inet_diag_lock_handler(r->sdiag_protocol);
-	if (IS_ERR(handler))
-		goto unlock;
-
-	hashinfo = handler->idiag_hashinfo;
 
 	s_i = cb->args[1];
 	s_num = num = cb->args[2];
@@ -790,7 +782,7 @@ skip_listen_ht:
 	}
 
 	if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV)))
-		goto unlock;
+		goto out;
 
 	for (i = s_i; i <= hashinfo->ehash_mask; i++) {
 		struct inet_ehash_bucket *head = &hashinfo->ehash[i];
@@ -863,8 +855,20 @@ next_dying:
 done:
 	cb->args[1] = i;
 	cb->args[2] = num;
-unlock:
+out:
+	;
+}
+
+static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+		struct inet_diag_req *r, struct nlattr *bc)
+{
+	const struct inet_diag_handler *handler;
+
+	handler = inet_diag_lock_handler(r->sdiag_protocol);
+	if (!IS_ERR(handler))
+		inet_diag_dump_icsk(handler->idiag_hashinfo, skb, cb, r, bc);
 	inet_diag_unlock_handler(handler);
+
 	return skb->len;
 }
 
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 6/13] inet_diag: Introduce the byte-code run on an inet socket
From: Pavel Emelyanov @ 2011-12-09 16:22 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

The upcoming UDP module will require exactly this ability, so just
move the existing code to provide one.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 include/linux/inet_diag.h |    2 +
 net/ipv4/inet_diag.c      |   55 +++++++++++++++++++++++++-------------------
 2 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index 5036747..907c899 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -135,6 +135,7 @@ struct tcpvegas_info {
 #ifdef __KERNEL__
 struct sock;
 struct inet_hashinfo;
+struct nlattr;
 
 struct inet_diag_handler {
 	struct inet_hashinfo    *idiag_hashinfo;
@@ -144,6 +145,7 @@ struct inet_diag_handler {
 	__u16                   idiag_type;
 };
 
+int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk);
 int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req);
 
 extern int  inet_diag_register(const struct inet_diag_handler *handler);
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index f50df2e..08e5498 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -449,6 +449,35 @@ static int inet_diag_bc_run(const struct nlattr *_bc,
 	return len == 0;
 }
 
+int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk)
+{
+	struct inet_diag_entry entry;
+	struct inet_sock *inet = inet_sk(sk);
+
+	if (bc == NULL)
+		return 1;
+
+	entry.family = sk->sk_family;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+	if (entry.family == AF_INET6) {
+		struct ipv6_pinfo *np = inet6_sk(sk);
+
+		entry.saddr = np->rcv_saddr.s6_addr32;
+		entry.daddr = np->daddr.s6_addr32;
+	} else
+#endif
+	{
+		entry.saddr = &inet->inet_rcv_saddr;
+		entry.daddr = &inet->inet_daddr;
+	}
+	entry.sport = inet->inet_num;
+	entry.dport = ntohs(inet->inet_dport);
+	entry.userlocks = sk->sk_userlocks;
+
+	return inet_diag_bc_run(bc, &entry);
+}
+EXPORT_SYMBOL_GPL(inet_diag_bc_sk);
+
 static int valid_cc(const void *bc, int len, int cc)
 {
 	while (len >= 0) {
@@ -509,30 +538,8 @@ static int inet_csk_diag_dump(struct sock *sk,
 			      struct inet_diag_req *r,
 			      const struct nlattr *bc)
 {
-	if (bc != NULL) {
-		struct inet_diag_entry entry;
-		struct inet_sock *inet = inet_sk(sk);
-
-		entry.family = sk->sk_family;
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		if (entry.family == AF_INET6) {
-			struct ipv6_pinfo *np = inet6_sk(sk);
-
-			entry.saddr = np->rcv_saddr.s6_addr32;
-			entry.daddr = np->daddr.s6_addr32;
-		} else
-#endif
-		{
-			entry.saddr = &inet->inet_rcv_saddr;
-			entry.daddr = &inet->inet_daddr;
-		}
-		entry.sport = inet->inet_num;
-		entry.dport = ntohs(inet->inet_dport);
-		entry.userlocks = sk->sk_userlocks;
-
-		if (!inet_diag_bc_run(bc, &entry))
-			return 0;
-	}
+	if (!inet_diag_bc_sk(bc, sk))
+		return 0;
 
 	return inet_csk_diag_fill(sk, skb, r,
 				  NETLINK_CB(cb->skb).pid,
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 7/13] inet_diag: Introduce the inet socket dumping routine
From: Pavel Emelyanov @ 2011-12-09 16:23 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

The existing inet_csk_diag_fill dumps the inet connection sock info
into the netlink inet_diag_message. Prepare this routine to be able
to dump only the inet_sock part of a socket if the icsk part is missing.

This will be used by UDP diag module when dumping UDP sockets.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 include/linux/inet_diag.h |    7 ++++++
 net/ipv4/inet_diag.c      |   53 ++++++++++++++++++++++++++++----------------
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index 907c899..eaf5865 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -136,6 +136,8 @@ struct tcpvegas_info {
 struct sock;
 struct inet_hashinfo;
 struct nlattr;
+struct nlmsghdr;
+struct sk_buff;
 
 struct inet_diag_handler {
 	struct inet_hashinfo    *idiag_hashinfo;
@@ -145,6 +147,11 @@ struct inet_diag_handler {
 	__u16                   idiag_type;
 };
 
+struct inet_connection_sock;
+int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
+			      struct sk_buff *skb, struct inet_diag_req *req,
+			      u32 pid, u32 seq, u16 nlmsg_flags,
+			      const struct nlmsghdr *unlh);
 int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk);
 int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req);
 
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 08e5498..dc8611e 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -70,13 +70,12 @@ static inline void inet_diag_unlock_handler(
 	mutex_unlock(&inet_diag_table_mutex);
 }
 
-static int inet_csk_diag_fill(struct sock *sk,
+int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
 			      struct sk_buff *skb, struct inet_diag_req *req,
 			      u32 pid, u32 seq, u16 nlmsg_flags,
 			      const struct nlmsghdr *unlh)
 {
 	const struct inet_sock *inet = inet_sk(sk);
-	const struct inet_connection_sock *icsk = inet_csk(sk);
 	struct inet_diag_msg *r;
 	struct nlmsghdr  *nlh;
 	void *info = NULL;
@@ -97,16 +96,6 @@ static int inet_csk_diag_fill(struct sock *sk,
 	if (ext & (1 << (INET_DIAG_MEMINFO - 1)))
 		minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO, sizeof(*minfo));
 
-	if (ext & (1 << (INET_DIAG_INFO - 1)))
-		info = INET_DIAG_PUT(skb, INET_DIAG_INFO, sizeof(struct tcp_info));
-
-	if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) {
-		const size_t len = strlen(icsk->icsk_ca_ops->name);
-
-		strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1),
-		       icsk->icsk_ca_ops->name);
-	}
-
 	r->idiag_family = sk->sk_family;
 	r->idiag_state = sk->sk_state;
 	r->idiag_timer = 0;
@@ -138,6 +127,21 @@ static int inet_csk_diag_fill(struct sock *sk,
 	}
 #endif
 
+	r->idiag_uid = sock_i_uid(sk);
+	r->idiag_inode = sock_i_ino(sk);
+
+	if (minfo) {
+		minfo->idiag_rmem = sk_rmem_alloc_get(sk);
+		minfo->idiag_wmem = sk->sk_wmem_queued;
+		minfo->idiag_fmem = sk->sk_forward_alloc;
+		minfo->idiag_tmem = sk_wmem_alloc_get(sk);
+	}
+
+	if (icsk == NULL) {
+		r->idiag_rqueue = r->idiag_wqueue = 0;
+		goto out;
+	}
+
 #define EXPIRES_IN_MS(tmo)  DIV_ROUND_UP((tmo - jiffies) * 1000, HZ)
 
 	if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
@@ -158,14 +162,14 @@ static int inet_csk_diag_fill(struct sock *sk,
 	}
 #undef EXPIRES_IN_MS
 
-	r->idiag_uid = sock_i_uid(sk);
-	r->idiag_inode = sock_i_ino(sk);
+	if (ext & (1 << (INET_DIAG_INFO - 1)))
+		info = INET_DIAG_PUT(skb, INET_DIAG_INFO, sizeof(struct tcp_info));
 
-	if (minfo) {
-		minfo->idiag_rmem = sk_rmem_alloc_get(sk);
-		minfo->idiag_wmem = sk->sk_wmem_queued;
-		minfo->idiag_fmem = sk->sk_forward_alloc;
-		minfo->idiag_tmem = sk_wmem_alloc_get(sk);
+	if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) {
+		const size_t len = strlen(icsk->icsk_ca_ops->name);
+
+		strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1),
+		       icsk->icsk_ca_ops->name);
 	}
 
 	handler->idiag_get_info(sk, r, info);
@@ -174,6 +178,7 @@ static int inet_csk_diag_fill(struct sock *sk,
 	    icsk->icsk_ca_ops && icsk->icsk_ca_ops->get_info)
 		icsk->icsk_ca_ops->get_info(sk, ext, skb);
 
+out:
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	return skb->len;
 
@@ -182,6 +187,16 @@ nlmsg_failure:
 	nlmsg_trim(skb, b);
 	return -EMSGSIZE;
 }
+EXPORT_SYMBOL_GPL(inet_sk_diag_fill);
+
+static int inet_csk_diag_fill(struct sock *sk,
+			      struct sk_buff *skb, struct inet_diag_req *req,
+			      u32 pid, u32 seq, u16 nlmsg_flags,
+			      const struct nlmsghdr *unlh)
+{
+	return inet_sk_diag_fill(sk, inet_csk(sk),
+			skb, req, pid, seq, nlmsg_flags, unlh);
+}
 
 static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
 			       struct sk_buff *skb, struct inet_diag_req *req,
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 8/13] inet_diag: Generalize inet_diag dump and get_exact calls
From: Pavel Emelyanov @ 2011-12-09 16:23 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

Introduce two callbacks in inet_diag_handler -- one for dumping all
sockets (with filters) and the other one for dumping a single sk.

Replace direct calls to icsk handlers with indirect calls to callbacks
provided by handlers.

Make existing TCP and DCCP handlers use provided helpers for icsk-s.

The UDP diag module will provide its own.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 include/linux/inet_diag.h |   18 +++++++++++++++++-
 net/dccp/diag.c           |   15 ++++++++++++++-
 net/ipv4/inet_diag.c      |   11 ++++++-----
 net/ipv4/tcp_diag.c       |   15 ++++++++++++++-
 4 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index eaf5865..78972a1 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -138,9 +138,18 @@ struct inet_hashinfo;
 struct nlattr;
 struct nlmsghdr;
 struct sk_buff;
+struct netlink_callback;
 
 struct inet_diag_handler {
-	struct inet_hashinfo    *idiag_hashinfo;
+	void			(*dump)(struct sk_buff *skb,
+					struct netlink_callback *cb,
+					struct inet_diag_req *r,
+					struct nlattr *bc);
+
+	int			(*dump_one)(struct sk_buff *in_skb,
+					const struct nlmsghdr *nlh,
+					struct inet_diag_req *req);
+
 	void			(*idiag_get_info)(struct sock *sk,
 						  struct inet_diag_msg *r,
 						  void *info);
@@ -152,6 +161,13 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
 			      struct sk_buff *skb, struct inet_diag_req *req,
 			      u32 pid, u32 seq, u16 nlmsg_flags,
 			      const struct nlmsghdr *unlh);
+void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb,
+		struct netlink_callback *cb, struct inet_diag_req *r,
+		struct nlattr *bc);
+int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo,
+		struct sk_buff *in_skb, const struct nlmsghdr *nlh,
+		struct inet_diag_req *req);
+
 int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk);
 int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req);
 
diff --git a/net/dccp/diag.c b/net/dccp/diag.c
index 9343f52..e29214d 100644
--- a/net/dccp/diag.c
+++ b/net/dccp/diag.c
@@ -48,8 +48,21 @@ static void dccp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
 		dccp_get_info(sk, _info);
 }
 
+static void dccp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+		struct inet_diag_req *r, struct nlattr *bc)
+{
+	inet_diag_dump_icsk(&dccp_hashinfo, skb, cb, r, bc);
+}
+
+static int dccp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh,
+		struct inet_diag_req *req)
+{
+	return inet_diag_dump_one_icsk(&dccp_hashinfo, in_skb, nlh, req);
+}
+
 static const struct inet_diag_handler dccp_diag_handler = {
-	.idiag_hashinfo	 = &dccp_hashinfo,
+	.dump		 = dccp_diag_dump,
+	.dump_one	 = dccp_diag_dump_one,
 	.idiag_get_info	 = dccp_diag_get_info,
 	.idiag_type	 = IPPROTO_DCCP,
 };
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index dc8611e..9b3e0b1 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -273,7 +273,7 @@ int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req)
 }
 EXPORT_SYMBOL_GPL(inet_diag_check_cookie);
 
-static int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
+int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
 		const struct nlmsghdr *nlh, struct inet_diag_req *req)
 {
 	int err;
@@ -339,6 +339,7 @@ out:
 out_nosk:
 	return err;
 }
+EXPORT_SYMBOL_GPL(inet_diag_dump_one_icsk);
 
 static int inet_diag_get_exact(struct sk_buff *in_skb,
 			       const struct nlmsghdr *nlh,
@@ -351,8 +352,7 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
 	if (IS_ERR(handler))
 		err = PTR_ERR(handler);
 	else
-		err = inet_diag_dump_one_icsk(handler->idiag_hashinfo,
-				in_skb, nlh, req);
+		err = handler->dump_one(in_skb, nlh, req);
 	inet_diag_unlock_handler(handler);
 
 	return err;
@@ -731,7 +731,7 @@ out:
 	return err;
 }
 
-static void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
+void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
 		struct netlink_callback *cb, struct inet_diag_req *r, struct nlattr *bc)
 {
 	int i, num;
@@ -880,6 +880,7 @@ done:
 out:
 	;
 }
+EXPORT_SYMBOL_GPL(inet_diag_dump_icsk);
 
 static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
 		struct inet_diag_req *r, struct nlattr *bc)
@@ -888,7 +889,7 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
 
 	handler = inet_diag_lock_handler(r->sdiag_protocol);
 	if (!IS_ERR(handler))
-		inet_diag_dump_icsk(handler->idiag_hashinfo, skb, cb, r, bc);
+		handler->dump(skb, cb, r, bc);
 	inet_diag_unlock_handler(handler);
 
 	return skb->len;
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 42e6bec..6334b1f 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -34,8 +34,21 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
 		tcp_get_info(sk, info);
 }
 
+static void tcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+		struct inet_diag_req *r, struct nlattr *bc)
+{
+	inet_diag_dump_icsk(&tcp_hashinfo, skb, cb, r, bc);
+}
+
+static int tcp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh,
+		struct inet_diag_req *req)
+{
+	return inet_diag_dump_one_icsk(&tcp_hashinfo, in_skb, nlh, req);
+}
+
 static const struct inet_diag_handler tcp_diag_handler = {
-	.idiag_hashinfo	 = &tcp_hashinfo,
+	.dump		 = tcp_diag_dump,
+	.dump_one	 = tcp_diag_dump_one,
 	.idiag_get_info	 = tcp_diag_get_info,
 	.idiag_type	 = IPPROTO_TCP,
 };
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 9/13] udp: Export code sk lookup routines
From: Pavel Emelyanov @ 2011-12-09 16:23 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

The UDP diag get_exact handler will require them to find a
socket by provided net, [sd]addr-s, [sd]ports and device.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 include/net/udp.h |    6 ++++++
 net/ipv4/udp.c    |    3 ++-
 net/ipv6/udp.c    |    3 ++-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/net/udp.h b/include/net/udp.h
index f54a515..1ffb39c 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -194,9 +194,15 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
 				    __be32 daddr, __be16 dport,
 				    int dif);
+extern struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
+				    __be32 daddr, __be16 dport,
+				    int dif, struct udp_table *tbl);
 extern struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
 				    const struct in6_addr *daddr, __be16 dport,
 				    int dif);
+extern struct sock *__udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
+				    const struct in6_addr *daddr, __be16 dport,
+				    int dif, struct udp_table *tbl);
 
 /*
  * 	SNMP statistics for UDP and UDP-Lite
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ad481b3..5d075b5 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -445,7 +445,7 @@ exact_match:
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
  * harder than this. -DaveM
  */
-static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
+struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
 		__be16 sport, __be32 daddr, __be16 dport,
 		int dif, struct udp_table *udptable)
 {
@@ -512,6 +512,7 @@ begin:
 	rcu_read_unlock();
 	return result;
 }
+EXPORT_SYMBOL_GPL(__udp4_lib_lookup);
 
 static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
 						 __be16 sport, __be16 dport,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index adfe26a..4f96b5c 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -238,7 +238,7 @@ exact_match:
 	return result;
 }
 
-static struct sock *__udp6_lib_lookup(struct net *net,
+struct sock *__udp6_lib_lookup(struct net *net,
 				      const struct in6_addr *saddr, __be16 sport,
 				      const struct in6_addr *daddr, __be16 dport,
 				      int dif, struct udp_table *udptable)
@@ -305,6 +305,7 @@ begin:
 	rcu_read_unlock();
 	return result;
 }
+EXPORT_SYMBOL_GPL(__udp6_lib_lookup);
 
 static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
 					  __be16 sport, __be16 dport,
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 10/13] udp_diag: Basic skeleton
From: Pavel Emelyanov @ 2011-12-09 16:23 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

Introduce the transport level diag handler module for UDP (and UDP-lite)
sockets and register (empty for now) callbacks in the inet_diag module.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 net/ipv4/udp_diag.c |   96 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 96 insertions(+), 0 deletions(-)
 create mode 100644 net/ipv4/udp_diag.c

diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
new file mode 100644
index 0000000..15936a3
--- /dev/null
+++ b/net/ipv4/udp_diag.c
@@ -0,0 +1,96 @@
+/*
+ * udp_diag.c	Module for monitoring UDP transport protocols sockets.
+ *
+ * Authors:	Pavel Emelyanov, <xemul@parallels.com>
+ *
+ *	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.
+ */
+
+
+#include <linux/module.h>
+#include <linux/inet_diag.h>
+#include <linux/udp.h>
+#include <net/udp.h>
+#include <net/udplite.h>
+#include <linux/inet_diag.h>
+#include <linux/sock_diag.h>
+
+static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
+		const struct nlmsghdr *nlh, struct inet_diag_req *req)
+{
+	return 0;
+}
+
+static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlink_callback *cb,
+		struct inet_diag_req *r, struct nlattr *bc)
+{
+}
+
+static void udp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+		struct inet_diag_req *r, struct nlattr *bc)
+{
+	udp_dump(&udp_table, skb, cb, r, bc);
+}
+
+static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh,
+		struct inet_diag_req *req)
+{
+	return udp_dump_one(&udp_table, in_skb, nlh, req);
+}
+
+static const struct inet_diag_handler udp_diag_handler = {
+	.dump		 = udp_diag_dump,
+	.dump_one	 = udp_diag_dump_one,
+	.idiag_type	 = IPPROTO_UDP,
+};
+
+static void udplite_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+		struct inet_diag_req *r, struct nlattr *bc)
+{
+	udp_dump(&udplite_table, skb, cb, r, bc);
+}
+
+static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh,
+		struct inet_diag_req *req)
+{
+	return udp_dump_one(&udplite_table, in_skb, nlh, req);
+}
+
+static const struct inet_diag_handler udplite_diag_handler = {
+	.dump		 = udplite_diag_dump,
+	.dump_one	 = udplite_diag_dump_one,
+	.idiag_type	 = IPPROTO_UDPLITE,
+};
+
+static int __init udp_diag_init(void)
+{
+	int err;
+
+	err = inet_diag_register(&udp_diag_handler);
+	if (err)
+		goto out;
+	err = inet_diag_register(&udplite_diag_handler);
+	if (err)
+		goto out_lite;
+out:
+	return err;
+out_lite:
+	inet_diag_unregister(&udp_diag_handler);
+	goto out;
+}
+
+static void __exit udp_diag_exit(void)
+{
+	inet_diag_unregister(&udplite_diag_handler);
+	inet_diag_unregister(&udp_diag_handler);
+}
+
+module_init(udp_diag_init);
+module_exit(udp_diag_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 17);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 136);
+
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 11/13] udp_diag: Implement the get_exact dumping functionality
From: Pavel Emelyanov @ 2011-12-09 16:24 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

Do the same as TCP does -- lookup a socket in the given udp_table,
check cookie, fill the reply message with existing inet socket dumping
helper and send one back.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 net/ipv4/udp_diag.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index 15936a3..3938aef 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -21,7 +21,57 @@
 static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
 		const struct nlmsghdr *nlh, struct inet_diag_req *req)
 {
-	return 0;
+	int err = -EINVAL;
+	struct sock *sk;
+	struct sk_buff *rep;
+
+	if (req->sdiag_family == AF_INET)
+		sk = __udp4_lib_lookup(&init_net,
+				req->id.idiag_src[0], req->id.idiag_sport,
+				req->id.idiag_dst[0], req->id.idiag_dport,
+				req->id.idiag_if, tbl);
+	else if (req->sdiag_family == AF_INET6)
+		sk = __udp6_lib_lookup(&init_net,
+				(struct in6_addr *)req->id.idiag_src,
+				req->id.idiag_sport,
+				(struct in6_addr *)req->id.idiag_dst,
+				req->id.idiag_dport,
+				req->id.idiag_if, tbl);
+	else
+		goto out_nosk;
+
+	err = -ENOENT;
+	if (sk == NULL)
+		goto out_nosk;
+
+	err = inet_diag_check_cookie(sk, req);
+	if (err)
+		goto out;
+
+	err = -ENOMEM;
+	rep = alloc_skb(NLMSG_SPACE((sizeof(struct inet_diag_msg) +
+				     sizeof(struct inet_diag_meminfo) +
+				     64)), GFP_KERNEL);
+	if (!rep)
+		goto out;
+
+	err = inet_sk_diag_fill(sk, NULL, rep, req,
+			   NETLINK_CB(in_skb).pid,
+			   nlh->nlmsg_seq, 0, nlh);
+	if (err < 0) {
+		WARN_ON(err == -EMSGSIZE);
+		kfree_skb(rep);
+		goto out;
+	}
+	err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid,
+			      MSG_DONTWAIT);
+	if (err > 0)
+		err = 0;
+out:
+	if (sk)
+		sock_put(sk);
+out_nosk:
+	return err;
 }
 
 static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlink_callback *cb,
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 12/13] udp_diag: Implement the dump-all functionality
From: Pavel Emelyanov @ 2011-12-09 16:24 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

Do the same as TCP does -- iterate the given udp_table, filter
sockets with bytecode and dump sockets into reply message.

The same filtering as for TCP applies, though only some of the
state bits really matter.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 net/ipv4/udp_diag.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c
index 3938aef..3447634 100644
--- a/net/ipv4/udp_diag.c
+++ b/net/ipv4/udp_diag.c
@@ -18,6 +18,17 @@
 #include <linux/inet_diag.h>
 #include <linux/sock_diag.h>
 
+static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,
+		struct netlink_callback *cb, struct inet_diag_req *req,
+		struct nlattr *bc)
+{
+	if (!inet_diag_bc_sk(bc, sk))
+		return 0;
+
+	return inet_sk_diag_fill(sk, NULL, skb, req, NETLINK_CB(cb->skb).pid,
+			cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
+}
+
 static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
 		const struct nlmsghdr *nlh, struct inet_diag_req *req)
 {
@@ -77,6 +88,49 @@ out_nosk:
 static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlink_callback *cb,
 		struct inet_diag_req *r, struct nlattr *bc)
 {
+	int num, s_num, slot, s_slot;
+
+	s_slot = cb->args[0];
+	num = s_num = cb->args[1];
+
+	for (slot = s_slot; slot <= table->mask; num = s_num = 0, slot++) {
+		struct sock *sk;
+		struct hlist_nulls_node *node;
+		struct udp_hslot *hslot = &table->hash[slot];
+
+		if (hlist_nulls_empty(&hslot->head))
+			continue;
+
+		spin_lock_bh(&hslot->lock);
+		sk_nulls_for_each(sk, node, &hslot->head) {
+			struct inet_sock *inet = inet_sk(sk);
+
+			if (num < s_num)
+				goto next;
+			if (!(r->idiag_states & (1 << sk->sk_state)))
+				goto next;
+			if (r->sdiag_family != AF_UNSPEC &&
+					sk->sk_family != r->sdiag_family)
+				goto next;
+			if (r->id.idiag_sport != inet->inet_sport &&
+			    r->id.idiag_sport)
+				goto next;
+			if (r->id.idiag_dport != inet->inet_dport &&
+			    r->id.idiag_dport)
+				goto next;
+
+			if (sk_diag_dump(sk, skb, cb, r, bc) < 0) {
+				spin_unlock_bh(&hslot->lock);
+				goto done;
+			}
+next:
+			num++;
+		}
+		spin_unlock_bh(&hslot->lock);
+	}
+done:
+	cb->args[0] = slot;
+	cb->args[1] = num;
 }
 
 static void udp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH 13/13] udp_diag: Wire the udp_diag module into kbuild
From: Pavel Emelyanov @ 2011-12-09 16:24 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

Copy-s/tcp/udp/-paste from TCP bits.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---
 net/ipv4/Kconfig  |    4 ++++
 net/ipv4/Makefile |    1 +
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index cbb505b..a51e33e 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -409,6 +409,10 @@ config INET_TCP_DIAG
 	depends on INET_DIAG
 	def_tristate INET_DIAG
 
+config INET_UDP_DIAG
+	depends on INET_DIAG
+	def_tristate INET_DIAG
+
 menuconfig TCP_CONG_ADVANCED
 	bool "TCP: advanced congestion control"
 	---help---
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f2dc69c..e9d98e6 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_IP_PNP) += ipconfig.o
 obj-$(CONFIG_NETFILTER)	+= netfilter.o netfilter/
 obj-$(CONFIG_INET_DIAG) += inet_diag.o 
 obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
+obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o
 obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
 obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o
-- 
1.5.5.6

^ permalink raw reply related

* [PATCH] iproute: Dump UDP sockets via netlink
From: Pavel Emelyanov @ 2011-12-09 16:26 UTC (permalink / raw)
  To: David Miller, Linux Netdev List
In-Reply-To: <4EE23561.5020804@parallels.com>

Since for UDP the same binary API is used, just rename tcp_show_netlink and others
into inet_show_netlink (and others) and wire the calls into udp-related paths.

Applies on top of previous patch with support for the new sock_diag api.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>

---

diff -u b/misc/ss.c b/misc/ss.c
--- b/misc/ss.c
+++ b/misc/ss.c
@@ -1410,7 +1410,7 @@
 	}
 }
 
-static int tcp_show_sock(struct nlmsghdr *nlh, struct filter *f)
+static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f)
 {
 	struct inet_diag_msg *r = NLMSG_DATA(nlh);
 	struct tcpstat s;
@@ -1474,7 +1474,7 @@
 	return 0;
 }
 
-static int __tcp_show_netlink(struct filter *f, FILE *dump_fp, int family, int socktype)
+static int __inet_show_netlink(struct filter *f, FILE *dump_fp, int family, int socktype)
 {
 	int fd;
 	struct sockaddr_nl nladdr;
@@ -1590,7 +1590,7 @@
 				return 0;
 			}
 			if (!dump_fp) {
-				err = tcp_show_sock(h, NULL);
+				err = inet_show_sock(h, NULL);
 				if (err < 0)
 					return err;
 			}
@@ -1610,19 +1610,19 @@
 	return 0;
 }
 
-static int tcp_show_netlink(struct filter *f, FILE *dump_fp, int socktype)
+static int inet_show_netlink(struct filter *f, FILE *dump_fp, int socktype)
 {
 	int err = 0;
 
 	if (f->families & (1 << AF_INET))
-		err |= __tcp_show_netlink(f, dump_fp, AF_INET, socktype);
+		err |= __inet_show_netlink(f, dump_fp, AF_INET, socktype);
 	if (f->families & (1 << AF_INET6))
-		err |= __tcp_show_netlink(f, dump_fp, AF_INET6, socktype);
+		err |= __inet_show_netlink(f, dump_fp, AF_INET6, socktype);
 
 	return err;
 }
 
-static int tcp_show_netlink_file(struct filter *f)
+static int inet_show_netlink_file(struct filter *f)
 {
 	FILE	*fp;
 	char	buf[8192];
@@ -1672,7 +1672,7 @@
 			return -1;
 		}
 
-		err = tcp_show_sock(h, f);
+		err = inet_show_sock(h, f);
 		if (err < 0)
 			return err;
 	}
@@ -1687,10 +1687,10 @@
 	dg_proto = TCP_PROTO;
 
 	if (getenv("TCPDIAG_FILE"))
-		return tcp_show_netlink_file(f);
+		return inet_show_netlink_file(f);
 
 	if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
-	    && tcp_show_netlink(f, NULL, socktype) == 0)
+	    && inet_show_netlink(f, NULL, socktype) == 0)
 		return 0;
 
 	/* Sigh... We have to parse /proc/net/tcp... */
@@ -1852,6 +1852,15 @@
 {
 	FILE *fp = NULL;
 
+	if (getenv("TCPDIAG_FILE"))
+		return inet_show_netlink_file(f);
+
+	if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT")
+	    && inet_show_netlink(f, NULL, IPPROTO_UDP) == 0)
+		return 0;
+
+	/* legacy proc files parse */
+
 	dg_proto = UDP_PROTO;
 
 	if (f->families&(1<<AF_INET)) {
@@ -2787,7 +2796,7 @@
 
 	if (dump_tcpdiag) {
 		FILE *dump_fp = stdout;
-		if (!(current_filter.dbs & (1<<TCP_DB))) {
+		if (!(current_filter.dbs & ((1<<TCP_DB) | (1<<UDP_DB)))) {
 			fprintf(stderr, "ss: tcpdiag dump requested and no tcp in filter.\n");
 			exit(0);
 		}
@@ -2798,7 +2807,13 @@
 				exit(-1);
 			}
 		}
-		tcp_show_netlink(&current_filter, dump_fp, IPPROTO_TCP);
+
+		if (current_filter.dbs & (1<<UDP_DB))
+			inet_show_netlink(&current_filter, dump_fp, IPPROTO_UDP);
+
+		if (current_filter.dbs & (1<<TCP_DB))
+			inet_show_netlink(&current_filter, dump_fp, IPPROTO_TCP);
+
 		fflush(dump_fp);
 		exit(0);
 	}

^ permalink raw reply

* Re: TCP fast retransmit
From: Eric Dumazet @ 2011-12-09 16:31 UTC (permalink / raw)
  To: Esztermann, Ansgar; +Cc: netdev@vger.kernel.org
In-Reply-To: <6DA1FA31-8983-4338-A1B8-5697A876E2B6@mpi-bpc.mpg.de>

Le vendredi 09 décembre 2011 à 17:17 +0100, Esztermann, Ansgar a écrit :
> On Dec 9, 2011, at 15:43 , Eric Dumazet wrote:
> 
> > It seems you have a lot of packet reorders.
> > 
> > Are you using multipath or some channel bonding ?
> 
> Not that I am aware of (i.e. not on our end). However, the connection
> will probably routed through a firewall. I will have to check if it is
> configured to avoid reordering.
> 

Is it a linux based firewall ?

I suspect this firewall terminates a tunnel ?

If so, make sure network interrupts are handled by the same cpu.

(because tunneling means calling netif_rx() : This can be the reason for
Out Of Order packets, if next hardware interrupt is delivered to another
cpu)

We really should call netif_receive_skb() for the first tunnel level to
avoid this...

^ permalink raw reply

* Re: [net-next PATCH] net: netprio_cgroup: make net_prio_subsys static
From: John Fastabend @ 2011-12-09 16:31 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, nhorman@tuxdriver.com, netdev@vger.kernel.org
In-Reply-To: <1323446704.2336.20.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>

On 12/9/2011 8:05 AM, Eric Dumazet wrote:
> Le jeudi 08 décembre 2011 à 19:53 -0500, David Miller a écrit :
>> From: Neil Horman <nhorman@tuxdriver.com>
>> Date: Thu, 8 Dec 2011 06:45:55 -0500
>>
>>> On Wed, Dec 07, 2011 at 09:17:17PM -0800, John Fastabend wrote:
>>>> net_prio_subsys can be made static this removes the sparse
>>>> warning it was throwing.
>>>>
>>>> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
>>  ...
>>> Acked-by: Neil Horman <nhorman@tuxdriver.com>
>>
>> Applied.
>> --
> 
> But it trivialy breaks the build ? Or am I mistaken ?
> 

Dang. No your right. When its not built as a module it breaks. Sorry
I'll revert it.

> 
> $ grep CONFIG_NETPRIO_CGROUP .config
> CONFIG_NETPRIO_CGROUP=y
> 
> $ make net/core/netprio_cgroup.o
>   CC      net/core/netprio_cgroup.o
> net/core/netprio_cgroup.c:31:29: error: static declaration of ‘net_prio_subsys’ follows non-static declaration
> include/linux/cgroup_subsys.h:71:1: note: previous declaration of ‘net_prio_subsys’ was here
> make[1]: *** [net/core/netprio_cgroup.o] Error 1
> make: *** [net/core/netprio_cgroup.o] Error 2
> 
> 
> 

^ permalink raw reply

* Re: [PATCH] net/hyperv: Fix the stop/wake queue mechanism
From: Greg KH @ 2011-12-09 16:35 UTC (permalink / raw)
  To: Haiyang Zhang
  Cc: KY Srinivasan, davem@davemloft.net, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, devel@linuxdriverproject.org
In-Reply-To: <A1F3067C9B68744AA19F6802BAB8FFDC0CCD457B@TK5EX14MBXC227.redmond.corp.microsoft.com>

On Fri, Dec 09, 2011 at 04:00:59PM +0000, Haiyang Zhang wrote:
> > -----Original Message-----
> > From: Haiyang Zhang [mailto:haiyangz@microsoft.com]
> > Sent: Friday, December 02, 2011 2:56 PM
> > To: Haiyang Zhang; KY Srinivasan; davem@davemloft.net; gregkh@suse.de;
> > linux-kernel@vger.kernel.org; netdev@vger.kernel.org;
> > devel@linuxdriverproject.org
> > Subject: [PATCH] net/hyperv: Fix the stop/wake queue mechanism
> > 
> > The ring buffer is only used to pass meta data for outbound packets. The
> > actual payload is accessed by DMA from the host. So the stop/wake queue
> > mechanism based on counting and comparing number of pages sent v.s.
> > number
> > of pages in the ring buffer is wrong. Also, there is a race condition in
> > the stop/wake queue calls, which can stop xmit queue forever.
> > 
> > The new stop/wake queue mechanism is based on the actual bytes used by
> > outbound packets in the ring buffer. The check for number of outstanding
> > sends after stop queue prevents the race condition that can cause wake
> > queue happening earlier than stop queue.
> > 
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reported-by: Long Li <longli@microsoft.com>
> > ---
> >  drivers/net/hyperv/netvsc.c     |   14 +++++++++++---
> >  drivers/net/hyperv/netvsc_drv.c |   24 +-----------------------
> >  2 files changed, 12 insertions(+), 26 deletions(-)
> 
> Hi Greg,
> 
> Since the netvsc haven't been merged into Dave's tree yet after out of staging,
> could you consider this patch for your tree?

It's in my "to-apply" queue already.

thanks,

greg k-h

^ permalink raw reply

* Re: [net-next PATCH] net: netprio_cgroup: make net_prio_subsys static
From: Neil Horman @ 2011-12-09 16:40 UTC (permalink / raw)
  To: John Fastabend; +Cc: Eric Dumazet, David Miller, netdev@vger.kernel.org
In-Reply-To: <4EE237FF.20409@intel.com>

On Fri, Dec 09, 2011 at 08:31:59AM -0800, John Fastabend wrote:
> On 12/9/2011 8:05 AM, Eric Dumazet wrote:
> > Le jeudi 08 décembre 2011 à 19:53 -0500, David Miller a écrit :
> >> From: Neil Horman <nhorman@tuxdriver.com>
> >> Date: Thu, 8 Dec 2011 06:45:55 -0500
> >>
> >>> On Wed, Dec 07, 2011 at 09:17:17PM -0800, John Fastabend wrote:
> >>>> net_prio_subsys can be made static this removes the sparse
> >>>> warning it was throwing.
> >>>>
> >>>> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> >>  ...
> >>> Acked-by: Neil Horman <nhorman@tuxdriver.com>
> >>
> >> Applied.
> >> --
> > 
> > But it trivialy breaks the build ? Or am I mistaken ?
> > 
> 
> Dang. No your right. When its not built as a module it breaks. Sorry
> I'll revert it.
> 
Yeah, I'd say revert it for now, but I think the real problem is that the SUBSYS
macro in the cgroup core code automatically defines a subsys structure as
extern.  We should look into fixing that properly instead long term.

> > 
> > $ grep CONFIG_NETPRIO_CGROUP .config
> > CONFIG_NETPRIO_CGROUP=y
> > 
> > $ make net/core/netprio_cgroup.o
> >   CC      net/core/netprio_cgroup.o
> > net/core/netprio_cgroup.c:31:29: error: static declaration of ‘net_prio_subsys’ follows non-static declaration
> > include/linux/cgroup_subsys.h:71:1: note: previous declaration of ‘net_prio_subsys’ was here
> > make[1]: *** [net/core/netprio_cgroup.o] Error 1
> > make: *** [net/core/netprio_cgroup.o] Error 2
> > 
> > 
> > 
> 
> 

^ permalink raw reply

* RE: [PATCH] net/hyperv: Fix the stop/wake queue mechanism
From: Haiyang Zhang @ 2011-12-09 16:49 UTC (permalink / raw)
  To: Greg KH
  Cc: KY Srinivasan, davem@davemloft.net, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, devel@linuxdriverproject.org
In-Reply-To: <20111209163508.GA19001@suse.de>

> -----Original Message-----
> From: Greg KH [mailto:gregkh@suse.de]
> Sent: Friday, December 09, 2011 11:35 AM
> To: Haiyang Zhang
> Cc: KY Srinivasan; davem@davemloft.net; linux-kernel@vger.kernel.org;
> netdev@vger.kernel.org; devel@linuxdriverproject.org
> Subject: Re: [PATCH] net/hyperv: Fix the stop/wake queue mechanism
> 
> On Fri, Dec 09, 2011 at 04:00:59PM +0000, Haiyang Zhang wrote:
> > > -----Original Message-----
> > > From: Haiyang Zhang [mailto:haiyangz@microsoft.com]
> > >  drivers/net/hyperv/netvsc.c     |   14 +++++++++++---
> > >  drivers/net/hyperv/netvsc_drv.c |   24 +-----------------------
> > >  2 files changed, 12 insertions(+), 26 deletions(-)
> >
> > Hi Greg,
> >
> > Since the netvsc haven't been merged into Dave's tree yet after out of
> staging,
> > could you consider this patch for your tree?
> 
> It's in my "to-apply" queue already.

Thank you!

- Haiyang

^ permalink raw reply

* [PATCH] Revert "net: netprio_cgroup: make net_prio_subsys static"
From: John Fastabend @ 2011-12-09 17:03 UTC (permalink / raw)
  To: davem; +Cc: nhorman, eric.dumazet, netdev

This reverts commit 865d9f9f748fdc1943679ea65d9ee1dc55e4a6ae.

This commit breaks the build with CONFIG_NETPRIO_CGROUP=y so
revert it. It does build as a module though. The SUBSYS macro
in the cgroup core code automatically defines a subsys structure
as extern. Long term we should fix the macro. And I need to
fully build test things.

Tested with CONFIG_NETPRIO_CGROUP={y|m|n} with and without
CONFIG_CGROUPS defined.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
CC: Neil Horman <nhorman@tuxdriver.com>
Reported-By: Eric Dumazet <eric.dumazet@gmail.com>
---

 net/core/netprio_cgroup.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index ea16c8f..3a9fd48 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -28,7 +28,7 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
 static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
 static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
 
-static struct cgroup_subsys net_prio_subsys = {
+struct cgroup_subsys net_prio_subsys = {
 	.name		= "net_prio",
 	.create		= cgrp_create,
 	.destroy	= cgrp_destroy,

^ permalink raw reply related

* Re: Testing server performance
From: Ben Greear @ 2011-12-09 17:18 UTC (permalink / raw)
  To: igorm; +Cc: netdev
In-Reply-To: <CAFdo_mW0sKSZp3L75BOPBN1Sa+ZQ8WiBRC98eFLM5BaxCVrpJQ@mail.gmail.com>

On 12/09/2011 07:26 AM, Igor Maravić wrote:
> Hi all,
> I'm currently testing how much traffic can I push through my server.
> I'm running on Ubuntu 11.10 server with net-next kernel.
> I'm using 2 Gbps NICs, Netgear GA311 and D-Link DGE-528T, that use r8169 driver.
> I'm generating UDP packets from a router with constant speed.
>
> After I push traffic to my server with max speed, it saturates.
> It receives packets at 77MBps and it sends packet with 14MBps.
> When there are no incoming traffic, but there are remaining packets in
> tx fifo queue, it sends them with 40MBps.
>
> That all wouldn't be strange because my machine isn't any thing special
> (AMD Athlon(tm) II X2 240 on 2,8GHz, motherboard ASUS M2N68 PLUS and
> 2x2GB DDR2 RAM memory on 1066MHz),
> but the dstat shows that CPUs are maximally using 6% of their
> resources for interrupt handling.
> Beside that, nothing else is using CPU time.
> Why does it saturate on this values then? Am I doing something wrong?
> Any help is appreciated.

Check the bus speed and width on your NICs.  dmesg usually shows this
info when the interfaces are first detected.

If you can, try some Intel NICs..they will usually run wire speed
if the motherboard is reasonably fast.

Thanks,
Ben


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: [PATCH iproute2] red: harddrop support and cleanups
From: Stephen Hemminger @ 2011-12-09 17:33 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1323403837.2529.14.camel@edumazet-laptop>

On Fri, 09 Dec 2011 05:10:37 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Le jeudi 08 décembre 2011 à 16:44 -0800, Stephen Hemminger a écrit :
> 
> > Applied (minor whitespace cleanup).
> 
> Thanks Stephen !
> 
> Could you push the final patch so that I add the adaptative part on top
> of it ?
> 
> 
> 

done

^ permalink raw reply

* Re: [PATCH RESEND] sctp: fix incorrect overflow check on autoclose
From: Vladislav Yasevich @ 2011-12-09 17:38 UTC (permalink / raw)
  To: Xi Wang
  Cc: netdev, linux-sctp, Andrew Morton, Andrei Pelinescu-Onciul,
	David S. Miller
In-Reply-To: <1323393883-3759-1-git-send-email-xi.wang@gmail.com>

On 12/08/2011 08:24 PM, Xi Wang wrote:
> The commit 8ffd3208 voids the previous patches f6778aab and 810c0719
> for limiting the maximum autoclose value.  If userspace passes in -1
> on 32-bit platform, the overflow check didn't work and autoclose
> would be set to 0xffffffff.
> 
> Signed-off-by: Xi Wang <xi.wang@gmail.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Andrei Pelinescu-Onciul <andrei@iptel.org>
> Cc: Vlad Yasevich <vladislav.yasevich@hp.com>
> Cc: David S. Miller <davem@davemloft.net>
> ---
>  net/sctp/socket.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 13bf5fc..bb91281 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -2201,7 +2201,8 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
>  	if (copy_from_user(&sp->autoclose, optval, optlen))
>  		return -EFAULT;
>  	/* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
> -	sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ);
> +	sp->autoclose = min_t(unsigned long, sp->autoclose,
> +			      MAX_SCHEDULE_TIMEOUT / HZ);

I think this should be u32 since that's what sp->autoclose is.

-vlad

>  
>  	return 0;
>  }

^ permalink raw reply

* pulling net-netx git tree
From: Kevin Wilson @ 2011-12-09 17:42 UTC (permalink / raw)
  To: netdev

Hi,
  I am trying to update my net-next tree, and I get
git pull

Already up-to-date.

git log
shows:

commit 88c5100c28b02c4b2b2c6f6fafbbd76d90f698b9
Merge: 8083f0f 3ee72ca
Author: David S. Miller <davem@davemloft.net>
Date:   Fri Oct 7 13:38:43 2011 -0400

    Merge branch 'master' of github.com:davem330/net

...
...

commit 8083f0fc969d9b5353061a7a6f963405057e26b1
Author: Johannes Berg <johannes.berg@intel.com>
Date:   Fri Oct 7 03:30:20 2011 +0000

...
...


more .git/config
shows
url = https://github.com/davem330/net-next.git


should I change this url ?  and if so - to what ?


rgs,
Kevin

^ permalink raw reply

* Re: kernel 3.1.1 message:  <IRQ> warn_alloc_failed
From: Stephen Hemminger @ 2011-12-09 17:50 UTC (permalink / raw)
  To: starlight, Sony Chacko, Rajesh Borundia; +Cc: linux-kernel, netdev
In-Reply-To: <6.2.5.6.2.20111208210303.03a06228@flumedata.com>

On Thu, 08 Dec 2011 21:10:02 -0500
starlight@binnacle.cx wrote:

> Hello.
> 
> FYI saw several of these when running
> multiple 'rcp' commands copying multi-gigabyte
> files to/from system.
> 
> 'rcp' target files were all on an encrypted
> mirrored USB3-attached pair of 3TB hard
> drives.
> 
> One outgoing 'rcp' was to a system with
> a much slower disk (due to a USB2 attachment)
> and that transfer was putting back-pressure
> on the connection.
> 
> Kernel is running on a CentOS 6.0
> distribution.
> 
> Not subscribing to the lists, so please
> CC me with any queries.  Please note that
> email originating from most non-US MTAs
> will bounce, but I will check the list
> archives if I see any.
> 
> Can't spend a lot of time on this but am
> willing to answer a few questions.  Hopefully
> the call stack will tell the story well
> enough.

You are seeing memory allocation failures because device
is allocating a 16K (order 2) size socket buffer. You are using
netxen device, and it looks like the problem.

>From reading the netxen driver source. The LRO buffers in this device
are very large (8060+skb overhead).
Until the driver is fixed to use fragmented page size memory,
I recommend turning off LRO.

^ permalink raw reply

* Re: pulling net-netx git tree
From: Eric Dumazet @ 2011-12-09 17:55 UTC (permalink / raw)
  To: Kevin Wilson; +Cc: netdev
In-Reply-To: <CAGXs5wXc-dFs8uJXUpNpYUMs_rSwXV_r4zfWPSzkLPf0qxV-rw@mail.gmail.com>

Le vendredi 09 décembre 2011 à 19:42 +0200, Kevin Wilson a écrit :
> Hi,
>   I am trying to update my net-next tree, and I get
> git pull
> 
> Already up-to-date.
> 
> git log
> shows:
> 
> commit 88c5100c28b02c4b2b2c6f6fafbbd76d90f698b9
> Merge: 8083f0f 3ee72ca
> Author: David S. Miller <davem@davemloft.net>
> Date:   Fri Oct 7 13:38:43 2011 -0400
> 
>     Merge branch 'master' of github.com:davem330/net
> 
> ...
> ...
> 
> commit 8083f0fc969d9b5353061a7a6f963405057e26b1
> Author: Johannes Berg <johannes.berg@intel.com>
> Date:   Fri Oct 7 03:30:20 2011 +0000
> 
> ...
> ...
> 
> 
> more .git/config
> shows
> url = https://github.com/davem330/net-next.git
> 
> 
> should I change this url ?  and if so - to what ?
> 

David went back to : 

http://git.kernel.org/?p=linux/kernel/git/davem/net-next.git

^ permalink raw reply

* Re: BCM43224 hanging [3.2.0-rc4-00248-gb835c0f]
From: Nico Schottelius @ 2011-12-09 18:00 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: Nico Schottelius, LKML, netdev, b43-dev, Greg KH
In-Reply-To: <4EE0F50B.5040407@broadcom.com>

Hey Arend,

Arend van Spriel [Thu, Dec 08, 2011 at 06:34:03PM +0100]:
> On 12/07/2011 08:08 PM, Nico Schottelius wrote:
> Could you try and see what happens when you kill wpa_supplicant.

I can't kill it, it's in D state :-/

I was just browsing through
drivers/net/wireless/brcm80211/brcmsmac/main.c and it seems that
your patch from my last problem has already been applied.

What may be different this time that the network being used
is *not* on 5Ghz, but 2.4 Ghz (I'm not in the same environment anymore).

Nico

-- 
PGP key: 7ED9 F7D3 6B10 81D7 0EC5  5C09 D7DC C8E4 3187 7DF0

^ 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