Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next RFC 0/5] xen-netback: TX grant mapping instead of copy
From: Ian Campbell @ 2013-11-07 10:52 UTC (permalink / raw)
  To: Zoltan Kiss; +Cc: wei.liu2, xen-devel, netdev, linux-kernel, jonathan.davies
In-Reply-To: <5273FA37.6020903@citrix.com>

On Fri, 2013-11-01 at 19:00 +0000, Zoltan Kiss wrote:
> On 01/11/13 10:50, Ian Campbell wrote:
> > Does this always avoid copying when bridging/openvswitching/forwarding
> > (e.g. masquerading etc)? For both domU->domU and domU->physical NIC?
> I've tested the domU->domU, domU->physical with bridge and openvswitch 
> usecase, and now I've created a new stat counter to see how often copy 
> happens (the callback's second parameter tells you whether the skb was 
> freed or copied). It doesn't do copy in all of these scenarios.
> What do you mean by forwarding? The scenario when you use bridge and 
> iptables mangling with the packet, not just filtering?

I mean using L3 routing rather L2 bridging. Which might involve
NAT/MASQUERADE or might just be normal IP routing.

> > How does it deal with broadcast traffic?
> Most of the real broadcast traffic actually small packets fit in the 
> PKT_PROT_LEN sized linear space, so it doesn't make any difference, 
> apart from doing a mapping before copy. But that will be eliminated 
> later on, I plan to add an incremental improvement to grant copy the 
> linear part.

OK. If I were a malicious guest and decided to start sending out loads
of huge broadcasts would that lead to a massive spike of activity in
dom0?

> I haven't spent too much time on that, but I couldn't find any broadcast 
> protocol which use large enough packets and easy to test, so I'm open to 
> ideas.

I guess you could hack something up using raw sockets?

> What I already know, skb_clone trigger a copy, and if the caller use the 
> original skb for every cloning, it will do several copy. I think that 
> could be fixed by using the first clone to do any further clones.

Yes. I suppose doing this automatically might be an interesting
extension to SKBTX_DEV_ZEROCOPY?

Ian.

^ permalink raw reply

* Re: [PATCH net-next 6/8] bonding: add arp_ip_target netlink support
From: Scott Feldman @ 2013-11-07 10:56 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: vfalico, fubar, andy, netdev, shm
In-Reply-To: <20131107101640.GA2463@minipsycho.orion>


On Nov 7, 2013, at 12:16 AM, Jiri Pirko <jiri@resnulli.us> wrote:

> Thu, Nov 07, 2013 at 10:43:30AM CET, sfeldma@cumulusnetworks.com wrote:
>> Add IFLA_BOND_ARP_IP_TARGET to allow get/set of bonding parameter
>> arp_ip_target via netlink.
>> 
>> Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
>> ---
>> drivers/net/bonding/bond_netlink.c |   43 ++++++++++++++-
>> drivers/net/bonding/bond_options.c |  102 ++++++++++++++++++++++++++++++++++++
>> drivers/net/bonding/bond_sysfs.c   |   77 +++------------------------
>> drivers/net/bonding/bonding.h      |    3 +
>> include/uapi/linux/if_link.h       |    1 
>> 5 files changed, 155 insertions(+), 71 deletions(-)
>> 
>> diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
>> index 9c50165..e4673ba 100644
>> --- a/drivers/net/bonding/bond_netlink.c
>> +++ b/drivers/net/bonding/bond_netlink.c
>> @@ -29,6 +29,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
>> 	[IFLA_BOND_DOWNDELAY]		= { .type = NLA_U32 },
>> 	[IFLA_BOND_USE_CARRIER]		= { .type = NLA_U8 },
>> 	[IFLA_BOND_ARP_INTERVAL]	= { .type = NLA_U32 },
>> +	[IFLA_BOND_ARP_IP_TARGET]	= { .type = NLA_NESTED },
>> };
>> 
>> static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
>> @@ -109,6 +110,21 @@ static int bond_changelink(struct net_device *bond_dev,
>> 		if (err)
>> 			return err;
>> 	}
>> +	if (data[IFLA_BOND_ARP_IP_TARGET]) {
>> +		struct nlattr *attr;
>> +		int rem;
>> +
>> +		err = bond_option_arp_ip_target_clear_all(bond);
>> +		if (err)
>> +			return err;
>> +
> 
> Hmm. I think this is not correct. I think you should not clear all. They
> might be needed to be used but for a brief moment, they disappear.
> 
> Just set or unset them one by one.

That’s a good catch.  I should compare existing set with new set and retain entries entries common to both sets (and add/remove uncommon ones).

Just to be clear, for netlink, the idea is to push a set of ip targets addrs as a nested attribute and process as a set.  This is consistent with arp_ip_target documentation in Documentation/networking/bonding.txt where arp_ip_target is passed as a comma-separated list of addrs.  However, it’s not consistent with the sysfs interface where addrs are added/removed one at a time using “+” or “-“ prefix.

e.g.:

ip link add bond7 type bond mode 1
ip link set dev bond7 type bond arp_ip_target 10.0.0.1,10.0.0.5
ip link set dev bond7 type bond arp_ip_target 10.0.0.1


>> @@ -141,6 +159,8 @@ static int bond_fill_info(struct sk_buff *skb,
>> {
>> 	struct bonding *bond = netdev_priv(bond_dev);
>> 	struct net_device *slave_dev = bond_option_active_slave_get(bond);
>> +	struct nlattr *targets;
>> +	int i, targets_added;
>> 
>> 	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
>> 		goto nla_put_failure;
>> @@ -152,10 +172,12 @@ static int bond_fill_info(struct sk_buff *skb,
>> 	if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
>> 		goto nla_put_failure;
>> 
>> -	if (nla_put_u32(skb, IFLA_BOND_UPDELAY, bond->params.updelay))
>> +	if (nla_put_u32(skb, IFLA_BOND_UPDELAY,
>> +		bond->params.updelay * bond->params.miimon))
>> 		goto nla_put_failure;
> 
> 	This bit should probably no be here :)

Drats, that change goes with earlier patch.  I’ll fix on patch set resend for issue above.

-scott

^ permalink raw reply

* Re: [PATCH net-next 1/8] bonding: add miimon netlink support
From: Veaceslav Falico @ 2013-11-07 10:59 UTC (permalink / raw)
  To: Scott Feldman; +Cc: fubar, andy, netdev, shm
In-Reply-To: <20131107094254.15846.53456.stgit@monster-03.cumulusnetworks.com>

On Thu, Nov 07, 2013 at 01:42:54AM -0800, Scott Feldman wrote:
>Add IFLA_BOND_MIIMON to allow get/set of bonding parameter
>miimon via netlink.
>
>Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>

As it seems you're going to send a V2, so some nitpicks.

>---
> drivers/net/bonding/bond_netlink.c |   32 ++++++++++++++++++----
> drivers/net/bonding/bond_options.c |   42 +++++++++++++++++++++++++++++
> drivers/net/bonding/bond_sysfs.c   |   53 +++++++-----------------------------
> drivers/net/bonding/bonding.h      |    1 +
> include/uapi/linux/if_link.h       |    1 +
> 5 files changed, 80 insertions(+), 49 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
>index 40e7b1c..38dd2f1 100644
>--- a/drivers/net/bonding/bond_netlink.c
>+++ b/drivers/net/bonding/bond_netlink.c
>@@ -1,6 +1,7 @@
> /*
>  * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
>  * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
>+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
>  *
>  * This program is free software; you can redistribute it and/or modify
>  * it under the terms of the GNU General Public License as published by
>@@ -23,6 +24,7 @@
> static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
> 	[IFLA_BOND_MODE]		= { .type = NLA_U8 },
> 	[IFLA_BOND_ACTIVE_SLAVE]	= { .type = NLA_U32 },
>+	[IFLA_BOND_MIIMON]		= { .type = NLA_U32 },
> };
>
> static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
>@@ -42,14 +44,17 @@ static int bond_changelink(struct net_device *bond_dev,
> 	struct bonding *bond = netdev_priv(bond_dev);
> 	int err;
>
>-	if (data && data[IFLA_BOND_MODE]) {
>+	if (!data)
>+		return 0;
>+
>+	if (data[IFLA_BOND_MODE]) {
> 		int mode = nla_get_u8(data[IFLA_BOND_MODE]);
>
> 		err = bond_option_mode_set(bond, mode);
> 		if (err)
> 			return err;
> 	}
>-	if (data && data[IFLA_BOND_ACTIVE_SLAVE]) {
>+	if (data[IFLA_BOND_ACTIVE_SLAVE]) {
> 		int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
> 		struct net_device *slave_dev;
>
>@@ -65,6 +70,13 @@ static int bond_changelink(struct net_device *bond_dev,
> 		if (err)
> 			return err;
> 	}
>+	if (data[IFLA_BOND_MIIMON]) {
>+		int miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
>+
>+		err = bond_option_miimon_set(bond, miimon);
>+		if (err)
>+			return err;
>+	}
> 	return 0;
> }
>
>@@ -83,7 +95,9 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
> static size_t bond_get_size(const struct net_device *bond_dev)
> {
> 	return nla_total_size(sizeof(u8)) +	/* IFLA_BOND_MODE */
>-		nla_total_size(sizeof(u32));	/* IFLA_BOND_ACTIVE_SLAVE */
>+		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_ACTIVE_SLAVE */
>+		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_MIIMON */
>+		0;
> }
>
> static int bond_fill_info(struct sk_buff *skb,
>@@ -92,10 +106,16 @@ static int bond_fill_info(struct sk_buff *skb,
> 	struct bonding *bond = netdev_priv(bond_dev);
> 	struct net_device *slave_dev = bond_option_active_slave_get(bond);
>
>-	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode) ||
>-	    (slave_dev &&
>-	     nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex)))
>+	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
> 		goto nla_put_failure;
>+
>+	if (slave_dev &&
>+	     nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))
	    ^^^^^^^^^^
Alignment.

>+		goto nla_put_failure;
>+
>+	if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
>+		goto nla_put_failure;
>+
> 	return 0;
>
> nla_put_failure:
>diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
>index 9a5223c..eaafab9 100644
>--- a/drivers/net/bonding/bond_options.c
>+++ b/drivers/net/bonding/bond_options.c
>@@ -1,6 +1,7 @@
> /*
>  * drivers/net/bond/bond_options.c - bonding options
>  * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
>+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
>  *
>  * This program is free software; you can redistribute it and/or modify
>  * it under the terms of the GNU General Public License as published by
>@@ -140,3 +141,44 @@ int bond_option_active_slave_set(struct bonding *bond,
> 	unblock_netpoll_tx();
> 	return ret;
> }
>+
>+int bond_option_miimon_set(struct bonding *bond, int miimon)
>+{
>+	if (miimon < 0) {
>+		pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
>+		       bond->dev->name, miimon, 0, INT_MAX);
>+		return -EINVAL;
>+	}
>+	pr_info("%s: Setting MII monitoring interval to %d.\n",
>+		bond->dev->name, miimon);
>+	bond->params.miimon = miimon;
>+	if (bond->params.updelay)
>+		pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
>+			bond->dev->name,
>+			bond->params.updelay * bond->params.miimon);
>+	if (bond->params.downdelay)
>+		pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
>+			bond->dev->name,
>+			bond->params.downdelay * bond->params.miimon);
>+	if (miimon && bond->params.arp_interval) {
>+		pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
>+			bond->dev->name);
>+		bond->params.arp_interval = 0;
>+		if (bond->params.arp_validate)
>+			bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
>+	}
>+	if (bond->dev->flags & IFF_UP) {
>+		/* If the interface is up, we may need to fire off
>+		 * the MII timer. If the interface is down, the
>+		 * timer will get fired off when the open function
>+		 * is called.
>+		 */
>+		if (!miimon) {
>+			cancel_delayed_work_sync(&bond->mii_work);
>+		} else {
>+			cancel_delayed_work_sync(&bond->arp_work);
>+			queue_delayed_work(bond->wq, &bond->mii_work, 0);
>+		}
>+	}
>+	return 0;
>+}
>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>index 47749c9..2fb9777 100644
>--- a/drivers/net/bonding/bond_sysfs.c
>+++ b/drivers/net/bonding/bond_sysfs.c
>@@ -981,55 +981,22 @@ static ssize_t bonding_store_miimon(struct device *d,
> 				    struct device_attribute *attr,
> 				    const char *buf, size_t count)
> {
>-	int new_value, ret = count;
>+	int new_value, ret;
> 	struct bonding *bond = to_bond(d);
>
>-	if (!rtnl_trylock())
>-		return restart_syscall();
> 	if (sscanf(buf, "%d", &new_value) != 1) {
> 		pr_err("%s: no miimon value specified.\n",
> 		       bond->dev->name);
>-		ret = -EINVAL;
>-		goto out;
>-	}
>-	if (new_value < 0) {
>-		pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
>-		       bond->dev->name, new_value, 0, INT_MAX);
>-		ret = -EINVAL;
>-		goto out;
>-	}
>-	pr_info("%s: Setting MII monitoring interval to %d.\n",
>-		bond->dev->name, new_value);
>-	bond->params.miimon = new_value;
>-	if (bond->params.updelay)
>-		pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
>-			bond->dev->name,
>-			bond->params.updelay * bond->params.miimon);
>-	if (bond->params.downdelay)
>-		pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
>-			bond->dev->name,
>-			bond->params.downdelay * bond->params.miimon);
>-	if (new_value && bond->params.arp_interval) {
>-		pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
>-			bond->dev->name);
>-		bond->params.arp_interval = 0;
>-		if (bond->params.arp_validate)
>-			bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
>-	}
>-	if (bond->dev->flags & IFF_UP) {
>-		/* If the interface is up, we may need to fire off
>-		 * the MII timer. If the interface is down, the
>-		 * timer will get fired off when the open function
>-		 * is called.
>-		 */
>-		if (!new_value) {
>-			cancel_delayed_work_sync(&bond->mii_work);
>-		} else {
>-			cancel_delayed_work_sync(&bond->arp_work);
>-			queue_delayed_work(bond->wq, &bond->mii_work, 0);
>-		}
>+		return -EINVAL;
> 	}
>-out:
>+
>+	if (!rtnl_trylock())
>+		return restart_syscall();
>+
>+	ret = bond_option_miimon_set(bond, new_value);
>+	if (!ret)
>+		ret = count;
>+
> 	rtnl_unlock();
> 	return ret;
> }
>diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>index 046a605..91d7eae 100644
>--- a/drivers/net/bonding/bonding.h
>+++ b/drivers/net/bonding/bonding.h
>@@ -428,6 +428,7 @@ int bond_netlink_init(void);
> void bond_netlink_fini(void);
> int bond_option_mode_set(struct bonding *bond, int mode);
> int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev);
>+int bond_option_miimon_set(struct bonding *bond, int miimon);
> struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
> struct net_device *bond_option_active_slave_get(struct bonding *bond);
>
>diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
>index b78566f..b38472b 100644
>--- a/include/uapi/linux/if_link.h
>+++ b/include/uapi/linux/if_link.h
>@@ -331,6 +331,7 @@ enum {
> 	IFLA_BOND_UNSPEC,
> 	IFLA_BOND_MODE,
> 	IFLA_BOND_ACTIVE_SLAVE,
>+	IFLA_BOND_MIIMON,
> 	__IFLA_BOND_MAX,
> };
>
>

^ permalink raw reply

* Re: [PATCH net-next 3/8] bonding: add downdelay netlink support
From: Veaceslav Falico @ 2013-11-07 11:02 UTC (permalink / raw)
  To: Scott Feldman; +Cc: fubar, andy, netdev, shm
In-Reply-To: <20131107094308.15846.58301.stgit@monster-03.cumulusnetworks.com>

On Thu, Nov 07, 2013 at 01:43:08AM -0800, Scott Feldman wrote:
>Add IFLA_BOND_DOWNDELAY to allow get/set of bonding parameter
>downdelay via netlink.
>
>Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
>---
> drivers/net/bonding/bond_netlink.c |   12 +++++++++++
> drivers/net/bonding/bond_options.c |   29 +++++++++++++++++++++++++++
> drivers/net/bonding/bond_sysfs.c   |   38 +++++++++---------------------------
> drivers/net/bonding/bonding.h      |    1 +
> include/uapi/linux/if_link.h       |    1 +
> 5 files changed, 52 insertions(+), 29 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
>index 9ba5431..e684713 100644
>--- a/drivers/net/bonding/bond_netlink.c
>+++ b/drivers/net/bonding/bond_netlink.c
>@@ -26,6 +26,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
> 	[IFLA_BOND_ACTIVE_SLAVE]	= { .type = NLA_U32 },
> 	[IFLA_BOND_MIIMON]		= { .type = NLA_U32 },
> 	[IFLA_BOND_UPDELAY]		= { .type = NLA_U32 },
>+	[IFLA_BOND_DOWNDELAY]		= { .type = NLA_U32 },
> };
>
> static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
>@@ -85,6 +86,13 @@ static int bond_changelink(struct net_device *bond_dev,
> 		if (err)
> 			return err;
> 	}
>+	if (data[IFLA_BOND_DOWNDELAY]) {
>+		int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]);
>+
>+		err = bond_option_downdelay_set(bond, downdelay);
>+		if (err)
>+			return err;
>+	}
> 	return 0;
> }
>
>@@ -106,6 +114,7 @@ static size_t bond_get_size(const struct net_device *bond_dev)
> 		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_ACTIVE_SLAVE */
> 		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_MIIMON */
> 		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_UPDELAY */
>+		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_DOWNDELAY */
> 		0;
> }
>
>@@ -128,6 +137,9 @@ static int bond_fill_info(struct sk_buff *skb,
> 	if (nla_put_u32(skb, IFLA_BOND_UPDELAY, bond->params.updelay))
> 		goto nla_put_failure;
>
>+	if (nla_put_u32(skb, IFLA_BOND_DOWNDELAY, bond->params.downdelay))
>+		goto nla_put_failure;
>+
> 	return 0;
>
> nla_put_failure:
>diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
>index c0fea66..738be5f 100644
>--- a/drivers/net/bonding/bond_options.c
>+++ b/drivers/net/bonding/bond_options.c
>@@ -211,3 +211,32 @@ int bond_option_updelay_set(struct bonding *bond, int updelay)
>
> 	return 0;
> }
>+
>+int bond_option_downdelay_set(struct bonding *bond, int downdelay)
>+{
>+	if (!(bond->params.miimon)) {
>+		pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", bond->dev->name);

Maybe get bond->dev->name on the next line?

>+		return -EPERM;
>+	}
>+
>+	if (downdelay < 0) {
>+		pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
>+		       bond->dev->name, downdelay, 0, INT_MAX);
>+		return -EINVAL;
>+	} else {
>+		if ((downdelay % bond->params.miimon) != 0) {
>+			pr_warn("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
>+				bond->dev->name, downdelay,
>+				bond->params.miimon,
>+				(downdelay / bond->params.miimon) *
>+				bond->params.miimon);
>+		}
>+		bond->params.downdelay = downdelay / bond->params.miimon;
>+		pr_info("%s: Setting down delay to %d.\n",
>+			bond->dev->name,
>+			bond->params.downdelay * bond->params.miimon);
>+
>+	}
>+
>+	return 0;
>+}
>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>index 1125bef..41a62ac 100644
>--- a/drivers/net/bonding/bond_sysfs.c
>+++ b/drivers/net/bonding/bond_sysfs.c
>@@ -706,42 +706,22 @@ static ssize_t bonding_store_downdelay(struct device *d,
> 				       struct device_attribute *attr,
> 				       const char *buf, size_t count)
> {
>-	int new_value, ret = count;
>+	int new_value, ret;
> 	struct bonding *bond = to_bond(d);
>
>-	if (!(bond->params.miimon)) {
>-		pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
>-		       bond->dev->name);
>-		ret = -EPERM;
>-		goto out;
>-	}
>-
> 	if (sscanf(buf, "%d", &new_value) != 1) {
> 		pr_err("%s: no down delay value specified.\n", bond->dev->name);
>-		ret = -EINVAL;
>-		goto out;
>+		return -EINVAL;
> 	}
>-	if (new_value < 0) {
>-		pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
>-		       bond->dev->name, new_value, 0, INT_MAX);
>-		ret = -EINVAL;
>-		goto out;
>-	} else {
>-		if ((new_value % bond->params.miimon) != 0) {
>-			pr_warning("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
>-				   bond->dev->name, new_value,
>-				   bond->params.miimon,
>-				   (new_value / bond->params.miimon) *
>-				   bond->params.miimon);
>-		}
>-		bond->params.downdelay = new_value / bond->params.miimon;
>-		pr_info("%s: Setting down delay to %d.\n",
>-			bond->dev->name,
>-			bond->params.downdelay * bond->params.miimon);
>
>-	}
>+	if (!rtnl_trylock())
>+		return restart_syscall();
>
>-out:
>+	ret = bond_option_downdelay_set(bond, new_value);
>+	if (!ret)
>+		ret = count;
>+
>+	rtnl_unlock();
> 	return ret;
> }
> static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
>diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>index 408e6c2..40987f3 100644
>--- a/drivers/net/bonding/bonding.h
>+++ b/drivers/net/bonding/bonding.h
>@@ -430,6 +430,7 @@ int bond_option_mode_set(struct bonding *bond, int mode);
> int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev);
> int bond_option_miimon_set(struct bonding *bond, int miimon);
> int bond_option_updelay_set(struct bonding *bond, int updelay);
>+int bond_option_downdelay_set(struct bonding *bond, int downdelay);
> struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
> struct net_device *bond_option_active_slave_get(struct bonding *bond);
>
>diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
>index 361414e..a372831 100644
>--- a/include/uapi/linux/if_link.h
>+++ b/include/uapi/linux/if_link.h
>@@ -333,6 +333,7 @@ enum {
> 	IFLA_BOND_ACTIVE_SLAVE,
> 	IFLA_BOND_MIIMON,
> 	IFLA_BOND_UPDELAY,
>+	IFLA_BOND_DOWNDELAY,
> 	__IFLA_BOND_MAX,
> };
>
>

