Netdev List
 help / color / mirror / Atom feed
* [net-next 6/8] bnx2x: Do not call load/unload functionality from DCC
From: Eilon Greenstein @ 2009-10-14 15:10 UTC (permalink / raw)
  To: David Miller; +Cc: netdev



There is really no need to clear the MAC or the FW filtering rules - it was
added for completion, but caused race conditions with load/unload. Removing this
redundant code

Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x_main.c |   19 +++++--------------
 1 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 7c5c300..42cd957 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2565,21 +2565,12 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
 static void bnx2x_e1h_disable(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
-	int i;
-
-	bp->rx_mode = BNX2X_RX_MODE_NONE;
-	bnx2x_set_storm_rx_mode(bp);
 
 	netif_tx_disable(bp->dev);
 	bp->dev->trans_start = jiffies;	/* prevent tx timeout */
 
 	REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
 
-	bnx2x_set_eth_mac_addr_e1h(bp, 0);
-
-	for (i = 0; i < MC_HASH_SIZE; i++)
-		REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
-
 	netif_carrier_off(bp->dev);
 }
 
@@ -2589,13 +2580,13 @@ static void bnx2x_e1h_enable(struct bnx2x *bp)
 
 	REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
 
-	bnx2x_set_eth_mac_addr_e1h(bp, 1);
-
 	/* Tx queue should be only reenabled */
 	netif_tx_wake_all_queues(bp->dev);
 
-	/* Initialize the receive filter. */
-	bnx2x_set_rx_mode(bp->dev);
+	/*
+	 * Should not call netif_carrier_on since it will be called if the link
+	 * is up when checking for link state
+	 */
 }
 
 static void bnx2x_update_min_max(struct bnx2x *bp)
@@ -10538,7 +10529,7 @@ static void bnx2x_self_test(struct net_device *dev,
 		/* disable input for TX port IF */
 		REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
 
-		link_up = bp->link_vars.link_up;
+		link_up = (bnx2x_link_test(bp) == 0);
 		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
 		bnx2x_nic_load(bp, LOAD_DIAG);
 		/* wait until link state is restored */
-- 
1.5.4.3





^ permalink raw reply related

* [net-next 2/8] bnx2x: Allowing 0 as initial fairness value
From: Eilon Greenstein @ 2009-10-14 15:08 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Value of zero was used to disable the fairness mechanism. Though the code
(driver and FW) allowed changing the value at run time, it did not allow to do
that if the mechanism was disabled to begin with.
Fixed the FW to allow turning on and off the mechanism at run time. Fixed the
code to read the value from the chip at the right sequence.
Without this fix, if the initial value was set to zero, traffic could not run on
the interface.

Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x_hsi.h  |    4 +-
 drivers/net/bnx2x_main.c |   56 +++++++++++++++++++++++-----------------------
 firmware/Makefile        |    2 +-
 firmware/WHENCE          |    4 +-
 4 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index 994743d..dc2f8ed 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -1259,8 +1259,8 @@ struct host_func_stats {
 
 
 #define BCM_5710_FW_MAJOR_VERSION			5
-#define BCM_5710_FW_MINOR_VERSION			0
-#define BCM_5710_FW_REVISION_VERSION			21
+#define BCM_5710_FW_MINOR_VERSION			2
+#define BCM_5710_FW_REVISION_VERSION			7
 #define BCM_5710_FW_ENGINEERING_VERSION 		0
 #define BCM_5710_FW_COMPILE_FLAGS			1
 
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index b4e9c6e..691cf15 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2333,8 +2333,14 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
 	}
 
 	/* ... only if all min rates are zeros - disable fairness */
-	if (all_zero)
-		bp->vn_weight_sum = 0;
+	if (all_zero) {
+		bp->cmng.flags.cmng_enables &=
+					~CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
+		DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+		   "  fairness will be disabled\n");
+	} else
+		bp->cmng.flags.cmng_enables |=
+					CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
 }
 
 static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
@@ -2353,17 +2359,14 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
 	} else {
 		vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
 				FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
-		/* If fairness is enabled (not all min rates are zeroes) and
-		   if current min rate is zero - set it to 1.
-		   This is a requirement of the algorithm. */
-		if (bp->vn_weight_sum && (vn_min_rate == 0))
+		/* If min rate is zero - set it to 1 */
+		if (!vn_min_rate)
 			vn_min_rate = DEF_MIN_RATE;
 		vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
 				FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
 	}
