* query: bnx2 and tg3 don't check tcp and/or ip header length validity?
From: William Allen Simpson @ 2009-10-14 15:50 UTC (permalink / raw)
To: netdev
My question is whether it would be OK to add a simple test, and set it to
zero in case of bad values?
In both cases, they get a number that could be negative (in the case of a
badly formed header), and mash it into a flag vector of some sort.
No comments/documentation explaining purpose.
===
bnx2.c:
u32 tcp_opt_len;
(ipv6 variant)
vlan_tag_flags |= ((tcp_opt_len >> 2) << 8) |
TX_BD_FLAGS_SW_FLAGS;
(ipv4 variant)
if (tcp_opt_len || (iph->ihl > 5)) {
vlan_tag_flags |= ((iph->ihl - 5) +
(tcp_opt_len >> 2)) << 8;
}
At least in the latter case, it bothers to check the IP header validity....
These are transmit-only, I cannot find where they use them on receive?
===
tg3.c:
int tcp_opt_len, ip_tcp_len;
tcp_opt_len = tcp_optlen(skb);
ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
iph->check = 0;
iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
hdrlen = ip_tcp_len + tcp_opt_len;
...
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
mss |= (hdrlen & 0xc) << 12;
if (hdrlen & 0x10)
base_flags |= 0x00000010;
base_flags |= (hdrlen & 0x3e0) << 5;
} else
mss |= hdrlen << 9;
Likewise, transmit-only. With completely different code later, in a dma
bug fix function. But that's the overall picture....
Anybody have any idea what's going on here?
^ permalink raw reply
* Re: query: tcpdump versus atomic?
From: William Allen Simpson @ 2009-10-14 15:20 UTC (permalink / raw)
To: netdev
In-Reply-To: <4AD5522B.50101@gmail.com>
William Allen Simpson wrote:
> Anybody know what code path tcpdump changes to running atomic?
>
> Is there a function to test whether you're running atomic?
>
To partially answer my own question, after laboriously #if'ing compiling
section by section, it affects the tcp_minisockets.c code at
tcp_create_openreq_child().
I've not found a function to test. I've found sk->sk_allocation, but
that doesn't seem to be dynamically updated to reflect the current state.
Anyway, sorry David, but there's at least two GFP_ATOMIC here (one existing,
one new). I've managed to change the others, by careful rearrangement. At
least, I hope so, until some future testing reveals otherwise....
^ permalink raw reply
* Re: [PATCH] ax25: unsigned cannot be less than 0 in ax25_ctl_ioctl()
From: Roel Kluin @ 2009-10-14 15:26 UTC (permalink / raw)
To: Kevin Dawson; +Cc: wharms, linux-hams, netdev, Joerg Reuter, Andrew Morton
In-Reply-To: <4AD3A67B.6070703@cerebellum.kd>
struct ax25_ctl_struct member `arg' is unsigned and cannot be less
than 0.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
Op 12-10-09 23:58, Kevin Dawson schreef:
>>> tmp_arg=ax25_ctl.arg * HZ;
>>>
>>> if (arg == 0 || arg > ULONG_MAX )
>>> goto einval_put;
>>
>> I'm not sure, I think this would only work if we made `arg' an
>> unsigned long long.
>
> That depends on the possible values of ax25_ctl.arg.
>
>> + if (ax25_ctl.arg * HZ > ULONG_MAX && ax25_ctl.cmd != AX25_KILL)
>> + return -EINVAL;
>
> Why the need to change arg before comparing it with a constant? Let the
> compiler do the work:
>
> if (ax25_ctl.arg > ULONG_MAX / HZ && ...
Ok, How about this then?
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index f454607..d923ac4 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -369,6 +369,9 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
if (ax25_ctl.digi_count > AX25_MAX_DIGIS)
return -EINVAL;
+ if (ax25_ctl.arg > ULONG_MAX / HZ && ax25_ctl.cmd != AX25_KILL)
+ return -EINVAL;
+
digi.ndigi = ax25_ctl.digi_count;
for (k = 0; k < digi.ndigi; k++)
digi.calls[k] = ax25_ctl.digi_addr[k];
@@ -418,14 +421,10 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
break;
case AX25_T3:
- if (ax25_ctl.arg < 0)
- goto einval_put;
ax25->t3 = ax25_ctl.arg * HZ;
break;
case AX25_IDLE:
- if (ax25_ctl.arg < 0)
- goto einval_put;
ax25->idle = ax25_ctl.arg * 60 * HZ;
break;
^ permalink raw reply related
* [net-next 8/8] bnx2x: Update to version 1.52.1-1
From: Eilon Greenstein @ 2009-10-14 15:10 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index ba131f4..59b58d8 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -56,8 +56,8 @@
#include "bnx2x_init_ops.h"
#include "bnx2x_dump.h"
-#define DRV_MODULE_VERSION "1.52.1"
-#define DRV_MODULE_RELDATE "2009/08/12"
+#define DRV_MODULE_VERSION "1.52.1-1"
+#define DRV_MODULE_RELDATE "2009/10/13"
#define BNX2X_BC_VER 0x040200
#include <linux/firmware.h>
--
1.5.4.3
^ permalink raw reply related
* [net-next 7/8] bnx2x: Report the maximal available BW as link speed
From: Eilon Greenstein @ 2009-10-14 15:10 UTC (permalink / raw)
To: David Miller; +Cc: netdev
The device is limited to the maximal BW allocation, so it should be displayed as
the link speed to notify the user.
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 42cd957..ba131f4 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2163,11 +2163,23 @@ static void bnx2x_link_report(struct bnx2x *bp)
}
if (bp->link_vars.link_up) {
+ u16 line_speed;
+
if (bp->state == BNX2X_STATE_OPEN)
netif_carrier_on(bp->dev);
printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
- printk("%d Mbps ", bp->link_vars.line_speed);
+ line_speed = bp->link_vars.line_speed;
+ if (IS_E1HMF(bp)) {
+ u16 vn_max_rate;
+
+ vn_max_rate =
+ ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
+ FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
+ if (vn_max_rate < line_speed)
+ line_speed = vn_max_rate;
+ }
+ printk("%d Mbps ", line_speed);
if (bp->link_vars.duplex == DUPLEX_FULL)
printk("full duplex");
--
1.5.4.3
^ permalink raw reply related
* [net-next 5/8] bnx2x: Adding FW mailbox mutex
From: Eilon Greenstein @ 2009-10-14 15:10 UTC (permalink / raw)
To: David Miller; +Cc: netdev
DCC commands are not protected with the RTNL lock, so a mutex should be added
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x.h | 3 +++
drivers/net/bnx2x_main.c | 7 +++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 185a6ba..c3b32f7 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1023,6 +1023,9 @@ struct bnx2x {
/* used to synchronize dmae accesses */
struct mutex dmae_mutex;
+ /* used to protect the FW mail box */
+ struct mutex fw_mb_mutex;
+
/* used to synchronize stats collecting */
int stats_state;
/* used by dmae command loader */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index e7b3b27..7c5c300 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2528,6 +2528,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
u32 cnt = 1;
u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
+ mutex_lock(&bp->fw_mb_mutex);
SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
@@ -2537,8 +2538,8 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
- /* Give the FW up to 2 second (200*10ms) */
- } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 200));
+ /* Give the FW up to 5 second (500*10ms) */
+ } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500));
DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n",
cnt*delay, rc, seq);
@@ -2552,6 +2553,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
bnx2x_fw_dump(bp);
rc = 0;
}
+ mutex_unlock(&bp->fw_mb_mutex);
return rc;
}
@@ -8956,6 +8958,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */
mutex_init(&bp->port.phy_mutex);
+ mutex_init(&bp->fw_mb_mutex);
#ifdef BCM_CNIC
mutex_init(&bp->cnic_mutex);
#endif
--
1.5.4.3
^ permalink raw reply related
* [net-next 4/8] bnx2x: Changing the Disabled state to a flag
From: Eilon Greenstein @ 2009-10-14 15:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev
When working with DCC, a function can be disabled or enabled (virtual link down
or up). Using the function state introduced some race conditions with the
load/unload flow.
Using a separate flag to indicate that the function is disabled.
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x.h | 2 +-
drivers/net/bnx2x_main.c | 34 +++++++++++++++++++---------------
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 60fa14f..185a6ba 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -900,6 +900,7 @@ struct bnx2x {
#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
#define HW_VLAN_TX_FLAG 0x400
#define HW_VLAN_RX_FLAG 0x800
+#define MF_FUNC_DIS 0x1000
int func;
#define BP_PORT(bp) (bp->func % PORT_MAX)
@@ -965,7 +966,6 @@ struct bnx2x {
#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000
#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000
-#define BNX2X_STATE_DISABLED 0xd000
#define BNX2X_STATE_DIAG 0xe000
#define BNX2X_STATE_ERROR 0xf000
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 691cf15..e7b3b27 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1043,7 +1043,6 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DISABLED):
DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
bp->set_mac_pending--;
smp_wmb();
@@ -2157,7 +2156,7 @@ static void bnx2x_calc_fc_adv(struct bnx2x *bp)
static void bnx2x_link_report(struct bnx2x *bp)
{
- if (bp->state == BNX2X_STATE_DISABLED) {
+ if (bp->flags & MF_FUNC_DIS) {
netif_carrier_off(bp->dev);
printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
return;
@@ -2437,8 +2436,7 @@ static void bnx2x_link_attn(struct bnx2x *bp)
memset(&(pstats->mac_stx[0]), 0,
sizeof(struct mac_stx));
}
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED))
+ if (bp->state == BNX2X_STATE_OPEN)
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
}
@@ -2481,9 +2479,7 @@ static void bnx2x_link_attn(struct bnx2x *bp)
static void bnx2x__link_status_update(struct bnx2x *bp)
{
- int func = BP_FUNC(bp);
-
- if (bp->state != BNX2X_STATE_OPEN)
+ if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS))
return;
bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
@@ -2640,14 +2636,19 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
+ /*
+ * This is the only place besides the function initialization
+ * where the bp->flags can change so it is done without any
+ * locks
+ */
if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n");
- bp->state = BNX2X_STATE_DISABLED;
+ bp->flags |= MF_FUNC_DIS;
bnx2x_e1h_disable(bp);
} else {
DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n");
- bp->state = BNX2X_STATE_OPEN;
+ bp->flags &= ~MF_FUNC_DIS;
bnx2x_e1h_enable(bp);
}
@@ -4695,8 +4696,7 @@ static void bnx2x_timer(unsigned long data)
}
}
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED))
+ if (bp->state == BNX2X_STATE_OPEN)
bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
timer_restart:
@@ -7629,7 +7629,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (CHIP_IS_E1H(bp))
if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
- bp->state = BNX2X_STATE_DISABLED;
+ bp->flags |= MF_FUNC_DIS;
}
if (bp->state == BNX2X_STATE_OPEN) {
@@ -9034,7 +9034,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->supported = bp->port.supported;
cmd->advertising = bp->port.advertising;
- if (netif_carrier_ok(dev)) {
+ if ((bp->state == BNX2X_STATE_OPEN) &&
+ !(bp->flags & MF_FUNC_DIS) &&
+ (bp->link_vars.link_up)) {
cmd->speed = bp->link_vars.line_speed;
cmd->duplex = bp->link_vars.duplex;
if (IS_E1HMF(bp)) {
@@ -9433,6 +9435,9 @@ static u32 bnx2x_get_link(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
+ if (bp->flags & MF_FUNC_DIS)
+ return 0;
+
return bp->link_vars.link_up;
}
@@ -9837,8 +9842,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
} else if (eeprom->magic == 0x50485952) {
/* 'PHYR' (0x50485952): re-init link after FW upgrade */
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED)) {
+ if (bp->state == BNX2X_STATE_OPEN) {
bnx2x_acquire_phy_lock(bp);
rc |= bnx2x_link_reset(&bp->link_params,
&bp->link_vars, 1);
--
1.5.4.3
^ permalink raw reply related
* [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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox