Netdev List
 help / color / mirror / Atom feed
* [PATCH V4 net-next 25/26] ucc_geth: Support the get_ts_info ethtool method.
From: Richard Cochran @ 2012-04-04  8:59 UTC (permalink / raw)
  To: netdev
  Cc: David Miller, Ben Hutchings, Martin Porter, Jacob Keller,
	Jeff Kirsher, John Ronciak, e1000-devel
In-Reply-To: <cover.1333529504.git.richardcochran@gmail.com>

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 drivers/net/ethernet/freescale/ucc_geth_ethtool.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
index a97257f..37b0353 100644
--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
@@ -415,6 +415,7 @@ static const struct ethtool_ops uec_ethtool_ops = {
 	.get_ethtool_stats      = uec_get_ethtool_stats,
 	.get_wol		= uec_get_wol,
 	.set_wol		= uec_set_wol,
+	.get_ts_info		= ethtool_op_get_ts_info,
 };
 
 void uec_set_ethtool_ops(struct net_device *netdev)
-- 
1.7.2.5

^ permalink raw reply related

* Commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 has broken ss command
From: Kusanagi Kouichi @ 2012-04-04  9:03 UTC (permalink / raw)
  To: netdev; +Cc: Pavel Emelyanov, linux-kernel

Since commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 ("sock_diag:
Move the sock_ code to net/core/"), ss command from iproute package
doesn't work if INET_DIAG is not enabled.

$ ss
State       Recv-Q Send-Q                                             Local Address:Port                                                 Peer Address:Port
TCPDIAG answers: Operation not supported

^ permalink raw reply

* Re: [PATCH net-next 2/2] e100: enable transmit time stamping.
From: Jeff Kirsher @ 2012-04-04  9:04 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, David Miller
In-Reply-To: <33c61d135f4fd62e5128466633302414ead0092e.1331400160.git.richardcochran@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1229 bytes --]

On Sat, 2012-03-10 at 09:29 -0800, Richard Cochran wrote:
> This patch enables software (and phy device) transmit time stamping.
> Tested on an old PIII laptop with built in NIC.
> 
> Cc: Alex Duyck <alexander.h.duyck@intel.com>
> Cc: Bruce Allan <bruce.w.allan@intel.com>
> Cc: Carolyn Wyborny <carolyn.wyborny@intel.com>
> Cc: Don Skidmore <donald.c.skidmore@intel.com>
> Cc: Greg Rose <gregory.v.rose@intel.com>
> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Cc: John Ronciak <john.ronciak@intel.com>
> Cc: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
> 
> Signed-off-by: Richard Cochran <richardcochran@gmail.com>
> ---
>  drivers/net/ethernet/intel/e100.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-) 

Richard-

I had this patch in my queue, but during testing we found some serious
issues with some adapters.  With every 82559 based adapter Aaron tried
the system would panic on driver load.  This included at least one
sampling of D101S and D101M.  Every other e100 chipset Aaron tried
(82557, 82558, 82550) appeared to work fine.

So I am dropping this patch as is due to the kernel panics.

Cheers,
Jeff

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: Commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 has broken ss command
From: Eric Dumazet @ 2012-04-04  9:07 UTC (permalink / raw)
  To: Kusanagi Kouichi; +Cc: netdev, Pavel Emelyanov, linux-kernel
In-Reply-To: <20120404090312.1B68C6AC03E@msa102.auone-net.jp>