-
 	DP(NETIF_MSG_IFUP,
-	   "func %d: vn_min_rate=%d  vn_max_rate=%d  vn_weight_sum=%d\n",
+	   "func %d: vn_min_rate %d  vn_max_rate %d  vn_weight_sum %d\n",
 	   func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
 
 	memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
@@ -2490,7 +2493,6 @@ static void bnx2x__link_status_update(struct bnx2x *bp)
 	else
 		bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
-	bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
 	bnx2x_calc_vn_weight_sum(bp);
 
 	/* indicate link status */
@@ -2634,10 +2636,7 @@ static void bnx2x_update_min_max(struct bnx2x *bp)
 
 static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
 {
-	int func = BP_FUNC(bp);
-
 	DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
-	bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
 
 	if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
 
@@ -3067,6 +3066,8 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
 			int func = BP_FUNC(bp);
 
 			REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
+			bp->mf_config = SHMEM_RD(bp,
+					   mf_cfg.func_mf_config[func].config);
 			val = SHMEM_RD(bp, func_mb[func].drv_status);
 			if (val & DRV_STATUS_DCC_EVENT_MASK)
 				bnx2x_dcc_event(bp,
@@ -5559,20 +5560,18 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
 		bp->link_vars.line_speed = SPEED_10000;
 		bnx2x_init_port_minmax(bp);
 
+		if (!BP_NOMCP(bp))
+			bp->mf_config =
+			      SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
 		bnx2x_calc_vn_weight_sum(bp);
 
 		for (vn = VN_0; vn < E1HVN_MAX; vn++)
 			bnx2x_init_vn_minmax(bp, 2*vn + port);
 
 		/* Enable rate shaping and fairness */
-		bp->cmng.flags.cmng_enables =
+		bp->cmng.flags.cmng_enables |=
 					CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
-		if (bp->vn_weight_sum)
-			bp->cmng.flags.cmng_enables |=
-					CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
-		else
-			DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
-			   "  fairness will be disabled\n");
+
 	} else {
 		/* rate shaping and fairness are disabled */
 		DP(NETIF_MSG_IFUP,
@@ -9038,17 +9037,18 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	if (netif_carrier_ok(dev)) {
 		cmd->speed = bp->link_vars.line_speed;
 		cmd->duplex = bp->link_vars.duplex;
-	} else {
-		cmd->speed = bp->link_params.req_line_speed;
-		cmd->duplex = bp->link_params.req_duplex;
-	}
-	if (IS_E1HMF(bp)) {
-		u16 vn_max_rate;
+		if (IS_E1HMF(bp)) {
+			u16 vn_max_rate;
 
-		vn_max_rate = ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
+			vn_max_rate =
+				((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
 				FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
-		if (vn_max_rate < cmd->speed)
-			cmd->speed = vn_max_rate;
+			if (vn_max_rate < cmd->speed)
+				cmd->speed = vn_max_rate;
+		}
+	} else {
+		cmd->speed = -1;
+		cmd->duplex = -1;
 	}
 
 	if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
diff --git a/firmware/Makefile b/firmware/Makefile
index a6c7c3e..45c0466 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,7 +32,7 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
 					 adaptec/starfire_tx.bin
 fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
 fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
-fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.0.21.0.fw bnx2x-e1h-5.0.21.0.fw
+fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.2.7.0.fw bnx2x-e1h-5.2.7.0.fw
 fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j3.fw \
 			     bnx2/bnx2-rv2p-09-5.0.0.j3.fw \
 			     bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw \
diff --git a/firmware/WHENCE b/firmware/WHENCE
index c437e14..a07aede 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -674,8 +674,8 @@ Found in hex form in kernel source.
 
 Driver: bnx2x: Broadcom Everest
 
-File: bnx2x-e1-4.8.53.0.fw.ihex
-File: bnx2x-e1h-4.8.53.0.fw.ihex
+File: bnx2x-e1-5.2.7.0.fw.ihex
+File: bnx2x-e1h-5.2.7.0.fw.ihex
 
 License:
   Copyright (c) 2007-2009 Broadcom Corporation
-- 
1.5.4.3





^ permalink raw reply related

* [net-next 0/8] bnx2x: Device Control Channel bug fixes
From: Eilon Greenstein @ 2009-10-14 15:07 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Hi Dave,

This bnx2x patch series is fixing some bugs that relates to the Device
Control Channel (DCC) code. There are actually 3 different failures:

1. When the fairness initial value was set to zero, the device could not
be enabled. This is caused since zero indicated that the mechanism is
disabled, and the code (both FW and driver) was not ready to allow
enabling it at run time. This patch requires replacing the FW - to allow
easier review, it is split to 3 patches:
        P1: adding the new FW
        P2: the actually patch
        P3: removing the old FW
        
2. Races when loading/unloading the driver when DCC link enable/disable
commands are received. There were 3 different races:
        P4: The state of the driver which indicates if it is loaded or
        not was also used to signal if its link is enabled/disabled by
        DCC
        P5: The FW commands to acknowledge the DCC command and
        loading/unloading the driver run over each other
        P6: Setting/clearing the MAC address and the FW filtering rules
        
3.	P7: Reporting the maximal BW as the link speed

Patch number 8 is the version update.

The patches were made based on net-next. Since those are bug fixes,
please let me know if I should send them based on net-2.6 as well.

Thanks,
Eilon




^ permalink raw reply

* PF_RING: Include in main line kernel?
From: Brad Doctor @ 2009-10-14 14:33 UTC (permalink / raw)
  To: netdev; +Cc: Luca Deri

Greetings,

On behalf of the users and developers of the PF_RING project, we would
like to ask consideration to include the PF_RING module in the main
line kernel.

PF_RING (http://www.ntop.org/PF_RING.html) is a kernel module that
implements an mmap()-ed memory ring for accelerating packet capture
and for providing all the basic features a network monitoring
application needs. PF_RING includes several features such as packet
filtering, balancing across capture applications, packet reflection
(i.e. capture application can decide to bounce selected packets onto
an as-specified interface). Packets are filtered both using BPF and
using ACL-like rules (e.g. tcp and ports from 80 to 100). Using
PF_RING it is also possible to exploit multiple RX queues provided by
modern NIC adapters. PF_RING achieves a significant speedup by making
only one copy of the packet. Additionally, PF_RING is able to operate
in a capture-only installation, further increasing performance.

PF_RING has been around since 2003 and is very mature with an active
contributing developer base. The developer and user community use a
mailing list (http://listgateway.unipi.it/pipermail/ntop-misc/) for
discussions and submissions. PF_RING is used in several projects,
ranging from distributions such as DD-WRT/OpenWrt to improving
performance of applications like Snort and Wireshark. Many commercial
companies around the world in the field of intrusion detection and
traffic analysis rely on PF_RING for accelerating their products and
operations.

The PF_RING module relies on a small patch to net/core/dev.c that
intercepts when a packet is received/transmitted so that it can be
passed to the PF_RING module when present and with an active listener.
Other than these minor changes, all the PF_RING code is
self-contained, comprising jut two files: ring.c and ring.h. PF_RING
is the result of many years of research and development specifically
into high-speed packet capture, and is homegrown. PF_RING uses the
stock GPL license.

We feel that PF_RING is ready to be included with the mainline kernel.
We are ready and eager to support PF_RING for the long term.

Thank you in advance for your consideration!

-brad

^ permalink raw reply

* Re: Moving drivers into staging (was Re: [GIT PULL] SCSI fixes for 2.6.32-rc3)
From: James Smart @ 2009-10-14 14:13 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Joe Perches, Greg KH, Luis R. Rodriguez, James Bottomley,
	Linus Torvalds, Theodore Tso, Andrew Morton, linux-scsi,
	linux-kernel, Jing Huang, netdev@vger.kernel.org,
	linux-wireless@vger.kernel.org
In-Reply-To: <20091014063308.GE784@elte.hu>



Ingo Molnar wrote:
> Yes, that's a real worry. Some time ago i suggested:
> 
>   drivers/staging/good/
>   drivers/staging/bad/
>   drivers/staging/ugly/
> 
>  good:  drivers that are to go upstream in the next cycle 
>  bad:   outgoing drivers being obsoleted or abandoned
>  ugly:  incoming messy drivers with active developers
> 
> The messaging of this looks nice and the names are short and obvious.
> 
> An added benefit is that this kind of separation makes it easy for 
> people interested in drivers/staging to follow the 'status' of drivers. 
> Once stuff goes into 'good' a different kind of review is needed than if 
> a driver goes into 'ugly'.
> 
> The main disadvantage would be the PR angle: putting new drivers into a 
> path named 'ugly'. Not something you want to put into a quarterly status 
> report, right? If we put drivers/staging/ugly/ drivers into 
> drivers/staging/ itself, we'd solve that problem. I.e. we'd keep the 
> current scheme, but we'd also add drivers/staging/good/ and 
> drivers/staging/bad/ as two extra stages for incoming and outgoing 
> drivers.

Change "ugly" to "wip"  (work in progress).  Should remove the negative 
connotation and keeps things short. Does miss the spaghetti western theme
though :)

-- james s

^ permalink raw reply

* [RFC][PATCH] pkt_sched: skbedit add support for setting mark
From: jamal @ 2009-10-14 12:25 UTC (permalink / raw)
  To: Denys Fedoryschenko, Alexander Duyck; +Cc: netdev

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


Here are two patches, one for kernel and one for iproute2.
I have tested it and it works fine. Unless there are objections, I
would like to make a formal submission of this.

cheers,
jamal



[-- Attachment #2: skbeiprt-mark --]
[-- Type: text/plain, Size: 3137 bytes --]

commit 2c7524fc3ba82306e9834a22adc731bd563ed158
Author: Jamal Hadi Salim <hadi@cyberus.ca>
Date:   Wed Oct 14 08:09:54 2009 -0400

    skbedit: Add support to mark packets
    
    This adds support for setting the skb mark.
    
    Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>

diff --git a/include/linux/tc_act/tc_skbedit.h b/include/linux/tc_act/tc_skbedit.h
index a14e461..7a2e910 100644
--- a/include/linux/tc_act/tc_skbedit.h
+++ b/include/linux/tc_act/tc_skbedit.h
@@ -26,6 +26,7 @@
 
 #define SKBEDIT_F_PRIORITY		0x1
 #define SKBEDIT_F_QUEUE_MAPPING		0x2
+#define SKBEDIT_F_MARK			0x4
 
 struct tc_skbedit {
 	tc_gen;
@@ -37,6 +38,7 @@ enum {
 	TCA_SKBEDIT_PARMS,
 	TCA_SKBEDIT_PRIORITY,
 	TCA_SKBEDIT_QUEUE_MAPPING,
+	TCA_SKBEDIT_MARK,
 	__TCA_SKBEDIT_MAX
 };
 #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)
diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
index ecb1f2d..623dc53 100644
--- a/tc/m_skbedit.c
+++ b/tc/m_skbedit.c
@@ -31,11 +31,13 @@
 static void
 explain(void)
 {
-	fprintf(stderr, "Usage: ... skbedit <[QM] [PM]>\n"
+	fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n"
 			"QM = queue_mapping QUEUE_MAPPING\n"
 			"PM = priority PRIORITY \n"
+			"MM = mark MARK \n"
 			"QUEUE_MAPPING = device transmit queue to use\n"
-			"PRIORITY = classID to assign to priority field\n");
+			"PRIORITY = classID to assign to priority field\n"
+			"MARK = firewall mark to set\n");
 }
 
 static void
@@ -55,7 +57,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 	struct rtattr *tail;
 	unsigned int tmp;
 	__u16 queue_mapping;
-	__u32 flags = 0, priority;
+	__u32 flags = 0, priority, mark;
 	struct tc_skbedit sel = { 0 };
 
 	if (matches(*argv, "skbedit") != 0)
@@ -81,6 +83,14 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 				return -1;
 			}
 			ok++;
+		} else if (matches(*argv, "mark") == 0) {
+			flags |= SKBEDIT_F_MARK;
+			NEXT_ARG();
+			if (get_tc_classid(&mark, *argv)) {
+				fprintf(stderr, "Illegal mark\n");
+				return -1;
+			}
+			ok++;
 		} else if (matches(*argv, "help") == 0) {
 			usage();
 		} else {
@@ -138,6 +148,9 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 	if (flags & SKBEDIT_F_PRIORITY)
 		addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY,
 			  &priority, sizeof(priority));
+	if (flags & SKBEDIT_F_MARK)
+		addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
+			  &mark, sizeof(mark));
 	tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;
 
 	*argc_p = argc;
@@ -151,6 +164,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
 	struct rtattr *tb[TCA_SKBEDIT_MAX + 1];
 	SPRINT_BUF(b1);
 	__u32 *priority;
+	__u32 *mark;
 	__u16 *queue_mapping;
 
 	if (arg == NULL)
@@ -175,6 +189,10 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
 		priority = RTA_DATA(tb[TCA_SKBEDIT_PRIORITY]);
 		fprintf(f, " priority %s", sprint_tc_classid(*priority, b1));
 	}
+	if (tb[TCA_SKBEDIT_MARK] != NULL) {
+		mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]);
+		fprintf(f, " mark %d", *mark);
+	}
 
 	if (show_stats) {
 		if (tb[TCA_SKBEDIT_TM]) {

[-- Attachment #3: skbe-mark --]
[-- Type: text/plain, Size: 3617 bytes --]

commit 6da17c574694ad4c02268dd64e85792051946aab
Author: Jamal Hadi Salim <hadi@cyberus.ca>
Date:   Wed Oct 14 08:16:23 2009 -0400

    [PATCH] pkt_sched: skbedit add support for setting mark
    
    This adds support for setting the skb mark.
    
    Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>

diff --git a/include/linux/tc_act/tc_skbedit.h b/include/linux/tc_act/tc_skbedit.h
index a14e461..7a2e910 100644
--- a/include/linux/tc_act/tc_skbedit.h
+++ b/include/linux/tc_act/tc_skbedit.h
@@ -26,6 +26,7 @@
 
 #define SKBEDIT_F_PRIORITY		0x1
 #define SKBEDIT_F_QUEUE_MAPPING		0x2
+#define SKBEDIT_F_MARK			0x4
 
 struct tc_skbedit {
 	tc_gen;
@@ -37,6 +38,7 @@ enum {
 	TCA_SKBEDIT_PARMS,
 	TCA_SKBEDIT_PRIORITY,
 	TCA_SKBEDIT_QUEUE_MAPPING,
+	TCA_SKBEDIT_MARK,
 	__TCA_SKBEDIT_MAX
 };
 #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)
diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h
index 6abb3ed..e103fe0 100644
--- a/include/net/tc_act/tc_skbedit.h
+++ b/include/net/tc_act/tc_skbedit.h
@@ -26,7 +26,9 @@ struct tcf_skbedit {
 	struct tcf_common	common;
 	u32			flags;
 	u32     		priority;
+	u32     		mark;
 	u16			queue_mapping;
+	/* XXX: 16-bit pad here? */
 };
 #define to_skbedit(pc) \
 	container_of(pc, struct tcf_skbedit, common)
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 4ab916b..e9607fe 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -54,6 +54,8 @@ static int tcf_skbedit(struct sk_buff *skb, struct tc_action *a,
 	if (d->flags & SKBEDIT_F_QUEUE_MAPPING &&
 	    skb->dev->real_num_tx_queues > d->queue_mapping)
 		skb_set_queue_mapping(skb, d->queue_mapping);
+	if (d->flags & SKBEDIT_F_MARK)
+		skb->mark = d->mark;
 
 	spin_unlock(&d->tcf_lock);
 	return d->tcf_action;
@@ -63,6 +65,7 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
 	[TCA_SKBEDIT_PARMS]		= { .len = sizeof(struct tc_skbedit) },
 	[TCA_SKBEDIT_PRIORITY]		= { .len = sizeof(u32) },
 	[TCA_SKBEDIT_QUEUE_MAPPING]	= { .len = sizeof(u16) },
+	[TCA_SKBEDIT_MARK]		= { .len = sizeof(u32) },
 };
 
 static int tcf_skbedit_init(struct nlattr *nla, struct nlattr *est,
@@ -72,7 +75,7 @@ static int tcf_skbedit_init(struct nlattr *nla, struct nlattr *est,
 	struct tc_skbedit *parm;
 	struct tcf_skbedit *d;
 	struct tcf_common *pc;
-	u32 flags = 0, *priority = NULL;
+	u32 flags = 0, *priority = NULL, *mark = NULL;
 	u16 *queue_mapping = NULL;
 	int ret = 0, err;
 
@@ -95,6 +98,12 @@ static int tcf_skbedit_init(struct nlattr *nla, struct nlattr *est,
 		flags |= SKBEDIT_F_QUEUE_MAPPING;
 		queue_mapping = nla_data(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
 	}
+
+	if (tb[TCA_SKBEDIT_MARK] != NULL) {
+		flags |= SKBEDIT_F_MARK;
+		mark = nla_data(tb[TCA_SKBEDIT_MARK]);
+	}
+
 	if (!flags)
 		return -EINVAL;
 
@@ -124,6 +133,9 @@ static int tcf_skbedit_init(struct nlattr *nla, struct nlattr *est,
 		d->priority = *priority;
 	if (flags & SKBEDIT_F_QUEUE_MAPPING)
 		d->queue_mapping = *queue_mapping;
+	if (flags & SKBEDIT_F_MARK)
+		d->mark = *mark;
+
 	d->tcf_action = parm->action;
 
 	spin_unlock_bh(&d->tcf_lock);
@@ -161,6 +173,9 @@ static inline int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
 	if (d->flags & SKBEDIT_F_QUEUE_MAPPING)
 		NLA_PUT(skb, TCA_SKBEDIT_QUEUE_MAPPING,
 			sizeof(d->queue_mapping), &d->queue_mapping);
+	if (d->flags & SKBEDIT_F_MARK)
+		NLA_PUT(skb, TCA_SKBEDIT_MARK, sizeof(d->mark),
+			&d->mark);
 	t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
 	t.expires = jiffies_to_clock_t(d->tcf_tm.expires);

^ permalink raw reply related

* [net-next-2.6 PATCH 2/2] be2net: Bump the driver version number.
From: Ajit Khaparde @ 2009-10-14 12:24 UTC (permalink / raw)
  To: David Miller, netdev

Bump the version number to 2.101.260

Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
 drivers/net/benet/be.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 151e73e..9fd66dc 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -32,7 +32,7 @@
 
 #include "be_hw.h"
 
-#define DRV_VER			"2.101.205"
+#define DRV_VER			"2.101.260"
 #define DRV_NAME		"be2net"
 #define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC"
 #define BE3_NAME		"ServerEngines BladeEngine3 10Gbps NIC"
-- 
1.6.0.4


^ permalink raw reply related

* [net-next-2.6 PATCH 1/2] be2net: Add support for next generation of BladeEngine device
From: Ajit Khaparde @ 2009-10-14 12:24 UTC (permalink / raw)
  To: David Miller, netdev

Add new PCI ids to support next generation of BladeEnigne device.

Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
---
 drivers/net/benet/be.h |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 4b61a91..151e73e 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -35,20 +35,31 @@
 #define DRV_VER			"2.101.205"
 #define DRV_NAME		"be2net"
 #define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC"
+#define BE3_NAME		"ServerEngines BladeEngine3 10Gbps NIC"
 #define OC_NAME			"Emulex OneConnect 10Gbps NIC"
+#define OC_NAME1		"Emulex OneConnect 10Gbps NIC (be3)"
 #define DRV_DESC		BE_NAME "Driver"
 
 #define BE_VENDOR_ID 		0x19a2
 #define BE_DEVICE_ID1		0x211
+#define BE_DEVICE_ID1		0x221
 #define OC_DEVICE_ID1		0x700
 #define OC_DEVICE_ID2		0x701
+#define OC_DEVICE_ID2		0x710
 
 static inline char *nic_name(struct pci_dev *pdev)
 {
-	if (pdev->device == OC_DEVICE_ID1 || pdev->device == OC_DEVICE_ID2)
+	switch (pdev->device) {
+	case OC_DEVICE_ID1:
+	case OC_DEVICE_ID2:
 		return OC_NAME;
-	else
+	case OC_DEVICE_ID3:
+		return OC_NAME1;
+	case BE_DEVICE_ID2:
+		return BE3_NAME;
+	default:
 		return BE_NAME;
+	}
 }
 
 /* Number of bytes of an RX frame that are copied to skb->data */
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH] iproute2: skbedit: Fix help message
From: jamal @ 2009-10-14 12:07 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: netdev, Stephen Hemminger

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


This fixes the help message on the skbedit action.
Stephen, please apply if Alexander ACKs.

cheers,
jamal

[-- Attachment #2: skbe-help --]
[-- Type: text/plain, Size: 842 bytes --]

commit 28dd9c19a1fa618105238a3302f272e2aee7918a
Author: Jamal Hadi Salim <hadi@cyberus.ca>
Date:   Tue Oct 14 07:32:51 2009 -0400

    skbedit: Fix help message
    
    Currently the help text implies you can either pass queue mapping
    or priority. Truth is you can pass both
    
    Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>

diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
index 9044353..ecb1f2d 100644
--- a/tc/m_skbedit.c
+++ b/tc/m_skbedit.c
@@ -31,8 +31,9 @@
 static void
 explain(void)
 {
-	fprintf(stderr, "Usage: ... skbedit "
-			"queue_mapping QUEUE_MAPPING | priority PRIORITY \n"
+	fprintf(stderr, "Usage: ... skbedit <[QM] [PM]>\n"
+			"QM = queue_mapping QUEUE_MAPPING\n"
+			"PM = priority PRIORITY \n"
 			"QUEUE_MAPPING = device transmit queue to use\n"
 			"PRIORITY = classID to assign to priority field\n");
 }

^ permalink raw reply related

* Re: kernel mode pppoe ppp if + ifb + mirred redirect, ethernet packets in ifb?!
From: jamal @ 2009-10-14 12:00 UTC (permalink / raw)
  To: Denys Fedoryschenko; +Cc: netdev
In-Reply-To: <1255438959.6305.13.camel@dogo.mojatatu.com>

On Tue, 2009-10-13 at 09:18 -0400, jamal wrote:

> Ok - makes sense. I know some people using mark for ingress pseudo RPF.
> And given instability of netfilter interface, I may just end up patching
> skbedit.


Ok, I just whipped a quick patch for skbedit to set the mark - and it
seems to work well after some basic testing. I will post.

cheers,
jamal


^ permalink raw reply

* Re: [PATCH] Add sk_mark route lookup support for IPv4 listening sockets, and for IPv4 multicast forwarding
From: steve @ 2009-10-14 10:16 UTC (permalink / raw)
  To: Atis Elsts
  Cc: Maciej Żenczykowski, David Miller, netdev, panther,
	eric.dumazet, brian.haley
In-Reply-To: <200910141404.37882.atis@mikrotik.com>

Hi,

On Wed, Oct 14, 2009 at 02:04:37PM +0300, Atis Elsts wrote:
> On Wednesday 14 October 2009 12:27:43 steve@chygwyn.com wrote:
> >
> > The mark is supposed to be a generic thing, not just for routing
> > lookups, it can be used for classification, etc as well. 
> 
> In general, sounds like a good idea, but IMHO exactly this could be a problem.
> skb->mark is already used for a lot of things. What if I am setting the mark 
> by a firewall rule in prerouting chain, and matching it by a postrouting 
> rule? If routing lookup was changing the mark, then my setup would break.
>
Yes, thats exactly why I said that it should default to the current
behaviour.
 
> Perhaps one more field could be added dst_entry? The field would be filled 
> from route's table (if "setmark" for that route was specified). The use of 
> that field would be similar to tclassid (e.g matching in firewall), except 
> that it would also be used in routing lookups, if set.
>
Yes, I think that we are both thinking along the same lines. There
must obviously be a default "don't touch" setting,

Steve.

^ permalink raw reply

* Re: [PATCH] Add sk_mark route lookup support for IPv4 listening sockets, and for IPv4 multicast forwarding
From: Atis Elsts @ 2009-10-14 11:04 UTC (permalink / raw)
  To: steve
  Cc: Maciej Żenczykowski, David Miller, netdev, panther,
	eric.dumazet, brian.haley
In-Reply-To: <20091014092743.GA13374@fogou.chygwyn.com>

On Wednesday 14 October 2009 12:27:43 steve@chygwyn.com wrote:
>
> The mark is supposed to be a generic thing, not just for routing
> lookups, it can be used for classification, etc as well. 

In general, sounds like a good idea, but IMHO exactly this could be a problem.
skb->mark is already used for a lot of things. What if I am setting the mark 
by a firewall rule in prerouting chain, and matching it by a postrouting 
rule? If routing lookup was changing the mark, then my setup would break.

Perhaps one more field could be added dst_entry? The field would be filled 
from route's table (if "setmark" for that route was specified). The use of 
that field would be similar to tclassid (e.g matching in firewall), except 
that it would also be used in routing lookups, if set.

> I would 
> expect to see such a thing used for maybe specifying a VLAN or
> a reference to an MPLS label stack, or something similar too,
>
> Steve.



^ permalink raw reply

* [PATCH 2/5] Phonet: routing table backend
From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Rémi Denis-Courmont
In-Reply-To: <1255517311-19527-1-git-send-email-remi@remlab.net>

From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>

The Phonet "universe" only has 64 addresses, so we keep a trivial flat
routing table.

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/pn_dev.h |    5 ++
 net/phonet/pn_dev.c         |  100 ++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 99 insertions(+), 6 deletions(-)

diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
index 44c923c..87b5d81 100644
--- a/include/net/phonet/pn_dev.h
+++ b/include/net/phonet/pn_dev.h
@@ -47,6 +47,11 @@ u8 phonet_address_get(struct net_device *dev, u8 addr);
 int phonet_address_lookup(struct net *net, u8 addr);
 void phonet_address_notify(int event, struct net_device *dev, u8 addr);
 
+int phonet_route_add(struct net_device *dev, u8 daddr);
+int phonet_route_del(struct net_device *dev, u8 daddr);
+struct net_device *phonet_route_get(struct net *net, u8 daddr);
+struct net_device *phonet_route_output(struct net *net, u8 daddr);
+
 #define PN_NO_ADDR	0xff
 
 extern const struct file_operations pn_sock_seq_fops;
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 5f42f30..71fffa5 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -33,8 +33,14 @@
 #include <net/netns/generic.h>
 #include <net/phonet/pn_dev.h>
 
+struct phonet_routes {
+	spinlock_t		lock;
+	struct net_device	*table[64];
+};
+
 struct phonet_net {
 	struct phonet_device_list pndevs;
+	struct phonet_routes routes;
 };
 
 int phonet_net_id;
@@ -154,10 +160,11 @@ int phonet_address_del(struct net_device *dev, u8 addr)
 }
 
 /* Gets a source address toward a destination, through a interface. */
-u8 phonet_address_get(struct net_device *dev, u8 addr)
+u8 phonet_address_get(struct net_device *dev, u8 daddr)
 {
 	struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev));
 	struct phonet_device *pnd;
+	u8 saddr;
 
 	spin_lock_bh(&pndevs->lock);
 	pnd = __phonet_get(dev);
@@ -165,12 +172,26 @@ u8 phonet_address_get(struct net_device *dev, u8 addr)
 		BUG_ON(bitmap_empty(pnd->addrs, 64));
 
 		/* Use same source address as destination, if possible */
-		if (!test_bit(addr >> 2, pnd->addrs))
-			addr = find_first_bit(pnd->addrs, 64) << 2;
+		if (test_bit(daddr >> 2, pnd->addrs))
+			saddr = daddr;
+		else
+			saddr = find_first_bit(pnd->addrs, 64) << 2;
 	} else
-		addr = PN_NO_ADDR;
+		saddr = PN_NO_ADDR;
 	spin_unlock_bh(&pndevs->lock);
-	return addr;
+
+	if (saddr == PN_NO_ADDR) {
+		/* Fallback to another device */
+		struct net_device *def_dev;
+
+		def_dev = phonet_device_get(dev_net(dev));
+		if (def_dev) {
+			if (def_dev != dev)
+				saddr = phonet_address_get(def_dev, daddr);
+			dev_put(def_dev);
+		}
+	}
+	return saddr;
 }
 
 int phonet_address_lookup(struct net *net, u8 addr)
@@ -246,7 +267,7 @@ static struct notifier_block phonet_device_notifier = {
 /* Per-namespace Phonet devices handling */
 static int phonet_init_net(struct net *net)
 {
-	struct phonet_net *pnn = kmalloc(sizeof(*pnn), GFP_KERNEL);
+	struct phonet_net *pnn = kzalloc(sizeof(*pnn), GFP_KERNEL);
 	if (!pnn)
 		return -ENOMEM;
 
@@ -257,6 +278,7 @@ static int phonet_init_net(struct net *net)
 
 	INIT_LIST_HEAD(&pnn->pndevs.list);
 	spin_lock_init(&pnn->pndevs.lock);
+	spin_lock_init(&pnn->routes.lock);
 	net_assign_generic(net, phonet_net_id, pnn);
 	return 0;
 }
@@ -300,3 +322,69 @@ void phonet_device_exit(void)
 	unregister_netdevice_notifier(&phonet_device_notifier);
 	unregister_pernet_gen_device(phonet_net_id, &phonet_net_ops);
 }
+
+int phonet_route_add(struct net_device *dev, u8 daddr)
+{
+	struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id);
+	struct phonet_routes *routes = &pnn->routes;
+	int err = -EEXIST;
+
+	daddr = daddr >> 2;
+	spin_lock_bh(&routes->lock);
+	if (routes->table[daddr] == NULL) {
+		routes->table[daddr] = dev;
+		dev_hold(dev);
+		err = 0;
+	}
+	spin_unlock_bh(&routes->lock);
+	return err;
+}
+
+int phonet_route_del(struct net_device *dev, u8 daddr)
+{
+	struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id);
+	struct phonet_routes *routes = &pnn->routes;
+	int err = -ENOENT;
+
+	daddr = daddr >> 2;
+	spin_lock_bh(&routes->lock);
+	if (dev == routes->table[daddr]) {
+		routes->table[daddr] = NULL;
+		dev_put(dev);
+		err = 0;
+	}
+	spin_unlock_bh(&routes->lock);
+	return err;
+}
+
+struct net_device *phonet_route_get(struct net *net, u8 daddr)
+{
+	struct phonet_net *pnn = net_generic(net, phonet_net_id);
+	struct phonet_routes *routes = &pnn->routes;
+	struct net_device *dev;
+
+	ASSERT_RTNL(); /* no need to hold the device */
+
+	daddr >>= 2;
+	spin_lock_bh(&routes->lock);
+	dev = routes->table[daddr];
+	spin_unlock_bh(&routes->lock);
+	return dev;
+}
+
+struct net_device *phonet_route_output(struct net *net, u8 daddr)
+{
+	struct phonet_net *pnn = net_generic(net, phonet_net_id);
+	struct phonet_routes *routes = &pnn->routes;
+	struct net_device *dev;
+
+	spin_lock_bh(&routes->lock);
+	dev = routes->table[daddr >> 2];
+	if (dev)
+		dev_hold(dev);
+	spin_unlock_bh(&routes->lock);
+
+	if (!dev)
+		dev = phonet_device_get(net); /* Default route */
+	return dev;
+}
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 4/5] Phonet: route outgoing packets
From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Rémi Denis-Courmont
In-Reply-To: <1255517311-19527-3-git-send-email-remi@remlab.net>

From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 net/phonet/af_phonet.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index b113fe0..cc2eef1 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -190,9 +190,8 @@ static int pn_send(struct sk_buff *skb, struct net_device *dev,
 	skb->priority = 0;
 	skb->dev = dev;
 
-	if (pn_addr(src) == pn_addr(dst)) {
+	if (skb->pkt_type == PACKET_LOOPBACK) {
 		skb_reset_mac_header(skb);
-		skb->pkt_type = PACKET_LOOPBACK;
 		skb_orphan(skb);
 		if (irq)
 			netif_rx(skb);
@@ -222,6 +221,9 @@ static int pn_raw_send(const void *data, int len, struct net_device *dev,
 	if (skb == NULL)
 		return -ENOMEM;
 
+	if (phonet_address_lookup(dev_net(dev), pn_addr(dst)) == 0)
+		skb->pkt_type = PACKET_LOOPBACK;
+
 	skb_reserve(skb, MAX_PHONET_HEADER);
 	__skb_put(skb, len);
 	skb_copy_to_linear_data(skb, data, len);
@@ -235,6 +237,7 @@ static int pn_raw_send(const void *data, int len, struct net_device *dev,
 int pn_skb_send(struct sock *sk, struct sk_buff *skb,
 		const struct sockaddr_pn *target)
 {
+	struct net *net = sock_net(sk);
 	struct net_device *dev;
 	struct pn_sock *pn = pn_sk(sk);
 	int err;
@@ -243,9 +246,13 @@ int pn_skb_send(struct sock *sk, struct sk_buff *skb,
 
 	err = -EHOSTUNREACH;
 	if (sk->sk_bound_dev_if)
-		dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if);
-	else
-		dev = phonet_device_get(sock_net(sk));
+		dev = dev_get_by_index(net, sk->sk_bound_dev_if);
+	else if (phonet_address_lookup(net, daddr) == 0) {
+		dev = phonet_device_get(net);
+		skb->pkt_type = PACKET_LOOPBACK;
+	} else
+		dev = phonet_route_output(net, daddr);
+
 	if (!dev || !(dev->flags & IFF_UP))
 		goto drop;
 
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 5/5] Phonet: forward incoming packets
From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Rémi Denis-Courmont
In-Reply-To: <1255517311-19527-4-git-send-email-remi@remlab.net>

From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 net/phonet/af_phonet.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index cc2eef1..66737aa 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -394,6 +394,38 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
 			send_obj_unreachable(skb);
 			send_reset_indications(skb);
 		}
+	} else if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
+		goto out; /* Race between address deletion and loopback */
+	else {
+		/* Phonet packet routing */
+		struct net_device *out_dev;
+
+		out_dev = phonet_route_output(net, pn_sockaddr_get_addr(&sa));
+		if (!out_dev) {
+			LIMIT_NETDEBUG(KERN_WARNING"No Phonet route to %02X\n",
+					pn_sockaddr_get_addr(&sa));
+			goto out;
+		}
+
+		__skb_push(skb, sizeof(struct phonethdr));
+		skb->dev = out_dev;
+		if (out_dev == dev) {
+			LIMIT_NETDEBUG(KERN_ERR"Phonet loop to %02X on %s\n",
+					pn_sockaddr_get_addr(&sa), dev->name);
+			goto out_dev;
+		}
+		/* Some drivers (e.g. TUN) do not allocate HW header space */
+		if (skb_cow_head(skb, out_dev->hard_header_len))
+			goto out_dev;
+
+		if (dev_hard_header(skb, out_dev, ETH_P_PHONET, NULL, NULL,
+					skb->len) < 0)
+			goto out_dev;
+		dev_queue_xmit(skb);
+		dev_put(out_dev);
+		return NET_RX_SUCCESS;
+out_dev:
+		dev_put(out_dev);
 	}
 
 out:
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 3/5] Phonet: routing table Netlink interface
From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Rémi Denis-Courmont
In-Reply-To: <1255517311-19527-2-git-send-email-remi@remlab.net>

From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/pn_dev.h |    1 +
 net/phonet/pn_dev.c         |   31 ++++++++++
 net/phonet/pn_netlink.c     |  130 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 162 insertions(+), 0 deletions(-)

diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
index 87b5d81..afa7def 100644
--- a/include/net/phonet/pn_dev.h
+++ b/include/net/phonet/pn_dev.h
@@ -49,6 +49,7 @@ void phonet_address_notify(int event, struct net_device *dev, u8 addr);
 
 int phonet_route_add(struct net_device *dev, u8 daddr);
 int phonet_route_del(struct net_device *dev, u8 daddr);
+void rtm_phonet_notify(int event, struct net_device *dev, u8 dst);
 struct net_device *phonet_route_get(struct net *net, u8 daddr);
 struct net_device *phonet_route_output(struct net *net, u8 daddr);
 
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 71fffa5..6d64fda 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -240,6 +240,27 @@ static int phonet_device_autoconf(struct net_device *dev)
 	return 0;
 }
 
+static void phonet_route_autodel(struct net_device *dev)
+{
+	struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id);
+	unsigned i;
+	DECLARE_BITMAP(deleted, 64);
+
+	/* Remove left-over Phonet routes */
+	bitmap_zero(deleted, 64);
+	spin_lock_bh(&pnn->routes.lock);
+	for (i = 0; i < 64; i++)
+		if (dev == pnn->routes.table[i]) {
+			set_bit(i, deleted);
+			pnn->routes.table[i] = NULL;
+			dev_put(dev);
+		}
+	spin_unlock_bh(&pnn->routes.lock);
+	for (i = find_first_bit(deleted, 64); i < 64;
+			i = find_next_bit(deleted, 64, i + 1))
+		rtm_phonet_notify(RTM_DELROUTE, dev, i);
+}
+
 /* notify Phonet of device events */
 static int phonet_device_notify(struct notifier_block *me, unsigned long what,
 				void *arg)
@@ -253,6 +274,7 @@ static int phonet_device_notify(struct notifier_block *me, unsigned long what,
 		break;
 	case NETDEV_UNREGISTER:
 		phonet_device_destroy(dev);
+		phonet_route_autodel(dev);
 		break;
 	}
 	return 0;
@@ -287,10 +309,19 @@ static void phonet_exit_net(struct net *net)
 {
 	struct phonet_net *pnn = net_generic(net, phonet_net_id);
 	struct net_device *dev;
+	unsigned i;
 
 	rtnl_lock();
 	for_each_netdev(net, dev)
 		phonet_device_destroy(dev);
+
+	for (i = 0; i < 64; i++) {
+		dev = pnn->routes.table[i];
+		if (dev) {
+			rtm_phonet_notify(RTM_DELROUTE, dev, i);
+			dev_put(dev);
+		}
+	}
 	rtnl_unlock();
 
 	proc_net_remove(net, "phonet");
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index d21fd35..d8f5d3f 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -29,6 +29,8 @@
 #include <net/sock.h>
 #include <net/phonet/pn_dev.h>
 
+/* Device address handling */
+
 static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
 		     u32 pid, u32 seq, int event);
 
@@ -160,6 +162,131 @@ out:
 	return skb->len;
 }
 
+/* Routes handling */
+
+static int fill_route(struct sk_buff *skb, struct net_device *dev, u8 dst,
+			u32 pid, u32 seq, int event)
+{
+	struct rtmsg *rtm;
+	struct nlmsghdr *nlh;
+
+	nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
+
+	rtm = nlmsg_data(nlh);
+	rtm->rtm_family = AF_PHONET;
+	rtm->rtm_dst_len = 6;
+	rtm->rtm_src_len = 0;
+	rtm->rtm_tos = 0;
+	rtm->rtm_table = RT_TABLE_MAIN;
+	rtm->rtm_protocol = RTPROT_STATIC;
+	rtm->rtm_scope = RT_SCOPE_UNIVERSE;
+	rtm->rtm_type = RTN_UNICAST;
+	rtm->rtm_flags = 0;
+	NLA_PUT_U8(skb, RTA_DST, dst);
+	NLA_PUT_U32(skb, RTA_OIF, dev->ifindex);
+	return nlmsg_end(skb, nlh);
+
+nla_put_failure:
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
+}
+
+void rtm_phonet_notify(int event, struct net_device *dev, u8 dst)
+{
+	struct sk_buff *skb;
+	int err = -ENOBUFS;
+
+	skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
+			nla_total_size(1) + nla_total_size(4), GFP_KERNEL);
+	if (skb == NULL)
+		goto errout;
+	err = fill_route(skb, dev, dst, 0, 0, event);
+	if (err < 0) {
+		WARN_ON(err == -EMSGSIZE);
+		kfree_skb(skb);
+		goto errout;
+	}
+	rtnl_notify(skb, dev_net(dev), 0,
+			  RTNLGRP_PHONET_ROUTE, NULL, GFP_KERNEL);
+	return;
+errout:
+	if (err < 0)
+		rtnl_set_sk_err(dev_net(dev), RTNLGRP_PHONET_ROUTE, err);
+}
+
+static const struct nla_policy rtm_phonet_policy[RTA_MAX+1] = {
+	[RTA_DST] = { .type = NLA_U8 },
+	[RTA_OIF] = { .type = NLA_U32 },
+};
+
+static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
+{
+	struct net *net = sock_net(skb->sk);
+	struct nlattr *tb[RTA_MAX+1];
+	struct net_device *dev;
+	struct rtmsg *rtm;
+	int err;
+	u8 dst;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	ASSERT_RTNL();
+
+	err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_phonet_policy);
+	if (err < 0)
+		return err;
+
+	rtm = nlmsg_data(nlh);
+	if (rtm->rtm_table != RT_TABLE_MAIN || rtm->rtm_type != RTN_UNICAST)
+		return -EINVAL;
+	if (tb[RTA_DST] == NULL || tb[RTA_OIF] == NULL)
+		return -EINVAL;
+	dst = nla_get_u8(tb[RTA_DST]);
+	if (dst & 3) /* Phonet addresses only have 6 high-order bits */
+		return -EINVAL;
+
+	dev = __dev_get_by_index(net, nla_get_u32(tb[RTA_OIF]));
+	if (dev == NULL)
+		return -ENODEV;
+
+	if (nlh->nlmsg_type == RTM_NEWROUTE)
+		err = phonet_route_add(dev, dst);
+	else
+		err = phonet_route_del(dev, dst);
+	if (!err)
+		rtm_phonet_notify(nlh->nlmsg_type, dev, dst);
+	return err;
+}
+
+static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct net *net = sock_net(skb->sk);
+	u8 addr, addr_idx = 0, addr_start_idx = cb->args[0];
+
+	for (addr = 0; addr < 64; addr++) {
+		struct net_device *dev;
+
+		dev = phonet_route_get(net, addr << 2);
+		if (!dev)
+			continue;
+
+		if (addr_idx++ < addr_start_idx)
+			continue;
+		if (fill_route(skb, dev, addr << 2, NETLINK_CB(cb->skb).pid,
+				cb->nlh->nlmsg_seq, RTM_NEWROUTE))
+			goto out;
+	}
+
+out:
+	cb->args[0] = addr_idx;
+	cb->args[1] = 0;
+
+	return skb->len;
+}
+
 int __init phonet_netlink_register(void)
 {
 	int err = __rtnl_register(PF_PHONET, RTM_NEWADDR, addr_doit, NULL);
@@ -169,5 +296,8 @@ int __init phonet_netlink_register(void)
 	/* Further __rtnl_register() cannot fail */
 	__rtnl_register(PF_PHONET, RTM_DELADDR, addr_doit, NULL);
 	__rtnl_register(PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit);
+	__rtnl_register(PF_PHONET, RTM_NEWROUTE, route_doit, NULL);
+	__rtnl_register(PF_PHONET, RTM_DELROUTE, route_doit, NULL);
+	__rtnl_register(PF_PHONET, RTM_GETROUTE, NULL, route_dumpit);
 	return 0;
 }
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 1/5] Phonet: deliver broadcast packets to broadcast sockets
From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw)
  To: netdev; +Cc: Rémi Denis-Courmont
In-Reply-To: <06dcdf33b2a0132b2a05c3220735a81e@chewa.net>

From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/phonet.h |    1 +
 net/phonet/af_phonet.c      |    6 ++++++
 net/phonet/socket.c         |   21 +++++++++++++++++++++
 3 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index d43f71b..fdb05fa 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -47,6 +47,7 @@ static inline struct pn_sock *pn_sk(struct sock *sk)
 extern const struct proto_ops phonet_dgram_ops;
 
 struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *sa);
+void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb);
 void phonet_get_local_port_range(int *min, int *max);
 void pn_sock_hash(struct sock *sk);
 void pn_sock_unhash(struct sock *sk);
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index c711d58..b113fe0 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -369,6 +369,12 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
 
 	pn_skb_get_dst_sockaddr(skb, &sa);
 
+	/* check if this is broadcasted */
+	if (pn_sockaddr_get_addr(&sa) == PNADDR_BROADCAST) {
+		pn_deliver_sock_broadcast(net, skb);
+		goto out;
+	}
+
 	/* check if we are the destination */
 	if (phonet_address_lookup(net, pn_sockaddr_get_addr(&sa)) == 0) {
 		/* Phonet packet input */
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index aa5b5a9..8c84190 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -94,7 +94,28 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn)
 	spin_unlock_bh(&pnsocks.lock);
 
 	return rval;
