Netdev List
 help / color / mirror / Atom feed
* [PATCHv2 iproute2 1/3] bridge: Add support for setting bridge port attributes
From: Vlad Yasevich @ 2013-03-15 16:46 UTC (permalink / raw)
  To: netdev; +Cc: shemminger, john.r.fastabend
In-Reply-To: <1363366001-27622-1-git-send-email-vyasevic@redhat.com>

Add netlink support bridge port attributes such as cost, priority, state
and flags.  This also adds support for HW mode such as VEPA or VEB.

Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 bridge/br_common.h |    1 +
 bridge/bridge.c    |    3 +-
 bridge/link.c      |  217 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 220 insertions(+), 1 deletions(-)

diff --git a/bridge/br_common.h b/bridge/br_common.h
index 8764563..12fce3e 100644
--- a/bridge/br_common.h
+++ b/bridge/br_common.h
@@ -10,6 +10,7 @@ extern int do_fdb(int argc, char **argv);
 extern int do_mdb(int argc, char **argv);
 extern int do_monitor(int argc, char **argv);
 extern int do_vlan(int argc, char **argv);
+extern int do_link(int argc, char **argv);
 
 extern int preferred_family;
 extern int show_stats;
diff --git a/bridge/bridge.c b/bridge/bridge.c
index 06b7a54..77e260f 100644
--- a/bridge/bridge.c
+++ b/bridge/bridge.c
@@ -27,7 +27,7 @@ static void usage(void)
 {
 	fprintf(stderr,
 "Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }\n"
-"where  OBJECT := { fdb | mdb | vlan | monitor }\n"
+"where  OBJECT := { link | fdb | mdb | vlan | monitor }\n"
 "       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails]\n" );
 	exit(-1);
 }
@@ -42,6 +42,7 @@ static const struct cmd {
 	const char *cmd;
 	int (*func)(int argc, char **argv);
 } cmds[] = {
+	{ "link", 	do_link },
 	{ "fdb", 	do_fdb },
 	{ "mdb", 	do_mdb },
 	{ "vlan",	do_vlan },
diff --git a/bridge/link.c b/bridge/link.c
index edb6fbf..5811ee9 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -9,10 +9,14 @@
 #include <linux/if.h>
 #include <linux/if_bridge.h>
 #include <string.h>
+#include <stdbool.h>
 
+#include "libnetlink.h"
 #include "utils.h"
 #include "br_common.h"
 
+unsigned int filter_index;
+
 static const char *port_states[] = {
 	[BR_STATE_DISABLED] = "disabled",
 	[BR_STATE_LISTENING] = "listening",
@@ -87,6 +91,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
 	if (!(ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_UNSPEC))
 		return 0;
 
+	if (filter_index && filter_index != ifi->ifi_index)
+		return 0;
+
 	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
 
 	if (tb[IFLA_IFNAME] == NULL) {
@@ -136,3 +143,213 @@ int print_linkinfo(const struct sockaddr_nl *who,
 	fflush(fp);
 	return 0;
 }
+
+static void usage(void)
+{
+	fprintf(stderr, "Usage: bridge link set dev DEV [ cost COST ] [ priority PRIO ] [ state STATE ]\n");
+	fprintf(stderr, "                               [ guard {on | off} ]\n");
+	fprintf(stderr, "                               [ hairpin {on | off} ] \n");
+	fprintf(stderr, "                               [ fastleave {on | off} ]\n");
+	fprintf(stderr,	"                               [ root_block {on | off} ]\n");
+	fprintf(stderr, "                               [ hwmode {vepa | veb} ]\n");
+	fprintf(stderr, "       bridge link show [dev DEV]\n");
+	exit(-1);
+}
+
+static bool on_off(char *arg, __s8 *attr, char *val)
+{
+	if (strcmp(val, "on") == 0)
+		*attr = 1;
+	else if (strcmp(val, "off") == 0)
+		*attr = 0;
+	else {
+		fprintf(stderr,
+			"Error: argument of \"%s\" must be \"on\" or \"off\"\n",
+			arg);
+		return false;
+	}
+
+	return true;
+}
+
+static int brlink_modify(int argc, char **argv)
+{
+	struct {
+		struct nlmsghdr  n;
+		struct ifinfomsg ifm;
+		char             buf[512];
+	} req;
+	char *d = NULL;
+	__s8 hairpin = -1;
+	__s8 bpdu_guard = -1;
+	__s8 fast_leave = -1;
+	__u32 cost = 0;
+	__s16 priority = -1;
+	__s8 state = -1;
+	__s16 mode = -1;
+	__u16 flags = BRIDGE_FLAGS_MASTER;
+	struct rtattr *nest;
+
+	memset(&req, 0, sizeof(req));
+
+	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.n.nlmsg_flags = NLM_F_REQUEST;
+	req.n.nlmsg_type = RTM_SETLINK;
+	req.ifm.ifi_family = PF_BRIDGE;
+
+	while (argc > 0) {
+		if (strcmp(*argv, "dev") == 0) {
+			NEXT_ARG();
+			d = *argv;
+		} else if (strcmp(*argv, "guard") == 0) {
+			NEXT_ARG();
+			if (!on_off("guard", &bpdu_guard, *argv))
+				exit(-1);
+		} else if (strcmp(*argv, "hairpin") == 0) {
+			NEXT_ARG();
+			if (!on_off("hairping", &hairpin, *argv))
+				exit(-1);
+		} else if (strcmp(*argv, "fastleave") == 0) {
+			NEXT_ARG();
+			if (!on_off("fastleave", &fast_leave, *argv))
+				exit(-1);
+		} else if (strcmp(*argv, "cost")) {
+			NEXT_ARG();
+			cost = atoi(*argv);
+		} else if (strcmp(*argv, "priority")) {
+			NEXT_ARG();
+			priority = atoi(*argv);
+		} else if (strcmp(*argv, "state")) {
+			NEXT_ARG();
+			state = atoi(*argv);
+		} else if (strcmp(*argv, "mode")) {
+			NEXT_ARG();
+			flags |= BRIDGE_FLAGS_SELF;
+			if (strcmp(*argv, "vepa") == 0)
+				mode = BRIDGE_MODE_VEPA;
+			else if (strcmp(*argv, "veb") == 0)
+				mode = BRIDGE_MODE_VEB;
+			else {
+				fprintf(stderr,
+					"Mode argument must be \"vepa\" or "
+					"\"veb\".\n");
+				exit(-1);
+			}
+		} else {
+			usage();
+		}
+		argc--; argv++;
+	}
+	if (d == NULL) {
+		fprintf(stderr, "Device is a required argument.\n");
+		exit(-1);
+	}
+
+
+	req.ifm.ifi_index = ll_name_to_index(d);
+	if (req.ifm.ifi_index == 0) {
+		fprintf(stderr, "Cannot find bridge device \"%s\"\n", d);
+		exit(-1);
+	}
+
+	/* Nested PROTINFO attribute.  Contains: port flags, cost, priority and
+	 * state.
+	 */
+	nest = addattr_nest(&req.n, sizeof(req),
+			    IFLA_PROTINFO | NLA_F_NESTED);
+	/* Flags first */
+	if (bpdu_guard >= 0)
+		addattr8(&req.n, sizeof(req), IFLA_BRPORT_GUARD, bpdu_guard);
+	if (hairpin >= 0)
+		addattr8(&req.n, sizeof(req), IFLA_BRPORT_MODE, hairpin);
+	if (fast_leave >= 0)
+		addattr8(&req.n, sizeof(req), IFLA_BRPORT_FAST_LEAVE,
+			 fast_leave);
+
+	if (cost > 0)
+		addattr32(&req.n, sizeof(req), IFLA_BRPORT_COST, cost);
+
+	if (priority >= 0)
+		addattr16(&req.n, sizeof(req), IFLA_BRPORT_PRIORITY, priority);
+
+	if (state >= 0)
+		addattr8(&req.n, sizeof(req), IFLA_BRPORT_STATE, state);
+
+	addattr_nest_end(&req.n, nest);
+
+	/* IFLA_AF_SPEC nested attribute.  Contains IFLA_BRIDGE_FLAGS that
+	 * designates master or self operation as well as 'vepa' or 'veb'
+	 * operation modes.  These are only valid in 'self' mode on some
+	 * devices so far.  Thus we only need to include the flags attribute
+	 * if we are setting the hw mode.
+	 */
+	if (mode >= 0) {
+		nest = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC);
+
+		addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags);
+
+		if (mode >= 0)
+			addattr16(&req.n, sizeof(req), IFLA_BRIDGE_MODE, mode);
+
+		addattr_nest_end(&req.n, nest);
+	}
+
+	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
+		exit(2);
+
+	return 0;
+}
+
+static int brlink_show(int argc, char **argv)
+{
+	char *filter_dev = NULL;
+
+	while (argc > 0) {
+		if (strcmp(*argv, "dev") == 0) {
+			NEXT_ARG();
+			if (filter_dev)
+				duparg("dev", *argv);
+			filter_dev = *argv;
+		}
+		argc--; argv++;
+	}
+
+	if (filter_dev) {
+		if ((filter_index = ll_name_to_index(filter_dev)) == 0) {
+			fprintf(stderr, "Cannot find device \"%s\"\n",
+				filter_dev);
+			return -1;
+		}
+	}
+
+	if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) {
+		perror("Cannon send dump request");
+		exit(1);
+	}
+
+	if (rtnl_dump_filter(&rth, print_linkinfo, stdout) < 0) {
+		fprintf(stderr, "Dump terminated\n");
+		exit(1);
+	}
+	return 0;
+}
+
+int do_link(int argc, char **argv)
+{
+	ll_init_map(&rth);
+	if (argc > 0) {
+		if (matches(*argv, "set") == 0 ||
+		    matches(*argv, "change") == 0)
+			return brlink_modify(argc-1, argv+1);
+		if (matches(*argv, "show") == 0 ||
+		    matches(*argv, "lst") == 0 ||
+		    matches(*argv, "list") == 0)
+			return brlink_show(argc-1, argv+1);
+		if (matches(*argv, "help") == 0)
+			usage();
+	} else
+		return brlink_show(0, NULL);
+
+	fprintf(stderr, "Command \"%s\" is unknown, try \"bridge link help\".\n", *argv);
+	exit(-1);
+}
-- 
1.7.7.6

^ permalink raw reply related

* [PATCHv2 iproute2 2/3] bridge: Add support for printing bridge port attributes
From: Vlad Yasevich @ 2013-03-15 16:46 UTC (permalink / raw)
  To: netdev; +Cc: shemminger, john.r.fastabend
In-Reply-To: <1363366001-27622-1-git-send-email-vyasevic@redhat.com>

Output new nested bridge port attributes.

Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 bridge/link.c        |   79 +++++++++++++++++++++++++++++++++++++++++++++----
 include/libnetlink.h |    2 +
 lib/libnetlink.c     |   13 +++++++-
 3 files changed, 85 insertions(+), 9 deletions(-)

diff --git a/bridge/link.c b/bridge/link.c
index 5811ee9..6b53833 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -65,6 +65,8 @@ static const char *oper_states[] = {
 	"TESTING", "DORMANT",	 "UP"
 };
 
+static const char *hw_mode[] = {"VEB", "VEPA"};
+
 static void print_operstate(FILE *f, __u8 state)
 {
 	if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
@@ -73,6 +75,27 @@ static void print_operstate(FILE *f, __u8 state)
 		fprintf(f, "state %s ", oper_states[state]);
 }
 
+static void print_portstate(FILE *f, __u8 state)
+{
+	if (state <= BR_STATE_BLOCKING)
+		fprintf(f, "state %s ", port_states[state]);
+	else
+		fprintf(f, "state (%d) ", state);
+}
+
+static void print_onoff(FILE *f, char *flag, __u8 val)
+{
+	fprintf(f, "%s %s ", flag, val ? "on" : "off");
+}
+
+static void print_hwmode(FILE *f, __u16 mode)
+{
+	if (mode >= sizeof(hw_mode)/sizeof(hw_mode[0]))
+		fprintf(f, "hwmode %#hx ", mode);
+	else
+		fprintf(f, "hwmode %s ", hw_mode[mode]);
+}
+
 int print_linkinfo(const struct sockaddr_nl *who,
 		   struct nlmsghdr *n, void *arg)
 {
@@ -94,7 +117,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
 	if (filter_index && filter_index != ifi->ifi_index)
 		return 0;
 
-	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+	parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);
 
 	if (tb[IFLA_IFNAME] == NULL) {
 		fprintf(stderr, "BUG: nil ifname\n");
@@ -131,13 +154,48 @@ int print_linkinfo(const struct sockaddr_nl *who,
 			if_indextoname(rta_getattr_u32(tb[IFLA_MASTER]), b1));
 
 	if (tb[IFLA_PROTINFO]) {
-		__u8 state = rta_getattr_u8(tb[IFLA_PROTINFO]);
-		if (state <= BR_STATE_BLOCKING)
-			fprintf(fp, "state %s", port_states[state]);
-		else
-			fprintf(fp, "state (%d)", state);
+		if (tb[IFLA_PROTINFO]->rta_type & NLA_F_NESTED) {
+			struct rtattr *prtb[IFLA_BRPORT_MAX+1];
+
+			parse_rtattr_nested(prtb, IFLA_BRPORT_MAX,
+					    tb[IFLA_PROTINFO]);
+
+			if (prtb[IFLA_BRPORT_STATE])
+				print_portstate(fp,
+						rta_getattr_u8(prtb[IFLA_BRPORT_STATE]));
+			if (prtb[IFLA_BRPORT_PRIORITY])
+				fprintf(fp, "priority %hu ",
+					rta_getattr_u16(prtb[IFLA_BRPORT_PRIORITY]));
+			if (prtb[IFLA_BRPORT_COST])
+				fprintf(fp, "cost %u ",
+					rta_getattr_u32(prtb[IFLA_BRPORT_COST]));
+			if (prtb[IFLA_BRPORT_MODE])
+				print_onoff(fp, "hairpin",
+					    rta_getattr_u8(prtb[IFLA_BRPORT_MODE]));
+			if (prtb[IFLA_BRPORT_GUARD])
+				print_onoff(fp, "guard",
+					    rta_getattr_u8(prtb[IFLA_BRPORT_GUARD]));
+			if (prtb[IFLA_BRPORT_PROTECT])
+				print_onoff(fp, "root_block",
+					    rta_getattr_u8(prtb[IFLA_BRPORT_PROTECT]));
+			if (prtb[IFLA_BRPORT_FAST_LEAVE])
+				print_onoff(fp, "fastleave",
+					    rta_getattr_u8(prtb[IFLA_BRPORT_FAST_LEAVE]));
+		} else
+			print_portstate(fp, rta_getattr_u8(tb[IFLA_PROTINFO]));
 	}
 
+	if (tb[IFLA_AF_SPEC]) {
+		/* This is reported by HW devices that have some bridging
+		 * capabilities.
+		 */
+		struct rtattr *aftb[IFLA_BRIDGE_MAX+1];
+
+		parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]);
+
+		if (tb[IFLA_BRIDGE_MODE])
+			print_hwmode(fp, rta_getattr_u16(tb[IFLA_BRIDGE_MODE]));
+	}
 
 	fprintf(fp, "\n");
 	fflush(fp);
@@ -183,6 +241,7 @@ static int brlink_modify(int argc, char **argv)
 	__s8 hairpin = -1;
 	__s8 bpdu_guard = -1;
 	__s8 fast_leave = -1;
+	__s8 root_block = -1;
 	__u32 cost = 0;
 	__s16 priority = -1;
 	__s8 state = -1;
@@ -213,6 +272,10 @@ static int brlink_modify(int argc, char **argv)
 			NEXT_ARG();
 			if (!on_off("fastleave", &fast_leave, *argv))
 				exit(-1);
+		} else if (strcmp(*argv, "root_block") == 0) {
+			NEXT_ARG();
+			if (!on_off("root_block", &root_block, *argv))
+				exit(-1);
 		} else if (strcmp(*argv, "cost")) {
 			NEXT_ARG();
 			cost = atoi(*argv);
@@ -222,7 +285,7 @@ static int brlink_modify(int argc, char **argv)
 		} else if (strcmp(*argv, "state")) {
 			NEXT_ARG();
 			state = atoi(*argv);
-		} else if (strcmp(*argv, "mode")) {
+		} else if (strcmp(*argv, "hwmode")) {
 			NEXT_ARG();
 			flags |= BRIDGE_FLAGS_SELF;
 			if (strcmp(*argv, "vepa") == 0)
@@ -265,6 +328,8 @@ static int brlink_modify(int argc, char **argv)
 	if (fast_leave >= 0)
 		addattr8(&req.n, sizeof(req), IFLA_BRPORT_FAST_LEAVE,
 			 fast_leave);
+	if (root_block >= 0)
+		addattr8(&req.n, sizeof(req), IFLA_BRPORT_PROTECT, root_block);
 
 	if (cost > 0)
 		addattr32(&req.n, sizeof(req), IFLA_BRPORT_COST, cost);
diff --git a/include/libnetlink.h b/include/libnetlink.h
index 8d15ee5..ec3d657 100644
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -65,6 +65,8 @@ extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data);
 extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen);
 
 extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