On Wed, 2012-04-04 at 18:03 +0900, Kusanagi Kouichi wrote:
> Since commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 ("sock_diag:
> Move the sock_ code to net/core/"), ss command from iproute package
> doesn't work if INET_DIAG is not enabled.
> 
> $ ss
> State       Recv-Q Send-Q                                             Local Address:Port                                                 Peer Address:Port
> TCPDIAG answers: Operation not supported
> --

Try to update your iproute2 package ?

^ permalink raw reply

* [PATCH] vmsplice: relax alignement requirements for SPLICE_F_GIFT
From: Eric Dumazet @ 2012-04-04  9:08 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-kernel, David Miller, netdev, Tom Herbert, Al Viro,
	Hugh Dickins, Changli Gao, Andrew Morton, Miklos Szeredi

It seems there is no fundamental reason to limit vmsplice()
SPLICE_F_GIFT to page aligned chunks.

All helpers are prepared to cope with offsets in page.

This limitation makes vmsplice() API very impractical in the zero-copy
land.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Miller <davem@davemloft.net>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Hugh Dickins <hughd@google.com>
Cc: Changli Gao <xiaosuo@gmail.com>
Cc: Miklos Szeredi <mszeredi@suse.cz>
---
 fs/splice.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/splice.c b/fs/splice.c
index 5f883de..5417aa3 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1385,7 +1385,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
  */
 static int get_iovec_page_array(const struct iovec __user *iov,
 				unsigned int nr_vecs, struct page **pages,
-				struct partial_page *partial, int aligned,
+				struct partial_page *partial, bool aligned,
 				unsigned int pipe_buffers)
 {
 	int buffers = 0, error = 0;
@@ -1623,7 +1623,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
 		return -ENOMEM;
 
 	spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages,
-					    spd.partial, flags & SPLICE_F_GIFT,
+					    spd.partial, false,
 					    pipe->buffers);
 	if (spd.nr_pages <= 0)
 		ret = spd.nr_pages;

^ permalink raw reply related

* [PATCH] ipv6: Fix 'inet6_rtm_getroute' to release 'rt->dst' in case of 'alloc_skb' failure
From: Shmulik Ladkani @ 2012-04-04  9:13 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, linux-kernel, Eric Dumazet, Alexey Kuznetsov,
	James Morris, Hideaki YOSHIFUJI, Patrick McHardy

In 72331bc [ipv6: Fix RTM_GETROUTE's interpretation of RTA_IIF to be
consistent with ipv4] the code of 'inet6_rtm_getroute()' was re-ordered
such that the reference to 'rt->dst' is incremented prior skb
allocation.

Hence, if 'alloc_skb()' fails, must drop a reference from 'rt->dst'.
Add the missing 'dst_release()' call.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1178345..00b987c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2581,6 +2581,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
 
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 	if (!skb) {
+		dst_release(&rt->dst);
 		err = -ENOBUFS;
 		goto errout;
 	}

^ permalink raw reply related

* [RFC PATCH 0/2] PID-based network traffic monitoring
From: Nuno Martins @ 2012-04-04  9:16 UTC (permalink / raw)
  To: netdev, nuno.martins; +Cc: Alfredo Matos, Paulo Trezentos

 In this patchset we introduce the support for pid-based network monitoring, through a new BPF/LSF instruction, supported by KProbes to dynamically detect opening and closing connections.
 With these changes it is possible to pass a PID to tcpdump, and monitor the traffic on the network which belongs to a specific PID. More information can be found at the project page [1].

 * The first patch provides the infrastructure to registering custom BPF filter functions through setsockopt.
 * The second patch introduces a pid monitor that keeps track of the ongoing connections (src addr, dst addr, src port, dst, port and protocol), associated to a PID, passed from userspace as part of a custom BFP filter.

 For testing with tcpdump, a modified pcap library is required. The patch can be found at [2].
 This approach is still in early stages of development and under heavy testing. Any feedback or suggestions are appreciated.

 Thanks,

 Nuno Martins.

 [1] http://projects.caixamagica.pt/projects/pidmonitoring
 [2] http://projects.caixamagica.pt/projects/pidmonitoring/attachment/wiki/WikiStart/libpcap.patch

Nuno Martins (2):
  Multiple filter function support for BPF filters
  PID-based packet filtering support

 include/asm-generic/socket.h      |    4 +
 include/linux/filter.h            |    4 +-
 include/linux/socket.h            |   28 +++
 net/Kconfig                       |   15 ++
 net/Makefile                      |    1 +
 net/core/Makefile                 |    3 +-
 net/core/filter.c                 |    8 +-
 net/core/filter_function.c        |  133 +++++++++++
 net/core/sock.c                   |   23 +-
 net/pidmonitor/Makefile           |    3 +
 net/pidmonitor/db_monitor.c       |  389 ++++++++++++++++++++++++++++++
 net/pidmonitor/db_monitor.h       |   51 ++++
 net/pidmonitor/filter.c           |  476 +++++++++++++++++++++++++++++++++++++
 net/pidmonitor/filter.h           |   31 +++
 net/pidmonitor/pidmonitor.c       |  102 ++++++++
 net/pidmonitor/pidmonitor.h       |   63 +++++
 net/pidmonitor/proc_monitor.c     |  116 +++++++++
 net/pidmonitor/proc_monitor.h     |   23 ++
 net/pidmonitor/syscalls_monitor.c |  423 ++++++++++++++++++++++++++++++++
 net/pidmonitor/syscalls_monitor.h |   31 +++
 net/pidmonitor/task_monitor.c     |   77 ++++++
 net/pidmonitor/task_monitor.h     |   23 ++
 22 files changed, 2023 insertions(+), 4 deletions(-)
 create mode 100644 net/core/filter_function.c
 create mode 100644 net/pidmonitor/Makefile
 create mode 100644 net/pidmonitor/db_monitor.c
 create mode 100644 net/pidmonitor/db_monitor.h
 create mode 100644 net/pidmonitor/filter.c
 create mode 100644 net/pidmonitor/filter.h
 create mode 100644 net/pidmonitor/pidmonitor.c
 create mode 100644 net/pidmonitor/pidmonitor.h
 create mode 100644 net/pidmonitor/proc_monitor.c
 create mode 100644 net/pidmonitor/proc_monitor.h
 create mode 100644 net/pidmonitor/syscalls_monitor.c
 create mode 100644 net/pidmonitor/syscalls_monitor.h
 create mode 100644 net/pidmonitor/task_monitor.c
 create mode 100644 net/pidmonitor/task_monitor.h

-- 
1.7.10.rc3.11.gd8282

^ permalink raw reply

* [RFC PATCH 1/2] Multiple filter function support for BPF filters
From: Nuno Martins @ 2012-04-04  9:16 UTC (permalink / raw)
  To: netdev, nuno.martins; +Cc: Alfredo Matos, Paulo Trezentos
In-Reply-To: <cover.1333466900.git.nuno.martins@caixamagica.pt>

This patch introduces the possibility of attaching multiple filter functions to a PF socket, useful for custom packet filtering.
It maintains a list of registered functions, received through setsockopt from userspace.
The custom filtering functions are compatible with BPF/LSF filter in order to retain compatibility with sk_run_filter and the pcap library.

This mechanism was developed to support the network monitoring by process id on the kernel (second patch in this series).

Signed-off-by: Nuno Martins <nuno.martins@caixamagica.pt>
---
 include/asm-generic/socket.h |    4 ++
 include/linux/filter.h       |    3 +-
 include/linux/socket.h       |   28 +++++++++
 net/Kconfig                  |    8 +++
 net/core/Makefile            |    3 +-
 net/core/filter.c            |    3 +-
 net/core/filter_function.c   |  138 ++++++++++++++++++++++++++++++++++++++++++
 net/core/sock.c              |   23 ++++++-
 8 files changed, 206 insertions(+), 4 deletions(-)

diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
index b1bea03..89c45a9 100644
--- a/include/asm-generic/socket.h
+++ b/include/asm-generic/socket.h
@@ -72,4 +72,8 @@
 /* Instruct lower device to use last 4-bytes of skb data as FCS */
 #define SO_NOFCS		43
 
+#ifdef CONFIG_FILTER_FUNCTION
+#define SO_ATTACH_FILTER_FUNC	44
+#define SO_DETACH_FILTER_FUNC	45
+#endif
 #endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 8eeb205..8d2d9c2 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -90,6 +90,7 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
 #define BPF_MISCOP(code) ((code) & 0xf8)
 #define         BPF_TAX         0x00
 #define         BPF_TXA         0x80
+#define         BPF_PROC        0xf0
 
 #ifndef BPF_MAXINSNS
 #define BPF_MAXINSNS 4096
@@ -168,7 +169,7 @@ static inline void bpf_jit_compile(struct sk_filter *fp)
 static inline void bpf_jit_free(struct sk_filter *fp)
 {
 }
-#define SK_RUN_FILTER(FILTER, SKB) sk_run_filter(SKB, FILTER->insns)
+#define SK_RUN_FILTER(FILTER, SKB) (*FILTER->bpf_func)(SKB, FILTER->insns)
 #endif
 
 enum {
diff --git a/include/linux/socket.h b/include/linux/socket.h
index da2d3e2..12acea5 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -316,6 +316,34 @@ struct ucred {
 /* IPX options */
 #define IPX_TYPE	1
 
+#ifdef CONFIG_FILTER_FUNCTION
+#define FILTER_FUNCTION_NAME_LEN 25
+struct filter_function_struct {
+	char name[FILTER_FUNCTION_NAME_LEN];
+	int pid;
+};
+
+#include <linux/list.h>
+
+struct sk_buff;
+struct sock_filter;
+struct sock;
+struct sk_filter;
+
+struct filter_function {
+	struct list_head list;
+	char name[FILTER_FUNCTION_NAME_LEN];
+	int (*init_func)(struct filter_function_struct *ffs);
+	unsigned int (*func)(const struct sk_buff *skb, const struct sock_filter *filter);
+};
+
+extern int attach_filter_function(struct filter_function_struct *ffs, struct sock *sk);
+extern int detach_filter_function(struct filter_function_struct *ffs, struct sock *sk);
+extern int register_filter_function(struct filter_function *ff);
+extern int unregister_filter_function(struct filter_function *ff);
+extern int detect_filter_function(struct sk_filter *fp);
+#endif
+
 extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);
 
 extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
diff --git a/net/Kconfig b/net/Kconfig
index e07272d..6bbce29 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -260,6 +260,14 @@ config BPF_JIT
 	  packet sniffing (libpcap/tcpdump). Note : Admin should enable
 	  this feature changing /proc/sys/net/core/bpf_jit_enable
 
+config FILTER_FUNCTION
+	bool "enable definition of a sniff function"
+	depends on MODULES
+	default y
+	---help---
+	  Dynamicaly define what sniffer function would be used to filter
+	  packets
+
 menu "Network testing"
 
 config NET_PKTGEN
diff --git a/net/core/Makefile b/net/core/Makefile
index 674641b..c3378c5 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -3,7 +3,8 @@
 #
 
 obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
-	 gen_stats.o gen_estimator.o net_namespace.o secure_seq.o flow_dissector.o
+	 gen_stats.o gen_estimator.o net_namespace.o secure_seq.o flow_dissector.o \
+	 filter_function.o
 
 obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 
diff --git a/net/core/filter.c b/net/core/filter.c
index 5dea452..0aa1ac6 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -582,7 +582,8 @@ void sk_filter_release_rcu(struct rcu_head *rcu)
 {
 	struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
 
-	bpf_jit_free(fp);
+	if (detect_filter_function(fp))
+		bpf_jit_free(fp);
 	kfree(fp);
 }
 EXPORT_SYMBOL(sk_filter_release_rcu);
diff --git a/net/core/filter_function.c b/net/core/filter_function.c
new file mode 100644
index 0000000..c9b62e3
--- /dev/null
+++ b/net/core/filter_function.c
@@ -0,0 +1,138 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifdef CONFIG_FILTER_FUNCTION
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/skbuff.h>
+#include <linux/filter.h>
+#include <net/sock.h>
+
+LIST_HEAD(filter_list);
+/*EXPORT_SYMBOL(sniff_list);*/
+
+static DEFINE_MUTEX(filter_list_mutex);
+
+int register_filter_function(struct filter_function *ff)
+{
+	list_add(&(ff->list), &filter_list);
+
+	return 0;
+}
+EXPORT_SYMBOL(register_filter_function);
+
+static struct filter_function *find_filter_function_by_addr(void *addr)
+{
+	struct filter_function *ff;
+
+	if (addr == sk_run_filter)
+		return NULL;
+
+	list_for_each_entry(ff, &filter_list, list) {
+		if (ff->func == addr)
+			return ff;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(find_filter_function_by_addr);
+
+static struct filter_function *find_filter_function_by_name(const char *name)
+{
+	struct filter_function *ff;
+	list_for_each_entry(ff, &filter_list, list) {
+		if (strcmp(ff->name, name) == 0)
+			return ff;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(find_filter_function_by_name);
+
+int unregister_filter_function(struct filter_function *ff)
+{
+	list_del(&(ff->list));
+	return 0;
+}
+EXPORT_SYMBOL(unregister_filter_function);
+
+int attach_filter_function(struct filter_function_struct *ffs, struct sock *sk)
+{
+	struct filter_function *ff = NULL;
+	struct sk_filter *old_fp;
+
+	if (strcmp(ffs->name, "sk_run_filter") == 0) {
+		/*if (init_process_filter_function != NULL)
+			init_process_filter_function(ffs);*/
+	} else
+		ff = find_filter_function_by_name(ffs->name);
+
+	if (ff != NULL) {
+		int ret;
+		if (ff->init_func != NULL)
+			ret = ff->init_func(ffs);
+
+		if (ff->func != NULL) {
+			old_fp = rcu_dereference_protected(sk->sk_filter,
+					sock_owned_by_user(sk));
+			if (detect_filter_function(old_fp)) {
+				bpf_jit_free(old_fp);
+			}
+
+			old_fp->bpf_func = ff->func;
+			rcu_assign_pointer(sk->sk_filter, old_fp);
+		}
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(attach_filter_function);
+
+int detach_filter_function(struct filter_function_struct *ffs, struct sock *sk)
+{
+	struct sk_filter *old_fp;
+	struct filter_function *ff;
+
+	old_fp = rcu_dereference_protected(sk->sk_filter,
+			sock_owned_by_user(sk));
+
+	ff = find_filter_function_by_addr(old_fp->bpf_func);
+	if (ff) {
+		return 0;
+	}
+
+	return -1;
+}
+EXPORT_SYMBOL(detach_filter_function);
+
+int detect_filter_function(struct sk_filter *fp)
+{
+	return find_filter_function_by_addr(fp->bpf_func) ? 0 : -1;
+}
+EXPORT_SYMBOL(detect_filter_function);
+#endif
diff --git a/net/core/sock.c b/net/core/sock.c
index 9be6d0d..0583bf6d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -769,7 +769,28 @@ set_rcvbuf:
 	case SO_DETACH_FILTER:
 		ret = sk_detach_filter(sk);
 		break;
-
+#ifdef CONFIG_FILTER_FUNCTION
+	case SO_ATTACH_FILTER_FUNC:
+		ret = -EINVAL;
+		if (optlen == sizeof(struct filter_function_struct)) {
+			struct filter_function_struct ff;
+			ret = -EFAULT;
+			if (copy_from_user(&ff, optval, sizeof(ff)))
+				break;
+			ret = attach_filter_function(&ff, sk);
+		}
+		break;
+	case SO_DETACH_FILTER_FUNC:
+		ret = -EINVAL;
+		if (optlen == sizeof(struct filter_function_struct)) {
+			struct filter_function_struct ff;
+			ret = -EFAULT;
+			if (copy_from_user(&ff, optval, sizeof(ff)))
+				break;
+			ret = detach_filter_function(&ff, sk);
+		}
+		break;
+#endif
 	case SO_PASSSEC:
 		if (valbool)
 			set_bit(SOCK_PASSSEC, &sock->flags);
-- 
1.7.10.rc3.11.gd8282

^ permalink raw reply related

* [RFC PATCH 2/2] PID-based packet filtering support
From: Nuno Martins @ 2012-04-04  9:16 UTC (permalink / raw)
  To: netdev, nuno.martins; +Cc: Alfredo Matos, Paulo Trezentos
In-Reply-To: <cover.1333466900.git.nuno.martins@caixamagica.pt>

This patch introduces the pidmonitor module through three main components:

* a custom BFP filter function that acts on PID information

* dynamic KProbes handlers (kretprobe handlers) that intercept system calls (connect, bind, etc.) to determine the connections established by a specific process (pid).

* a repository (RB Tree) for maintaining the packet information to PID
mapping, to allow runtime use of the BPF filter.

Currently, the PID monitor is only available for TCP and UDP on IPv4. IPv6 support is under development.

Signed-off-by: Nuno Martins <nuno.martins@caixamagica.pt>
---
 include/linux/filter.h            |    1 +
 net/Kconfig                       |    7 +
 net/Makefile                      |    1 +
 net/core/filter.c                 |    5 +
 net/core/filter_function.c        |    9 +-
 net/pidmonitor/Makefile           |    3 +
 net/pidmonitor/db_monitor.c       |  389 ++++++++++++++++++++++++++++++
 net/pidmonitor/db_monitor.h       |   51 ++++
 net/pidmonitor/filter.c           |  476 +++++++++++++++++++++++++++++++++++++
 net/pidmonitor/filter.h           |   31 +++
 net/pidmonitor/pidmonitor.c       |  102 ++++++++
 net/pidmonitor/pidmonitor.h       |   63 +++++
 net/pidmonitor/proc_monitor.c     |  116 +++++++++
 net/pidmonitor/proc_monitor.h     |   23 ++
 net/pidmonitor/syscalls_monitor.c |  423 ++++++++++++++++++++++++++++++++
 net/pidmonitor/syscalls_monitor.h |   31 +++
 net/pidmonitor/task_monitor.c     |   77 ++++++
 net/pidmonitor/task_monitor.h     |   23 ++
 18 files changed, 1824 insertions(+), 7 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 8d2d9c2..f50dc35 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -204,6 +204,7 @@ enum {
 	BPF_S_LDX_IMM,
 	BPF_S_MISC_TAX,
 	BPF_S_MISC_TXA,
+	BPF_S_MISC_PROC,
 	BPF_S_ALU_DIV_K,
 	BPF_S_LD_MEM,
 	BPF_S_LDX_MEM,
diff --git a/net/Kconfig b/net/Kconfig
index 6bbce29..9c74a0f 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -268,6 +268,13 @@ config FILTER_FUNCTION
 	  Dynamicaly define what sniffer function would be used to filter
 	  packets
 
+config MONITOR_PID
+	tristate "network monitoring by process id"
+	depends on MODULES && KPROBES && FILTER_FUNCTION
+	default m
+	---help---
+	  Monitor network defining a pid to sniff the packets
+
 menu "Network testing"
 
 config NET_PKTGEN
diff --git a/net/Makefile b/net/Makefile
index ad432fa..b5e35ab 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -70,3 +70,4 @@ obj-$(CONFIG_CEPH_LIB)		+= ceph/
 obj-$(CONFIG_BATMAN_ADV)	+= batman-adv/
 obj-$(CONFIG_NFC)		+= nfc/
 obj-$(CONFIG_OPENVSWITCH)	+= openvswitch/
+obj-$(CONFIG_MONITOR_PID)	+= pidmonitor/
diff --git a/net/core/filter.c b/net/core/filter.c
index 0aa1ac6..51b41a0 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -277,6 +277,10 @@ load_b:
 		case BPF_S_MISC_TXA:
 			A = X;
 			continue;
+		case BPF_S_MISC_PROC:
+			if ((fentry+1)->code == BPF_S_JMP_JEQ_K)
+				fentry += 1;
+			continue;
 		case BPF_S_RET_K:
 			return K;
 		case BPF_S_RET_A:
@@ -472,6 +476,7 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
 		[BPF_LDX|BPF_IMM]        = BPF_S_LDX_IMM,
 		[BPF_MISC|BPF_TAX]       = BPF_S_MISC_TAX,
 		[BPF_MISC|BPF_TXA]       = BPF_S_MISC_TXA,
+		[BPF_MISC|BPF_PROC]	 = BPF_S_MISC_PROC,
 		[BPF_RET|BPF_K]          = BPF_S_RET_K,
 		[BPF_RET|BPF_A]          = BPF_S_RET_A,
 		[BPF_ALU|BPF_DIV|BPF_K]  = BPF_S_ALU_DIV_K,
diff --git a/net/core/filter_function.c b/net/core/filter_function.c
index c9b62e3..ee5f5be 100644
--- a/net/core/filter_function.c
+++ b/net/core/filter_function.c
@@ -32,9 +32,7 @@
 #include <linux/filter.h>
 #include <net/sock.h>
 
-LIST_HEAD(filter_list);
-/*EXPORT_SYMBOL(sniff_list);*/
-
+static LIST_HEAD(filter_list);
 static DEFINE_MUTEX(filter_list_mutex);
 
 int register_filter_function(struct filter_function *ff)
@@ -84,10 +82,7 @@ int attach_filter_function(struct filter_function_struct *ffs, struct sock *sk)
 	struct filter_function *ff = NULL;
 	struct sk_filter *old_fp;
 
-	if (strcmp(ffs->name, "sk_run_filter") == 0) {
-		/*if (init_process_filter_function != NULL)
-			init_process_filter_function(ffs);*/
-	} else
+	if (strcmp(ffs->name, "sk_run_filter") != 0)
 		ff = find_filter_function_by_name(ffs->name);
 
 	if (ff != NULL) {
diff --git a/net/pidmonitor/Makefile b/net/pidmonitor/Makefile
new file mode 100644
index 0000000..3fa01dd
--- /dev/null
+++ b/net/pidmonitor/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_MONITOR_PID) += pidnetmonitor.o
+
+pidnetmonitor-objs := syscalls_monitor.o task_monitor.o filter.o proc_monitor.o db_monitor.o pidmonitor.o
diff --git a/net/pidmonitor/db_monitor.c b/net/pidmonitor/db_monitor.c
new file mode 100644
index 0000000..45dfb6d
--- /dev/null
+++ b/net/pidmonitor/db_monitor.c
@@ -0,0 +1,389 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include <linux/types.h>
+
+#include <linux/in.h>
+
+#include "pidmonitor.h"
+#include "db_monitor.h"
+
+static struct rb_root db;
+
+/*
+ * returns NULL if there isn't that port int the tree
+ */
+static int is_equal_packet_info(struct packetInfo *pi,
+		struct portInfo *info)
+{
+
+	struct local_addresses_list *tmp = NULL;
+	struct local_addresses_list *address = NULL;
+	struct list_head *pos = NULL;
+
+	switch (pi->protocol) {
+	case IPPROTO_TCP:
+		if (info->tcp)
+			tmp = info->tcp;
+		break;
+	case IPPROTO_UDP:
+		if (info->udp)
+			tmp = info->udp;
+		break;
+	default:
+		return 0;
+	}
+
+	if (!tmp)
+		return 0;
+
+	list_for_each(pos, &(tmp->list)) {
+		address = list_entry(pos, struct local_addresses_list, list);
+		if (pi->address == address->address && pi->pid == address->pid)
+			return 1;
+	}
+
+	return 0;
+}
+
+static struct portInfo *__monitor_search(struct rb_root *root, struct packetInfo *pi)
+{
+	struct rb_node *node = root->rb_node;
+	struct portInfo *data = NULL;
+
+	while (node) {
+		data = container_of(node, struct portInfo, node);
+
+		if (pi->port < data->port)
+			node = node->rb_left;
+		else
+			if (pi->port > data->port)
+				node = node->rb_right;
+			else
+				if (pi->port == data->port) {
+					if (is_equal_packet_info(pi, data) != 0)
+						return data;
+					else
+						return NULL;
+				} else
+					return NULL;
+	}
+	return NULL;
+}
+
+struct portInfo *monitor_search(struct packetInfo *pi)
+{
+	return __monitor_search(&db, pi);
+}
+
+static int add_address(struct packetInfo *lpi, struct local_addresses_list *tmp,
+		int *list_counter, int pid)
+{
+	struct local_addresses_list *address = NULL;
+	struct list_head *pos = NULL;
+	struct local_addresses_list *node = NULL;
+
+	list_for_each(pos, &(tmp->list)) {
+		address = list_entry(pos, struct local_addresses_list, list);
+		if (lpi->address == address->address) {
+			address->counter++;
+			address->pid = pid;
+			return 1;
+		}
+	}
+
+	node = kmalloc(sizeof(*node), GFP_KERNEL);
+
+	if (!node)
+		return -1;
+
+	node->address = lpi->address;
+	node->counter = 1;
+
+	list_add(&(node->list), &(tmp->list));
+	(*list_counter)++;
+	node->pid = pid;
+
+	return 1;
+}
+
+static int insert_address(struct packetInfo *lpi, struct portInfo *port_info)
+{
+
+	switch (lpi->protocol) {
+	case IPPROTO_TCP:
+		if (!(port_info->tcp)) {
+			port_info->tcp = kmalloc(sizeof(struct local_addresses_list), GFP_KERNEL);
+
+			if (!port_info->tcp)
+				return -1;
+
+			INIT_LIST_HEAD(&((port_info->tcp)->list));
+			port_info->tcp->counter = 0;
+		}
+
+		if (lpi->address == 0) {
+			struct local_addresses_list *address = NULL;
+			struct list_head *pos = NULL;
+
+			list_for_each(pos, &(local_list->list)) {
+				struct packetInfo pi;
+				address = list_entry(pos, struct local_addresses_list, list);
+				pi.address = address->address;
+				add_address(&pi, port_info->tcp, &(port_info->tcp_list_counter), lpi->pid);
+			}
+		} else {
+			add_address(lpi, port_info->tcp, &(port_info->tcp_list_counter),lpi->pid);
+		}
+
+		break;
+	case IPPROTO_UDP:
+		if (!(port_info->udp)) {
+			port_info->udp = kmalloc(sizeof(struct local_addresses_list), GFP_KERNEL);
+			if (!port_info->udp)
+				return -1;
+			INIT_LIST_HEAD(&((port_info->udp)->list));
+			port_info->udp->counter = 0;
+		}
+		if (lpi->address == 0) {
+			struct local_addresses_list *address = NULL;
+			struct list_head *pos = NULL;
+
+			list_for_each(pos, &(local_list->list)) {
+				struct packetInfo pi;
+				address = list_entry(pos, struct local_addresses_list, list);
+				pi.address = address->address;
+				add_address(&pi, port_info->udp, &(port_info->udp_list_counter), lpi->pid);
+			}
+		} else {
+			add_address(lpi, port_info->udp, &(port_info->udp_list_counter), lpi->pid);
+		}
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static struct portInfo *create_packet_info(struct packetInfo *lpi)
+{
+	struct portInfo *pi = NULL;
+	pi = kmalloc(sizeof(*pi), GFP_KERNEL);
+
+	if (!pi)
+		return NULL;
+
+	pi->port = lpi->port;
+	pi->tcp = NULL;
+	pi->tcp_list_counter = 0;
+	pi->udp = NULL;
+	pi->udp_list_counter = 0;
+
+	insert_address(lpi, pi);
+
+	return pi;
+}
+
+static int __monitor_insert(struct rb_root *root, struct packetInfo *lpi)
+{
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+	struct portInfo *port = NULL;
+
+	while (*new) {
+		struct portInfo *this = container_of(*new, struct portInfo, node);
+
+		parent = *new;
+		if (lpi->port < this->port) {
+			new = &((*new)->rb_left);
+		} else
+			if (lpi->port > this->port) {
+				new = &((*new)->rb_right);
+			} else {
+				insert_address(lpi, this);
+				return 1;
+			}
+	}
+	port = create_packet_info(lpi);
+	if (!port)
+		return -1;
+
+	rb_link_node(&port->node, parent, new);
+	rb_insert_color(&port->node, root);
+
+	return 1;
+}
+
+int monitor_insert(struct packetInfo *lpi)
+{
+	return __monitor_insert(&db, lpi);
+}
+
+int decrement_address(struct packetInfo *lpi,
+		struct local_addresses_list *protocol, int *list_counter)
+{
+	struct local_addresses_list *address = NULL;
+	struct list_head *pos = NULL, *q = NULL;
+
+	list_for_each_safe(pos, q, &(protocol->list)) {
+		address = list_entry(pos, struct local_addresses_list, list);
+		if (lpi->address == address->address) {
+			(address->counter)--;
+			if (address->counter <= 0) {
+				list_del(pos);
+				kfree(address);
+				(*(list_counter))--;
+			}
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static void remove_address_from_node(struct portInfo *pi, struct packetInfo *lpi)
+{
+
+	switch (lpi->protocol) {
+	case IPPROTO_TCP:
+		if (lpi->address) {
+			decrement_address(lpi, pi->tcp, &(pi->tcp_list_counter));
+		} else {
+			struct local_addresses_list *address = NULL;
+			struct list_head *pos = NULL;
+
+			list_for_each(pos, &(local_list->list)) {
+				struct packetInfo aux;
+				address = list_entry(pos, struct local_addresses_list, list);
+				aux.address = address->address;
+				decrement_address(&aux, pi->tcp, &(pi->tcp_list_counter));
+			}
+		}
+		if (pi->tcp_list_counter == 0) {
+			kfree(pi->tcp);
+			pi->tcp = NULL;
+		}
+		break;
+
+	case IPPROTO_UDP:
+		if (lpi->address) {
+			decrement_address(lpi, pi->udp, &(pi->udp_list_counter));
+		} else {
+			struct local_addresses_list *address = NULL;
+			struct list_head *pos = NULL;
+
+			list_for_each(pos, &(local_list->list)) {
+				struct packetInfo aux;
+				address = list_entry(pos, struct local_addresses_list, list);
+				aux.address = address->address;
+				decrement_address(&aux, pi->udp, &(pi->udp_list_counter));
+			}
+
+		}
+		if (pi->udp_list_counter == 0) {
+			kfree(pi->udp);
+			pi->udp = NULL;
+		}
+		break;
+	default:
+		return;
+	}
+}
+
+static void __monitor_erase(struct rb_root *root, struct packetInfo *pi)
+{
+	struct portInfo *data = __monitor_search(root, pi);
+
+	if (data) {
+		remove_address_from_node(data, pi);
+
+		if ((!data->tcp) && !(data->udp)) {
+			rb_erase(&data->node, root);
+			kfree(data);
+		}
+	}
+}
+
+void monitor_erase(struct packetInfo *pi)
+{
+	__monitor_erase(&db, pi);
+}
+
+static void clear_node_info(struct portInfo *pi)
+{
+	struct local_addresses_list *tmp = NULL;
+	struct list_head *pos = NULL, *q = NULL;
+
+	if (pi->tcp_list_counter > 0 && pi->tcp != NULL) {
+		struct local_addresses_list *aux = pi->tcp;
+		list_for_each_safe(pos, q, &(aux->list)) {
+			tmp = list_entry(pos, struct local_addresses_list, list);
+			list_del(pos);
+			kfree(tmp);
+		}
+		pi->tcp_list_counter = 0;
+		kfree(pi->tcp);
+	}
+
+	if (pi->udp_list_counter > 0 && pi->udp != NULL) {
+		struct local_addresses_list *aux = pi->udp;
+		list_for_each_safe(pos, q, &(aux->list))
+		{
+			tmp = list_entry(pos, struct local_addresses_list, list);
+			list_del(pos);
+			kfree(tmp);
+		}
+		pi->udp_list_counter = 0;
+		kfree(pi->udp);
+	}
+}
+
+void clear_all_info(struct rb_root *root)
+{
+	struct rb_node *node = NULL, *next_node = NULL;
+	struct portInfo *p = NULL;
+
+	node = rb_first(root);
+	while (node) {
+		next_node = rb_next(node);
+		p = rb_entry(node, struct portInfo, node);
+		clear_node_info(p);
+
+		rb_erase(node, root);
+		kfree(p);
+		p = NULL;
+		node = next_node;
+	}
+}
+
+void init_db_monitor(void)
+{
+}
+
+void exit_db_monitor(void)
+{
+	clear_all_info(&db);
+}
diff --git a/net/pidmonitor/db_monitor.h b/net/pidmonitor/db_monitor.h
new file mode 100644
index 0000000..ddc18d7
--- /dev/null
+++ b/net/pidmonitor/db_monitor.h
@@ -0,0 +1,51 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef PORTSDB_H_
+#define PORTSDB_H_
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/rbtree.h>
+
+#include "pidmonitor.h"
+
+struct portInfo {
+	struct rb_node node;
+	u16 port;
+	struct local_addresses_list *udp;
+	struct local_addresses_list *tcp;
+	int tcp_list_counter;
+	int udp_list_counter;
+};
+
+extern struct portInfo *monitor_search(struct packetInfo *pi);
+extern int monitor_insert(struct packetInfo *lpi);
+extern void monitor_erase(struct packetInfo *pi);
+void clear_all_info(struct rb_root *root);
+
+extern void init_db_monitor(void);
+extern void exit_db_monitor(void);
+
+#endif /* PORTSDB_H_ */
diff --git a/net/pidmonitor/filter.c b/net/pidmonitor/filter.c
new file mode 100644
index 0000000..121c36a
--- /dev/null
+++ b/net/pidmonitor/filter.c
@@ -0,0 +1,476 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/*
+ * Linux Socket Filter - Kernel level socket filtering
+ *
+ * Author:
+ *     Jay Schulist <jschlst@samba.org>
+ *
+ * Based on the design of:
+ *     - The Berkeley Packet Filter
+ *
+ * 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.
+ *
+ * Andi Kleen - Fix a few bad bugs and races.
+ * Kris Katterjohn - Added many additional checks in sk_chk_filter()
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/fcntl.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/if_packet.h>
+#include <linux/gfp.h>
+#include <net/ip.h>
+#include <net/protocol.h>
+#include <net/netlink.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#include <linux/filter.h>
+#include <linux/reciprocal_div.h>
+#include <linux/ratelimit.h>
+
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/socket.h>
+
+#include <linux/skbuff.h>
+#include <linux/filter.h>
+#include <asm/unaligned.h>
+
+#include "pidmonitor.h"
+#include "db_monitor.h"
+
+#define		BPF_PROC	0xf0
+
+/* No hurry in this branch */
+static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
+{
+	u8 *ptr = NULL;
+
+	if (k >= SKF_NET_OFF)
+		ptr = skb_network_header(skb) + k - SKF_NET_OFF;
+	else if (k >= SKF_LL_OFF)
+		ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
+
+	if (ptr >= skb->head && ptr + size <= skb_tail_pointer(skb))
+		return ptr;
+	return NULL;
+}
+
+static inline void *load_pointer(const struct sk_buff *skb, int k,
+				 unsigned int size, void *buffer)
+{
+	if (k >= 0)
+		return skb_header_pointer(skb, k, size, buffer);
+	return __load_pointer(skb, k, size);
+}
+
+int dynamic_filter(const struct sk_buff *skb, const int pid);
+
+unsigned int process_packets(const struct sk_buff *skb,
+			   const struct sock_filter *fentry)
+{
+	void *ptr;
+	u32 A = 0;			/* Accumulator */
+	u32 X = 0;			/* Index Register */
+	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
+	u32 tmp;
+	int k;
+	/*
+	 * Process array of filter instructions.
+	 */
+	for (;; fentry++) {
+#if defined(CONFIG_X86_32)
+#define	K (fentry->k)
+#else
+		const u32 K = fentry->k;
+#endif
+
+		switch (fentry->code) {
+		case BPF_S_ALU_ADD_X:
+			A += X;
+			continue;
+		case BPF_S_ALU_ADD_K:
+			A += K;
+			continue;
+		case BPF_S_ALU_SUB_X:
+			A -= X;
+			continue;
+		case BPF_S_ALU_SUB_K:
+			A -= K;
+			continue;
+		case BPF_S_ALU_MUL_X:
+			A *= X;
+			continue;
+		case BPF_S_ALU_MUL_K:
+			A *= K;
+			continue;
+		case BPF_S_ALU_DIV_X:
+			if (X == 0)
+				return 0;
+			A /= X;
+			continue;
+		case BPF_S_ALU_DIV_K:
+			A = reciprocal_divide(A, K);
+			continue;
+		case BPF_S_ALU_AND_X:
+			A &= X;
+			continue;
+		case BPF_S_ALU_AND_K:
+			A &= K;
+			continue;
+		case BPF_S_ALU_OR_X:
+			A |= X;
+			continue;
+		case BPF_S_ALU_OR_K:
+			A |= K;
+			continue;
+		case BPF_S_ALU_LSH_X:
+			A <<= X;
+			continue;
+		case BPF_S_ALU_LSH_K:
+			A <<= K;
+			continue;
+		case BPF_S_ALU_RSH_X:
+			A >>= X;
+			continue;
+		case BPF_S_ALU_RSH_K:
+			A >>= K;
+			continue;
+		case BPF_S_ALU_NEG:
+			A = -A;
+			continue;
+		case BPF_S_JMP_JA:
+			fentry += K;
+			continue;
+		case BPF_S_JMP_JGT_K:
+			fentry += (A > K) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JGE_K:
+			fentry += (A >= K) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JEQ_K:
+			fentry += (A == K) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JSET_K:
+			fentry += (A & K) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JGT_X:
+			fentry += (A > X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JGE_X:
+			fentry += (A >= X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JEQ_X:
+			fentry += (A == X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JSET_X:
+			fentry += (A & X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_LD_W_ABS:
+			k = K;
+load_w:
+			ptr = load_pointer(skb, k, 4, &tmp);
+			if (ptr != NULL) {
+				A = get_unaligned_be32(ptr);
+				continue;
+			}
+			return 0;
+		case BPF_S_LD_H_ABS:
+			k = K;
+load_h:
+			ptr = load_pointer(skb, k, 2, &tmp);
+			if (ptr != NULL) {
+				A = get_unaligned_be16(ptr);
+				continue;
+			}
+			return 0;
+		case BPF_S_LD_B_ABS:
+			k = K;
+load_b:
+			ptr = load_pointer(skb, k, 1, &tmp);
+			if (ptr != NULL) {
+				A = *(u8 *)ptr;
+				continue;
+			}
+			return 0;
+		case BPF_S_LD_W_LEN:
+			A = skb->len;
+			continue;
+		case BPF_S_LDX_W_LEN:
+			X = skb->len;
+			continue;
+		case BPF_S_LD_W_IND:
+			k = X + K;
+			goto load_w;
+		case BPF_S_LD_H_IND:
+			k = X + K;
+			goto load_h;
+		case BPF_S_LD_B_IND:
+			k = X + K;
+			goto load_b;
+		case BPF_S_LDX_B_MSH:
+			ptr = load_pointer(skb, K, 1, &tmp);
+			if (ptr != NULL) {
+				X = (*(u8 *)ptr & 0xf) << 2;
+				continue;
+			}
+			return 0;
+		case BPF_S_LD_IMM:
+			A = K;
+			continue;
+		case BPF_S_LDX_IMM:
+			X = K;
+			continue;
+		case BPF_S_LD_MEM:
+			A = mem[K];
+			continue;
+		case BPF_S_LDX_MEM:
+			X = mem[K];
+			continue;
+		case BPF_S_MISC_TAX:
+			X = A;
+			continue;
+		case BPF_S_MISC_TXA:
+			A = X;
+			continue;
+		case BPF_S_MISC_PROC:
+			A = dynamic_filter(skb, ((fentry+1)->k)) ? ((fentry+1)->k) : 0;
+			continue;
+		case BPF_S_RET_K:
+			return K;
+		case BPF_S_RET_A:
+			return A;
+		case BPF_S_ST:
+			mem[K] = A;
+			continue;
+		case BPF_S_STX:
+			mem[K] = X;
+			continue;
+		case BPF_S_ANC_PROTOCOL:
+			A = ntohs(skb->protocol);
+			continue;
+		case BPF_S_ANC_PKTTYPE:
+			A = skb->pkt_type;
+			continue;
+		case BPF_S_ANC_IFINDEX:
+			if (!skb->dev)
+				return 0;
+			A = skb->dev->ifindex;
+			continue;
+		case BPF_S_ANC_MARK:
+			A = skb->mark;
+			continue;
+		case BPF_S_ANC_QUEUE:
+			A = skb->queue_mapping;
+			continue;
+		case BPF_S_ANC_HATYPE:
+			if (!skb->dev)
+				return 0;
+			A = skb->dev->type;
+			continue;
+		case BPF_S_ANC_RXHASH:
+			A = skb->rxhash;
+			continue;
+		case BPF_S_ANC_CPU:
+			A = raw_smp_processor_id();
+			continue;
+		case BPF_S_ANC_NLATTR: {
+			struct nlattr *nla;
+
+			if (skb_is_nonlinear(skb))
+				return 0;
+			if (A > skb->len - sizeof(struct nlattr))
+				return 0;
+
+			nla = nla_find((struct nlattr *)&skb->data[A],
+				       skb->len - A, X);
+			if (nla)
+				A = (void *)nla - (void *)skb->data;
+			else
+				A = 0;
+			continue;
+		}
+		case BPF_S_ANC_NLATTR_NEST: {
+			struct nlattr *nla;
+
+			if (skb_is_nonlinear(skb))
+				return 0;
+			if (A > skb->len - sizeof(struct nlattr))
+				return 0;
+
+			nla = (struct nlattr *)&skb->data[A];
+			if (nla->nla_len > A - skb->len)
+				return 0;
+
+			nla = nla_find_nested(nla, X);
+			if (nla)
+				A = (void *)nla - (void *)skb->data;
+			else
+				A = 0;
+			continue;
+		}
+		default:
+			WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n",
+				       fentry->code, fentry->jt,
+				       fentry->jf, fentry->k);
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+
+unsigned int process_filter_function(const struct sk_buff *skb,
+		const struct sock_filter *filter, const int pid);
+
+extern int init_process_filter_function_fn(struct filter_function_struct *ffs);
+
+static struct filter_function ff = {
+	.name = "process_packet_filter",
+	.init_func = &init_process_filter_function_fn,
+	.func = &process_packets
+};
+
+/*
+ * @pi must be allocated previously
+ * @skb is the buffer passed to the filter
+ */
+static inline int getPacketInfo(const struct sk_buff *skb,
+	struct packetInfo *src_pi, struct packetInfo *dst_pi)
+{
+	u32 tmp;
+	void *ptr;
+	u32 X;
+
+	ptr = skb_header_pointer(skb, 23, 1, &tmp);
+	if (ptr != NULL) {
+		src_pi->protocol = *(u8 *)ptr;
+		dst_pi->protocol = *(u8 *)ptr;
+	} else
+		goto out;
+
+	ptr = skb_header_pointer(skb, 26, 4, &tmp);
+	if (ptr != NULL)
+		src_pi->address = get_unaligned_be32(ptr);
+	else
+		goto out;
+
+	ptr = skb_header_pointer(skb, 30, 4, &tmp);
+	if (ptr != NULL)
+		dst_pi->address = get_unaligned_be32(ptr);
+	else
+		goto out;
+
+	ptr = skb_header_pointer(skb, 14, 1, &tmp);
+	if (ptr != NULL) {
+		X = (*(u8 *)ptr & 0xf) << 2;
+		X += 14;
+		ptr = skb_header_pointer(skb, X, 2, &tmp);
+		if (ptr != NULL)
+			src_pi->port = get_unaligned_be16(ptr);
+		else
+			goto out;
+
+		X += 2;
+		ptr = skb_header_pointer(skb, X, 2, &tmp);
+		if (ptr != NULL)
+			dst_pi->port = get_unaligned_be16(ptr);
+		else
+			goto out;
+	} else
+		goto out;
+
+	return 0;
+
+out:
+	return -1;
+}
+
+int packet_belongs(struct packetInfo *src_pi, struct packetInfo *dst_pi)
+{
+	if ((src_pi->protocol == IPPROTO_TCP || src_pi->protocol == IPPROTO_UDP)) {
+		if (monitor_search(src_pi)) {
+			return src_pi->pid;
+		}
+
+		if (monitor_search(dst_pi)) {
+			return dst_pi->pid;
+		}
+	}
+
+	return 0;
+}
+
+int dynamic_filter(const struct sk_buff *skb, const int pid)
+{
+	void *ptr;
+	u32 A;
+	u32 tmp;
+	int err = -ENODATA;
+
+	ptr = skb_header_pointer(skb, 12, 2, &tmp);
+	if (ptr != NULL) {
+		A = get_unaligned_be16(ptr);
+		if (A == 0x800) {
+			struct packetInfo dst_pi;
+			struct packetInfo src_pi;
+			dst_pi.pid = pid;
+			src_pi.pid = pid;
+			if (!getPacketInfo(skb, &src_pi, &dst_pi))
+				return packet_belongs(&src_pi, &dst_pi);
+		}
+	}
+	return err;
+}
+
+unsigned int process_filter_function(const struct sk_buff *skb,
+					const struct sock_filter *filter, const int pid)
+{
+	return dynamic_filter(skb, pid);
+}
+
+int init_filter(void)
+{
+	register_filter_function(&ff);
+	return 0;
+}
+void exit_filter(void)
+{
+	unregister_filter_function(&ff);
+}
diff --git a/net/pidmonitor/filter.h b/net/pidmonitor/filter.h
new file mode 100644
index 0000000..9405aea
--- /dev/null
+++ b/net/pidmonitor/filter.h
@@ -0,0 +1,31 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef FILTER_H_
+#define FILTER_H_
+
+extern int init_filter(void);
+extern void exit_filter(void);
+
+#endif /* FILTER_H_ */
diff --git a/net/pidmonitor/pidmonitor.c b/net/pidmonitor/pidmonitor.c
new file mode 100644
index 0000000..6acfcfc
--- /dev/null
+++ b/net/pidmonitor/pidmonitor.c
@@ -0,0 +1,102 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <net/net_namespace.h>
+#include <linux/inetdevice.h>
+
+#include "pidmonitor.h"
+#include "filter.h"
+#include "syscalls_monitor.h"
+#include "db_monitor.h"
+
+struct local_addresses_list *local_list;
+
+struct local_addresses_list *list_all_devices_address(void)
+{
+	struct net_device *dev;
+	struct net *net = &init_net;
+	struct local_addresses_list *list = NULL;
+	struct local_addresses_list *tmp = NULL;
+
+	list = kmalloc(sizeof(*list), GFP_KERNEL);
+	INIT_LIST_HEAD(&(list->list));
+
+	for_each_netdev(net, dev) {
+		if (dev->ip_ptr) {
+			struct in_device *in4 = dev->ip_ptr;
+			struct in_ifaddr *addr;
+			for (addr = in4->ifa_list; addr; addr = addr->ifa_next) {
+				tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+				tmp->address = ntohl(addr->ifa_address);
+				list_add(&(tmp->list), &(list->list));
+			}
+		}
+	}
+	return list;
+}
+
+int remove_local_addresses_list(struct local_addresses_list *list)
+{
+	struct local_addresses_list *tmp;
+	struct list_head *pos = NULL, *q = NULL;
+
+	list_for_each_safe(pos, q, &(list->list)) {
+		tmp = list_entry(pos, struct local_addresses_list, list);
+		list_del(pos);
+		kfree(tmp);
+	}
+
+	return 0;
+}
+
+static int __init monitor_init(void)
+{
+	init_syscalls_monitor();
+	init_db_monitor();
+	init_filter();
+
+	local_list = list_all_devices_address();
+	return 0;
+}
+
+static void __exit monitor_exit(void)
+{
+	int ret = -1;
+
+	exit_db_monitor();
+	exit_filter();
+	exit_syscalls_monitor();
+
+	ret = remove_local_addresses_list(local_list);
+	if (ret == 0)
+		kfree(local_list);
+}
+
+module_init(monitor_init);
+module_exit(monitor_exit);
+MODULE_LICENSE("GPL");
diff --git a/net/pidmonitor/pidmonitor.h b/net/pidmonitor/pidmonitor.h
new file mode 100644
index 0000000..69d4306
--- /dev/null
+++ b/net/pidmonitor/pidmonitor.h
@@ -0,0 +1,63 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef PCAP_MONITORING_H_
+#define PCAP_MONITORING_H_
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <net/net_namespace.h>
+#include <linux/list.h>
+
+struct packetInfo {
+	u8 protocol;
+	u16 port;
+	u32 address;
+	int pid;
+};
+
+#define NIPQUAD(addr) \
+	((unsigned char *)&addr)[3], \
+	((unsigned char *)&addr)[2], \
+	((unsigned char *)&addr)[1], \
+	((unsigned char *)&addr)[0]
+
+struct local_addresses_list {
+	struct list_head list;
+	u32 address;
+	unsigned int pid;
+	int counter;
+};
+
+extern struct local_addresses_list *local_list;
+extern struct socket *sockfd_lookup(int fd, int *err);
+int get_local_packet_info_from_fd(unsigned int fd, struct packetInfo *ret);
+int get_local_packet_info_from_file(struct file *f, struct packetInfo *ret);
+struct local_addresses_list *list_all_devices_address(void);
+int remove_local_addresses_list(struct local_addresses_list *list);
+extern struct net inet;
+
+int init_process_filter_function_fn(struct filter_function_struct *ffs);
+void init_repo_task(int pidnr);
+
+#endif /* PCAP_MONITORING_H_ */
diff --git a/net/pidmonitor/proc_monitor.c b/net/pidmonitor/proc_monitor.c
new file mode 100644
index 0000000..5b41db3
--- /dev/null
+++ b/net/pidmonitor/proc_monitor.c
@@ -0,0 +1,116 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/stat.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/path.h>
+#include <linux/dcache.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/tcp.h>
+#include <net/inet_sock.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <net/net_namespace.h>
+#include <linux/inetdevice.h>
+
+
+#include "pidmonitor.h"
+
+static void get_inet_sock_param(struct inet_sock *inetsock, struct packetInfo *ret)
+{
+	ret->port = inetsock->inet_num;
+	ret->protocol = ((struct sock *)inetsock)->sk_protocol;
+
+	if (ret->port == ntohs(inetsock->inet_sport)) {
+		if (!inetsock->inet_rcv_saddr)
+			ret->address = inetsock->inet_saddr;
+		else
+			ret->address = inetsock->inet_rcv_saddr;
+
+	} else
+		ret->address = inetsock->inet_daddr;
+
+	ret->address = ntohl(ret->address);
+}
+
+
+int get_local_packet_info_from_fd(unsigned int fd, struct packetInfo *ret)
+{
+	struct file *f = fget(fd);
+
+	if (f != NULL) {
+		fput(f);
+		return get_local_packet_info_from_file(f, ret);
+	}
+	return -3;
+}
+
+int get_local_packet_info_from_file(struct file *f, struct packetInfo *ret)
+{
+	struct socket *socket = NULL;
+	short type;
+	unsigned short family;
+	int err = 0;
+
+	if (f != NULL) {
+		struct dentry *dentry;
+		struct inode *d_inode;
+		dentry = f->f_dentry;
+		if (dentry != NULL) {
+			d_inode = dentry->d_inode;
+			if (S_ISSOCK(d_inode->i_mode)) {
+				socket = f->private_data;
+				if (socket == NULL) {
+					err = -5;
+					goto out;
+				}
+				type = socket->type;
+				if (socket->sk == NULL) {
+					err = -6;
+					goto out;
+				}
+				family = socket->sk->__sk_common.skc_family;
+				if (family != AF_INET) {
+					err = -4;
+					goto out;
+				} else {
+					get_inet_sock_param((struct inet_sock *)(socket->sk), ret);
+					err = 0;
+				}
+			} else {
+				err = -1;
+			}
+		} else {
+			err = -2;
+		}
+	} else {
+		err = -3;
+	}
+out:
+	return err;
+
+}
diff --git a/net/pidmonitor/proc_monitor.h b/net/pidmonitor/proc_monitor.h
new file mode 100644
index 0000000..c9ba064
--- /dev/null
+++ b/net/pidmonitor/proc_monitor.h
@@ -0,0 +1,23 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
diff --git a/net/pidmonitor/syscalls_monitor.c b/net/pidmonitor/syscalls_monitor.c
new file mode 100644
index 0000000..69016d5
--- /dev/null
+++ b/net/pidmonitor/syscalls_monitor.c
@@ -0,0 +1,423 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/ptrace.h>
+
+#include <linux/module.h>
+#include <linux/kprobes.h>
+
+#include <net/sock.h>
+#include <linux/string.h>
+#include <net/inet_sock.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <linux/pid.h>
+#include <asm-generic/errno.h>
+
+#include "pidmonitor.h"
+#include "db_monitor.h"
+
+u64 pid = -1, ppid = -1, tgid = -1;
+
+void set_process_identifiers(u64 lpid)
+{
+	pid = lpid;
+}
+
+int init_process_filter_function_fn(struct filter_function_struct *ffs)
+{
+	set_process_identifiers(ffs->pid);
+	init_repo_task(ffs->pid);
+	return 0;
+}
+int kprobes_index;
+
+#define TO_MONITOR(t) { \
+	if (pid == t->pid) \
+		goto monitor; \
+	else { \
+		my_data->fd = -1; \
+		return 0; \
+	}\
+} while(0);
+
+#define NR_PROBES 7
+
+struct kretprobe *kretprobes;
+
+struct cell {
+	int fd;
+};
+
+struct closeInfo {
+	int fd;
+	struct packetInfo pi;
+};
+
+struct connect_extern_info {
+	struct packetInfo external;
+	int fd;
+};
+
+static int sendto_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	struct task_struct *task = ri->task;
+
+#ifdef CONFIG_X86_32
+	int fd = regs->ax;
+#else
+	int fd = regs->di;
+#endif
+	struct cell *my_data = (struct cell *)ri->data;
+	TO_MONITOR(task)
+
+monitor :
+	my_data->fd = fd;
+	return 0;
+}
+static int sendto_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+
+	int retval = regs_return_value(regs);
+	struct cell *my_data = (struct cell *)ri->data;
+	struct packetInfo pi;
+	int fd = my_data->fd;
+
+	if (my_data->fd == -1) {
+		return 0;
+	}
+
+
+	if (retval >= 0 || retval == -EAGAIN || retval == -EINPROGRESS || retval == -EALREADY) {
+		pi.pid = ri->task->pid;
+		if (!get_local_packet_info_from_fd(fd, &pi))
+			monitor_insert(&pi);
+	}
+	return 0;
+}
+
+static int recvfrom_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	struct task_struct *task = ri->task;
+	struct cell *my_data = (struct cell *)ri->data;
+#ifdef CONFIG_X86_32
+	int fd = regs->ax;
+#else
+	int fd = regs->di;
+#endif
+	TO_MONITOR(task)
+
+monitor :
+	my_data->fd = fd;
+	return 0;
+}
+static int recvfrom_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	int retval = regs_return_value(regs);
+	struct cell *my_data = (struct cell *)ri->data;
+	struct packetInfo pi;
+	int fd = my_data->fd;
+	int err = 0;
+
+	if (my_data->fd == -1) {
+		return 0;
+	}
+
+	if (retval >= 0 || retval == -EAGAIN || retval == -EINPROGRESS) {
+		pi.pid = ri->task->pid;
+		get_local_packet_info_from_fd(fd, &pi);
+		if (err == 0)
+			monitor_insert(&pi);
+	}
+
+	return 0;
+}
+
+static int accept_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	struct task_struct *task = ri->task;
+	struct cell *my_data = (struct cell *)ri->data;
+
+	TO_MONITOR(task)
+
+monitor :
+	my_data->fd = 0;
+	return 0;
+}
+static int accept_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	int retval = regs_return_value(regs);
+	struct cell *my_data = (struct cell *)ri->data;
+	struct packetInfo pi;
+
+	if (my_data->fd == -1) {
+		return 0;
+	}
+
+	if (retval > 0) {
+		pi.pid = ri->task->pid;
+		if (!get_local_packet_info_from_fd(retval, &pi))
+			monitor_insert(&pi);
+	}
+
+	return 0;
+}
+
+static int close_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	struct task_struct *task = ri->task;
+	struct closeInfo *my_data = (struct closeInfo *)ri->data;
+
+#ifdef CONFIG_X86_32
+	struct file *filp = (struct file *)regs->bx;
+#else
+	struct file *filp = (struct file *)regs->si;
+#endif
+
+	int err = -1;
+	TO_MONITOR(task)
+
+monitor :
+
+	err = get_local_packet_info_from_file(filp, &(my_data->pi));
+	if (err >= 0) {
+		my_data->fd = -2;
+	} else {
+		my_data->fd = -1;
+	}
+
+	return 0;
+}
+
+static int close_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	int retval = regs_return_value(regs);
+	struct closeInfo *cI = (struct closeInfo *)ri->data;
+
+	if (cI->fd == -1) {
+		return 0;
+	}
+	if (retval == 0)
+		monitor_erase(&(cI->pi));
+	return 0;
+}
+
+static int bind_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	struct task_struct *task = ri->task;
+#ifdef CONFIG_X86_32
+	int fd = regs->ax;
+#else
+	int fd = regs->di;
+#endif
+	struct cell *my_data = (struct cell *)ri->data;
+	TO_MONITOR(task)
+
+monitor :
+	my_data->fd = fd;
+	return 0;
+}
+
+static int bind_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	int retval = regs_return_value(regs);
+	struct cell *my_data = (struct cell *)ri->data;
+	struct packetInfo pi;
+	int fd = my_data->fd;
+
+	if (my_data->fd == -1) {
+		return 0;
+	}
+
+	pi.pid = ri->task->pid;
+	if (retval == 0 && !get_local_packet_info_from_fd(fd, &pi))
+		monitor_insert(&pi);
+
+	return 0;
+}
+
+static int connect_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	struct task_struct *task = ri->task;
+	struct connect_extern_info *my_data = (struct connect_extern_info *)ri->data;
+#ifdef CONFIG_X86_32
+	int fd = regs->ax;
+	struct sockaddr_in *in = (struct sockaddr_in *)regs->dx;
+#else
+	int fd = regs->di;
+	struct sockaddr_in *in = (struct sockaddr_in *)regs->si;
+#endif
+	TO_MONITOR(task)
+
+monitor :
+	my_data->fd = fd;
+
+	if (!get_local_packet_info_from_fd(fd, &(my_data->external))){
+		my_data->external.address = ntohl(in->sin_addr.s_addr);
+		my_data->external.port = ntohs(in->sin_port);
+		(my_data->external).pid = task->pid;
+		monitor_insert(&(my_data->external));
+	} else {
+		my_data->fd = -1;
+	}
+
+	return 0;
+}
+
+static int connect_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	int retval = regs_return_value(regs);
+	struct connect_extern_info *my_data = (struct connect_extern_info *)ri->data;
+	int fd = my_data->fd;
+	struct packetInfo pi;
+
+	if (fd == -1) {
+		return 0;
+	}
+
+	if (retval == 0 || retval == -EINPROGRESS || retval == -EALREADY || retval == -EISCONN || retval == -EAGAIN) {
+		monitor_erase(&(my_data->external));
+		pi.pid = ri->task->pid;
+		if (!get_local_packet_info_from_fd(fd, &pi))
+			monitor_insert(&pi);
+	}
+
+	return 0;
+}
+
+static int instantiationKRETProbe(struct kretprobe *kret,
+				const char *function_name,
+				kretprobe_handler_t func_handler,
+				kretprobe_handler_t func_entry_handler,
+				ssize_t data_size)
+{
+	int ret = -1;
+
+	struct kprobe kp = {
+		.symbol_name = function_name,
+	};
+
+	kret->kp = kp;
+	kret->handler = func_handler;
+	kret->entry_handler = func_entry_handler;
+	kret->data_size	= data_size;
+	kret->maxactive = 8;
+
+	ret = register_kretprobe(kret);
+	if (ret < 0) {
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * function called on module init to initialize kretprobes common to tcp and udp
+ */
+
+static int init_kretprobes_syscalls(void)
+{
+	int ret = 0;
+
+	kretprobes = kmalloc(sizeof(*kretprobes)*NR_PROBES, GFP_KERNEL);
+
+	if (!kretprobes) {
+		return -1;
+	}
+
+	ret = instantiationKRETProbe((kretprobes+kprobes_index),
+			"sys_bind", bind_ret_handler, bind_entry_handler,
+			(ssize_t)sizeof(struct cell));
+	kprobes_index += 1;
+	if (ret < 0)
+		return -1;
+
+	ret = instantiationKRETProbe((kretprobes+kprobes_index),
+			"sys_connect", connect_ret_handler,
+			connect_entry_handler,
+			(ssize_t)sizeof(struct connect_extern_info));
+	kprobes_index += 1;
+	if (ret < 0)
+		return -1;
+
+	ret = instantiationKRETProbe((kretprobes+kprobes_index),
+			"sock_close", close_ret_handler, close_entry_handler,
+			(ssize_t)sizeof(struct packetInfo));
+	kprobes_index += 1;
+	if (ret < 0)
+		return -1;
+
+	ret = instantiationKRETProbe((kretprobes+kprobes_index),
+			"sys_accept4", accept_ret_handler, accept_entry_handler,
+			(ssize_t)sizeof(struct cell));
+	kprobes_index += 1;
+		if (ret < 0)
+			return -1;
+
+	ret = instantiationKRETProbe((kretprobes+kprobes_index),
+			"sys_sendto", sendto_ret_handler, sendto_entry_handler,
+			(ssize_t)sizeof(struct cell));
+	kprobes_index += 1;
+	if (ret < 0)
+		return -1;
+
+	ret = instantiationKRETProbe((kretprobes+kprobes_index),
+			"sys_recvfrom", recvfrom_ret_handler,
+			recvfrom_entry_handler, (ssize_t)sizeof(struct cell));
+	kprobes_index += 1;
+	if (ret < 0)
+		return -1;
+
+	return kprobes_index;
+}
+
+static void removeKprobe(int index)
+{
+	if ((kretprobes+index) != NULL) {
+		unregister_kretprobe((kretprobes+index));
+	}
+}
+
+static void destroy_kretprobes_syscalls(void)
+{
+	int i = -1;
+
+	for (i = 0; i < kprobes_index ; i++)
+		removeKprobe(i);
+
+	if (kretprobes)
+		kfree(kretprobes);
+}
+
+int init_syscalls_monitor(void)
+{
+	return init_kretprobes_syscalls();
+}
+
+void exit_syscalls_monitor(void)
+{
+	destroy_kretprobes_syscalls();
+}
diff --git a/net/pidmonitor/syscalls_monitor.h b/net/pidmonitor/syscalls_monitor.h
new file mode 100644
index 0000000..1d1a2f6
--- /dev/null
+++ b/net/pidmonitor/syscalls_monitor.h
@@ -0,0 +1,31 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef SYSCALLS_MONITOR_H_
+#define SYSCALLS_MONITOR_H_
+
+extern int init_syscalls_monitor(void);
+extern void exit_syscalls_monitor(void);
+
+#endif /* SYSCALLS_MONITOR_H_ */
diff --git a/net/pidmonitor/task_monitor.c b/net/pidmonitor/task_monitor.c
new file mode 100644
index 0000000..4b9932c
--- /dev/null
+++ b/net/pidmonitor/task_monitor.c
@@ -0,0 +1,77 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/byteorder/generic.h>
+#include <linux/uaccess.h>
+#include <linux/filter.h>
+#include <linux/fdtable.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+
+#include "pidmonitor.h"
+#include "db_monitor.h"
+
+static void read_from_fdtable(struct task_struct *task)
+{
+	int fd;
+	int max_fds;
+	struct file *file;
+
+	max_fds = task->files->fdt->max_fds;
+	for (fd = 0; fd < max_fds ; fd++) {
+		file = fcheck_files(task->files, fd);
+		if (file) {
+			struct packetInfo p;
+			p.pid = task->pid;
+			if (!get_local_packet_info_from_file(file, &p)) {
+				monitor_insert(&p);
+			}
+		}
+	}
+}
+
+static void init_tree(struct task_struct *task)
+{
+
+	if (task == NULL)
+		return;
+
+	rcu_read_lock();
+	read_from_fdtable(task);
+	rcu_read_unlock();
+}
+
+void init_repo_task(int pidnr)
+{
+	struct task_struct *task = NULL;
+	struct pid *pid = find_get_pid(pidnr);
+	rcu_read_lock();
+	task = pid_task(pid, PIDTYPE_PID);
+	put_pid(pid);
+	rcu_read_unlock();
+	init_tree(task);
+}
diff --git a/net/pidmonitor/task_monitor.h b/net/pidmonitor/task_monitor.h
new file mode 100644
index 0000000..c9ba064
--- /dev/null
+++ b/net/pidmonitor/task_monitor.h
@@ -0,0 +1,23 @@
+/*
+ * Packet Filtering System based on BPF / LSF
+ *
+ * Author: Nuno Martins <nuno.martins@caixamagica.pt>
+ *
+ * (c) Copyright Caixa Magica Software, LDA., 2012
+ * (c) Copyright Universidade Nova de Lisboa, 2010-2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program;  if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
-- 
1.7.10.rc3.11.gd8282

^ permalink raw reply related

* [PATCH RFC] virtio-net: remove useless disable on freeze
From: Michael S. Tsirkin @ 2012-04-04  9:19 UTC (permalink / raw)
  To: netdev; +Cc: Amit Shah, linux-kernel, kvm, virtualization

disable_cb is just an optimization: it
can not guarantee that there are no callbacks.

I didn't yet figure out whether a callback
in freeze will trigger a bug, but disable_cb
won't address it in any case. So let's remove
the useless calls as a first step.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 drivers/net/virtio_net.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 019da01..971931e5 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1182,11 +1182,6 @@ static int virtnet_freeze(struct virtio_device *vdev)
 {
 	struct virtnet_info *vi = vdev->priv;
 
-	virtqueue_disable_cb(vi->rvq);
-	virtqueue_disable_cb(vi->svq);
-	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
-		virtqueue_disable_cb(vi->cvq);
-
 	netif_device_detach(vi->dev);
 	cancel_delayed_work_sync(&vi->refill);
 
-- 
1.7.9.111.gf3fb0

^ permalink raw reply related

* Re: Commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 has broken ss command
From: David Miller @ 2012-04-04  9:24 UTC (permalink / raw)
  To: eric.dumazet; +Cc: slash, netdev, xemul, linux-kernel
In-Reply-To: <1333530463.18626.545.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 04 Apr 2012 11:07:43 +0200

> On Wed, 2012-04-04 at 18:03 +0900, Kusanagi Kouichi wrote:
>> Since commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 ("sock_diag:
>> Move the sock_ code to net/core/"), ss command from iproute package
>> doesn't work if INET_DIAG is not enabled.
>> 
>> $ ss
>> State       Recv-Q Send-Q                                             Local Address:Port                                                 Peer Address:Port
>> TCPDIAG answers: Operation not supported
>> --
> 
> Try to update your iproute2 package ?

Well, he doesn't INET_DIAG enabled in his kernel, so no matter what
iproute2 version he uses it won't work :-)

^ permalink raw reply

* Re: Commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 has broken ss command
From: David Miller @ 2012-04-04  9:25 UTC (permalink / raw)
  To: slash; +Cc: netdev, xemul, linux-kernel
In-Reply-To: <20120404090312.1B68C6AC03E@msa102.auone-net.jp>

From: Kusanagi Kouichi <slash@ac.auone-net.jp>
Date: Wed, 4 Apr 2012 18:03:11 +0900

> Since commit 8ef874bfc7296fa206eea2ad1e8a426f576bf6f6 ("sock_diag:
> Move the sock_ code to net/core/"), ss command from iproute package
> doesn't work if INET_DIAG is not enabled.

Well, of course you need to enable that Kconfig options to get
netlink socket dumping support for inet protocols.

^ permalink raw reply

* Re: [PATCH] ipv6: Fix 'inet6_rtm_getroute' to release 'rt->dst' in case of 'alloc_skb' failure
From: David Miller @ 2012-04-04  9:26 UTC (permalink / raw)
  To: shmulik.ladkani
  Cc: netdev, linux-kernel, eric.dumazet, kuznet, jmorris, yoshfuji,
	kaber
In-Reply-To: <20120404121300.2e05437b@pixies.home.jungo.com>

From: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Date: Wed, 4 Apr 2012 12:13:00 +0300

> In 72331bc [ipv6: Fix RTM_GETROUTE's interpretation of RTA_IIF to be
> consistent with ipv4] the code of 'inet6_rtm_getroute()' was re-ordered
> such that the reference to 'rt->dst' is incremented prior skb
> allocation.
> 
> Hence, if 'alloc_skb()' fails, must drop a reference from 'rt->dst'.
> Add the missing 'dst_release()' call.
> 
> Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH V4 net-next 00/26] ethtool: support time stamping and phc clocks
From: David Miller @ 2012-04-04  9:29 UTC (permalink / raw)
  To: richardcochran
  Cc: mporter, e1000-devel, netdev, jacob.e.keller, john.ronciak,
	bhutchings
In-Reply-To: <cover.1333529504.git.richardcochran@gmail.com>

From: Richard Cochran <richardcochran@gmail.com>
Date: Wed,  4 Apr 2012 10:59:15 +0200

> * Changes in V4:
>   - drop two patches requiring out of tree support
>   - added Ben's Reviewed-by tag on two commit messages
> * Changes in V3:
>   - works without ethtool_ops
>   - does not require special privileges
>   - neaten user space tool output

Applied, let's see if this one compiles :-)

------------------------------------------------------------------------------
Better than sec? Nothing is better than sec when it comes to
monitoring Big Data applications. Try Boundary one-second 
resolution app monitoring today. Free.
http://p.sf.net/sfu/Boundary-dev2dev
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* [net 00/10] bnx2x: Link fixes
From: Yaniv Rosner @ 2012-04-04 11:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner

Hi Dave,
The following patch series describe some link fixes.
These changes were held back a while until testing was completed to insure the
issues are really fixed. And though they are minor issues, we still prefer to
push those fixes to net and not just net-next as they improve the usability.
Please consider applying it to net.

Thanks,
Yaniv

^ permalink raw reply

* [net 02/10] bnx2x: Fix BCM57810-KR FC
From: Yaniv Rosner @ 2012-04-04 11:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

Fix 57810-KR flow-control handling link is achieved via CL37 AN.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |   27 ++++++++++++++++++++++
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h  |    4 +++
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 7e2ebba..8c00bbc 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -3655,6 +3655,33 @@ static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
 		bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
 		bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
+	} else if (CHIP_IS_E3(bp) &&
+		SINGLE_MEDIA_DIRECT(params)) {
+		u8 lane = bnx2x_get_warpcore_lane(phy, params);
+		u16 gp_status, gp_mask;
+		bnx2x_cl45_read(bp, phy,
+				MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
+				&gp_status);
+		gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
+			   MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
+			lane;
+		if ((gp_status & gp_mask) == gp_mask) {
+			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+					MDIO_AN_REG_ADV_PAUSE, &ld_pause);
+			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+					MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
+		} else {
+			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+					MDIO_AN_REG_CL37_FC_LD, &ld_pause);
+			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+					MDIO_AN_REG_CL37_FC_LP, &lp_pause);
+			ld_pause = ((ld_pause &
+				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
+				    << 3);
+			lp_pause = ((lp_pause &
+				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
+				    << 3);
+		}
 	} else {
 		bnx2x_cl45_read(bp, phy,
 				MDIO_AN_DEVAD,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index ecc7fa6..1ea2b95 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -6944,6 +6944,10 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_WC_REG_GP2_STATUS_GP_2_2			0x81d2
 #define MDIO_WC_REG_GP2_STATUS_GP_2_3			0x81d3
 #define MDIO_WC_REG_GP2_STATUS_GP_2_4			0x81d4
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL 0x1000
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CMPL 0x0100
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP 0x0010
+#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CAP 0x1
 #define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP		0x81EE
 #define MDIO_WC_REG_UC_INFO_B1_VERSION			0x81F0
 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE		0x81F2
-- 
1.7.7.1

^ permalink raw reply related

* [net 03/10] bnx2x: Fix BCM57810-KR AN speed transition
From: Yaniv Rosner @ 2012-04-04 11:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

BCM57810-KR link may not come up in 1G after running loopback test, so set
the relevant registers to their default values before starting KR autoneg.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 8c00bbc..ce0b0c2 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -3732,7 +3732,23 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
 	u16 val16 = 0, lane, bam37 = 0;
 	struct bnx2x *bp = params->bp;
 	DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
-
+	/* Set to default registers that may be overriden by 10G force */
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
+	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+			 MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0);
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff);
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555);
+	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
+			 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0);
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_RX66_CONTROL, 0x7415);
+	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+			 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190);
 	/* Disable Autoneg: re-enable it after adv is done. */
 	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
 			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0);
@@ -4402,7 +4418,7 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
 		switch (serdes_net_if) {
 		case PORT_HW_CFG_NET_SERDES_IF_KR:
 			/* Enable KR Auto Neg */
-			if (params->loopback_mode == LOOPBACK_NONE)
+			if (params->loopback_mode != LOOPBACK_EXT)
 				bnx2x_warpcore_enable_AN_KR(phy, params, vars);
 			else {
 				DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
-- 
1.7.7.1

^ permalink raw reply related

* [net 04/10] bnx2x: Fix BCM578x0-SFI pre-emphasis settings
From: Yaniv Rosner @ 2012-04-04 11:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

Fix 578x0-SFI pre-emphasis settings per HW recommendations to achieve better
link strength.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index ce0b0c2..1e2fea3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -3994,13 +3994,13 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
 
 	} else {
 		misc1_val |= 0x9;
-		tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
-			   (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
-			   (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
+		tap_val = ((0x0f << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
+			   (0x2b << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
+			   (0x02 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
 		tx_driver_val =
-		      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
+		      ((0x03 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
 		       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
-		       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
+		       (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
 	}
 	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
 			 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
-- 
1.7.7.1

^ permalink raw reply related

* [net 01/10] bnx2x: PFC fix
From: Yaniv Rosner @ 2012-04-04 11:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

Fix a problem in which PFC frames are not honored, due to incorrect link
attributes synchronization following PMF migration, and verify PFC XON is not
stuck from previous link change.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |   18 +++++++++++++++++-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h  |    1 +
 2 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index efa557b..7e2ebba 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -1371,7 +1371,14 @@ static void bnx2x_update_pfc_xmac(struct link_params *params,
 		pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
 			XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
 			XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
-			XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
+			XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
+			XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
+		/* Write pause and PFC registers */
+		REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
+		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
+		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
+		pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
+
 	}
 
 	/* Write pause and PFC registers */
@@ -6843,6 +6850,12 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
 			  SINGLE_MEDIA_DIRECT(params)) &&
 			 (phy_vars[active_external_phy].fault_detected == 0));
 
+	/* Update the PFC configuration in case it was changed */
+	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
+		vars->link_status |= LINK_STATUS_PFC_ENABLED;
+	else
+		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
+
 	if (vars->link_up)
 		rc = bnx2x_update_link_up(params, vars, link_10g_plus);
 	else
@@ -12049,6 +12062,9 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 
 	bnx2x_emac_init(params, vars);
 
+	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
+		vars->link_status |= LINK_STATUS_PFC_ENABLED;
+
 	if (params->num_phys == 0) {
 		DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
 		return -EINVAL;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index ab0a250..ecc7fa6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -5354,6 +5354,7 @@
 #define XMAC_CTRL_REG_TX_EN					 (0x1<<0)
 #define XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN				 (0x1<<18)
 #define XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN				 (0x1<<17)
+#define XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON			 (0x1<<1)
 #define XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN			 (0x1<<0)
 #define XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN			 (0x1<<3)
 #define XMAC_PFC_CTRL_HI_REG_RX_PFC_EN				 (0x1<<4)
-- 
1.7.7.1

^ permalink raw reply related

* [net 05/10] bnx2x: Restore 1G LED on BCM57712+BCM8727 designs.
From: Yaniv Rosner @ 2012-04-04 11:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

Fix no-LED problem when link speed is 1G on BCM57712 + BCM8727 designs, by
removing a logic error checking for a different PHY.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |   33 ++++++++++++----------
 1 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 1e2fea3..1438da8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -6216,12 +6216,14 @@ int bnx2x_set_led(struct link_params *params,
 
 		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
 		if (params->phy[EXT_PHY1].type ==
-			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
-			EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp & 0xfff1);
-		else {
-			EMAC_WR(bp, EMAC_REG_EMAC_LED,
-				(tmp | EMAC_LED_OVERRIDE));
-		}
+			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
+			tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
+				EMAC_LED_100MB_OVERRIDE |
+				EMAC_LED_10MB_OVERRIDE);
+		else
+			tmp |= EMAC_LED_OVERRIDE;
+
+		EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp);
 		break;
 
 	case LED_MODE_OPER:
@@ -6276,10 +6278,15 @@ int bnx2x_set_led(struct link_params *params,
 				       hw_led_mode);
 		} else if ((params->phy[EXT_PHY1].type ==
 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
-			   (mode != LED_MODE_OPER)) {
+			   (mode == LED_MODE_ON)) {
 			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
 			tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
-			EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp | 0x3);
+			EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp |
+				EMAC_LED_OVERRIDE | EMAC_LED_1000MB_OVERRIDE);
+			/* Break here; otherwise, it'll disable the
+			 * intended override.
+			 */
+			break;
 		} else
 			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
 			       hw_led_mode);
@@ -6294,13 +6301,9 @@ int bnx2x_set_led(struct link_params *params,
 			       LED_BLINK_RATE_VAL_E1X_E2);
 		REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
 		       port*4, 1);
-		if ((params->phy[EXT_PHY1].type !=
-		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
-		    (mode != LED_MODE_OPER)) {
-			tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
-			EMAC_WR(bp, EMAC_REG_EMAC_LED,
-				(tmp & (~EMAC_LED_OVERRIDE)));
-		}
+		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
+		EMAC_WR(bp, EMAC_REG_EMAC_LED,
+			(tmp & (~EMAC_LED_OVERRIDE)));
 
 		if (CHIP_IS_E1(bp) &&
 		    ((speed == SPEED_2500) ||
-- 
1.7.7.1

^ permalink raw reply related

* [net 06/10] bnx2x: Fix link issue for BCM8727 boards.
From: Yaniv Rosner @ 2012-04-04 11:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

This patch fixes a link problem on BCM57712 + BCM8727 designs in which the TX
laser is controller by GPIO, after 1.60.xx drivers were previously loaded.
On these designs the TX_LASER is enabled by logic AND between the PHY
(through MDIO), and the GPIO. When an old driver is used, it disables the
MDIO part, hence the GPIO control had no affect de facto.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 1438da8..732b4c8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -8089,7 +8089,9 @@ static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
 	netdev_err(bp->dev,  "Warning: Unqualified SFP+ module detected,"
 			      " Port %d from %s part number %s\n",
 			 params->port, vendor_name, vendor_pn);
-	phy->flags |= FLAGS_SFP_NOT_APPROVED;
+	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
+	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
+		phy->flags |= FLAGS_SFP_NOT_APPROVED;
 	return -EINVAL;
 }
 
@@ -9149,6 +9151,12 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
 		tmp2 &= 0xFFEF;
 		bnx2x_cl45_write(bp, phy,
 			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
+		bnx2x_cl45_read(bp, phy,
+				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
+				&tmp2);
+		bnx2x_cl45_write(bp, phy,
+				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
+				 (tmp2 & 0x7fff));
 	}
 
 	return 0;
@@ -9329,12 +9337,11 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
 				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
 				 ((1<<5) | (1<<2)));
 	}
-	DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
-	bnx2x_8727_specific_func(phy, params, ENABLE_TX);
-	/* If transmitter is disabled, ignore false link up indication */
-	bnx2x_cl45_read(bp, phy,
-			MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
-	if (val1 & (1<<15)) {
+
+	if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) {
+		DP(NETIF_MSG_LINK, "Enabling 8727 TX laser\n");
+		bnx2x_sfp_set_transmitter(params, phy, 1);
+	} else {
 		DP(NETIF_MSG_LINK, "Tx is disabled\n");
 		return 0;
 	}
-- 
1.7.7.1

^ permalink raw reply related

* [net 07/10] bnx2x: Fix BCM84833 PHY FW version presentation
From: Yaniv Rosner @ 2012-04-04 11:29 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 732b4c8..b576a3a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -9435,8 +9435,7 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
 
 	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
 		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
-		bnx2x_save_spirom_version(bp, port,
-				((fw_ver1 & 0xf000)>>5) | (fw_ver1 & 0x7f),
+		bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff,
 				phy->ver_addr);
 	} else {
 		/* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
-- 
1.7.7.1

^ permalink raw reply related

* [net 08/10] bnx2x: Clear BCM84833 LED after fan failure
From: Yaniv Rosner @ 2012-04-04 11:29 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |    9 +++++++++
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h  |    3 +++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index b576a3a..ce95ef7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -9858,6 +9858,15 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
 				other_shmem_base_addr));
 
 	u32 shmem_base_path[2];
+
+	/* Work around for 84833 LED failure inside RESET status */
+	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+		MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+		MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
+	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+		MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
+		MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
+
 	shmem_base_path[0] = params->shmem_base;
 	shmem_base_path[1] = other_shmem_base_addr;
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index 1ea2b95..c25803b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -6821,10 +6821,13 @@ Theotherbitsarereservedandshouldbezero*/
 
 #define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL	0x0020
 #define MDIO_AN_REG_8481_LEGACY_MII_CTRL	0xffe0
+#define MDIO_AN_REG_8481_MII_CTRL_FORCE_1G	0x40
 #define MDIO_AN_REG_8481_LEGACY_MII_STATUS	0xffe1
 #define MDIO_AN_REG_8481_LEGACY_AN_ADV		0xffe4
 #define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION	0xffe6
 #define MDIO_AN_REG_8481_1000T_CTRL		0xffe9
+#define MDIO_AN_REG_8481_1G_100T_EXT_CTRL	0xfff0
+#define MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF	0x0008
 #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW	0xfff5
 #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS	0xfff7
 #define MDIO_AN_REG_8481_AUX_CTRL		0xfff8
-- 
1.7.7.1

^ permalink raw reply related

* [net 09/10] bnx2x: Fix BCM57711+BCM84823 link issue
From: Yaniv Rosner @ 2012-04-04 11:29 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Yaniv Rosner, Eilon Greenstein
In-Reply-To: <1333538942-9904-1-git-send-email-yanivr@broadcom.com>

Fix a link problem on the second port of BCM57711 + BCM84823 boards due to 
incorrect macro usage.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index ce95ef7..7e41682 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -10177,7 +10177,7 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
 	u8 port;
 	u16 val16;
 
-	if (!(CHIP_IS_E1(bp)))
+	if (!(CHIP_IS_E1x(bp)))
 		port = BP_PATH(bp);
 	else
 		port = params->port;
@@ -10204,7 +10204,7 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
 	u16 val;
 	u8 port;
 
-	if (!(CHIP_IS_E1(bp)))
+	if (!(CHIP_IS_E1x(bp)))
 		port = BP_PATH(bp);
 	else
 		port = params->port;
-- 
1.7.7.1

^ permalink raw reply related

* Re: [PATCH net-next 2/2] e100: enable transmit time stamping.
From: Richard Cochran @ 2012-04-04  9:30 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: netdev@vger.kernel.org, David Miller
In-Reply-To: <1333530283.3046.14.camel@jtkirshe-mobl>

On Wed, Apr 04, 2012 at 02:04:43AM -0700, Jeff Kirsher wrote:
> 
> I had this patch in my queue, but during testing we found some serious
> issues with some adapters.  With every 82559 based adapter Aaron tried
> the system would panic on driver load.  This included at least one
> sampling of D101S and D101M.  Every other e100 chipset Aaron tried
> (82557, 82558, 82550) appeared to work fine.
> 
> So I am dropping this patch as is due to the kernel panics.

Okay, fine. That driver is strangely written, with weird callbacks and
passing function pointers around.

Taking a second look, I think I might have found the problem. The
drivers casts a firmware pointer onto a skb, and my patch then tries
to timestamp the firmware blob.

If I rework this, are you willing to give it another try?

Thanks,
Richard

^ 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