+}
+
+/* Deliver a broadcast packet (only in bottom-half) */
+void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb)
+{
+	struct hlist_node *node;
+	struct sock *sknode;
+
+	spin_lock(&pnsocks.lock);
+	sk_for_each(sknode, node, &pnsocks.hlist) {
+		struct sk_buff *clone;
+
+		if (!net_eq(sock_net(sknode), net))
+			continue;
+		if (!sock_flag(sknode, SOCK_BROADCAST))
+			continue;
 
+		clone = skb_clone(skb, GFP_ATOMIC);
+		if (clone)
+			sk_receive_skb(sknode, clone, 0);
+	}
+	spin_unlock(&pnsocks.lock);
 }
 
 void pn_sock_hash(struct sock *sk)
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH net-next 0/5] Phonet: basic routing support
From: Rémi Denis-Courmont @ 2009-10-14 10:47 UTC (permalink / raw)
  To: netdev


   Hello,

This patchset provides rudimentary support for routing Phonet packets.
Configuration is done with the common rtnetlink infrastructure.

This is useful when there is more than one Phonet interface in the same
namespace,
e.g. a serial bus to a cellular modem and a USB gadget function to a PC.

Comments welcome.

 include/net/phonet/phonet.h |    1
 include/net/phonet/pn_dev.h |    6 ++
 net/phonet/af_phonet.c      |   55 ++++++++++++++++--
 net/phonet/pn_dev.c         |  131