+extern int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
+			      int len, unsigned short flags);
 extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len);
 extern int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len);
 
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 67f046f..f262959 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -658,10 +658,19 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
 
 int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
 {
+	return parse_rtattr_flags(tb, max, rta, len, 0);
+}
+
+int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
+		       int len, unsigned short flags)
+{
+	unsigned short type;
+
 	memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
 	while (RTA_OK(rta, len)) {
-		if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
-			tb[rta->rta_type] = rta;
+		type = rta->rta_type & ~flags;
+		if ((type <= max) && (!tb[type]))
+			tb[type] = rta;
 		rta = RTA_NEXT(rta,len);
 	}
 	if (len)
-- 
1.7.7.6

^ permalink raw reply related

* [PATCHv2 iproute2 0/3] Add support for bridge port link information
From: Vlad Yasevich @ 2013-03-15 16:46 UTC (permalink / raw)
  To: netdev; +Cc: shemminger, john.r.fastabend

Bridge ports provide unique link information about the properties and flags of
the port.  This patch set allows bridge utility to configure and disaplay
this information.

Please take a look at the man page text and let me know if you have anything
to add.

Sinve v1:
 - Change the link output to match link command line options as suggested by
   Stephen.
 - Add man page text.
 - Add root_block attribute.

Vlad Yasevich (3):
  bridge: Add support for setting bridge port attributes
  bridge: Add support for printing bridge port attributes
  man: Add documentation for the bridge link operation.

 bridge/br_common.h   |    1 +
 bridge/bridge.c      |    3 +-
 bridge/link.c        |  294 ++++++++++++++++++++++++++++++++++++++++++++++++-
 include/libnetlink.h |    2 +
 lib/libnetlink.c     |   13 ++-
 man/man8/bridge.8    |  136 +++++++++++++++++++++---
 6 files changed, 427 insertions(+), 22 deletions(-)

-- 
1.7.7.6

^ permalink raw reply

* [PATCH] bridge: Add support for setting BR_ROOT_BLOCK flag.
From: Vlad Yasevich @ 2013-03-15 16:39 UTC (permalink / raw)
  To: netdev; +Cc: shemminger, Vlad Yasevich

Most of the support was already there.  The only thing that was missing
was the call to set the flag.  Add this call.

Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 net/bridge/br_netlink.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 1382842..84c3b7d 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -327,6 +327,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
 	br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
 	br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
 	br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
+	br_set_port_flag(p, tb, IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK);
 
 	if (tb[IFLA_BRPORT_COST]) {
 		err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
-- 
1.7.7.6

^ permalink raw reply related

* sctp: hang in sctp_remaddr_seq_show
From: Sasha Levin @ 2013-03-15 16:34 UTC (permalink / raw)
  To: vyasevich, sri, nhorman, David S. Miller
  Cc: linux-sctp, netdev, Dave Jones, linux-kernel@vger.kernel.org

Hi all,

While fuzzing with trinity inside a KVM tools guest running latest -next kernel,
I've stumbled on an interesting hang related to sctp.

After some fuzzing, I get a hang message about procfs not able to grab a hold
of a mutex for one of the files:

[  375.900309] INFO: task trinity-child21:7178 blocked for more than 120 seconds.
[  375.901767] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  375.903022] trinity-child21 D ffff88009b9f74a8  5336  7178   7121 0x00000004
[  375.904211]  ffff88009ba79cb8 0000000000000002 ffff8800abf48690 ffff8800abf48690
[  375.905972]  ffff880075308000 ffff88009c798000 ffff88009ba79cb8 00000000001d7140
[  375.907263]  ffff88009c798000 ffff88009ba79fd8 00000000001d7140 00000000001d7140
[  375.908987] Call Trace:
[  375.909415]  [<ffffffff83d89569>] __schedule+0x2e9/0x3b0
[  375.910795]  [<ffffffff83d89795>] schedule+0x55/0x60
[  375.911611]  [<ffffffff83d89ae3>] schedule_preempt_disabled+0x13/0x20
[  375.912644]  [<ffffffff83d87b7d>] __mutex_lock_common+0x36d/0x5a0
[  375.913986]  [<ffffffff8129f11a>] ? seq_read+0x3a/0x3d0
[  375.914838]  [<ffffffff8129f11a>] ? seq_read+0x3a/0x3d0
[  375.916187]  [<ffffffff8129f0e0>] ? seq_lseek+0x110/0x110
[  375.917075]  [<ffffffff83d87edf>] mutex_lock_nested+0x3f/0x50
[  375.918005]  [<ffffffff8129f11a>] seq_read+0x3a/0x3d0
[  375.919124]  [<ffffffff819f19cd>] ? delay_tsc+0xdd/0x110
[  375.920916]  [<ffffffff8129f0e0>] ? seq_lseek+0x110/0x110
[  375.921794]  [<ffffffff8129f0e0>] ? seq_lseek+0x110/0x110
[  375.922966]  [<ffffffff812e7b61>] proc_reg_read+0x201/0x230
[  375.923870]  [<ffffffff812e7960>] ? proc_reg_write+0x230/0x230
[  375.924820]  [<ffffffff81279e05>] vfs_read+0xb5/0x180
[  375.925668]  [<ffffffff81279f20>] SyS_read+0x50/0xa0
[  375.926476]  [<ffffffff83d946d8>] tracesys+0xe1/0xe6
[  375.940223] 1 lock held by trinity-child21/7178:
[  375.940985]  #0:  (&p->lock){+.+.+.}, at: [<ffffffff8129f11a>] seq_read+0x3a/0x3d

Digging deeper, there's another thread that's stuck holding that lock:

[  381.880804] trinity-child97 R  running task     4856  9490   7121 0x00000004
[  381.882064]  ffff880084cad708 0000000000000002 ffff8800bbbd71f8 ffff8800bbbd71f8
[  381.883341]  ffff8800b9490000 ffff88009a5e8000 ffff880084cad708 00000000001d7140
[  381.884652]  ffff88009a5e8000 ffff880084cadfd8 00000000001d7140 00000000001d7140
[  381.885977] Call Trace:
[  381.886392]  [<ffffffff83d89569>] __schedule+0x2e9/0x3b0
[  381.887238]  [<ffffffff83d89714>] preempt_schedule+0x44/0x70
[  381.888175]  [<ffffffff83b5674a>] ? sctp_remaddr_seq_show+0x2da/0x2f0
[  381.889314]  [<ffffffff8110e8a8>] local_bh_enable+0x128/0x140
[  381.890292]  [<ffffffff83b5674a>] sctp_remaddr_seq_show+0x2da/0x2f0
[  381.891397]  [<ffffffff83b56497>] ? sctp_remaddr_seq_show+0x27/0x2f0
[  381.892448]  [<ffffffff8129f11a>] ? seq_read+0x3a/0x3d0
[  381.893308]  [<ffffffff8129ec50>] traverse+0xe0/0x1f0
[  381.894135]  [<ffffffff8129f0e0>] ? seq_lseek+0x110/0x110
[  381.895100]  [<ffffffff8129f0e0>] ? seq_lseek+0x110/0x110
[  381.896074]  [<ffffffff8129f13c>] seq_read+0x5c/0x3d0
[  381.896912]  [<ffffffff819f19cd>] ? delay_tsc+0xdd/0x110
[  381.897796]  [<ffffffff8129f0e0>] ? seq_lseek+0x110/0x110
[  381.898734]  [<ffffffff8129f0e0>] ? seq_lseek+0x110/0x110
[  381.899629]  [<ffffffff812e7b61>] proc_reg_read+0x201/0x230
[  381.900592]  [<ffffffff812e7960>] ? proc_reg_write+0x230/0x230
[  381.901614]  [<ffffffff812e7960>] ? proc_reg_write+0x230/0x230
[  381.902543]  [<ffffffff8127a22b>] do_loop_readv_writev+0x4b/0x90
[  381.903480]  [<ffffffff8127a4a6>] do_readv_writev+0xf6/0x1d0
[  381.904456]  [<ffffffff8109b1c8>] ? kvm_clock_read+0x38/0x70
[  381.905460]  [<ffffffff8127a61e>] vfs_readv+0x3e/0x60
[  381.906306]  [<ffffffff812abb31>] default_file_splice_read+0x1e1/0x320
[  381.907365]  [<ffffffff81259396>] ? deactivate_slab+0x7d6/0x820
[  381.908412]  [<ffffffff81259396>] ? deactivate_slab+0x7d6/0x820
[  381.909404]  [<ffffffff8117db31>] ? __lock_release+0xf1/0x110
[  381.910435]  [<ffffffff81259396>] ? deactivate_slab+0x7d6/0x820
[  381.911483]  [<ffffffff81a06ee8>] ? do_raw_spin_unlock+0xc8/0xe0
[  381.912478]  [<ffffffff83d8b3d0>] ? _raw_spin_unlock+0x30/0x60
[  381.913438]  [<ffffffff81259396>] ? deactivate_slab+0x7d6/0x820
[  381.914478]  [<ffffffff812830ae>] ? alloc_pipe_info+0x3e/0xa0
[  381.915504]  [<ffffffff812830ae>] ? alloc_pipe_info+0x3e/0xa0
[  381.916461]  [<ffffffff812830ae>] ? alloc_pipe_info+0x3e/0xa0
[  381.917418]  [<ffffffff83d00b0c>] ? __slab_alloc.isra.34+0x2ed/0x31f
[  381.918533]  [<ffffffff8117acf8>] ? trace_hardirqs_on_caller+0x168/0x1a0
[  381.919637]  [<ffffffff8117ae35>] ? debug_check_no_locks_freed+0xf5/0x130
[  381.920799]  [<ffffffff812a9ef0>] ? page_cache_pipe_buf_release+0x20/0x20
[  381.921963]  [<ffffffff812aa823>] do_splice_to+0x83/0xb0
[  381.922849]  [<ffffffff812aabee>] splice_direct_to_actor+0xce/0x1c0
[  381.923874]  [<ffffffff812aa780>] ? do_splice_from+0xb0/0xb0
[  381.924855]  [<ffffffff812ac398>] do_splice_direct+0x48/0x60
[  381.925865]  [<ffffffff81279a25>] do_sendfile+0x165/0x310
[  381.926763]  [<ffffffff8117ad3d>] ? trace_hardirqs_on+0xd/0x10
[  381.927722]  [<ffffffff8127aaaa>] SyS_sendfile64+0x8a/0xc0
[  381.928702]  [<ffffffff83d94675>] ? tracesys+0x7e/0xe6
[  381.929556]  [<ffffffff83d946d8>] tracesys+0xe1/0xe6

It has gone to sleep while holding the proc mutex we're trying to acquire and
never woke up!

Looking at the code, we see:

        rcu_read_unlock();
        read_unlock(&head->lock);
        sctp_local_bh_enable(); <--- here

It hangs on local_bh_enable().

It seems that local_bh_enable() calls preempt_check_resched() which never
gets woken up. Why? I have no clue.

It's also pretty reproducible with sctp.


Thanks,
Sasha

^ permalink raw reply

* [PATCH] net core: optimize netdev_create_hash()
From: Wei Yang @ 2013-03-15 16:32 UTC (permalink / raw)
  To: davem, netdev; +Cc: Wei Yang

netdev_create_hash() is divded into two steps:
1. allocate space for hash_head
2. initialize hash_head->first to NULL for each hash_head

This patch merge the two steps into one step.

When allocating the space for hash_head, it will use kzalloc() instead of
kmalloc(). Then hash_head->first is set to NULL during the allocation step,
which means it is not necessary to call INIT_HLIST_HEAD() for each hash_head.

This will:
1. reduce the code size
2. reduce the run time of iteration on initializing hash_head array
---
 net/core/dev.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index f64e439..79f0666 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6564,13 +6564,15 @@ EXPORT_SYMBOL(netdev_increment_features);
 
 static struct hlist_head *netdev_create_hash(void)
 {
-	int i;
 	struct hlist_head *hash;
 
-	hash = kmalloc(sizeof(*hash) * NETDEV_HASHENTRIES, GFP_KERNEL);
-	if (hash != NULL)
-		for (i = 0; i < NETDEV_HASHENTRIES; i++)
-			INIT_HLIST_HEAD(&hash[i]);
+	hash = kzalloc(sizeof(*hash) * NETDEV_HASHENTRIES, GFP_KERNEL);
+
+	/*
+	 * hash[i]->first is set to NULL in kzalloc()
+	 *
+	 * INIT_HLIST_HEAD(&hash[i]) is not necessary now
+	 */
 
 	return hash;
 }
-- 
1.7.5.4

^ permalink raw reply related

* Re: igb_poll - device driver failed to check map error
From: Alexander Duyck @ 2013-03-15 16:07 UTC (permalink / raw)
  To: christoph.paasch
  Cc: Alexander Duyck, Jeff Kirsher, Jesse Brandeburg, Bruce Allan,
	Eric Dumazet, netdev
In-Reply-To: <1899985.NhtD8IVCbT@cpaasch-mac>

On 03/15/2013 12:52 AM, Christoph Paasch wrote:
> On Thursday 14 March 2013 19:18:18 Alexander Duyck wrote:
>> On 03/12/2013 02:31 AM, Christoph Paasch wrote:
>>> Hello,
>>>
>>> I'm seeing a warning while booting my machine when DMA_API_DEBUG is set:
>>>
>>> [   36.402824] ------------[ cut here ]------------
>>> [   36.458070] WARNING: at
>>> /home/cpaasch/builder/net-next/lib/dma-debug.c:934
>>> check_unmap+0x648/0x702()
>>> [   36.567377] Hardware name: ProLiant DL165 G7
>>> [   36.618452] igb 0000:04:00.0: DMA-API: device driver failed to check
>>> map
>>> error[device address=0x0000000233d9b232] [size=154 bytes] [mapped as
>>> single] [   36.776640] Modules linked in:
>>> [   36.815446] Pid: 0, comm: swapper/7 Not tainted 3.9.0-rc1-mptcp+ #101
>>> [   36.892515] Call Trace:
>>> [   36.921745]  <IRQ>  [<ffffffff8102ad7f>] warn_slowpath_common+0x80/0x9a
>>> [   37.001023]  [<ffffffff8102ae2d>] warn_slowpath_fmt+0x41/0x43
>>> [   37.069771]  [<ffffffff811db17f>] check_unmap+0x648/0x702
>>> [   37.134363]  [<ffffffff811db3e9>] debug_dma_unmap_page+0x50/0x52
>>> [   37.206234]  [<ffffffff8136676a>] igb_poll+0x144/0xf7c
>>> [   37.267706]  [<ffffffff8104dd19>] ? sched_clock_cpu+0x46/0xd1
>>> [   37.336456]  [<ffffffff814458ce>] net_rx_action+0xa7/0x1d0
>>> [   37.402085]  [<ffffffff81030b65>] __do_softirq+0xb4/0x16f
>>> [   37.466673]  [<ffffffff81030c90>] irq_exit+0x40/0x87
>>> [   37.526067]  [<ffffffff81002db1>] do_IRQ+0x98/0xaf
>>> [   37.583378]  [<ffffffff815210aa>] common_interrupt+0x6a/0x6a
>>> [   37.651086]  <EOI>  [<ffffffff8105d4be>] ?
>>> __tick_nohz_idle_enter+0x116/0x31f
>>> [   37.736595]  [<ffffffff81008a04>] ? default_idle+0x24/0x39
>>> [   37.802224]  [<ffffffff81008c62>] cpu_idle+0x68/0xa4
>>> [   37.861616]  [<ffffffff81519f78>] start_secondary+0x1a9/0x1ad
>>> [   37.930364] ---[ end trace 01b5bb0fd75a464c ]---
>>>
>>>
>>> It happens shortly after mounting the NFS-root filesystem.
>>>
>>> I tried to understand what is going on, but I am now at my wit's end.
>>>
>>> By adding some print-statements, here is what I found out (not sure if
>>> this is anyhow helpful):
>>>
>>> The difference between tx_buffer->time_stamp and the current 'jiffies' is
>>> up to 2000 jiffies (HZ==1000) at the first time the above warning happens
>>> (this seems too much for me). From then on, I see my print 3-4 times
>>> appear but without such a big difference between the timestamps
>>> (difference around 1 and 2 jiffies).
>>>
>>> Some other stuff, I printed:
>>> tx_buffer->skb: ffff880235054c80
>>> tx_buffer->bytecount: 154
>>> tx_buffer->gso_segs: 1
>>> tx_buffer->protocol: 8
>>> tx_buffer->tx_flags 0x20
>>>
>>>
>>> One last thing:
>>> Am I right that after each call to dma_map_single/page a call to
>>> dma_mapping_error is needed? If that's the case, I have some patches that
>>> add this statement at missing places in the e1000, e1000e and ixgb
>>> driver. But these patches do not fix my above problem.
>>>
>>>
>>> Thanks for your help,
>>> Christoph
>> Christoph,
>>
>> One thing that might be useful would be to reproduce this with a
>> standard 3.9-rc kernel instead of one using the multipath TCP patches.
>> This will help us to verify that the issue is reproducible with a stock
>> kernel and is not related to any ongoing work you may have only in your
>> tree.
> Hello,
>
> this is on a clean net-next kernel without any MPTCP-code.
>
> I bisected it down to  787314c35fbb (Merge tag 'iommu-updates-v3.8' of 
> git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu), which simply 
> introduces the debug_dma_mapping_error-checks.
>
> Am I right with the missing calls to dma_mapping_error in e1000, e1000e and 
> ixgb?
>
> Cheers,
> Christoph
>

Christoph,

I wasn't able to see any missing calls in e1000, however I did see one
in e1000e, and possibly another in the ixgb paths.  If you already have
patches please submit them.  It is much easier to verify the issues you
found if we know what exactly it is you found.

Thanks,

Alex

^ permalink raw reply

* RE: igb_poll - device driver failed to check map error
From: Allan, Bruce W @ 2013-03-15 16:03 UTC (permalink / raw)
  To: christoph.paasch@uclouvain.be, Alexander Duyck
  Cc: Kirsher, Jeffrey T, Brandeburg, Jesse, Duyck, Alexander H,
	Eric Dumazet, netdev@vger.kernel.org
In-Reply-To: <1899985.NhtD8IVCbT@cpaasch-mac>

> -----Original Message-----
> From: Christoph Paasch [mailto:christoph.paasch@gmail.com] On Behalf Of
> Christoph Paasch
> Sent: Friday, March 15, 2013 12:52 AM
> To: Alexander Duyck
> Cc: Kirsher, Jeffrey T; Brandeburg, Jesse; Allan, Bruce W; Duyck, Alexander
> H; Eric Dumazet; netdev@vger.kernel.org
> Subject: Re: igb_poll - device driver failed to check map error
> 
> On Thursday 14 March 2013 19:18:18 Alexander Duyck wrote:
> > On 03/12/2013 02:31 AM, Christoph Paasch wrote:
> > > Hello,
> > >
> > > I'm seeing a warning while booting my machine when DMA_API_DEBUG
> is set:
> > >
> > > [   36.402824] ------------[ cut here ]------------
> > > [   36.458070] WARNING: at
> > > /home/cpaasch/builder/net-next/lib/dma-debug.c:934
> > > check_unmap+0x648/0x702()
> > > [   36.567377] Hardware name: ProLiant DL165 G7
> > > [   36.618452] igb 0000:04:00.0: DMA-API: device driver failed to check
> > > map
> > > error[device address=0x0000000233d9b232] [size=154 bytes] [mapped
> as
> > > single] [   36.776640] Modules linked in:
> > > [   36.815446] Pid: 0, comm: swapper/7 Not tainted 3.9.0-rc1-mptcp+
> #101
> > > [   36.892515] Call Trace:
> > > [   36.921745]  <IRQ>  [<ffffffff8102ad7f>]
> warn_slowpath_common+0x80/0x9a
> > > [   37.001023]  [<ffffffff8102ae2d>] warn_slowpath_fmt+0x41/0x43
> > > [   37.069771]  [<ffffffff811db17f>] check_unmap+0x648/0x702
> > > [   37.134363]  [<ffffffff811db3e9>]
> debug_dma_unmap_page+0x50/0x52
> > > [   37.206234]  [<ffffffff8136676a>] igb_poll+0x144/0xf7c
> > > [   37.267706]  [<ffffffff8104dd19>] ? sched_clock_cpu+0x46/0xd1
> > > [   37.336456]  [<ffffffff814458ce>] net_rx_action+0xa7/0x1d0
> > > [   37.402085]  [<ffffffff81030b65>] __do_softirq+0xb4/0x16f
> > > [   37.466673]  [<ffffffff81030c90>] irq_exit+0x40/0x87
> > > [   37.526067]  [<ffffffff81002db1>] do_IRQ+0x98/0xaf
> > > [   37.583378]  [<ffffffff815210aa>] common_interrupt+0x6a/0x6a
> > > [   37.651086]  <EOI>  [<ffffffff8105d4be>] ?
> > > __tick_nohz_idle_enter+0x116/0x31f
> > > [   37.736595]  [<ffffffff81008a04>] ? default_idle+0x24/0x39
> > > [   37.802224]  [<ffffffff81008c62>] cpu_idle+0x68/0xa4
> > > [   37.861616]  [<ffffffff81519f78>] start_secondary+0x1a9/0x1ad
> > > [   37.930364] ---[ end trace 01b5bb0fd75a464c ]---
> > >
> > >
> > > It happens shortly after mounting the NFS-root filesystem.
> > >
> > > I tried to understand what is going on, but I am now at my wit's end.
> > >
> > > By adding some print-statements, here is what I found out (not sure if
> > > this is anyhow helpful):
> > >
> > > The difference between tx_buffer->time_stamp and the current 'jiffies'
> is
> > > up to 2000 jiffies (HZ==1000) at the first time the above warning
> happens
> > > (this seems too much for me). From then on, I see my print 3-4 times
> > > appear but without such a big difference between the timestamps
> > > (difference around 1 and 2 jiffies).
> > >
> > > Some other stuff, I printed:
> > > tx_buffer->skb: ffff880235054c80
> > > tx_buffer->bytecount: 154
> > > tx_buffer->gso_segs: 1
> > > tx_buffer->protocol: 8
> > > tx_buffer->tx_flags 0x20
> > >
> > >
> > > One last thing:
> > > Am I right that after each call to dma_map_single/page a call to
> > > dma_mapping_error is needed? If that's the case, I have some patches
> that
> > > add this statement at missing places in the e1000, e1000e and ixgb
> > > driver. But these patches do not fix my above problem.
> > >
> > >
> > > Thanks for your help,
> > > Christoph
> >
> > Christoph,
> >
> > One thing that might be useful would be to reproduce this with a
> > standard 3.9-rc kernel instead of one using the multipath TCP patches.
> > This will help us to verify that the issue is reproducible with a stock
> > kernel and is not related to any ongoing work you may have only in your
> > tree.
> 
> Hello,
> 
> this is on a clean net-next kernel without any MPTCP-code.
> 
> I bisected it down to  787314c35fbb (Merge tag 'iommu-updates-v3.8' of
> git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu), which simply
> introduces the debug_dma_mapping_error-checks.
> 
> Am I right with the missing calls to dma_mapping_error in e1000, e1000e
> and
> ixgb?
> 
> Cheers,
> Christoph
> 
> 
> 
> --
> IP Networking Lab --- http://inl.info.ucl.ac.be
> MultiPath TCP in the Linux Kernel --- http://multipath-tcp.org
> UCLouvain
> --

Hi Christoph,

You are correct re. the missing calls to dma_mapping_error and I have that on my
to-do list for e1000e, but if you have patches already feel free to send them along
(please cc the Intel wired ethernet list e1000-devel@lists.sourceforge.net).

Thanks,
Bruce.

^ permalink raw reply

* Re: Trying to implement secondary loopback
From: Benjamin LaHaise @ 2013-03-15 15:37 UTC (permalink / raw)
  To: Thomas Martitz
  Cc: richard -rw- weinberger, Eric W. Biederman,
	netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
	herbert@gondor.apana.org.au
In-Reply-To: <51433934.3080405@hhi.fraunhofer.de>

On Fri, Mar 15, 2013 at 04:07:32PM +0100, Thomas Martitz wrote:
> Same result. I assumed the kernel treats lo in a special way for 
> localhost-connections and that it would be impossible to achieve the 
> same with a custom interface.
> 
> I did the following:
> 
> ifconfig lo down
> insmod ./mykmod.ko
> ifconfig eth2 up
> ifconfig eth2 127.0.0.1
> 
> At this point ifconfig prints the same information for eth2 that it had 
> printed for lo before (except for the LOOPBACK flag, but I can enable 
> that one as well by adding IFF_LOOPBACK to the interface flags in the 
> module). Yet my test application only works with lo, not eth2.

Don't use loopback ip addresses; it makes no sense to do so.  I've worked  
on a couple opf nic implementations on FPGAs for a while now (a gige 
implementation that works, and now a 10G nic), and it's easy enough to 
develop it as a regular ethernet driver.  You can write test programs that 
use raw sockets to send/receive packets over the ethernet device, or use 
pktgen to send packets.  You don't even need to configure an ip address for 
testing with raw packets.  Testing with IP is a lot harder during early 
bring-up of your hardware as it requires everything to work (that is, you 
need ARP to work successfully before IP can work).  Just stick to simple 
packet injection initially, and don't confuse yourself by thinking about 
the loopback device.

		-ben
-- 
"Thought is the essence of where you are now."

^ permalink raw reply

* Re: sky2 negotiating only 100Mb/s (88E8055)
From: Mirko Lindner @ 2013-03-15 15:34 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: Network Development, Stephen Hemminger
In-Reply-To: <CACna6ryokPsaKVQmrF3ACmy99k3LiaOiZai5xrWdVjaxLWT80w@mail.gmail.com>

This is the first time somebody is reporting a problem with the autoneg/speed 
initialization so I would like to check it in the lab.

Mirko


On Friday, March 15, 2013 05:03:01 AM Rafał Miłecki wrote:
> 2013/3/3 Rafał Miłecki <zajec5@gmail.com>:
> 
> > I've problems with my:
> > 08:00.0 Ethernet controller [0200]: Marvell Technology Group Ltd.
> > 88E8055 PCI-E Gigabit Ethernet Controller [11ab:4363] (rev 13)
> > using 3.4.28 kernel on my Sony notebook.
> >
> >
> >
> > I've tried connecting it to the:
> > 1) HP#1 (Intel card)
> > 2) HP#2 (Broadcom card)
> > 3) Router based on BCM4706 with BCM53125 switch
> > I've tried two different CAT5e cables for all the above devices. In
> > every case sky2 established 100Mbps link only. It couldn't achieve
> > 1000Mb/s. Forcing it to 1000Mbps broke link. Lower speeds (100 half
> > duplex and 10 Mbps) are working fine.
> >
> >
> >
> > It's not the issue with the cable or devices, because all other
> > configurations are working fine. I can connect:
> > 1) HP#1 with HP#2
> > 2) HP#1 with router
> > 3) HP#2 with router
> > and I always get 1000Mbps.
> >
> >
> >
> > So it looks like some bugged hardware or (more likely?) issue in sky2.
> >
> >
> >
> > sky2 0000:08:00.0: eth0: disabling interface
> > sky2: driver version 1.30
> > sky2 0000:08:00.0: Yukon-2 EC Ultra chip revision 3
> > sky2 0000:08:00.0: irq 47 for MSI/MSI-X
> > sky2 0000:08:00.0: eth0: addr 00:1d:ba:19:9e:db
> > sky2 0000:08:00.0: eth0: enabling interface
> > sky2 0000:08:00.0: eth0: Link is up at 100 Mbps, full duplex, flow control
> > both
>
> >
> >
> > Can you help me with that?
> 
> 
> Ping?
> 
> -- 
> Rafał

^ permalink raw reply

* Re: sky2 negotiating only 100Mb/s (88E8055)
From: Rafał Miłecki @ 2013-03-15 15:39 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Network Development, Mirko Lindner
In-Reply-To: <20130315083520.72c1fd49@nehalam.linuxnetplumber.net>

2013/3/15 Stephen Hemminger <stephen@networkplumber.org>:
> On Fri, 15 Mar 2013 13:03:01 +0100
> Rafał Miłecki <zajec5@gmail.com> wrote:
>
>> 2013/3/3 Rafał Miłecki <zajec5@gmail.com>:
>> > I've problems with my:
>> > 08:00.0 Ethernet controller [0200]: Marvell Technology Group Ltd.
>> > 88E8055 PCI-E Gigabit Ethernet Controller [11ab:4363] (rev 13)
>> > using 3.4.28 kernel on my Sony notebook.
>> >
>> > I've tried connecting it to the:
>> > 1) HP#1 (Intel card)
>> > 2) HP#2 (Broadcom card)
>> > 3) Router based on BCM4706 with BCM53125 switch
>> > I've tried two different CAT5e cables for all the above devices. In
>> > every case sky2 established 100Mbps link only. It couldn't achieve
>> > 1000Mb/s. Forcing it to 1000Mbps broke link. Lower speeds (100 half
>> > duplex and 10 Mbps) are working fine.
>> >
>> > It's not the issue with the cable or devices, because all other
>> > configurations are working fine. I can connect:
>> > 1) HP#1 with HP#2
>> > 2) HP#1 with router
>> > 3) HP#2 with router
>> > and I always get 1000Mbps.
>> >
>> > So it looks like some bugged hardware or (more likely?) issue in sky2.
>> >
>> > sky2 0000:08:00.0: eth0: disabling interface
>> > sky2: driver version 1.30
>> > sky2 0000:08:00.0: Yukon-2 EC Ultra chip revision 3
>> > sky2 0000:08:00.0: irq 47 for MSI/MSI-X
>> > sky2 0000:08:00.0: eth0: addr 00:1d:ba:19:9e:db
>> > sky2 0000:08:00.0: eth0: enabling interface
>> > sky2 0000:08:00.0: eth0: Link is up at 100 Mbps, full duplex, flow control both
>> >
>> > Can you help me with that?
>
>
> PHY stuff is black magic, and sometimes vendors break things outside
> the driver. You might check for a BIOS update? Does it work with windows?

I'm afraid there isn't BIOS update available and I don't have Windows.
Well, I never had.

-- 
Rafał

^ permalink raw reply

* Re: sky2 negotiating only 100Mb/s (88E8055)
From: Stephen Hemminger @ 2013-03-15 15:35 UTC (permalink / raw)
  To: Rafał Miłecki; +Cc: Network Development, Mirko Lindner
In-Reply-To: <CACna6ryokPsaKVQmrF3ACmy99k3LiaOiZai5xrWdVjaxLWT80w@mail.gmail.com>

On Fri, 15 Mar 2013 13:03:01 +0100
Rafał Miłecki <zajec5@gmail.com> wrote:

> 2013/3/3 Rafał Miłecki <zajec5@gmail.com>:
> > I've problems with my:
> > 08:00.0 Ethernet controller [0200]: Marvell Technology Group Ltd.
> > 88E8055 PCI-E Gigabit Ethernet Controller [11ab:4363] (rev 13)
> > using 3.4.28 kernel on my Sony notebook.
> >
> > I've tried connecting it to the:
> > 1) HP#1 (Intel card)
> > 2) HP#2 (Broadcom card)
> > 3) Router based on BCM4706 with BCM53125 switch
> > I've tried two different CAT5e cables for all the above devices. In
> > every case sky2 established 100Mbps link only. It couldn't achieve
> > 1000Mb/s. Forcing it to 1000Mbps broke link. Lower speeds (100 half
> > duplex and 10 Mbps) are working fine.
> >
> > It's not the issue with the cable or devices, because all other
> > configurations are working fine. I can connect:
> > 1) HP#1 with HP#2
> > 2) HP#1 with router
> > 3) HP#2 with router
> > and I always get 1000Mbps.
> >
> > So it looks like some bugged hardware or (more likely?) issue in sky2.
> >
> > sky2 0000:08:00.0: eth0: disabling interface
> > sky2: driver version 1.30
> > sky2 0000:08:00.0: Yukon-2 EC Ultra chip revision 3
> > sky2 0000:08:00.0: irq 47 for MSI/MSI-X
> > sky2 0000:08:00.0: eth0: addr 00:1d:ba:19:9e:db
> > sky2 0000:08:00.0: eth0: enabling interface
> > sky2 0000:08:00.0: eth0: Link is up at 100 Mbps, full duplex, flow control both
> >
> > Can you help me with that?


PHY stuff is black magic, and sometimes vendors break things outside
the driver. You might check for a BIOS update? Does it work with windows?

^ permalink raw reply

* [PATCH] rename configure.in to configure.ac
From: yegorslists @ 2013-03-15 15:05 UTC (permalink / raw)
  To: netdev; +Cc: stephen, buytenh, Yegor Yefremov

From: Yegor Yefremov <yegorslists@googlemail.com>

Automake 1.14 will likely drop support for the long-deprecated
'configure.in' name for the Autoconf input file.

Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
---
 configure.ac |   27 +++++++++++++++++++++++++++
 configure.in |   27 ---------------------------
 2 files changed, 27 insertions(+), 27 deletions(-)
 create mode 100644 configure.ac
 delete mode 100644 configure.in

diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..5e3f89b
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,27 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(bridge-utils, 1.5)
+AC_CONFIG_HEADERS(libbridge/config.h)
+
+AC_ARG_WITH( linux-headers, [  --with-linux-headers     Location of the linux headers to use], 
+    KERNEL_HEADERS=$withval, KERNEL_HEADERS="/usr/src/linux/include")
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_RANLIB
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(sys/ioctl.h sys/time.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_CHECK_FUNCS(gethostname socket strdup uname)
+AC_CHECK_FUNCS(if_nametoindex if_indextoname)
+
+AC_SUBST(KERNEL_HEADERS)
+
+AC_OUTPUT(doc/Makefile libbridge/Makefile brctl/Makefile Makefile bridge-utils.spec)
diff --git a/configure.in b/configure.in
deleted file mode 100644
index 5e3f89b..0000000
--- a/configure.in
+++ /dev/null
@@ -1,27 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT(bridge-utils, 1.5)
-AC_CONFIG_HEADERS(libbridge/config.h)
-
-AC_ARG_WITH( linux-headers, [  --with-linux-headers     Location of the linux headers to use], 
-    KERNEL_HEADERS=$withval, KERNEL_HEADERS="/usr/src/linux/include")
-
-dnl Checks for programs.
-AC_PROG_CC
-AC_PROG_INSTALL
-AC_PROG_RANLIB
-
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(sys/ioctl.h sys/time.h)
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_HEADER_TIME
-
-dnl Checks for library functions.
-AC_CHECK_FUNCS(gethostname socket strdup uname)
-AC_CHECK_FUNCS(if_nametoindex if_indextoname)
-
-AC_SUBST(KERNEL_HEADERS)
-
-AC_OUTPUT(doc/Makefile libbridge/Makefile brctl/Makefile Makefile bridge-utils.spec)
-- 
1.7.7

^ permalink raw reply related

* [PATCH net] bnx2x: add missing napi deletion in error path
From: Michal Schmidt @ 2013-03-15 15:27 UTC (permalink / raw)
  To: netdev; +Cc: Merav Sicron, Eilon Greenstein, Dmitry Kravkov, Yuval Mintz

If the hardware initialization fails in bnx2x_nic_load() after adding
napi objects, they would not be deleted. A subsequent attempt to unload
the bnx2x module detects a corruption in the napi list.

Add the missing napi deletion to the error path.

Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index a923bc4..4046f97 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -2760,6 +2760,7 @@ load_error2:
 	bp->port.pmf = 0;
 load_error1:
 	bnx2x_napi_disable(bp);
+	bnx2x_del_all_napi(bp);
 
 	/* clear pf_load status, as it was already set */
 	if (IS_PF(bp))
-- 
1.8.1.4

^ permalink raw reply related

* pull request: wireless 2013-03-15
From: John W. Linville @ 2013-03-15 15:16 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

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

Dave,

Please pull these fixes for the 3.9 stream.

On the NFC bits, Samuel says:

"With this one we have:

- A fix for properly decreasing socket ack log.
- A timer and works cleanup upon NFC device removal.
- A monitoroing socket cleanup round from llcp_socket_release.
- A proper error report to pending sockets upon NFC device removal."

Regarding the Bluetooth bits, Gustavo says:

"I have these two patches for 3.9, these add support for two more devices to
the bluetooth drivers."

Along with those, we have a few wireless driver fixes...

Bing Zhao provides an mwifiex to prevent an out-of-bounds memory
access.

John Crispin offers a Kconfig fix to enable some otherwise dead code
in rt2x00.  The correct symbols were added in -rc1 through a different
tree, but the symbols for enabling the wireless driver didn't match.

Larry Finger brings an rtlwifi fix for a scheduling while atomic bug,
and another fix for a reassociation problem caused by failing to
clear the BSSID after a disconnect.

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit aaa0c23cb90141309f5076ba5e3bfbd39544b985:

  Fix dst_neigh_lookup/dst_neigh_lookup_skb return value handling bug (2013-03-15 09:06:58 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem

for you to fetch changes up to f3a3440063d6b01470507ecde9cf8ed0b033362a:

  Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-03-15 10:44:36 -0400)

----------------------------------------------------------------

Bing Zhao (1):
      mwifiex: fix potential out-of-boundary access to ibss rate table

John Crispin (1):
      rt2x00: fix rt2x00 to work with the new ralink SoC config symbols

John W. Linville (3):
      Merge tag 'nfc-fixes-3.9-1' of git://git.kernel.org/.../sameo/nfc-fixes
      Merge branch 'for-upstream' of git://git.kernel.org/.../bluetooth/bluetooth
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem

Josh Boyer (1):
      Bluetooth: Add support for atheros 04ca:3004 device to ath3k

Larry Finger (2):
      rtlwifi: rtl8192cu: Fix schedule while atomic bug splat
      rtlwifi: rtl8192cu: Fix problem that prevents reassociation

Samuel Ortiz (4):
      NFC: llcp: Decrease socket ack log when accepting a connection
      NFC: llcp: Clean local timers and works when removing a device
      NFC: llcp: Clean raw sockets from nfc_llcp_socket_release
      NFC: llcp: Report error to pending sockets when a device is removed

Sunguk Lee (1):
      Bluetooth: Device 0cf3:3008 should map AR 3012

 drivers/bluetooth/ath3k.c                   |  4 ++
 drivers/bluetooth/btusb.c                   |  2 +
 drivers/net/wireless/mwifiex/join.c         |  7 +--
 drivers/net/wireless/rt2x00/Kconfig         |  4 +-
 drivers/net/wireless/rt2x00/rt2800pci.c     | 14 ++---
 drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 89 ++++++++++++-----------------
 net/nfc/llcp/llcp.c                         | 62 +++++++++++++++++---
 net/nfc/llcp/sock.c                         |  2 +
 8 files changed, 108 insertions(+), 76 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index a8a41e07..b282af1 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -74,8 +74,10 @@ static struct usb_device_id ath3k_table[] = {
 
 	/* Atheros AR3012 with sflash firmware*/
 	{ USB_DEVICE(0x0CF3, 0x3004) },
+	{ USB_DEVICE(0x0CF3, 0x3008) },
 	{ USB_DEVICE(0x0CF3, 0x311D) },
 	{ USB_DEVICE(0x13d3, 0x3375) },
+	{ USB_DEVICE(0x04CA, 0x3004) },
 	{ USB_DEVICE(0x04CA, 0x3005) },
 	{ USB_DEVICE(0x04CA, 0x3006) },
 	{ USB_DEVICE(0x04CA, 0x3008) },
@@ -106,8 +108,10 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 
 	/* Atheros AR3012 with sflash firmware*/
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 7e351e3..e547851 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -132,8 +132,10 @@ static struct usb_device_id blacklist_table[] = {
 
 	/* Atheros 3012 with sflash firmware */
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 246aa62..2fe0ceb 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1117,10 +1117,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
 		adhoc_join->bss_descriptor.bssid,
 		adhoc_join->bss_descriptor.ssid);
 
-	for (i = 0; bss_desc->supported_rates[i] &&
-			i < MWIFIEX_SUPPORTED_RATES;
-			i++)
-			;
+	for (i = 0; i < MWIFIEX_SUPPORTED_RATES &&
+		    bss_desc->supported_rates[i]; i++)
+		;
 	rates_size = i;
 
 	/* Copy Data Rates from the Rates recorded in scan response */
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 44d6ead..2bf4efa 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -55,10 +55,10 @@ config RT61PCI
 
 config RT2800PCI
 	tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
-	depends on PCI || RALINK_RT288X || RALINK_RT305X
+	depends on PCI || SOC_RT288X || SOC_RT305X
 	select RT2800_LIB
 	select RT2X00_LIB_PCI if PCI
-	select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
+	select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
 	select RT2X00_LIB_FIRMWARE
 	select RT2X00_LIB_CRYPTO
 	select CRC_CCITT
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 48a01aa..ded73da 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 	rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 }
 
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 {
 	void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
@@ -107,7 +107,7 @@ static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 {
 	return -ENOMEM;
 }
-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
+#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
 
 #ifdef CONFIG_PCI
 static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -1177,7 +1177,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
 #endif /* CONFIG_PCI */
 MODULE_LICENSE("GPL");
 
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 static int rt2800soc_probe(struct platform_device *pdev)
 {
 	return rt2x00soc_probe(pdev, &rt2800pci_ops);
@@ -1194,7 +1194,7 @@ static struct platform_driver rt2800soc_driver = {
 	.suspend	= rt2x00soc_suspend,
 	.resume		= rt2x00soc_resume,
 };
-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
+#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
 
 #ifdef CONFIG_PCI
 static int rt2800pci_probe(struct pci_dev *pci_dev,
@@ -1217,7 +1217,7 @@ static int __init rt2800pci_init(void)
 {
 	int ret = 0;
 
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 	ret = platform_driver_register(&rt2800soc_driver);
 	if (ret)
 		return ret;
@@ -1225,7 +1225,7 @@ static int __init rt2800pci_init(void)
 #ifdef CONFIG_PCI
 	ret = pci_register_driver(&rt2800pci_driver);
 	if (ret) {
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 		platform_driver_unregister(&rt2800soc_driver);
 #endif
 		return ret;
@@ -1240,7 +1240,7 @@ static void __exit rt2800pci_exit(void)
 #ifdef CONFIG_PCI
 	pci_unregister_driver(&rt2800pci_driver);
 #endif
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 	platform_driver_unregister(&rt2800soc_driver);
 #endif
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index b1ccff4..c08d0f4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1377,74 +1377,57 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw)
 
 void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
 {
-	/* dummy routine needed for callback from rtl_op_configure_filter() */
-}
-
-/*========================================================================== */
-
-static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw,
-			      enum nl80211_iftype type)
-{
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
-	struct rtl_phy *rtlphy = &(rtlpriv->phy);
-	u8 filterout_non_associated_bssid = false;
+	u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
 
-	switch (type) {
-	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_STATION:
-		filterout_non_associated_bssid = true;
-		break;
-	case NL80211_IFTYPE_UNSPECIFIED:
-	case NL80211_IFTYPE_AP:
-	default:
-		break;
-	}
-	if (filterout_non_associated_bssid) {
+	if (rtlpriv->psc.rfpwr_state != ERFON)
+		return;
+
+	if (check_bssid) {
+		u8 tmp;
 		if (IS_NORMAL_CHIP(rtlhal->version)) {
-			switch (rtlphy->current_io_type) {
-			case IO_CMD_RESUME_DM_BY_SCAN:
-				reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
-				rtlpriv->cfg->ops->set_hw_reg(hw,
-						 HW_VAR_RCR, (u8 *)(&reg_rcr));
-				/* enable update TSF */
-				_rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
-				break;
-			case IO_CMD_PAUSE_DM_BY_SCAN:
-				reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
-				rtlpriv->cfg->ops->set_hw_reg(hw,
-						 HW_VAR_RCR, (u8 *)(&reg_rcr));
-				/* disable update TSF */
-				_rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
-				break;
-			}
+			reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+			tmp = BIT(4);
 		} else {
-			reg_rcr |= (RCR_CBSSID);
-			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
-						      (u8 *)(&reg_rcr));
-			_rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5)));
+			reg_rcr |= RCR_CBSSID;
+			tmp = BIT(4) | BIT(5);
 		}
-	} else if (filterout_non_associated_bssid == false) {
+		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
+					      (u8 *) (&reg_rcr));
+		_rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp);
+	} else {
+		u8 tmp;
 		if (IS_NORMAL_CHIP(rtlhal->version)) {
-			reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
-			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
-						      (u8 *)(&reg_rcr));
-			_rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
+			reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+			tmp = BIT(4);
 		} else {
-			reg_rcr &= (~RCR_CBSSID);
-			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
-						      (u8 *)(&reg_rcr));
-			_rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0);
+			reg_rcr &= ~RCR_CBSSID;
+			tmp = BIT(4) | BIT(5);
 		}