^ permalink raw reply

* [PATCH v2] net: calxedaxgmac: Fix panic caused by MTU change of active interface
From: Andreas Herrmann @ 2013-11-07 11:07 UTC (permalink / raw)
  To: Rob Herring; +Cc: Ben Hutchings, Grant Likely, David S. Miller, netdev
In-Reply-To: <20131106133126.GL22917@alberich>

Changing MTU size of an xgmac network interface while it is active can
cause a panic like

  skbuff: skb_over_panic: text:c03bc62c len:1090 put:1090 head:edfb6900 data:edfb6942 tail:0xedfb6d84 end:0xedfb6bc0 dev:eth0
  ------------[ cut here ]------------
  kernel BUG at net/core/skbuff.c:126!
  Internal error: Oops - BUG: 0 [#1] SMP ARM
  Modules linked in:
  CPU: 0 PID: 762 Comm: python Tainted: G        W    3.10.0-00015-g3e33cd7 #309
  task: edcfe000 ti: ed67e000 task.ti: ed67e000
  PC is at skb_panic+0x64/0x70
  LR is at wake_up_klogd+0x5c/0x68

This happens because xgmac_change_mtu modifies dev->mtu before the
network interface is quiesced. And thus there still might be buffers
in use which have a buffer size based on the old MTU.

To fix this I moved the change of dev->mtu after the call to
xgmac_stop.

Another modification is required (in xgmac_stop) to ensure that
xgmac_xmit is really not called anymore (xgmac_tx_complete might wake
up the queue again).

I've tested the fix by switching MTU size every second between 600 and
1500 while network traffic was going on. The test box survived a test
of several hours (until I've stopped it) whereas w/o this fix above
panic occurs after several minutes (at most).

Change since v1:
- remove call to netif_stop_queue at beginning of xgmac_stop
- use netif_tx_disable instead of locking+netif_stop_queue

Signed-off-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
---
 drivers/net/ethernet/calxeda/xgmac.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

Patch is against v3.12-1714-gaafc090.


Regards,
Andreas

diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 48f5288..4fc5c8e 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -1060,13 +1060,13 @@ static int xgmac_stop(struct net_device *dev)
 {
 	struct xgmac_priv *priv = netdev_priv(dev);
 
-	netif_stop_queue(dev);
-
 	if (readl(priv->base + XGMAC_DMA_INTR_ENA))
 		napi_disable(&priv->napi);
 
 	writel(0, priv->base + XGMAC_DMA_INTR_ENA);
 
+	netif_tx_disable(dev);
+
 	/* Disable the MAC core */
 	xgmac_mac_disable(priv->base);
 
@@ -1370,11 +1370,8 @@ static int xgmac_change_mtu(struct net_device *dev, int new_mtu)
 	}
 
 	old_mtu = dev->mtu;
-	dev->mtu = new_mtu;
 
 	/* return early if the buffer sizes will not change */
-	if (old_mtu <= ETH_DATA_LEN && new_mtu <= ETH_DATA_LEN)
-		return 0;
 	if (old_mtu == new_mtu)
 		return 0;
 
@@ -1382,8 +1379,9 @@ static int xgmac_change_mtu(struct net_device *dev, int new_mtu)
 	if (!netif_running(dev))
 		return 0;
 
-	/* Bring the interface down and then back up */
+	/* Bring interface down, change mtu and bring interface back up */
 	xgmac_stop(dev);
+	dev->mtu = new_mtu;
 	return xgmac_open(dev);
 }
 
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH net-next 8/8] bonding: add arp_all_targets netlink support
From: Veaceslav Falico @ 2013-11-07 11:08 UTC (permalink / raw)
  To: Scott Feldman; +Cc: fubar, andy, netdev, shm
In-Reply-To: <20131107094344.15846.93348.stgit@monster-03.cumulusnetworks.com>

On Thu, Nov 07, 2013 at 01:43:44AM -0800, Scott Feldman wrote:
>Add IFLA_BOND_ARP_ALL_TARGETS to allow get/set of bonding parameter
>arp_all_targets via netlink.
>
>Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
>---
> drivers/net/bonding/bond_netlink.c |   14 ++++++++++++++
> drivers/net/bonding/bond_options.c |   11 +++++++++++
> drivers/net/bonding/bond_sysfs.c   |   16 ++++++++++------
> drivers/net/bonding/bonding.h      |    1 +
> include/uapi/linux/if_link.h       |    1 +
> 5 files changed, 37 insertions(+), 6 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
>index a5ca6e0..818a7ba 100644
>--- a/drivers/net/bonding/bond_netlink.c
>+++ b/drivers/net/bonding/bond_netlink.c
>@@ -31,6 +31,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
> 	[IFLA_BOND_ARP_INTERVAL]	= { .type = NLA_U32 },
> 	[IFLA_BOND_ARP_IP_TARGET]	= { .type = NLA_NESTED },
> 	[IFLA_BOND_ARP_VALIDATE]	= { .type = NLA_U32 },
>+	[IFLA_BOND_ARP_ALL_TARGETS]	= { .type = NLA_U32 },
> };
>
> static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
>@@ -133,6 +134,14 @@ static int bond_changelink(struct net_device *bond_dev,
> 		if (err)
> 			return err;
> 	}
>+	if (data[IFLA_BOND_ARP_ALL_TARGETS]) {
>+		int arp_all_targets =
>+			nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]);
>+
>+		err = bond_option_arp_all_targets_set(bond, arp_all_targets);
>+		if (err)
>+			return err;
>+	}
> 	return 0;
> }
>
>@@ -160,6 +169,7 @@ static size_t bond_get_size(const struct net_device *bond_dev)
> 						/* IFLA_BOND_ARP_IP_TARGET */
> 		nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS +
> 		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_ARP_VALIDATE */
>+		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_ARP_ALL_TARGETS */
> 		0;
> }
>
>@@ -215,6 +225,10 @@ static int bond_fill_info(struct sk_buff *skb,
> 	if (nla_put_u32(skb, IFLA_BOND_ARP_VALIDATE, bond->params.arp_validate))
> 		goto nla_put_failure;
>
>+	if (nla_put_u32(skb, IFLA_BOND_ARP_ALL_TARGETS,
>+		bond->params.arp_all_targets))

One more tab to align?

>+		goto nla_put_failure;
>+
> 	return 0;
>
> nla_put_failure:
>diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
>index 9c36215..543a318 100644
>--- a/drivers/net/bonding/bond_options.c
>+++ b/drivers/net/bonding/bond_options.c
>@@ -426,3 +426,14 @@ int bond_option_arp_validate_set(struct bonding *bond, int arp_validate)
>
> 	return 0;
> }
>+
>+int bond_option_arp_all_targets_set(struct bonding *bond, int arp_all_targets)
>+{
>+	pr_info("%s: setting arp_all_targets to %s (%d).\n",
>+		bond->dev->name, arp_all_targets_tbl[arp_all_targets].modename,
>+		arp_all_targets);
>+
>+	bond->params.arp_all_targets = arp_all_targets;
>+
>+	return 0;
>+}
>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>index 8a35440..a3cd27e 100644
>--- a/drivers/net/bonding/bond_sysfs.c
>+++ b/drivers/net/bonding/bond_sysfs.c
>@@ -408,7 +408,7 @@ static ssize_t bonding_store_arp_all_targets(struct device *d,
> 					  const char *buf, size_t count)
> {
> 	struct bonding *bond = to_bond(d);
>-	int new_value;
>+	int new_value, ret;
>
> 	new_value = bond_parse_parm(buf, arp_all_targets_tbl);
> 	if (new_value < 0) {
>@@ -416,13 +416,17 @@ static ssize_t bonding_store_arp_all_targets(struct device *d,
> 		       bond->dev->name, buf);
> 		return -EINVAL;
> 	}
>-	pr_info("%s: setting arp_all_targets to %s (%d).\n",
>-		bond->dev->name, arp_all_targets_tbl[new_value].modename,
>-		new_value);
>
>-	bond->params.arp_all_targets = new_value;
>+	if (!rtnl_trylock())
>+		return restart_syscall();
>
>-	return count;
>+	ret = bond_option_arp_all_targets_set(bond, new_value);
>+	if (!ret)
>+		ret = count;
>+
>+	rtnl_unlock();
>+
>+	return ret;
> }
>
> static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
>diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>index 77bbd71..ed35c8c 100644
>--- a/drivers/net/bonding/bonding.h
>+++ b/drivers/net/bonding/bonding.h
>@@ -437,6 +437,7 @@ int bond_option_arp_ip_target_set(struct bonding *bond, __be32 target);
> int bond_option_arp_ip_target_unset(struct bonding *bond, __be32 target);
> int bond_option_arp_ip_target_clear_all(struct bonding *bond);
> int bond_option_arp_validate_set(struct bonding *bond, int arp_validate);
>+int bond_option_arp_all_targets_set(struct bonding *bond, int arp_all_targets);
> struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
> struct net_device *bond_option_active_slave_get(struct bonding *bond);
>
>diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
>index c17f801..ca01850 100644
>--- a/include/uapi/linux/if_link.h
>+++ b/include/uapi/linux/if_link.h
>@@ -338,6 +338,7 @@ enum {
> 	IFLA_BOND_ARP_INTERVAL,
> 	IFLA_BOND_ARP_IP_TARGET,
> 	IFLA_BOND_ARP_VALIDATE,
>+	IFLA_BOND_ARP_ALL_TARGETS,
> 	__IFLA_BOND_MAX,
> };
>
>

^ permalink raw reply

* BCM57786 driver
From: Joshua Richenhagen @ 2013-11-07 11:12 UTC (permalink / raw)
  To: netdev

Hello everyone,

I recently bought a Acer Aspire E1-572 notebook with the gigabit
ethernet controller Broadcom Corporation NetXtreme BCM57786 builtin.
However I can't get it working under Ubuntu, neither with standard
kernel nor with newest mainline kernel 3.12 final. I doesn't seem to
be recognized at all, does a driver for this chip exists, or do I have
to wait till one gets released? How far is the developmend process?

Thanks in advance
Joshua

^ permalink raw reply

* [PATCH iproute2] bridge: trivial: Fix typo in error message (hairpin)
From: Guillaume Nault @ 2013-11-07 11:09 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

Option name is hairpin (without 'g').

Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
---
 bridge/link.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bridge/link.c b/bridge/link.c
index 38dfaea..a82cce0 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -271,7 +271,7 @@ static int brlink_modify(int argc, char **argv)
 				exit(-1);
 		} else if (strcmp(*argv, "hairpin") == 0) {
 			NEXT_ARG();
-			if (!on_off("hairping", &hairpin, *argv))
+			if (!on_off("hairpin", &hairpin, *argv))
 				exit(-1);
 		} else if (strcmp(*argv, "fastleave") == 0) {
 			NEXT_ARG();
-- 
1.8.4.2

^ permalink raw reply related

* Re: [PATCH net v3] vti: fix spd lookup: match plaintext pkt, not ipsec pkt
From: Steffen Klassert @ 2013-11-07 11:25 UTC (permalink / raw)
  To: Christophe Gouault
  Cc: David S. Miller, Herbert Xu, netdev, Saurabh Mohan,
	Sergei Shtylyov, Eric Dumazet
In-Reply-To: <1383725153-26298-1-git-send-email-christophe.gouault@6wind.com>

On Wed, Nov 06, 2013 at 09:05:53AM +0100, Christophe Gouault wrote:
> The vti interface inbound and outbound SPD lookups are based on the
> ipsec packet instead of the plaintext packet.
> 
> Not only is it counterintuitive, it also restricts vti interfaces
> to a single policy (whose selector must match the tunnel local and
> remote addresses).
> 
> The policy selector is supposed to match the plaintext packet, before
> encryption or after decryption.
> 
> This patch performs the SPD lookup based on the plaintext packet. It
> enables to create several polices bound to the vti interface (via a
> mark equal to the vti interface okey).
> 
> It remains possible to apply the same policy to all packets entering
> the vti interface, by setting an any-to-any selector (src 0.0.0.0/0
> dst 0.0.0.0/0 proto any mark OKEY).
> 
> Signed-off-by: Christophe Gouault <christophe.gouault@6wind.com>

Hm, this patch breaks my current vti test setup. I would need to
configure the policies and states dependent on the kernel version
if we apply this patch...

It would be good to hear from the original author of the vti code
whether the current behaviour is intentional before we do anything
here.

^ permalink raw reply

* Re: [patch] net: make ndev->irq signed for error handling
From: Mugunthan V N @ 2013-11-07 12:14 UTC (permalink / raw)
  To: Dan Carpenter, David S. Miller; +Cc: netdev, linux-kernel, kernel-janitors
In-Reply-To: <20131107074849.GF21844@elgon.mountain>

On Thursday 07 November 2013 01:18 PM, Dan Carpenter wrote:
> There is a bug in cpsw_probe() where we do:
>
> 	ndev->irq = platform_get_irq(pdev, 0);
> 	if (ndev->irq < 0) {
>
> The problem is that "ndev->irq" is unsigned so the error handling
> doesn't work.  I have changed it to a regular int.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
ndev->irq is never used any where in the driver, I think its better to
remove this part of code from probe. If every one is ok, I can send a
patch to remove the code.

Regards
Mugunthan V N

^ permalink raw reply

* xen-netback stable backport requests
From: Ian Campbell @ 2013-11-07 12:15 UTC (permalink / raw)
  To: David Miller; +Cc: xen-devel, netdev, stable

Hi Dave,

279f438e36c0 "xen-netback: Don't destroy the netdev until the vif is
shut down" has hit stable but unfortunately is causing regressions. 

This should be fixed by dc62ccaccfb1 "xen-netback: transition to CLOSED
when removing a VIF" which depends on ea732dff5cfa "xen-netback: Handle
backend state transitions in a more robust way".

Please could you queue hose two for stable.

Thanks,
Ian.

^ permalink raw reply

* xen-netback regression in 3.10.18
From: David Vrabel @ 2013-11-07 12:15 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: stable@vger.kernel.org, David S. Miller, Paul Durrant,
	Ian Campbell, Wei Liu

3.10.18 included 279f438e36c0 (xen-netback: Don't destroy the netdev
until the vif is shut down) but this has a regression that was fixed by
dc62ccaccfb1 (xen-netback: transition to CLOSED when removing a VIF)

dc62ccaccfb1 depends on ea732dff5cfa (xen-netback: Handle backend state
transitions in a more robust way) which is also a bug fix for certain
Windows frontend drivers and is thus also a stable candidate.

Dave can you ensure these two commits are tagged for the next 3.10.y
stable release?

  ea732dff5cfa10789007bf4a5b935388a0bb2a8f
  dc62ccaccfb139d9b04bbc5a2688a4402adbfab3

Thanks.

David

^ permalink raw reply

* Re: ipv6: a question about ECMP
From: Hannes Frederic Sowa @ 2013-11-07 12:16 UTC (permalink / raw)
  To: Duan Jiong; +Cc: David Miller, nicolas.dichtel, netdev
In-Reply-To: <527B6C70.3010507@cn.fujitsu.com>

Hi Duan!

On Thu, Nov 07, 2013 at 06:33:20PM +0800, Duan Jiong wrote:
>   After reading the ip6_pol_route(), i have a question about ECMP. Why we call
> the rt6_multipath_select() after calling rt6_select()?
>   In my opinion, the route returned by rt6_select() has a highest score, but the route
> returned by rt6_multipath_select() may has a lower score than the former, because the
> ECMP don't take the route preference into consideration. That means that the kernel will
> choose a less-desirable route.

ECMP routes only differ in the gateway the specify, so I doubt there will be
any change in the score they woud receive. rt6_multipath_select does merly
make sure we don't select the same route again and again.

Please note, the rt6_info's siblings fields were added for the solely purpose
of ECMP and the insertion only updates the siblings list if the above criteria
did hold. They make sure the routes lookup up do differ on each lookup, so it
does actually do multipath and does not depend on the order the routes where
inserted.

Hope that helps,

  Hannes

^ permalink raw reply

* Re: [PATCH] ipv6: replace RTF_ROUTEINFO with RTF_ADDRCONF in  rt6_get_route_info()
From: Hannes Frederic Sowa @ 2013-11-07 12:19 UTC (permalink / raw)
  To: Duan Jiong; +Cc: David Miller, netdev
In-Reply-To: <527B14B9.7040305@cn.fujitsu.com>

On Thu, Nov 07, 2013 at 12:19:05PM +0800, Duan Jiong wrote:
> 于 2013年11月07日 10:42, Hannes Frederic Sowa 写道:
> > On Thu, Nov 07, 2013 at 10:01:27AM +0800, Duan Jiong wrote:
> >> 于 2013年11月07日 09:51, Hannes Frederic Sowa 写道:
> >>> On Wed, Nov 06, 2013 at 03:26:41PM +0800, Duan Jiong wrote:
> >>>>
> >>>> As the rfc 4191 said, the Router Preference and Lifetime values in a
> >>>> ::/0 Route Information Option should override the preference and lifetime
> >>>> values in the Router Advertisement header. But when the kernel deals with
> >>>> a ::/0 Route Information Option, the rt6_get_route_info() always return
> >>>> NULL, that means that overriding will not happen, because those default
> >>>> routers were added without flag RTF_ROUTEINFO in rt6_add_dflt_router().
> >>>>
> >>>> In order to match those default routers, we can replace RTF_ROUTEINFO 
> >>>> with RTF_ADDRCONF in rt6_get_route_info().
> >>>>
> >>>> Signed-off-by: Duan Jiong <duanj.fnst@cn.fujitsu.com>
> >>>
> >>> Hmm, that looks like a bug. Nice catch!
> >>>
> >>> Couldn't we just replace the rt6_get_route_info in rt6_route_rcv with a call
> >>> to rt6_get_dflt_router? Seems easier, already handles the ::/0 case and also
> >>> does preserve the check for the RTF_ROUTEINFO flag in rt6_add_route_info.
> >>
> >> Yeah, your idea is better. I will modify my patch.
> > 
> > Stop, stop, stop, sorry that suggestion is plain wrong and stupid.
> > 
> 
> In my opinion, i think that is well. According to your suggestion, we can 
> call the rt6_get_dflt_router or rt6_get_route_info in different situation.
> 
> if (rinfo->prefix_len == 0)
> 	rt = rt6_get_dflt_router(gwaddr, dev);
> else
> 	rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr,
> 				dev->ifindex);

That's perfect.

Greetings,

  Hannes

^ permalink raw reply

* Re: [patch] net: make ndev->irq signed for error handling
From: Dan Carpenter @ 2013-11-07 12:22 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: David S. Miller, netdev, linux-kernel, kernel-janitors
In-Reply-To: <527B842E.2060909@ti.com>

On Thu, Nov 07, 2013 at 05:44:38PM +0530, Mugunthan V N wrote:
> On Thursday 07 November 2013 01:18 PM, Dan Carpenter wrote:
> > There is a bug in cpsw_probe() where we do:
> >
> > 	ndev->irq = platform_get_irq(pdev, 0);
> > 	if (ndev->irq < 0) {
> >
> > The problem is that "ndev->irq" is unsigned so the error handling
> > doesn't work.  I have changed it to a regular int.
> >
> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ndev->irq is never used any where in the driver, I think its better to
> remove this part of code from probe. If every one is ok, I can send a
> patch to remove the code.

It seems like cpsw_ndo_poll_controller() uses it.

regards,
dan carpenter

^ permalink raw reply

* Re: BCM57786 driver
From: Peter Meerwald @ 2013-11-07 12:36 UTC (permalink / raw)
  To: Joshua Richenhagen; +Cc: netdev
In-Reply-To: <CAJZ9B5s87PHb3=eAxOy1dDo59Tq8pQbR78-=_zyKt8-0g5tGdg@mail.gmail.com>

Hi,

> I recently bought a Acer Aspire E1-572 notebook with the gigabit
> ethernet controller Broadcom Corporation NetXtreme BCM57786 builtin.
> However I can't get it working under Ubuntu, neither with standard
> kernel nor with newest mainline kernel 3.12 final. I doesn't seem to
> be recognized at all, does a driver for this chip exists, or do I have
> to wait till one gets released? How far is the developmend process?

I have the same notebook and reported to the Ubuntu bug tracker 
(https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1182868)
solution for me is to add the PCI vendor/product IDs to the tg3 driver

there seems to be a fix in the upstream kernel, see 
http://patchwork.ozlabs.org/patch/276813/
already

hope the Ubuntu folk act on this

regards, p.


-- 

Peter Meerwald
+43-664-2444418 (mobile)

^ permalink raw reply

* Re: [patch net-next 2/2] netfilter: push reasm skb through instead of original frag skbs
From: Marcelo Ricardo Leitner @ 2013-11-07 12:52 UTC (permalink / raw)
  To: Jiri Pirko, netdev
  Cc: davem, pablo, netfilter-devel, yoshfuji, kadlec, kaber, kuznet,
	jmorris, wensong, horms, ja, edumazet, pshelar, jasowang,
	alexander.h.duyck, fw
In-Reply-To: <1383756740-7392-3-git-send-email-jiri@resnulli.us>

Em 06-11-2013 14:52, Jiri Pirko escreveu:
> Pushing original fragments through causes several problems. For example
> for matching, frags may not be matched correctly. Take following
> example:
>
> <example>
> On HOSTA do:
> ip6tables -I INPUT -p icmpv6 -j DROP
> ip6tables -I INPUT -p icmpv6 -m icmp6 --icmpv6-type 128 -j ACCEPT
>
> and on HOSTB you do:
> ping6 HOSTA -s2000    (MTU is 1500)
>
> Incoming echo requests will be filtered out on HOSTA. This issue does
> not occur with smaller packets than MTU (where fragmentation does not happen)
> </example>
>
> As was discussed previously, the only correct solution seems to be to use
> reassembled skb instead of separete frags. Doing this has positive side
          just a typo here   ------^

> effects in reducing sk_buff by one pointer (nfct_reasm) and also the reams
                                                          and here   ------^

> dances in ipvs and conntrack can be removed.
>
> Future plan is to remove net/ipv6/netfilter/nf_conntrack_reasm.c
> entirely and use code in net/ipv6/reassembly.c instead.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>

Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>

> ---
>   include/linux/skbuff.h                         | 32 ---------------
>   include/net/ip_vs.h                            | 32 +--------------
>   include/net/netfilter/ipv6/nf_defrag_ipv6.h    |  4 +-
>   net/core/skbuff.c                              |  3 --
>   net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 56 +-------------------------
>   net/ipv6/netfilter/nf_conntrack_reasm.c        | 19 +--------
>   net/ipv6/netfilter/nf_defrag_ipv6_hooks.c      |  7 +++-
>   net/netfilter/ipvs/ip_vs_core.c                | 55 +------------------------
>   net/netfilter/ipvs/ip_vs_pe_sip.c              |  8 +---
>   9 files changed, 13 insertions(+), 203 deletions(-)
>
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index 2e153b6..8351614 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -337,11 +337,6 @@ typedef unsigned int sk_buff_data_t;
>   typedef unsigned char *sk_buff_data_t;
>   #endif
>
> -#if defined(CONFIG_NF_DEFRAG_IPV4) || defined(CONFIG_NF_DEFRAG_IPV4_MODULE) || \
> -    defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
> -#define NET_SKBUFF_NF_DEFRAG_NEEDED 1
> -#endif
> -
>   /**
>    *	struct sk_buff - socket buffer
>    *	@next: Next buffer in list
> @@ -374,7 +369,6 @@ typedef unsigned char *sk_buff_data_t;
>    *	@protocol: Packet protocol from driver
>    *	@destructor: Destruct function
>    *	@nfct: Associated connection, if any
> - *	@nfct_reasm: netfilter conntrack re-assembly pointer
>    *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
>    *	@skb_iif: ifindex of device we arrived on
>    *	@tc_index: Traffic control index
> @@ -463,9 +457,6 @@ struct sk_buff {
>   #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
>   	struct nf_conntrack	*nfct;
>   #endif
> -#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
> -	struct sk_buff		*nfct_reasm;
> -#endif
>   #ifdef CONFIG_BRIDGE_NETFILTER
>   	struct nf_bridge_info	*nf_bridge;
>   #endif
> @@ -2594,18 +2585,6 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
>   		atomic_inc(&nfct->use);
>   }
>   #endif
> -#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
> -static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
> -{
> -	if (skb)
> -		atomic_inc(&skb->users);
> -}
> -static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
> -{
> -	if (skb)
> -		kfree_skb(skb);
> -}
> -#endif
>   #ifdef CONFIG_BRIDGE_NETFILTER
>   static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
>   {
> @@ -2624,10 +2603,6 @@ static inline void nf_reset(struct sk_buff *skb)
>   	nf_conntrack_put(skb->nfct);
>   	skb->nfct = NULL;
>   #endif
> -#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
> -	nf_conntrack_put_reasm(skb->nfct_reasm);
> -	skb->nfct_reasm = NULL;
> -#endif
>   #ifdef CONFIG_BRIDGE_NETFILTER
>   	nf_bridge_put(skb->nf_bridge);
>   	skb->nf_bridge = NULL;
> @@ -2649,10 +2624,6 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
>   	nf_conntrack_get(src->nfct);
>   	dst->nfctinfo = src->nfctinfo;
>   #endif
> -#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
> -	dst->nfct_reasm = src->nfct_reasm;
> -	nf_conntrack_get_reasm(src->nfct_reasm);
> -#endif
>   #ifdef CONFIG_BRIDGE_NETFILTER
>   	dst->nf_bridge  = src->nf_bridge;
>   	nf_bridge_get(src->nf_bridge);
> @@ -2664,9 +2635,6 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src)
>   #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
>   	nf_conntrack_put(dst->nfct);
>   #endif
> -#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
> -	nf_conntrack_put_reasm(dst->nfct_reasm);
> -#endif
>   #ifdef CONFIG_BRIDGE_NETFILTER
>   	nf_bridge_put(dst->nf_bridge);
>   #endif
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index cd7275f..5679d92 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -109,7 +109,6 @@ extern int ip_vs_conn_tab_size;
>   struct ip_vs_iphdr {
>   	__u32 len;	/* IPv4 simply where L4 starts
>   			   IPv6 where L4 Transport Header starts */
> -	__u32 thoff_reasm; /* Transport Header Offset in nfct_reasm skb */
>   	__u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/
>   	__s16 protocol;
>   	__s32 flags;
> @@ -117,34 +116,12 @@ struct ip_vs_iphdr {
>   	union nf_inet_addr daddr;
>   };
>
> -/* Dependency to module: nf_defrag_ipv6 */
> -#if defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
> -static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
> -{
> -	return skb->nfct_reasm;
> -}
> -static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
> -				      int len, void *buffer,
> -				      const struct ip_vs_iphdr *ipvsh)
> -{
> -	if (unlikely(ipvsh->fragoffs && skb_nfct_reasm(skb)))
> -		return skb_header_pointer(skb_nfct_reasm(skb),
> -					  ipvsh->thoff_reasm, len, buffer);
> -
> -	return skb_header_pointer(skb, offset, len, buffer);
> -}
> -#else
> -static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
> -{
> -	return NULL;
> -}
>   static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
>   				      int len, void *buffer,
>   				      const struct ip_vs_iphdr *ipvsh)
>   {
>   	return skb_header_pointer(skb, offset, len, buffer);
>   }
> -#endif
>
>   static inline void
>   ip_vs_fill_ip4hdr(const void *nh, struct ip_vs_iphdr *iphdr)
> @@ -171,19 +148,12 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr)
>   			(struct ipv6hdr *)skb_network_header(skb);
>   		iphdr->saddr.in6 = iph->saddr;
>   		iphdr->daddr.in6 = iph->daddr;
> -		/* ipv6_find_hdr() updates len, flags, thoff_reasm */
> -		iphdr->thoff_reasm = 0;
> +		/* ipv6_find_hdr() updates len, flags */
>   		iphdr->len	 = 0;
>   		iphdr->flags	 = 0;
>   		iphdr->protocol  = ipv6_find_hdr(skb, &iphdr->len, -1,
>   						 &iphdr->fragoffs,
>   						 &iphdr->flags);
> -		/* get proto from re-assembled packet and it's offset */
> -		if (skb_nfct_reasm(skb))
> -			iphdr->protocol = ipv6_find_hdr(skb_nfct_reasm(skb),
> -							&iphdr->thoff_reasm,
> -							-1, NULL, NULL);
> -
>   	} else
>   #endif
>   	{
> diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
> index 5613412..27666d8 100644
> --- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h
> +++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
> @@ -6,9 +6,7 @@ void nf_defrag_ipv6_enable(void);
>   int nf_ct_frag6_init(void);
>   void nf_ct_frag6_cleanup(void);
>   struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
> -void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
> -			struct net_device *in, struct net_device *out,
> -			int (*okfn)(struct sk_buff *));
> +void nf_ct_frag6_consume_orig(struct sk_buff *skb);
>
>   struct inet_frags_ctl;
>
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 3735fad..e55e10a 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -592,9 +592,6 @@ static void skb_release_head_state(struct sk_buff *skb)
>   #if IS_ENABLED(CONFIG_NF_CONNTRACK)
>   	nf_conntrack_put(skb->nfct);
>   #endif
> -#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
> -	nf_conntrack_put_reasm(skb->nfct_reasm);
> -#endif
>   #ifdef CONFIG_BRIDGE_NETFILTER
>   	nf_bridge_put(skb->nf_bridge);
>   #endif
> diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> index 486545e..4cbc6b2 100644
> --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
> @@ -169,64 +169,13 @@ out:
>   	return nf_conntrack_confirm(skb);
>   }
>
> -static unsigned int __ipv6_conntrack_in(struct net *net,
> -					unsigned int hooknum,
> -					struct sk_buff *skb,
> -					const struct net_device *in,
> -					const struct net_device *out,
> -					int (*okfn)(struct sk_buff *))
> -{
> -	struct sk_buff *reasm = skb->nfct_reasm;
> -	const struct nf_conn_help *help;
> -	struct nf_conn *ct;
> -	enum ip_conntrack_info ctinfo;
> -
> -	/* This packet is fragmented and has reassembled packet. */
> -	if (reasm) {
> -		/* Reassembled packet isn't parsed yet ? */
> -		if (!reasm->nfct) {
> -			unsigned int ret;
> -
> -			ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
> -			if (ret != NF_ACCEPT)
> -				return ret;
> -		}
> -
> -		/* Conntrack helpers need the entire reassembled packet in the
> -		 * POST_ROUTING hook. In case of unconfirmed connections NAT
> -		 * might reassign a helper, so the entire packet is also
> -		 * required.
> -		 */
> -		ct = nf_ct_get(reasm, &ctinfo);
> -		if (ct != NULL && !nf_ct_is_untracked(ct)) {
> -			help = nfct_help(ct);
> -			if ((help && help->helper) || !nf_ct_is_confirmed(ct)) {
> -				nf_conntrack_get_reasm(reasm);
> -				NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
> -					       (struct net_device *)in,
> -					       (struct net_device *)out,
> -					       okfn, NF_IP6_PRI_CONNTRACK + 1);
> -				return NF_DROP_ERR(-ECANCELED);
> -			}
> -		}
> -
> -		nf_conntrack_get(reasm->nfct);
> -		skb->nfct = reasm->nfct;
> -		skb->nfctinfo = reasm->nfctinfo;
> -		return NF_ACCEPT;
> -	}
> -
> -	return nf_conntrack_in(net, PF_INET6, hooknum, skb);
> -}
> -
>   static unsigned int ipv6_conntrack_in(const struct nf_hook_ops *ops,
>   				      struct sk_buff *skb,
>   				      const struct net_device *in,
>   				      const struct net_device *out,
>   				      int (*okfn)(struct sk_buff *))
>   {
> -	return __ipv6_conntrack_in(dev_net(in), ops->hooknum, skb, in, out,
> -				   okfn);
> +	return nf_conntrack_in(dev_net(in), PF_INET6, ops->hooknum, skb);
>   }
>
>   static unsigned int ipv6_conntrack_local(const struct nf_hook_ops *ops,
> @@ -240,8 +189,7 @@ static unsigned int ipv6_conntrack_local(const struct nf_hook_ops *ops,
>   		net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
>   		return NF_ACCEPT;
>   	}
> -	return __ipv6_conntrack_in(dev_net(out), ops->hooknum, skb, in, out,
> -				   okfn);
> +	return nf_conntrack_in(dev_net(out), PF_INET6, ops->hooknum, skb);
>   }
>
>   static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
> diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
> index 4a25826..767ab8d 100644
> --- a/net/ipv6/netfilter/nf_conntrack_reasm.c
> +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
> @@ -633,31 +633,16 @@ ret_orig:
>   	return skb;
>   }
>
> -void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
> -			struct net_device *in, struct net_device *out,
> -			int (*okfn)(struct sk_buff *))
> +void nf_ct_frag6_consume_orig(struct sk_buff *skb)
>   {
>   	struct sk_buff *s, *s2;
> -	unsigned int ret = 0;
>
>   	for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
> -		nf_conntrack_put_reasm(s->nfct_reasm);
> -		nf_conntrack_get_reasm(skb);
> -		s->nfct_reasm = skb;
> -
>   		s2 = s->next;
>   		s->next = NULL;
> -
> -		if (ret != -ECANCELED)
> -			ret = NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s,
> -					     in, out, okfn,
> -					     NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
> -		else
> -			kfree_skb(s);
> -
> +		consume_skb(s);
>   		s = s2;
>   	}
> -	nf_conntrack_put_reasm(skb);
>   }
>
>   static int nf_ct_net_init(struct net *net)
> diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
> index ec483aa..7b9a748 100644
> --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
> +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
> @@ -75,8 +75,11 @@ static unsigned int ipv6_defrag(const struct nf_hook_ops *ops,
>   	if (reasm == skb)
>   		return NF_ACCEPT;
>
> -	nf_ct_frag6_output(ops->hooknum, reasm, (struct net_device *)in,
> -			   (struct net_device *)out, okfn);
> +	nf_ct_frag6_consume_orig(reasm);
> +
> +	NF_HOOK_THRESH(NFPROTO_IPV6, ops->hooknum, reasm,
> +		       (struct net_device *) in, (struct net_device *) out,
> +		       okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
>
>   	return NF_STOLEN;
>   }
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index 34fda62..4f26ee4 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -1139,12 +1139,6 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
>   	ip_vs_fill_iph_skb(af, skb, &iph);
>   #ifdef CONFIG_IP_VS_IPV6
>   	if (af == AF_INET6) {
> -		if (!iph.fragoffs && skb_nfct_reasm(skb)) {
> -			struct sk_buff *reasm = skb_nfct_reasm(skb);
> -			/* Save fw mark for coming frags */
> -			reasm->ipvs_property = 1;
> -			reasm->mark = skb->mark;
> -		}
>   		if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
>   			int related;
>   			int verdict = ip_vs_out_icmp_v6(skb, &related,
> @@ -1614,12 +1608,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
>
>   #ifdef CONFIG_IP_VS_IPV6
>   	if (af == AF_INET6) {
> -		if (!iph.fragoffs && skb_nfct_reasm(skb)) {
> -			struct sk_buff *reasm = skb_nfct_reasm(skb);
> -			/* Save fw mark for coming frags. */
> -			reasm->ipvs_property = 1;
> -			reasm->mark = skb->mark;
> -		}
>   		if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
>   			int related;
>   			int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum,
> @@ -1671,9 +1659,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
>   		/* sorry, all this trouble for a no-hit :) */
>   		IP_VS_DBG_PKT(12, af, pp, skb, 0,
>   			      "ip_vs_in: packet continues traversal as normal");
> -		if (iph.fragoffs && !skb_nfct_reasm(skb)) {
> +		if (iph.fragoffs) {
>   			/* Fragment that couldn't be mapped to a conn entry
> -			 * and don't have any pointer to a reasm skb
>   			 * is missing module nf_defrag_ipv6
>   			 */
>   			IP_VS_DBG_RL("Unhandled frag, load nf_defrag_ipv6\n");
> @@ -1756,38 +1743,6 @@ ip_vs_local_request4(const struct nf_hook_ops *ops, struct sk_buff *skb,
>   #ifdef CONFIG_IP_VS_IPV6
>
>   /*
> - * AF_INET6 fragment handling
> - * Copy info from first fragment, to the rest of them.
> - */
> -static unsigned int
> -ip_vs_preroute_frag6(const struct nf_hook_ops *ops, struct sk_buff *skb,
> -		     const struct net_device *in,
> -		     const struct net_device *out,
> -		     int (*okfn)(struct sk_buff *))
> -{
> -	struct sk_buff *reasm = skb_nfct_reasm(skb);
> -	struct net *net;
> -
> -	/* Skip if not a "replay" from nf_ct_frag6_output or first fragment.
> -	 * ipvs_property is set when checking first fragment
> -	 * in ip_vs_in() and ip_vs_out().
> -	 */
> -	if (reasm)
> -		IP_VS_DBG(2, "Fragment recv prop:%d\n", reasm->ipvs_property);
> -	if (!reasm || !reasm->ipvs_property)
> -		return NF_ACCEPT;
> -
> -	net = skb_net(skb);
> -	if (!net_ipvs(net)->enable)
> -		return NF_ACCEPT;
> -
> -	/* Copy stored fw mark, saved in ip_vs_{in,out} */
> -	skb->mark = reasm->mark;
> -
> -	return NF_ACCEPT;
> -}
> -
> -/*
>    *	AF_INET6 handler in NF_INET_LOCAL_IN chain
>    *	Schedule and forward packets from remote clients
>    */
> @@ -1924,14 +1879,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
>   		.priority	= 100,
>   	},
>   #ifdef CONFIG_IP_VS_IPV6
> -	/* After mangle & nat fetch 2:nd fragment and following */
> -	{
> -		.hook		= ip_vs_preroute_frag6,
> -		.owner		= THIS_MODULE,
> -		.pf		= NFPROTO_IPV6,
> -		.hooknum	= NF_INET_PRE_ROUTING,
> -		.priority	= NF_IP6_PRI_NAT_DST + 1,
> -	},
>   	/* After packet filtering, change source only for VS/NAT */
>   	{
>   		.hook		= ip_vs_reply6,
> diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c
> index 9ef22bd..bed5f70 100644
> --- a/net/netfilter/ipvs/ip_vs_pe_sip.c
> +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c
> @@ -65,7 +65,6 @@ static int get_callid(const char *dptr, unsigned int dataoff,
>   static int
>   ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb)
>   {
> -	struct sk_buff *reasm = skb_nfct_reasm(skb);
>   	struct ip_vs_iphdr iph;
>   	unsigned int dataoff, datalen, matchoff, matchlen;
>   	const char *dptr;
> @@ -79,15 +78,10 @@ ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb)
>   	/* todo: IPv6 fragments:
>   	 *       I think this only should be done for the first fragment. /HS
>   	 */
> -	if (reasm) {
> -		skb = reasm;
> -		dataoff = iph.thoff_reasm + sizeof(struct udphdr);
> -	} else
> -		dataoff = iph.len + sizeof(struct udphdr);
> +	dataoff = iph.len + sizeof(struct udphdr);
>
>   	if (dataoff >= skb->len)
>   		return -EINVAL;
> -	/* todo: Check if this will mess-up the reasm skb !!! /HS */
>   	retc = skb_linearize(skb);
>   	if (retc < 0)
>   		return retc;
>


^ permalink raw reply

* Re: [PATCH net v3] vti: fix spd lookup: match plaintext pkt, not ipsec pkt
From: Christophe Gouault @ 2013-11-07 12:55 UTC (permalink / raw)
  To: Steffen Klassert
  Cc: David S. Miller, Herbert Xu, netdev, Saurabh Mohan,
	Sergei Shtylyov, Eric Dumazet
In-Reply-To: <20131107112549.GP31491@secunet.com>

Hello Steffen,

I am also interested in knowing Saurabh's intentions regarding the 
behavior of policies bound to vti interfaces.

However, please note that setting a policy with a wildcard selector 
works in both cases (before or after this patch), so a common test case 
can be defined.

Actually the *previous* patch on vti (7263a5187f9e vti: get rid of nf 
mark rule in prerouting) introduced significant changes, and implies 
behaviors dependant on the kernel version, but it seemed to meet 
Saurabh's agreement, as the following thread witnesses:

http://www.spinics.net/lists/netdev/msg253134.html

Best Regards,
Christophe

On 11/07/2013 12:25 PM, Steffen Klassert wrote:
> On Wed, Nov 06, 2013 at 09:05:53AM +0100, Christophe Gouault wrote:
>> The vti interface inbound and outbound SPD lookups are based on the
>> ipsec packet instead of the plaintext packet.
>>
>> Not only is it counterintuitive, it also restricts vti interfaces
>> to a single policy (whose selector must match the tunnel local and
>> remote addresses).
>>
>> The policy selector is supposed to match the plaintext packet, before
>> encryption or after decryption.
>>
>> This patch performs the SPD lookup based on the plaintext packet. It
>> enables to create several polices bound to the vti interface (via a
>> mark equal to the vti interface okey).
>>
>> It remains possible to apply the same policy to all packets entering
>> the vti interface, by setting an any-to-any selector (src 0.0.0.0/0
>> dst 0.0.0.0/0 proto any mark OKEY).
>>
>> Signed-off-by: Christophe Gouault <christophe.gouault@6wind.com>
> Hm, this patch breaks my current vti test setup. I would need to
> configure the policies and states dependent on the kernel version
> if we apply this patch...
>
> It would be good to hear from the original author of the vti code
> whether the current behaviour is intentional before we do anything
> here.

^ permalink raw reply

* Re: [PATCH net-next 6/8] bonding: add arp_ip_target netlink support
From: Jiri Pirko @ 2013-11-07 12:56 UTC (permalink / raw)
  To: Scott Feldman; +Cc: vfalico, fubar, andy, netdev, shm
In-Reply-To: <C580A3C6-BF26-4316-A6F5-6DB02319B100@cumulusnetworks.com>

Thu, Nov 07, 2013 at 11:56:35AM CET, sfeldma@cumulusnetworks.com wrote:
>
>On Nov 7, 2013, at 12:16 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>
>> Thu, Nov 07, 2013 at 10:43:30AM CET, sfeldma@cumulusnetworks.com wrote:
>>> Add IFLA_BOND_ARP_IP_TARGET to allow get/set of bonding parameter
>>> arp_ip_target via netlink.
>>> 
>>> Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
>>> ---
>>> drivers/net/bonding/bond_netlink.c |   43 ++++++++++++++-
>>> drivers/net/bonding/bond_options.c |  102 ++++++++++++++++++++++++++++++++++++
>>> drivers/net/bonding/bond_sysfs.c   |   77 +++------------------------
>>> drivers/net/bonding/bonding.h      |    3 +
>>> include/uapi/linux/if_link.h       |    1 
>>> 5 files changed, 155 insertions(+), 71 deletions(-)
>>> 
>>> diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
>>> index 9c50165..e4673ba 100644
>>> --- a/drivers/net/bonding/bond_netlink.c
>>> +++ b/drivers/net/bonding/bond_netlink.c
>>> @@ -29,6 +29,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
>>> 	[IFLA_BOND_DOWNDELAY]		= { .type = NLA_U32 },
>>> 	[IFLA_BOND_USE_CARRIER]		= { .type = NLA_U8 },
>>> 	[IFLA_BOND_ARP_INTERVAL]	= { .type = NLA_U32 },
>>> +	[IFLA_BOND_ARP_IP_TARGET]	= { .type = NLA_NESTED },
>>> };
>>> 
>>> static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
>>> @@ -109,6 +110,21 @@ static int bond_changelink(struct net_device *bond_dev,
>>> 		if (err)
>>> 			return err;
>>> 	}
>>> +	if (data[IFLA_BOND_ARP_IP_TARGET]) {
>>> +		struct nlattr *attr;
>>> +		int rem;
>>> +
>>> +		err = bond_option_arp_ip_target_clear_all(bond);
>>> +		if (err)
>>> +			return err;
>>> +
>> 
>> Hmm. I think this is not correct. I think you should not clear all. They
>> might be needed to be used but for a brief moment, they disappear.
>> 
>> Just set or unset them one by one.
>
>That’s a good catch.  I should compare existing set with new set and retain entries entries common to both sets (and add/remove uncommon ones).
>
>Just to be clear, for netlink, the idea is to push a set of ip targets addrs as a nested attribute and process as a set.  This is consistent with arp_ip_target documentation in Documentation/networking/bonding.txt where arp_ip_target is passed as a comma-separated list of addrs.  However, it’s not consistent with the sysfs interface where addrs are added/removed one at a time using “+” or “-“ prefix.

I believe that the behaviour you described is ok.

>
>e.g.:
>
>ip link add bond7 type bond mode 1
>ip link set dev bond7 type bond arp_ip_target 10.0.0.1,10.0.0.5
>ip link set dev bond7 type bond arp_ip_target 10.0.0.1
>
>
>>> @@ -141,6 +159,8 @@ static int bond_fill_info(struct sk_buff *skb,
>>> {
>>> 	struct bonding *bond = netdev_priv(bond_dev);
>>> 	struct net_device *slave_dev = bond_option_active_slave_get(bond);
>>> +	struct nlattr *targets;
>>> +	int i, targets_added;
>>> 
>>> 	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
>>> 		goto nla_put_failure;
>>> @@ -152,10 +172,12 @@ static int bond_fill_info(struct sk_buff *skb,
>>> 	if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
>>> 		goto nla_put_failure;
>>> 
>>> -	if (nla_put_u32(skb, IFLA_BOND_UPDELAY, bond->params.updelay))
>>> +	if (nla_put_u32(skb, IFLA_BOND_UPDELAY,
>>> +		bond->params.updelay * bond->params.miimon))
>>> 		goto nla_put_failure;
>> 
>> 	This bit should probably no be here :)
>
>Drats, that change goes with earlier patch.  I’ll fix on patch set resend for issue above.
>
>-scott

^ permalink raw reply

* Using HTB over MultiQ
From: Anton 'EvilMan' Danilov @ 2013-11-07 13:12 UTC (permalink / raw)
  To: netdev

Hello.

I'm experimenting with high performance linux router with 10G NICs.
On high traffic rates the performance are limited by the lock of root
queue discipline. For avoid impact of locking i've decided to build
QoS scheme over the multiq qdisc.

And I have the issues with use to multiq discipline.

My setup:
1. Multiq qdisc is on top of interface.
2. To every multiq class i've attached htb discipline with own
hierachy of child classes.
3. The filters (u32 with hashing) are attached to the root multiq discipline.

Graphical scheme of hierarchy -
http://pixpin.ru/images/2013/11/07/multiq-hierarchy1.png

Fragments of script:

#add top qdisc and classes
 qdisc add dev eth0 root handle 10: multiq
 qdisc add dev eth0 parent 10:1 handle 11: htb
 class add dev eth0 parent 11: classid 11:1 htb rate 1250Mbit
 qdisc add dev eth0 parent 10:2 handle 12: htb
 class add dev eth0 parent 12: classid 12:1 htb rate 1250Mbit
 qdisc add dev eth0 parent 10:3 handle 13: htb
 class add dev eth0 parent 13: classid 13:1 htb rate 1250Mbit
 qdisc add dev eth0 parent 10:4 handle 14: htb
 class add dev eth0 parent 14: classid 14:1 htb rate 1250Mbit
 qdisc add dev eth0 parent 10:5 handle 15: htb
 class add dev eth0 parent 15: classid 15:1 htb rate 1250Mbit
 qdisc add dev eth0 parent 10:6 handle 16: htb
 class add dev eth0 parent 16: classid 16:1 htb rate 1250Mbit
 qdisc add dev eth0 parent 10:7 handle 17: htb
 class add dev eth0 parent 17: classid 17:1 htb rate 1250Mbit
 qdisc add dev eth0 parent 10:8 handle 18: htb
 class add dev eth0 parent 18: classid 18:1 htb rate 1250Mbit

#add leaf classes and qdiscs (several hundreds)
 ...
 class add dev eth0 parent 11:1 classid 11:1736 htb rate 1024kbit
 qdisc add dev eth0 parent 11:1736 handle 1736 pfifo limit 50
 ...

But I see zero statistics on the leaf htb classes and nonzero
statistics on the classifier filters:

~$ tc -s -p filter list dev eth1
 ...
 filter parent 10: protocol ip pref 5 u32 fh 2:f2:800 order 2048 key
ht 2 bkt f2 flowid 11:1736  (rule hit 306 success 306)
   match IP src xx.xx.xx.xx/30 (success 306 )
 ...

~$ tc -s -s -d c ls dev eth1 classid 11:1736
 class htb 11:1736 parent 11:1 leaf 1736: prio 0 quantum 12800 rate
1024Kbit ceil 1024Kbit burst 1599b/1 mpu 0b overhead 0b cburst 1599b/1
mpu 0b overhead 0b level 0
  Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
  rate 0bit 0pps backlog 0b 0p requeues 0
  lended: 0 borrowed: 0 giants: 0
  tokens: 195312 ctokens: 195312

I think I've lost from view the some aspects of settings.
Has anyone setuped the like complex scheme over the multiq discipline?



-- 
Anton.

^ permalink raw reply

* [PATCHv2 next-next 2/3] caif: use pskb_put() instead of reimplementing its functionality
From: Mathias Krause @ 2013-11-07 13:18 UTC (permalink / raw)
  To: David S. Miller, Steffen Klassert, Herbert Xu
  Cc: Dmitry Tarnyagin, Ben Hutchings, Eric Dumazet, netdev,
	Mathias Krause, David S. Miller
In-Reply-To: <1383830306-16697-1-git-send-email-mathias.krause@secunet.com>

Also remove the warning for fragmented packets -- skb_cow_data() will
linearize the buffer, removing all fragments.

Signed-off-by: Mathias Krause <mathias.krause@secunet.com>
Cc: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
Cc: "David S. Miller" <davem@davemloft.net>
---
 net/caif/cfpkt_skbuff.c |   12 +-----------
 1 files changed, 1 insertions(+), 11 deletions(-)

diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
index 6493351..1be0b52 100644
--- a/net/caif/cfpkt_skbuff.c
+++ b/net/caif/cfpkt_skbuff.c
@@ -203,20 +203,10 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len)
 			PKT_ERROR(pkt, "cow failed\n");
 			return -EPROTO;
 		}
-		/*
-		 * Is the SKB non-linear after skb_cow_data()? If so, we are
-		 * going to add data to the last SKB, so we need to adjust
-		 * lengths of the top SKB.
-		 */
-		if (lastskb != skb) {
-			pr_warn("Packet is non-linear\n");
-			skb->len += len;
-			skb->data_len += len;
-		}
 	}
 
 	/* All set to put the last SKB and optionally write data there. */
-	to = skb_put(lastskb, len);
+	to = pskb_put(skb, lastskb, len);
 	if (likely(data))
 		memcpy(to, data, len);
 	return 0;
-- 
1.7.2.3

^ permalink raw reply related

* [PATCHv2 next-next 0/3] move pskb_put (was: IPsec improvements)
From: Mathias Krause @ 2013-11-07 13:18 UTC (permalink / raw)
  To: David S. Miller, Steffen Klassert, Herbert Xu
  Cc: Dmitry Tarnyagin, Ben Hutchings, Eric Dumazet, netdev,
	Mathias Krause

This series moves pskb_put() to the core code, making the code
duplication in caif obsolete (patches 1 and 2).
Patch 3 fixes a few kernel-doc issues.

v2 of this series does no longer contain the skb_cow_data() patch and
therefore no performance improvements for IPsec. The change is still
under discussion, but otherwise independent from the above changes.

Please apply!

v2:
- kernel-doc fixes for pskb_put, as noticed by Ben
- dropped skb_cow_data patch as it's still discussed
- added a kernel-doc fixes patch (patch 3)

Mathias Krause (3):
  net: move pskb_put() to core code
  caif: use pskb_put() instead of reimplementing its functionality
  net: skbuff - kernel-doc fixes

 include/linux/skbuff.h  |    3 ++-
 include/net/esp.h       |    2 --
 net/caif/cfpkt_skbuff.c |   12 +-----------
 net/core/skbuff.c       |   33 ++++++++++++++++++++++++++++-----
 net/xfrm/xfrm_algo.c    |   13 -------------
 5 files changed, 31 insertions(+), 32 deletions(-)

-- 
1.7.2.3

^ permalink raw reply

* [PATCHv2 next-next 3/3] net: skbuff - kernel-doc fixes
From: Mathias Krause @ 2013-11-07 13:18 UTC (permalink / raw)
  To: David S. Miller, Steffen Klassert, Herbert Xu
  Cc: Dmitry Tarnyagin, Ben Hutchings, Eric Dumazet, netdev,
	Mathias Krause, David S. Miller
In-Reply-To: <1383830306-16697-1-git-send-email-mathias.krause@secunet.com>

Use "@" to refer to parameters in the kernel-doc description. According
to Documentation/kernel-doc-nano-HOWTO.txt "&" shall be used to refer to
structures only.

Signed-off-by: Mathias Krause <mathias.krause@secunet.com>
Cc: "David S. Miller" <davem@davemloft.net>
---
 include/linux/skbuff.h |    2 +-
 net/core/skbuff.c      |   10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 491dd6c..036ec7d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1357,7 +1357,7 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
  * @size: the length of the data
  *
  * As per __skb_fill_page_desc() -- initialises the @i'th fragment of
- * @skb to point to &size bytes at offset @off within @page. In
+ * @skb to point to @size bytes at offset @off within @page. In
  * addition updates @skb such that @i is the last fragment.
  *
  * Does not take any additional reference on the fragment.
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2fbea08..8c5197f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1051,8 +1051,8 @@ EXPORT_SYMBOL(__pskb_copy);
  *	@ntail: room to add at tail
  *	@gfp_mask: allocation priority
  *
- *	Expands (or creates identical copy, if &nhead and &ntail are zero)
- *	header of skb. &sk_buff itself is not changed. &sk_buff MUST have
+ *	Expands (or creates identical copy, if @nhead and @ntail are zero)
+ *	header of @skb. &sk_buff itself is not changed. &sk_buff MUST have
  *	reference count of 1. Returns zero in the case of success or error,
  *	if expansion failed. In the last case, &sk_buff is not changed.
  *
@@ -2563,14 +2563,14 @@ EXPORT_SYMBOL(skb_prepare_seq_read);
  * @data: destination pointer for data to be returned
  * @st: state variable
  *
- * Reads a block of skb data at &consumed relative to the
+ * Reads a block of skb data at @consumed relative to the
  * lower offset specified to skb_prepare_seq_read(). Assigns
- * the head of the data block to &data and returns the length
+ * the head of the data block to @data and returns the length
  * of the block or 0 if the end of the skb data or the upper
  * offset has been reached.
  *
  * The caller is not required to consume all of the data
- * returned, i.e. &consumed is typically set to the number
+ * returned, i.e. @consumed is typically set to the number
  * of bytes already consumed and the next call to
  * skb_seq_read() will return the remaining part of the block.
  *
-- 
1.7.2.3

^ permalink raw reply related

* [PATCHv2 next-next 1/3] net: move pskb_put() to core code
From: Mathias Krause @ 2013-11-07 13:18 UTC (permalink / raw)
  To: David S. Miller, Steffen Klassert, Herbert Xu
  Cc: Dmitry Tarnyagin, Ben Hutchings, Eric Dumazet, netdev,
	Mathias Krause, Steffen Klassert, David S. Miller, Herbert Xu
In-Reply-To: <1383830306-16697-1-git-send-email-mathias.krause@secunet.com>

This function has usage beside IPsec so move it to the core skbuff code.
While doing so, give it some documentation and change its return type to
'unsigned char *' to be in line with skb_put().

Signed-off-by: Mathias Krause <mathias.krause@secunet.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
---
v2: kernel-doc fixes, as noticed by Ben

 include/linux/skbuff.h |    1 +
 include/net/esp.h      |    2 --
 net/core/skbuff.c      |   23 +++++++++++++++++++++++
 net/xfrm/xfrm_algo.c   |   13 -------------
 4 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2e153b6..491dd6c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1417,6 +1417,7 @@ static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
 /*
  *	Add data to an sk_buff
  */
+unsigned char *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
 unsigned char *skb_put(struct sk_buff *skb, unsigned int len);
 static inline unsigned char *__skb_put(struct sk_buff *skb, unsigned int len)
 {
diff --git a/include/net/esp.h b/include/net/esp.h
index c92213c..a43be85 100644
--- a/include/net/esp.h
+++ b/include/net/esp.h
@@ -3,8 +3,6 @@
 
 #include <linux/skbuff.h>
 
-void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len);
-
 struct ip_esp_hdr;
 
 static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3735fad..2fbea08 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1264,6 +1264,29 @@ free_skb:
 EXPORT_SYMBOL(skb_pad);
 
 /**
+ *	pskb_put - add data to the tail of a potentially fragmented buffer
+ *	@skb: start of the buffer to use
+ *	@tail: tail fragment of the buffer to use
+ *	@len: amount of data to add
+ *
+ *	This function extends the used data area of the potentially
+ *	fragmented buffer. @tail must be the last fragment of @skb -- or
+ *	@skb itself. If this would exceed the total buffer size the kernel
+ *	will panic. A pointer to the first byte of the extra data is
+ *	returned.
+ */
+
+unsigned char *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len)
+{
+	if (tail != skb) {
+		skb->data_len += len;
+		skb->len += len;
+	}
+	return skb_put(tail, len);
+}
+EXPORT_SYMBOL_GPL(pskb_put);
+
+/**
  *	skb_put - add data to a buffer
  *	@skb: buffer to use
  *	@len: amount of data to add
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index ab4ef72..debe733 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -802,17 +802,4 @@ int xfrm_count_pfkey_enc_supported(void)
 }
 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
 
-#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
-
-void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len)
-{
-	if (tail != skb) {
-		skb->data_len += len;
-		skb->len += len;
-	}
-	return skb_put(tail, len);
-}
-EXPORT_SYMBOL_GPL(pskb_put);
-#endif
-
 MODULE_LICENSE("GPL");
-- 
1.7.2.3

^ permalink raw reply related

* Re: Using HTB over MultiQ
From: Eric Dumazet @ 2013-11-07 14:11 UTC (permalink / raw)
  To: Anton 'EvilMan' Danilov; +Cc: netdev
In-Reply-To: <CAEzD07+Haf-Kg52H7GsxC5XiQn2KXozHbxgL4Lvn0grhFXVFmA@mail.gmail.com>

On Thu, 2013-11-07 at 17:12 +0400, Anton 'EvilMan' Danilov wrote:
> Hello.
> 
> I'm experimenting with high performance linux router with 10G NICs.
> On high traffic rates the performance are limited by the lock of root
> queue discipline. For avoid impact of locking i've decided to build
> QoS scheme over the multiq qdisc.
> 
> And I have the issues with use to multiq discipline.
> 
> My setup:
> 1. Multiq qdisc is on top of interface.
> 2. To every multiq class i've attached htb discipline with own
> hierachy of child classes.
> 3. The filters (u32 with hashing) are attached to the root multiq discipline.
> 
> Graphical scheme of hierarchy -
> http://pixpin.ru/images/2013/11/07/multiq-hierarchy1.png
> 
> Fragments of script:
> 
> #add top qdisc and classes
>  qdisc add dev eth0 root handle 10: multiq
>  qdisc add dev eth0 parent 10:1 handle 11: htb
>  class add dev eth0 parent 11: classid 11:1 htb rate 1250Mbit
>  qdisc add dev eth0 parent 10:2 handle 12: htb
>  class add dev eth0 parent 12: classid 12:1 htb rate 1250Mbit
>  qdisc add dev eth0 parent 10:3 handle 13: htb
>  class add dev eth0 parent 13: classid 13:1 htb rate 1250Mbit
>  qdisc add dev eth0 parent 10:4 handle 14: htb
>  class add dev eth0 parent 14: classid 14:1 htb rate 1250Mbit
>  qdisc add dev eth0 parent 10:5 handle 15: htb
>  class add dev eth0 parent 15: classid 15:1 htb rate 1250Mbit
>  qdisc add dev eth0 parent 10:6 handle 16: htb
>  class add dev eth0 parent 16: classid 16:1 htb rate 1250Mbit
>  qdisc add dev eth0 parent 10:7 handle 17: htb
>  class add dev eth0 parent 17: classid 17:1 htb rate 1250Mbit
>  qdisc add dev eth0 parent 10:8 handle 18: htb
>  class add dev eth0 parent 18: classid 18:1 htb rate 1250Mbit
> 
> #add leaf classes and qdiscs (several hundreds)
>  ...
>  class add dev eth0 parent 11:1 classid 11:1736 htb rate 1024kbit
>  qdisc add dev eth0 parent 11:1736 handle 1736 pfifo limit 50
>  ...
> 
> But I see zero statistics on the leaf htb classes and nonzero
> statistics on the classifier filters:
> 
> ~$ tc -s -p filter list dev eth1
>  ...
>  filter parent 10: protocol ip pref 5 u32 fh 2:f2:800 order 2048 key
> ht 2 bkt f2 flowid 11:1736  (rule hit 306 success 306)
>    match IP src xx.xx.xx.xx/30 (success 306 )
>  ...
> 
> ~$ tc -s -s -d c ls dev eth1 classid 11:1736
>  class htb 11:1736 parent 11:1 leaf 1736: prio 0 quantum 12800 rate
> 1024Kbit ceil 1024Kbit burst 1599b/1 mpu 0b overhead 0b cburst 1599b/1
> mpu 0b overhead 0b level 0
>   Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>   rate 0bit 0pps backlog 0b 0p requeues 0
>   lended: 0 borrowed: 0 giants: 0
>   tokens: 195312 ctokens: 195312
> 
> I think I've lost from view the some aspects of settings.
> Has anyone setuped the like complex scheme over the multiq discipline?
> 

I think this is not going to work, because multiqueue selection happens
before applying the filters to find a flowid.

And queue selection selects the queue depending on factors that are not
coupled to your filters, like cpu number

It looks like you want to rate limit a large number of flows, you could
try the following setup :

for ETH in eth0
do
 tc qd del dev $ETH root 2>/dev/null

 tc qd add dev $ETH root handle 100: mq 
 for i in `seq 1 8`
 do
  tc qd add dev $ETH parent 100:$i handle $i fq maxrate 1Mbit
 done
done

^ 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