+++++++++++++++++++++++++++++++++++++++++---
 net/phonet/pn_netlink.c     |  130
+++++++++++++++++++++++++++++++++++++++++++
 net/phonet/socket.c         |   21 +++++++
 6 files changed, 333 insertions(+), 11 deletions(-)

-- 
Rémi Denis-Courmont


^ permalink raw reply

* Re: [PATCH] Add sk_mark route lookup support for IPv4 listening sockets, and for IPv4 multicast forwarding
From: steve @ 2009-10-14  9:27 UTC (permalink / raw)
  To: Maciej Żenczykowski
  Cc: David Miller, atis, netdev, panther, eric.dumazet, brian.haley
In-Reply-To: <55a4f86e0910140250o45532dabr33707c025dfa25f9@mail.gmail.com>

Hi,

On Wed, Oct 14, 2009 at 02:50:47AM -0700, Maciej Żenczykowski wrote:
> Problem is the primary purpose of the mark is to enable matching on
> the mark in the routing tables.
> 
> See 'ip rule  ... fwmark X ...'
> 
> ie. that fails due to circular dependency.
> 
>
I don't agree. There are two route lookups with a tunnel, the
internal one and the tunnel one. Here is an example of what I'm
thinking:

1. Look up a route which points at a remote ip addres via a tunnel device.
   The "setmark" on this route sets the skb mark