+		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+		rtlpriv->cfg->ops->set_hw_reg(hw,
+					      HW_VAR_RCR, (u8 *) (&reg_rcr));
+		_rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
 	}
 }
 
+/*========================================================================== */
+
 int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
 {
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
 	if (_rtl92cu_set_media_status(hw, type))
 		return -EOPNOTSUPP;
-	_rtl92cu_set_check_bssid(hw, type);
+
+	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+		if (type != NL80211_IFTYPE_AP)
+			rtl92cu_set_check_bssid(hw, true);
+	} else {
+		rtl92cu_set_check_bssid(hw, false);
+	}
+
 	return 0;
 }
 
@@ -2058,8 +2041,6 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
 			       (shortgi_rate << 4) | (shortgi_rate);
 	}
 	rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
-		 rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 7f8266d..b530afa 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
 	}
 }
 
-static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
+static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen,
+				    int err)
 {
 	struct sock *sk;
 	struct hlist_node *tmp;
@@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
 
 				nfc_llcp_accept_unlink(accept_sk);
 
+				if (err)
+					accept_sk->sk_err = err;
 				accept_sk->sk_state = LLCP_CLOSED;
+				accept_sk->sk_state_change(sk);
 
 				bh_unlock_sock(accept_sk);
 
@@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
 			continue;
 		}
 
+		if (err)
+			sk->sk_err = err;
 		sk->sk_state = LLCP_CLOSED;
+		sk->sk_state_change(sk);
 
 		bh_unlock_sock(sk);
 
@@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
 	}
 
 	write_unlock(&local->sockets.lock);
+
+	/*
+	 * If we want to keep the listening sockets alive,
+	 * we don't touch the RAW ones.
+	 */
+	if (listen == true)
+		return;
+
+	write_lock(&local->raw_sockets.lock);
+
+	sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
+		llcp_sock = nfc_llcp_sock(sk);
+
+		bh_lock_sock(sk);
+
+		nfc_llcp_socket_purge(llcp_sock);
+
+		if (err)
+			sk->sk_err = err;
+		sk->sk_state = LLCP_CLOSED;
+		sk->sk_state_change(sk);
+
+		bh_unlock_sock(sk);
+
+		sock_orphan(sk);
+
+		sk_del_node_init(sk);
+	}
+
+	write_unlock(&local->raw_sockets.lock);
 }
 
 struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
@@ -142,20 +179,25 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
 	return local;
 }
 
-static void local_release(struct kref *ref)
+static void local_cleanup(struct nfc_llcp_local *local, bool listen)
 {
-	struct nfc_llcp_local *local;
-
-	local = container_of(ref, struct nfc_llcp_local, ref);
-
-	list_del(&local->list);
-	nfc_llcp_socket_release(local, false);
+	nfc_llcp_socket_release(local, listen, ENXIO);
 	del_timer_sync(&local->link_timer);
 	skb_queue_purge(&local->tx_queue);
 	cancel_work_sync(&local->tx_work);
 	cancel_work_sync(&local->rx_work);
 	cancel_work_sync(&local->timeout_work);
 	kfree_skb(local->rx_pending);
+}
+
+static void local_release(struct kref *ref)
+{
+	struct nfc_llcp_local *local;
+
+	local = container_of(ref, struct nfc_llcp_local, ref);
+
+	list_del(&local->list);
+	local_cleanup(local, false);
 	kfree(local);
 }
 
@@ -1348,7 +1390,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
 		return;
 
 	/* Close and purge all existing sockets */
-	nfc_llcp_socket_release(local, true);
+	nfc_llcp_socket_release(local, true, 0);
 }
 
 void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
@@ -1427,6 +1469,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
 		return;
 	}
 
+	local_cleanup(local, false);
+
 	nfc_llcp_local_put(local);
 }
 
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index 5332751..5c7cdf3 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -278,6 +278,8 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
 
 			pr_debug("Returning sk state %d\n", sk->sk_state);
 
+			sk_acceptq_removed(parent);
+
 			return sk;
 		}
 
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* Re: Trying to implement secondary loopback
From: Hannes Frederic Sowa @ 2013-03-15 15:15 UTC (permalink / raw)
  To: Thomas Martitz
  Cc: richard -rw- weinberger, Eric W. Biederman,
	netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com,
	herbert@gondor.apana.org.au
In-Reply-To: <51433934.3080405@hhi.fraunhofer.de>

On Fri, Mar 15, 2013 at 04:07:32PM +0100, Thomas Martitz wrote:
> Same result. I assumed the kernel treats lo in a special way for 
> localhost-connections and that it would be impossible to achieve the 
> same with a custom interface.
> 
> I did the following:
> 
> ifconfig lo down
> insmod ./mykmod.ko
> ifconfig eth2 up
> ifconfig eth2 127.0.0.1
> 
> At this point ifconfig prints the same information for eth2 that it had 
> printed for lo before (except for the LOOPBACK flag, but I can enable 
> that one as well by adding IFF_LOOPBACK to the interface flags in the 
> module). Yet my test application only works with lo, not eth2.

127.0.0.0/8 is guarded by the kernel, but there is a sysctl for relaxing the
checks, /proc/sys/net/ipv4/conf/route_localnet. You could give it a try.

^ permalink raw reply

* Re: Trying to implement secondary loopback
From: Thomas Martitz @ 2013-03-15 15:07 UTC (permalink / raw)
  To: richard -rw- weinberger
  Cc: Eric W. Biederman, netdev@vger.kernel.org, davem@davemloft.net,
	edumazet@google.com, herbert@gondor.apana.org.au
In-Reply-To: <5143353C.3050107@hhi.fraunhofer.de>

Am 15.03.2013 15:50, schrieb Thomas Martitz:
> Am 15.03.2013 15:45, schrieb richard -rw- weinberger:
>> On Fri, Mar 15, 2013 at 3:35 PM, Thomas Martitz
>> <thomas.martitz@hhi.fraunhofer.de> wrote:
>>> Am 15.03.2013 15:32, schrieb richard -rw- weinberger:
>>>
>>>> On Fri, Mar 15, 2013 at 3:20 PM, Thomas Martitz
>>>> <thomas.martitz@hhi.fraunhofer.de> wrote:
>>>>>>
>>>>>> The real question is, why do you need a second one?
>>>>>> I assume your driver (for the non-existing hardware) is a ethernet
>>>>>> driver,
>>>>>> and now you're looking for a way to test your shiny new ethX device,
>>>>>> correct?
>>>>>>
>>>>>
>>>>> Yes. But that's only the first step. Once I have the basic ethX device
>>>>> working I want to make sure the PCIe data transfer is working (with
>>>>> good
>>>>> performance), ideally using the very same test application in user
>>>>> space.
>>>>
>>>>
>>>> And there is the second loopback device is this picture?
>>>>
>>>
>>> Mine is the second one, as I cannot modify "lo". The standard "lo"
>>> interface
>>> is the the first loopback and it seems to be hardcoded to be the only
>>> one.
>>
>> And why can't you implement a regular ethernet driver like everyone
>> else does?
>>
>
>
> That was actually my first attepmt, because I was sure it would work.
> However when I tried that I had trouble to get transfers on localhost
> routed to my code. I did "ifconfig lo down" but then it didn't transfer
> at all. I will retry.
>


Same result. I assumed the kernel treats lo in a special way for 
localhost-connections and that it would be impossible to achieve the 
same with a custom interface.

I did the following:

ifconfig lo down
insmod ./mykmod.ko
ifconfig eth2 up
ifconfig eth2 127.0.0.1

At this point ifconfig prints the same information for eth2 that it had 
printed for lo before (except for the LOOPBACK flag, but I can enable 
that one as well by adding IFF_LOOPBACK to the interface flags in the 
module). Yet my test application only works with lo, not eth2.

Best regards.

-----
visit us at

OFC 2013 / March 19-21 / Anaheim Convention Center, CA, USA / booth 11807

NABSHOW 2013 / April 8-11 / Las Vegas Convention Center, Nevada, USA / booth C7843

www.hhi.fraunhofer.de/events

^ permalink raw reply

* Re: Trying to implement secondary loopback
From: richard -rw- weinberger @ 2013-03-15 14:45 UTC (permalink / raw)
  To: Thomas Martitz
  Cc: Eric W. Biederman, netdev@vger.kernel.org, davem@davemloft.net,
	edumazet@google.com, herbert@gondor.apana.org.au
In-Reply-To: <514331BC.4080802@hhi.fraunhofer.de>

On Fri, Mar 15, 2013 at 3:35 PM, Thomas Martitz
<thomas.martitz@hhi.fraunhofer.de> wrote:
> Am 15.03.2013 15:32, schrieb richard -rw- weinberger:
>
>> On Fri, Mar 15, 2013 at 3:20 PM, Thomas Martitz
>> <thomas.martitz@hhi.fraunhofer.de> wrote:
>>>>
>>>> The real question is, why do you need a second one?
>>>> I assume your driver (for the non-existing hardware) is a ethernet
>>>> driver,
>>>> and now you're looking for a way to test your shiny new ethX device,
>>>> correct?
>>>>
>>>
>>> Yes. But that's only the first step. Once I have the basic ethX device
>>> working I want to make sure the PCIe data transfer is working (with good
>>> performance), ideally using the very same test application in user space.
>>
>>
>> And there is the second loopback device is this picture?
>>
>
> Mine is the second one, as I cannot modify "lo". The standard "lo" interface
> is the the first loopback and it seems to be hardcoded to be the only one.

And why can't you implement a regular ethernet driver like everyone else does?

-- 
Thanks,
//richard

^ permalink raw reply

* Re: Trying to implement secondary loopback
From: Thomas Martitz @ 2013-03-15 14:50 UTC (permalink / raw)
  To: richard -rw- weinberger
  Cc: Eric W. Biederman, netdev@vger.kernel.org, davem@davemloft.net,
	edumazet@google.com, herbert@gondor.apana.org.au
In-Reply-To: <CAFLxGvyzkoj_KtfH6=YK5LnpLW_N6sMdk7Hu=V=h5OK08oRE4Q@mail.gmail.com>

Am 15.03.2013 15:45, schrieb richard -rw- weinberger:
> On Fri, Mar 15, 2013 at 3:35 PM, Thomas Martitz
> <thomas.martitz@hhi.fraunhofer.de> wrote:
>> Am 15.03.2013 15:32, schrieb richard -rw- weinberger:
>>
>>> On Fri, Mar 15, 2013 at 3:20 PM, Thomas Martitz
>>> <thomas.martitz@hhi.fraunhofer.de> wrote:
>>>>>
>>>>> The real question is, why do you need a second one?
>>>>> I assume your driver (for the non-existing hardware) is a ethernet
>>>>> driver,
>>>>> and now you're looking for a way to test your shiny new ethX device,
>>>>> correct?
>>>>>
>>>>
>>>> Yes. But that's only the first step. Once I have the basic ethX device
>>>> working I want to make sure the PCIe data transfer is working (with good
>>>> performance), ideally using the very same test application in user space.
>>>
>>>
>>> And there is the second loopback device is this picture?
>>>
>>
>> Mine is the second one, as I cannot modify "lo". The standard "lo" interface
>> is the the first loopback and it seems to be hardcoded to be the only one.
>
> And why can't you implement a regular ethernet driver like everyone else does?
>


That was actually my first attepmt, because I was sure it would work. 
However when I tried that I had trouble to get transfers on localhost 
routed to my code. I did "ifconfig lo down" but then it didn't transfer 
at all. I will retry.

Best regards.

-----
visit us at

OFC 2013 / March 19-21 / Anaheim Convention Center, CA, USA / booth 11807

NABSHOW 2013 / April 8-11 / Las Vegas Convention Center, Nevada, USA / booth C7843

www.hhi.fraunhofer.de/events

^ permalink raw reply

* [PATCHv2 net-next] generalize VXLAN forwarding tables
From: David L Stevens @ 2013-03-15 14:35 UTC (permalink / raw)
  To: David Miller, Stephen Hemminger; +Cc: netdev


This patch generalizes VXLAN forwarding table entries allowing an administrator
to:
	1) specify multiple destinations for a given MAC
	2) specify alternate vni's in the VXLAN header
	3) specify alternate destination UDP ports
	4) use multicast MAC addresses as fdb lookup keys
	5) specify multicast destinations
	6) specify the outgoing interface for forwarded packets

The combination allows configuration of more complex topologies using VXLAN
encapsulation.

Changes since v1: rebase to 3.9.0-rc2

Signed-Off-By: David L Stevens <dlstevens@us.ibm.com>

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index f3a135c..4ce2dd4 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -81,13 +81,22 @@ struct vxlan_net {
 	struct hlist_head vni_list[VNI_HASH_SIZE];
 };
 
+struct vxlan_rdst {
+	struct rcu_head		 rcu;
+	__be32			 remote_ip;
+	__be16			 remote_port;
+	u32			 remote_vni;
+	u32			 remote_ifindex;
+	struct vxlan_rdst	*remote_next;
+};
+
 /* Forwarding table entry */
 struct vxlan_fdb {
 	struct hlist_node hlist;	/* linked list of entries */
 	struct rcu_head	  rcu;
 	unsigned long	  updated;	/* jiffies */
 	unsigned long	  used;
-	__be32		  remote_ip;
+	struct vxlan_rdst remote;
 	u16		  state;	/* see ndm_state */
 	u8		  eth_addr[ETH_ALEN];
 };
@@ -157,7 +166,8 @@ static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id)
 /* Fill in neighbour message in skbuff. */
 static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
 			   const struct vxlan_fdb *fdb,
-			   u32 portid, u32 seq, int type, unsigned int flags)
+			   u32 portid, u32 seq, int type, unsigned int flags,
+			   const struct vxlan_rdst *rdst)
 {
 	unsigned long now = jiffies;
 	struct nda_cacheinfo ci;
@@ -176,7 +186,7 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
 
 	if (type == RTM_GETNEIGH) {
 		ndm->ndm_family	= AF_INET;
-		send_ip = fdb->remote_ip != 0;
+		send_ip = rdst->remote_ip != htonl(INADDR_ANY);
 		send_eth = !is_zero_ether_addr(fdb->eth_addr);
 	} else
 		ndm->ndm_family	= AF_BRIDGE;
@@ -188,7 +198,17 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
 	if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
 		goto nla_put_failure;
 
-	if (send_ip && nla_put_be32(skb, NDA_DST, fdb->remote_ip))
+	if (send_ip && nla_put_be32(skb, NDA_DST, rdst->remote_ip))
+		goto nla_put_failure;
+
+	if (rdst->remote_port && rdst->remote_port != vxlan_port &&
+	    nla_put_be16(skb, NDA_PORT, rdst->remote_port))
+		goto nla_put_failure;
+	if (rdst->remote_vni != vxlan->vni &&
+	    nla_put_be32(skb, NDA_VNI, rdst->remote_vni))
+		goto nla_put_failure;
+	if (rdst->remote_ifindex &&
+	    nla_put_u32(skb, NDA_IFINDEX, rdst->remote_ifindex))
 		goto nla_put_failure;
 
 	ci.ndm_used	 = jiffies_to_clock_t(now - fdb->used);
@@ -211,6 +231,9 @@ static inline size_t vxlan_nlmsg_size(void)
 	return NLMSG_ALIGN(sizeof(struct ndmsg))
 		+ nla_total_size(ETH_ALEN) /* NDA_LLADDR */
 		+ nla_total_size(sizeof(__be32)) /* NDA_DST */
+		+ nla_total_size(sizeof(__be32)) /* NDA_PORT */
+		+ nla_total_size(sizeof(__be32)) /* NDA_VNI */
+		+ nla_total_size(sizeof(__u32)) /* NDA_IFINDEX */
 		+ nla_total_size(sizeof(struct nda_cacheinfo));
 }
 
@@ -225,7 +248,7 @@ static void vxlan_fdb_notify(struct vxlan_dev *vxlan,
 	if (skb == NULL)
 		goto errout;
 
-	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0);
+	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, &fdb->remote);
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */
 		WARN_ON(err == -EMSGSIZE);
@@ -247,7 +270,8 @@ static void vxlan_ip_miss(struct net_device *dev, __be32 ipa)
 
 	memset(&f, 0, sizeof f);
 	f.state = NUD_STALE;
-	f.remote_ip = ipa; /* goes to NDA_DST */
+	f.remote.remote_ip = ipa; /* goes to NDA_DST */
+	f.remote.remote_vni = VXLAN_N_VID;
 
 	vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
 }
@@ -300,10 +324,38 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
 	return NULL;
 }
 
+/* Add/update destinations for multicast */
+static int vxlan_fdb_append(struct vxlan_fdb *f,
+			    __be32 ip, __u32 port, __u32 vni, __u32 ifindex)
+{
+	struct vxlan_rdst *rd_prev, *rd;
+
+	rd_prev = NULL;
+	for (rd = &f->remote; rd; rd = rd->remote_next) {
+		if (rd->remote_ip == ip &&
+		    rd->remote_port == port &&
+		    rd->remote_vni == vni &&
+		    rd->remote_ifindex == ifindex)
+			return 0;
+		rd_prev = rd;
+	}
+	rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
+	if (rd == NULL)
+		return -ENOBUFS;
+	rd->remote_ip = ip;
+	rd->remote_port = port;
+	rd->remote_vni = vni;
+	rd->remote_ifindex = ifindex;
+	rd->remote_next = NULL;
+	rd_prev->remote_next = rd;
+	return 1;
+}
+
 /* Add new entry to forwarding table -- assumes lock held */
 static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 			    const u8 *mac, __be32 ip,
-			    __u16 state, __u16 flags)
+			    __u16 state, __u16 flags,
+			    __u32 port, __u32 vni, __u32 ifindex)
 {
 	struct vxlan_fdb *f;
 	int notify = 0;
@@ -320,6 +372,14 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 			f->updated = jiffies;
 			notify = 1;
 		}
+		if ((flags & NLM_F_APPEND) &&
+		    is_multicast_ether_addr(f->eth_addr)) {
+			int rc = vxlan_fdb_append(f, ip, port, vni, ifindex);
+
+			if (rc < 0)
+				return rc;
+			notify |= rc;
+		}
 	} else {
 		if (!(flags & NLM_F_CREATE))
 			return -ENOENT;
@@ -333,7 +393,11 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 			return -ENOMEM;
 
 		notify = 1;
-		f->remote_ip = ip;
+		f->remote.remote_ip = ip;
+		f->remote.remote_port = port;
+		f->remote.remote_vni = vni;
+		f->remote.remote_ifindex = ifindex;
+		f->remote.remote_next = NULL;
 		f->state = state;
 		f->updated = f->used = jiffies;
 		memcpy(f->eth_addr, mac, ETH_ALEN);
@@ -349,6 +413,19 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
 	return 0;
 }
 
+void vxlan_fdb_free(struct rcu_head *head)
+{
+	struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu);
+
+	while (f->remote.remote_next) {
+		struct vxlan_rdst *rd = f->remote.remote_next;
+
+		f->remote.remote_next = rd->remote_next;
+		kfree(rd);
+	}
+	kfree(f);
+}
+
 static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
 {
 	netdev_dbg(vxlan->dev,
@@ -358,7 +435,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
 	vxlan_fdb_notify(vxlan, f, RTM_DELNEIGH);
 
 	hlist_del_rcu(&f->hlist);
-	kfree_rcu(f, rcu);
+	call_rcu(&f->rcu, vxlan_fdb_free);
 }
 
 /* Add static entry (via netlink) */
@@ -367,7 +444,9 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 			 const unsigned char *addr, u16 flags)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct net *net = dev_net(vxlan->dev);
 	__be32 ip;
+	u32 port, vni, ifindex;
 	int err;
 
 	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
@@ -384,8 +463,36 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 
 	ip = nla_get_be32(tb[NDA_DST]);
 
+	if (tb[NDA_PORT]) {
+		if (nla_len(tb[NDA_PORT]) != sizeof(u32))
+			return -EINVAL;
+		port = nla_get_u32(tb[NDA_PORT]);
+	} else
+		port = vxlan_port;
+
+	if (tb[NDA_VNI]) {
+		if (nla_len(tb[NDA_VNI]) != sizeof(u32))
+			return -EINVAL;
+		vni = nla_get_u32(tb[NDA_VNI]);
+	} else
+		vni = vxlan->vni;
+
+	if (tb[NDA_IFINDEX]) {
+		struct net_device *dev;
+
+		if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
+			return -EINVAL;
+		ifindex = nla_get_u32(tb[NDA_IFINDEX]);
+		dev = dev_get_by_index(net, ifindex);
+		if (!dev)
+			return -EADDRNOTAVAIL;
+		dev_put(dev);
+	} else
+		ifindex = 0;
+
 	spin_lock_bh(&vxlan->hash_lock);
-	err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags);
+	err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags, port,
+		vni, ifindex);
 	spin_unlock_bh(&vxlan->hash_lock);
 
 	return err;
@@ -423,18 +530,21 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
 		int err;
 
 		hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) {
-			if (idx < cb->args[0])
-				goto skip;
-
-			err = vxlan_fdb_info(skb, vxlan, f,
-					     NETLINK_CB(cb->skb).portid,
-					     cb->nlh->nlmsg_seq,
-					     RTM_NEWNEIGH,
-					     NLM_F_MULTI);
-			if (err < 0)
-				break;
+			struct vxlan_rdst *rd;
+			for (rd = &f->remote; rd; rd = rd->remote_next) {
+				if (idx < cb->args[0])
+					goto skip;
+
+				err = vxlan_fdb_info(skb, vxlan, f,
+						     NETLINK_CB(cb->skb).portid,
+						     cb->nlh->nlmsg_seq,
+						     RTM_NEWNEIGH,
+						     NLM_F_MULTI, rd);
+				if (err < 0)
+					break;
 skip:
-			++idx;
+				++idx;
+			}
 		}
 	}
 
@@ -454,22 +564,23 @@ static void vxlan_snoop(struct net_device *dev,
 	f = vxlan_find_mac(vxlan, src_mac);
 	if (likely(f)) {
 		f->used = jiffies;
-		if (likely(f->remote_ip == src_ip))
+		if (likely(f->remote.remote_ip == src_ip))
 			return;
 
 		if (net_ratelimit())
 			netdev_info(dev,
 				    "%pM migrated from %pI4 to %pI4\n",
-				    src_mac, &f->remote_ip, &src_ip);
+				    src_mac, &f->remote.remote_ip, &src_ip);
 
-		f->remote_ip = src_ip;
+		f->remote.remote_ip = src_ip;
 		f->updated = jiffies;
 	} else {
 		/* learned new entry */
 		spin_lock(&vxlan->hash_lock);
 		err = vxlan_fdb_create(vxlan, src_mac, src_ip,
 				       NUD_REACHABLE,
-				       NLM_F_EXCL|NLM_F_CREATE);
+				       NLM_F_EXCL|NLM_F_CREATE,
+				       vxlan_port, vxlan->vni, 0);
 		spin_unlock(&vxlan->hash_lock);
 	}
 }
@@ -701,7 +812,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb)
 		}
 
 		f = vxlan_find_mac(vxlan, n->ha);
-		if (f && f->remote_ip == 0) {
+		if (f && f->remote.remote_ip == htonl(INADDR_ANY)) {
 			/* bridge-local neighbor */
 			neigh_release(n);
 			goto out;
@@ -834,47 +945,26 @@ static int handle_offloads(struct sk_buff *skb)
 	return 0;
 }
 
-/* Transmit local packets over Vxlan
- *
- * Outer IP header inherits ECN and DF from inner header.
- * Outer UDP destination is the VXLAN assigned port.
- *           source port is based on hash of flow
- */
-static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+				  struct vxlan_rdst *rdst, bool did_rsc)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct rtable *rt;
 	const struct iphdr *old_iph;
-	struct ethhdr *eth;
 	struct iphdr *iph;
 	struct vxlanhdr *vxh;
 	struct udphdr *uh;
 	struct flowi4 fl4;
 	unsigned int pkt_len = skb->len;
 	__be32 dst;
-	__u16 src_port;
+	__u16 src_port, dst_port;
+        u32 vni;
 	__be16 df = 0;
 	__u8 tos, ttl;
-	bool did_rsc = false;
-	const struct vxlan_fdb *f;
-
-	skb_reset_mac_header(skb);
-	eth = eth_hdr(skb);
-
-	if ((vxlan->flags & VXLAN_F_PROXY) && ntohs(eth->h_proto) == ETH_P_ARP)
-		return arp_reduce(dev, skb);
-	else if ((vxlan->flags&VXLAN_F_RSC) && ntohs(eth->h_proto) == ETH_P_IP)
-		did_rsc = route_shortcircuit(dev, skb);
 
-	f = vxlan_find_mac(vxlan, eth->h_dest);
-	if (f == NULL) {
-		did_rsc = false;
-		dst = vxlan->gaddr;
-		if (!dst && (vxlan->flags & VXLAN_F_L2MISS) &&
-		    !is_multicast_ether_addr(eth->h_dest))
-			vxlan_fdb_miss(vxlan, eth->h_dest);
-	} else
-		dst = f->remote_ip;
+	dst_port = rdst->remote_port ? rdst->remote_port : vxlan_port;
+	vni = rdst->remote_vni;
+	dst = rdst->remote_ip;
 
 	if (!dst) {
 		if (did_rsc) {
@@ -922,7 +1012,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
 	src_port = vxlan_src_port(vxlan, skb);
 
 	memset(&fl4, 0, sizeof(fl4));
-	fl4.flowi4_oif = vxlan->link;
+	fl4.flowi4_oif = rdst->remote_ifindex;
 	fl4.flowi4_tos = RT_TOS(tos);
 	fl4.daddr = dst;
 	fl4.saddr = vxlan->saddr;
@@ -949,13 +1039,13 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
 	vxh->vx_flags = htonl(VXLAN_FLAGS);
-	vxh->vx_vni = htonl(vxlan->vni << 8);
+	vxh->vx_vni = htonl(vni << 8);
 
 	__skb_push(skb, sizeof(*uh));
 	skb_reset_transport_header(skb);
 	uh = udp_hdr(skb);
 
-	uh->dest = htons(vxlan_port);
+	uh->dest = htons(dst_port);
 	uh->source = htons(src_port);
 
 	uh->len = htons(skb->len);
@@ -993,6 +1083,64 @@ tx_free:
 	return NETDEV_TX_OK;
 }
 
+/* Transmit local packets over Vxlan
+ *
+ * Outer IP header inherits ECN and DF from inner header.
+ * Outer UDP destination is the VXLAN assigned port.
+ *           source port is based on hash of flow
+ */
+static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct ethhdr *eth;
+	bool did_rsc = false;
+	struct vxlan_rdst group, *rdst0, *rdst;
+	struct vxlan_fdb *f;
+	int rc1, rc;
+
+	skb_reset_mac_header(skb);
+	eth = eth_hdr(skb);
+
+	if ((vxlan->flags & VXLAN_F_PROXY) && ntohs(eth->h_proto) == ETH_P_ARP)
+		return arp_reduce(dev, skb);
+	else if ((vxlan->flags&VXLAN_F_RSC) && ntohs(eth->h_proto) == ETH_P_IP)
+		did_rsc = route_shortcircuit(dev, skb);
+
+	f = vxlan_find_mac(vxlan, eth->h_dest);
+	if (f == NULL) {
+		did_rsc = false;
+		group.remote_port = vxlan_port;
+		group.remote_vni = vxlan->vni;
+		group.remote_ip = vxlan->gaddr;
+		group.remote_ifindex = vxlan->link;
+		group.remote_next = 0;
+		rdst0 = &group;
+
+		if (group.remote_ip == htonl(INADDR_ANY) &&
+		    (vxlan->flags & VXLAN_F_L2MISS) &&
+		    !is_multicast_ether_addr(eth->h_dest))
+			vxlan_fdb_miss(vxlan, eth->h_dest);
+	} else
+		rdst0 = &f->remote;
+
+	rc = NETDEV_TX_OK;
+
+	/* if there are multiple destinations, send copies */
+	for (rdst = rdst0->remote_next; rdst; rdst = rdst->remote_next) {
+		struct sk_buff *skb1;
+
+		skb1 = skb_clone(skb, GFP_ATOMIC);
+		rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
+		if (rc == NETDEV_TX_OK)
+			rc = rc1;
+	}
+
+	rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc);
+	if (rc == NETDEV_TX_OK)
+		rc = rc1;
+	return rc;
+}
+
 /* Walk the forwarding table and purge stale entries */
 static void vxlan_cleanup(unsigned long arg)
 {
@@ -1548,6 +1696,7 @@ static void __exit vxlan_cleanup_module(void)
 {
 	rtnl_link_unregister(&vxlan_link_ops);
 	unregister_pernet_device(&vxlan_net_ops);
+	rcu_barrier();
 }
 module_exit(vxlan_cleanup_module);
 
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h
index adb068c..f175212 100644
--- a/include/uapi/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
@@ -21,6 +21,9 @@ enum {
 	NDA_CACHEINFO,
 	NDA_PROBES,
 	NDA_VLAN,
+	NDA_PORT,
+	NDA_VNI,
+	NDA_IFINDEX,
 	__NDA_MAX
 };
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f95b6fb..466c474 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2111,7 +2111,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 	}
 
 	addr = nla_data(tb[NDA_LLADDR]);
-	if (!is_valid_ether_addr(addr)) {
+	if (is_zero_ether_addr(addr)) {
 		pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ether address\n");
 		return -EINVAL;
 	}

^ permalink raw reply related

* Re: Trying to implement secondary loopback
From: Thomas Martitz @ 2013-03-15 14:35 UTC (permalink / raw)
  To: richard -rw- weinberger
  Cc: Eric W. Biederman, netdev@vger.kernel.org, davem@davemloft.net,
	edumazet@google.com, herbert@gondor.apana.org.au
In-Reply-To: <CAFLxGvyDaaOtm1TrD-gfvhja_Uow8jtRbPyb2WcMscSLgo1umg@mail.gmail.com>

Am 15.03.2013 15:32, schrieb richard -rw- weinberger:
> On Fri, Mar 15, 2013 at 3:20 PM, Thomas Martitz
> <thomas.martitz@hhi.fraunhofer.de> wrote:
>>> The real question is, why do you need a second one?
>>> I assume your driver (for the non-existing hardware) is a ethernet driver,
>>> and now you're looking for a way to test your shiny new ethX device,
>>> correct?
>>>
>>
>> Yes. But that's only the first step. Once I have the basic ethX device
>> working I want to make sure the PCIe data transfer is working (with good
>> performance), ideally using the very same test application in user space.
>
> And there is the second loopback device is this picture?
>

Mine is the second one, as I cannot modify "lo". The standard "lo" 
interface is the the first loopback and it seems to be hardcoded to be 
the only one.

Best regards.

-----
visit us at

OFC 2013 / March 19-21 / Anaheim Convention Center, CA, USA / booth 11807

NABSHOW 2013 / April 8-11 / Las Vegas Convention Center, Nevada, USA / booth C7843

www.hhi.fraunhofer.de/events

^ permalink raw reply

* Re: Trying to implement secondary loopback
From: richard -rw- weinberger @ 2013-03-15 14:32 UTC (permalink / raw)
  To: Thomas Martitz
  Cc: Eric W. Biederman, netdev@vger.kernel.org, davem@davemloft.net,
	edumazet@google.com, herbert@gondor.apana.org.au
In-Reply-To: <51432E13.5060003@hhi.fraunhofer.de>

On Fri, Mar 15, 2013 at 3:20 PM, Thomas Martitz
<thomas.martitz@hhi.fraunhofer.de> wrote:
>> The real question is, why do you need a second one?
>> I assume your driver (for the non-existing hardware) is a ethernet driver,
>> and now you're looking for a way to test your shiny new ethX device,
>> correct?
>>
>
> Yes. But that's only the first step. Once I have the basic ethX device
> working I want to make sure the PCIe data transfer is working (with good
> performance), ideally using the very same test application in user space.

And there is the second loopback device is this picture?

-- 
Thanks,
//richard

^ permalink raw reply

* Re: Trying to implement secondary loopback
From: Thomas Martitz @ 2013-03-15 14:20 UTC (permalink / raw)
  To: richard -rw- weinberger
  Cc: Eric W. Biederman, netdev@vger.kernel.org, davem@davemloft.net,
	edumazet@google.com, herbert@gondor.apana.org.au
In-Reply-To: <CAFLxGvyCFHk=vhNYCY8obrVJR2rW9M7+J_ppyVpFq3AHAxjRjA@mail.gmail.com>

Am 15.03.2013 15:16, schrieb richard -rw- weinberger:
> On Fri, Mar 15, 2013 at 3:08 PM, Thomas Martitz
> <thomas.martitz@hhi.fraunhofer.de> wrote:
>> What's wrong with loopback? It's the simplest method to get basic
>> bidirectional data transfer going.
>>
>> Can you suggest an alternative approach?
>
> The real question is, why do you need a second one?
> I assume your driver (for the non-existing hardware) is a ethernet driver,
> and now you're looking for a way to test your shiny new ethX device, correct?
>

Yes. But that's only the first step. Once I have the basic ethX device 
working I want to make sure the PCIe data transfer is working (with good 
performance), ideally using the very same test application in user space.

Best regards.

-----
visit us at

OFC 2013 / March 19-21 / Anaheim Convention Center, CA, USA / booth 11807

NABSHOW 2013 / April 8-11 / Las Vegas Convention Center, Nevada, USA / booth C7843

www.hhi.fraunhofer.de/events

^ permalink raw reply

* Re: DaVinci platform unable to boot via NFS
From: Mugunthan V N @ 2013-03-15 14:17 UTC (permalink / raw)
  To: Prabhakar Lad; +Cc: Sekhar Nori, dlos, LAK, netdev
In-Reply-To: <CA+V-a8sNLBi1zB942ZbK26POrzcq7oOpNW9yPG5dG_gX7ZZ1oQ@mail.gmail.com>

On 3/15/2013 7:11 PM, Prabhakar Lad wrote:
> Hi Mugunthan,
>
> With 3.9 release I am not able to boot any davinci board via nfs, finally
> digging Into I found that there were recent changes for Ethernet davinci.
> Finally I reverting this to some safe commit I was able to boot via nfs.
> I reverted back as following:-
> git checkout  f9a8f83b04e0c362a2fc660dbad980d24af209fc  drivers/net/ethernet/ti/
>
> Can you please take a look at and fix it.
>
> Cheers,
> --Prabhakar Lad
> http://in.linkedin.com/pub/prabhakar-lad/19/92b/955
The issue is also reported in CPSW driver and is fixed already. I have
posted the patch for Davinci EMAC in the below link.

http://patchwork.ozlabs.org/patch/228003/

Regards
Mugunthan V N

^ permalink raw reply

* Re: DaVinci platform unable to boot via NFS
From: Sekhar Nori @ 2013-03-15 14:17 UTC (permalink / raw)
  To: Prabhakar Lad; +Cc: mugunthanvnm, dlos, LAK, netdev, Daniel Mack, Mark Jackson
In-Reply-To: <CA+V-a8sNLBi1zB942ZbK26POrzcq7oOpNW9yPG5dG_gX7ZZ1oQ@mail.gmail.com>

Prabhakar,

On 3/15/2013 7:11 PM, Prabhakar Lad wrote:
> Hi Mugunthan,
> 
> With 3.9 release I am not able to boot any davinci board via nfs, finally
> digging Into I found that there were recent changes for Ethernet davinci.
> Finally I reverting this to some safe commit I was able to boot via nfs.
> I reverted back as following:-
> git checkout  f9a8f83b04e0c362a2fc660dbad980d24af209fc  drivers/net/ethernet/ti/
> 
> Can you please take a look at and fix it.
> 
> Cheers,
> --Prabhakar Lad
> http://in.linkedin.com/pub/prabhakar-lad/19/92b/955
> 

A similar bug was reported on cpsw and the following patch from Daniel 
seems to have helped.

https://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=d35162f89b8f00537d7b240b76d2d0e8b8d29aa0

I made a similar fix for davinci_emac.c and the resulting diff is below 
(not tested or built).

Can you please check if this helps in DaVinci case?

Thanks,
Sekhar

----8<----
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 52c0536..ae1b77a 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1102,7 +1102,7 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
        /* If there is no more tx desc left free then we need to
         * tell the kernel to stop sending us tx frames.
         */
-       if (unlikely(cpdma_check_free_tx_desc(priv->txchan)))
+       if (unlikely(!cpdma_check_free_tx_desc(priv->txchan)))
                netif_stop_queue(ndev);

        return NETDEV_TX_OK;

^ permalink raw reply related


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