2. Look up a route on the tunnel itself (i.e. the tunnel endpoint not
   the socket endpoint) using the mark from the initial lookup. This
   route can depend on the previous lookup (if there are multiple
   routes for multiple marks) and also set the mark to use.

The default would be to inherit the mark over a route lookup, in
case that no "setmark" had been specified for that route. In
other words, it would be the same as it is now.

The mark is supposed to be a generic thing, not just for routing
lookups, it can be used for classification, etc as well. I would
expect to see such a thing used for maybe specifying a VLAN or
a reference to an MPLS label stack, or something similar too,

Steve.

^ permalink raw reply

* Re: [PATCH] Add sk_mark route lookup support for IPv4 listening sockets, and for IPv4 multicast forwarding
From: Maciej Żenczykowski @ 2009-10-14  9:50 UTC (permalink / raw)
  To: David Miller; +Cc: steve, atis, netdev, panther, eric.dumazet, brian.haley
In-Reply-To: <20091014.021505.181431380.davem@davemloft.net>

Problem is the primary purpose of the mark is to enable matching on
the mark in the routing tables.

See 'ip rule  ... fwmark X ...'

ie. that fails due to circular dependency.


On Wed, Oct 14, 2009 at 02:15, David Miller <davem@davemloft.net> wrote:
> From: steve@chygwyn.com
> Date: Wed, 14 Oct 2009 08:23:19 +0100
>
>> On Wed, Oct 14, 2009 at 12:51:56AM -0700, Maciej Żenczykowski wrote:
>>> I'm thinking that the mark should be a tunnel parameter with values of
>>> inherit or a constant.
>>>
>> Why not do this on a per-route basis (i.e. lets suppose we add a
>> "setmark" parameter to each route) and this would allow changing
>> a mark when a packet matches the route. This not only solves the
>> tunnel case, but would be generically useful as well.
>>
>> Since we have to look up routes anyway, it shouldn't add any
>> real overhead to the routing process and we can benefit from
>> all the existing infrastructure (route cache, etc).
>
> This idea, I like :-)
>

^ permalink raw reply

* Re: [PATCH] Add sk_mark route lookup support for IPv4 listening sockets, and for IPv4 multicast forwarding
From: steve @ 2009-10-14  7:23 UTC (permalink / raw)
  To: Maciej Żenczykowski
  Cc: David Miller, atis, netdev, panther, eric.dumazet, brian.haley
In-Reply-To: <55a4f86e0910140051v69441b09gd364b32f8e2d0c68@mail.gmail.com>

Hi,

On Wed, Oct 14, 2009 at 12:51:56AM -0700, Maciej Żenczykowski wrote:
> I'm thinking that the mark should be a tunnel parameter with values of
> inherit or a constant.
>
Why not do this on a per-route basis (i.e. lets suppose we add a
"setmark" parameter to each route) and this would allow changing
a mark when a packet matches the route. This not only solves the
tunnel case, but would be generically useful as well.

Since we have to look up routes anyway, it shouldn't add any
real overhead to the routing process and we can benefit from
all the existing infrastructure (route cache, etc).

Steve.

^ permalink raw reply

* Re: [PATCH] Add sk_mark route lookup support for IPv4 listening sockets, and for IPv4 multicast forwarding
From: David Miller @ 2009-10-14  9:15 UTC (permalink / raw)
  To: steve; +Cc: zenczykowski, atis, netdev, panther, eric.dumazet, brian.haley
In-Reply-To: <20091014072319.GA12095@fogou.chygwyn.com>

From: steve@chygwyn.com
Date: Wed, 14 Oct 2009 08:23:19 +0100

> On Wed, Oct 14, 2009 at 12:51:56AM -0700, Maciej Żenczykowski wrote:
>> I'm thinking that the mark should be a tunnel parameter with values of
>> inherit or a constant.
>>
> Why not do this on a per-route basis (i.e. lets suppose we add a
> "setmark" parameter to each route) and this would allow changing
> a mark when a packet matches the route. This not only solves the
> tunnel case, but would be generically useful as well.
> 
> Since we have to look up routes anyway, it shouldn't add any
> real overhead to the routing process and we can benefit from
> all the existing infrastructure (route cache, etc).

This idea, I like :-)

^ permalink raw reply

* Re: [PATCH 0/6] netdev: Octeon MGMT new driver + octeon_ethernet updates.
From: Ralf Baechle @ 2009-10-14  9:04 UTC (permalink / raw)
  To: David Miller; +Cc: ddaney, linux-mips, netdev
In-Reply-To: <20091014.010913.21176323.davem@davemloft.net>

On Wed, Oct 14, 2009 at 01:09:13AM -0700, David Miller wrote:

> > The main thrust of this patch set is to add a driver for the Cavium
> > Networks Octeon processor's MII (Management port) Ethernet devices.
> > Since it shares an mdio bus with the existing octeon-ethernet driver,
> > there is also some rearrangement of that code.
> 
> Ralf how do you want to handle this patch set?
> 
> Since it's mostly MIPS infrastructure bits, please just add my:
> 
> Acked-by: David S. Miller <davem@davemloft.net>
> 
> to the commit that adds the actual driver under drivers/net/
> and you can merge all of it via your tree.

Okay, will merge.  Thanks!

  Ralf

^ permalink raw reply

* Re: [PATCH 0/6] netdev: Octeon MGMT new driver + octeon_ethernet updates.
From: David Miller @ 2009-10-14  8:09 UTC (permalink / raw)
  To: ddaney; +Cc: ralf, linux-mips, netdev
In-Reply-To: <4ACD1F4E.8090603@caviumnetworks.com>

From: David Daney <ddaney@caviumnetworks.com>
Date: Wed, 07 Oct 2009 16:07:58 -0700

> The main thrust of this patch set is to add a driver for the Cavium
> Networks Octeon processor's MII (Management port) Ethernet devices.
> Since it shares an mdio bus with the existing octeon-ethernet driver,
> there is also some rearrangement of that code.

Ralf how do you want to handle this patch set?

Since it's mostly MIPS infrastructure bits, please just add my:

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

to the commit that adds the actual driver under drivers/net/
and you can merge all of it via your tree.

Thanks!

^ permalink raw reply

* Re: [PATCH 1/2] net: enable smsc911x on MIPS
From: Steve.Glendinning @ 2009-10-14  7:45 UTC (permalink / raw)
  To: Manuel Lauss; +Cc: Manuel Lauss, netdev
In-Reply-To: <1255454749-26895-1-git-send-email-manuel.lauss@gmail.com>

> Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>

Acked-by: Steve Glendinning <steve.glendinning@smsc.com>


^ 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