Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next] sunvnet: don't change gso data on clones
From: Eric Dumazet @ 2015-02-12  3:06 UTC (permalink / raw)
  To: David L Stevens; +Cc: David Miller, netdev
In-Reply-To: <54DB5711.3040705@oracle.com>

On Wed, 2015-02-11 at 08:20 -0500, David L Stevens wrote:
> This patch unclones an skb for the case where the sunvnet driver needs to
> change the segmentation size so that it doesn't interfere with TCP SACK's
> use of them.
> 
> Signed-off-by: David L Stevens <david.stevens@oracle.com>
> ---

Acked-by: Eric Dumazet <edumazet@google.com>

^ permalink raw reply

* Re: xt_recent broken in kernel 3.19.0 + PATCH
From: Cong Wang @ 2015-02-12  3:15 UTC (permalink / raw)
  To: Chris Vine
  Cc: Linux Kernel Mailing List, netfilter-devel,
	Linux Kernel Network Developers
In-Reply-To: <20150211183121.6688aec8@bother.homenet>

(Cc'ing netdev and netfilter-devel lists)

On Wed, Feb 11, 2015 at 10:31 AM, Chris Vine
<chris@cvine.freeserve.co.uk> wrote:
> On Wed, 11 Feb 2015 09:28:34 +0000
> Chris Vine <chris@cvine.freeserve.co.uk> wrote:
>> With kernel 3.19.0, the following iptables rule, where SSH_TRIES is
>> set to 4:
>>
>>   iptables -D SSH_CHAIN -m conntrack --ctstate NEW \
>>     -m recent --update --seconds $SSH_LOGIN_PERIOD --hitcount
>> $SSH_TRIES -j DROP
>>
>> generates this error message in syslog:
>>
>>   kernel: xt_recent: hitcount (4) is larger than packets to be
>>   remembered (4) for table DEFAULT
>>
>> and the rule fails to install in the table.  No error is generated
>> with kernel 3.18.6.
>
> The rule provoking this should of course have been the one appending
> the rule, which is:
>
>   iptables -A SSH_CHAIN -m conntrack --ctstate NEW \
>     -m recent --update --seconds $SSH_LOGIN_PERIOD --hitcount $SSH_TRIES -j DROP
>
> On looking at the code, the changes in the 3.19 kernel seem not to have
> been tested and there is an off-by-one error.  The patch below restores
> behaviour to be identical to that found in the 3.18 kernel.
>
> Chris
>
> --- linux-3.19.0/net/netfilter/xt_recent.c~     2015-02-10 09:18:44.657376355 +0000
> +++ linux-3.19.0/net/netfilter/xt_recent.c      2015-02-11 17:58:33.311608835 +0000
> @@ -378,7 +378,7 @@
>         mutex_lock(&recent_mutex);
>         t = recent_table_lookup(recent_net, info->name);
>         if (t != NULL) {
> -               if (info->hit_count > t->nstamps_max_mask) {
> +               if (info->hit_count > t->nstamps_max_mask + 1) {
>                         pr_info("hitcount (%u) is larger than packets to be remembered (%u) for table %s\n",
>                                 info->hit_count, t->nstamps_max_mask + 1,
>                                 info->name);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: [PATCH net-next] sunvnet: don't change gso data on clones
From: David L Stevens @ 2015-02-12  3:17 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1423709570.4847.21.camel@edumazet-glaptop2.roam.corp.google.com>

Yes, I've seen that patch. The bug I'm fixing has the same symptoms,
but the mangling is being done by the sunvnet driver and the fix is
the same-- don't mangle packets that are cloned (and unclone them if you
need to mangle them).

The original sunvnet code changed gso_size temporarily, but that still
had a race where TCP could see the driver-modified gso_size with low probability
and end up with a negative packets-in-flight.

The unclone removes that bug, created (by me) after your fix, but in the sunvnet driver
with the addition of TSO support.

						+-DLS

On 02/11/2015 09:52 PM, Eric Dumazet wrote:

> 
> Well, we had a very hard to find bug in TCP stack, I want to make sure
> we fixed all relevant points.
> 
> commit c52e2421f7368fd36cbe330d2cf41b10452e39a9
> Author: Eric Dumazet <edumazet@google.com>
> Date:   Tue Oct 15 11:54:30 2013 -0700
> 
>     tcp: must unclone packets before mangling them
>     
>     TCP stack should make sure it owns skbs before mangling them.
...

^ permalink raw reply

* [PATCH v3] brcmfmac: avoid duplicated suspend/resume operation
From: Fu, Zhonghui @ 2015-02-12  3:26 UTC (permalink / raw)
  To: Kalle Valo, brudley, Arend van Spriel, Franky Lin, meuleman,
	linville, pieterpg, hdegoede, wens, linux-wireless,
	brcm80211-dev-list, netdev, linux-kernel@vger.kernel.org

>From a05d35ab334c20970c236fb971dae88810078c88 Mon Sep 17 00:00:00 2001
From: Fu Zhonghui <zhonghui.fu@linux.intel.com>
Date: Thu, 12 Feb 2015 10:49:35 +0800
Subject: [PATCH v3] brcmfmac: avoid duplicated suspend/resume operation

WiFi chip has 2 SDIO functions, and PM core will trigger
twice suspend/resume operations for one WiFi chip to do
the same things. This patch avoid this case.

Acked-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Fu Zhonghui <zhonghui.fu@linux.intel.com>
---
Changes in v3:
- Rebase to wireless-drivers-next/master branch

 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 7944224..b8832a7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -1117,9 +1117,13 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
 	struct brcmf_bus *bus_if;
 	struct brcmf_sdio_dev *sdiodev;
 	mmc_pm_flag_t sdio_flags;
+	struct sdio_func *func = dev_to_sdio_func(dev);
 
 	brcmf_dbg(SDIO, "Enter\n");
 
+	if (func->num == 2)
+		return 0;
+
 	bus_if = dev_get_drvdata(dev);
 	sdiodev = bus_if->bus_priv.sdio;
 
@@ -1148,9 +1152,16 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
 static int brcmf_ops_sdio_resume(struct device *dev)
 {
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
-	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+	struct brcmf_sdio_dev *sdiodev;
+	struct sdio_func *func = dev_to_sdio_func(dev);
 
 	brcmf_dbg(SDIO, "Enter\n");
+
+	if (func->num == 2)
+		return 0;
+
+	sdiodev = bus_if->bus_priv.sdio;
+
 	if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)
 		disable_irq_wake(sdiodev->pdata->oob_irq_nr);
 	brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
-- 1.9.1

^ permalink raw reply related

* Re: [PATCH v2] brcmfmac: avoid duplicated suspend/resume operation
From: Fu, Zhonghui @ 2015-02-12  3:30 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Kalle Valo, brudley, Franky Lin, meuleman, linville, pieterpg,
	hdegoede, wens, linux-wireless, brcm80211-dev-list, netdev,
	linux-kernel@vger.kernel.org
In-Reply-To: <54D871A9.4050603@broadcom.com>


On 2015/2/9 16:36, Arend van Spriel wrote:
> On 02/09/15 05:43, Fu, Zhonghui wrote:
>>  From ff39ed4af9f1c50358fe92ec4c8eaac9db183e00 Mon Sep 17 00:00:00 2001
>> From: Zhonghui Fu<zhonghui.fu@linux.intel.com>
>> Date: Mon, 26 Jan 2015 10:13:21 +0800
>> Subject: [PATCH v2] brcmfmac: avoid duplicated suspend/resume operation
>>
>> WiFi chip has 2 SDIO functions, and PM core will trigger
>> twice suspend/resume operations for one WiFi chip to do
>> the same things. This patch avoid this case.
>
> Well, another remark from Kalle was that this patch does not apply to wireless-drivers-next/master branch. So I tried to apply this patch and it failed. Please rebase this patch.

I have re-based this patch to wireless-drivers-next/master branch and sent it with the subject "[PATCH v3] brcmfmac: avoid duplicated suspend/resume operation" in another mail.

Thanks,
Zhonghui
 
>
> Regards,
> Arend
>
>> Acked-by: Arend van Spriel<arend@broadcom.com>
>> Signed-off-by: Zhonghui Fu<zhonghui.fu@linux.intel.com>
>> ---
>> Changes in v2:
>>   - Remove two "Acked-by" lines
>>
>>   drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |   17 +++++++++++++++--
>>   1 files changed, 15 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> index 9880dae..618b545 100644
>> --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>> @@ -1139,11 +1139,17 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
>>   static int brcmf_ops_sdio_suspend(struct device *dev)
>>   {
>>       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
>> -    struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
>> +    struct brcmf_sdio_dev *sdiodev;
>>       mmc_pm_flag_t sdio_flags;
>> +    struct sdio_func *func = dev_to_sdio_func(dev);
>>
>>       brcmf_dbg(SDIO, "Enter\n");
>>
>> +    if (func->num == 2)
>> +        return 0;
>> +
>> +    sdiodev = bus_if->bus_priv.sdio;
>> +
>>       atomic_set(&sdiodev->suspend, true);
>>
>>       if (sdiodev->wowl_enabled) {
>> @@ -1164,9 +1170,16 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
>>   static int brcmf_ops_sdio_resume(struct device *dev)
>>   {
>>       struct brcmf_bus *bus_if = dev_get_drvdata(dev);
>> -    struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
>> +    struct brcmf_sdio_dev *sdiodev;
>> +    struct sdio_func *func = dev_to_sdio_func(dev);
>>
>>       brcmf_dbg(SDIO, "Enter\n");
>> +
>> +    if (func->num == 2)
>> +        return 0;
>> +
>> +    sdiodev = bus_if->bus_priv.sdio;
>> +
>>       if (sdiodev->pdata&&  sdiodev->pdata->oob_irq_supported)
>>           disable_irq_wake(sdiodev->pdata->oob_irq_nr);
>>       brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
>> -- 1.7.1
>>
>
> -- 
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next] sunvnet: don't change gso data on clones
From: David Miller @ 2015-02-12  3:41 UTC (permalink / raw)
  To: david.stevens; +Cc: netdev
In-Reply-To: <54DB5711.3040705@oracle.com>

From: David L Stevens <david.stevens@oracle.com>
Date: Wed, 11 Feb 2015 08:20:17 -0500

> This patch unclones an skb for the case where the sunvnet driver needs to
> change the segmentation size so that it doesn't interfere with TCP SACK's
> use of them.
> 
> Signed-off-by: David L Stevens <david.stevens@oracle.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH net] net/mlx5_core: Fix configuration of log_uar_page_sz
From: David Miller @ 2015-02-12  3:42 UTC (permalink / raw)
  To: eli; +Cc: netdev, clsoto, ogerlitz
In-Reply-To: <20150211144038.GA18543@mtldesk30>

From: Eli Cohen <eli@dev.mellanox.co.il>
Date: Wed, 11 Feb 2015 16:40:38 +0200

> The current code failed to configure the page size for architectures with page
> size different than 4K - PPC for example.
> 
> Signed-off-by: Carol L Soto <clsoto@us.ibm.com>
> Signed-off-by: Eli Cohen <eli@mellanox.com>

Applied.

^ permalink raw reply

* Re: [PATCH net 1/1] qlcnic: Delete existing multicast MAC list before adding new
From: David Miller @ 2015-02-12  3:43 UTC (permalink / raw)
  To: shahed.shaikh; +Cc: netdev, Dept-GELinuxNICDev
In-Reply-To: <1423665924-4403-1-git-send-email-shahed.shaikh@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Date: Wed, 11 Feb 2015 09:45:24 -0500

> From: Shahed Shaikh <shahed.shaikh@qlogic.com>
> 
> Driver keeps adding multicast addresses without deleting removed MACs and
> worrying about adapters filter limit. This results into actual count of programmed
> multicast addresses get accumulated over the time and overruns the adapter's
> filter limit without putting device in ACCEPT_ALL_MULTI mode. This causes
> newly added multicast traffic to fail after the sequence of addition - deletion
> in certain pattern.
> 
> This issue is seen only when netdev's mcast list count is less than adapters
> mcast filter limit.
> 
> e.g. If adapters multicast filter limit is 38 per function
>      then following sequence would result in multicast traffic failure for
>      newly added MACs.
>      - add less than 38 multicast MACs
>      - remove previously added multicast MACs
>      - add new multicast MACs (less than 38)
> 
> Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com>

Applied.

^ permalink raw reply

* Re: [PATCH FIX] bgmac: fix device initialization on Northstar SoCs (condition typo)
From: David Miller @ 2015-02-12  3:44 UTC (permalink / raw)
  To: zajec5; +Cc: netdev, hauke
In-Reply-To: <1423674394-8578-1-git-send-email-zajec5@gmail.com>

From: Rafał Miłecki <zajec5@gmail.com>
Date: Wed, 11 Feb 2015 18:06:34 +0100

> On Northstar (Broadcom's ARM architecture) we need to manually enable
> all cores. Code for that is already in place, but the condition for it
> was wrong.
> 
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH] et131x: use msecs_to_jiffies for conversions
From: David Miller @ 2015-02-12  3:38 UTC (permalink / raw)
  To: hofrat; +Cc: mark.einon, netdev, linux-kernel
In-Reply-To: <1423646874-24403-1-git-send-email-hofrat@osadl.org>

From: Nicholas Mc Guire <hofrat@osadl.org>
Date: Wed, 11 Feb 2015 04:27:54 -0500

> This is only an API consolidation and should make things more readable.
> Converting milliseconds to jiffies by "val * HZ / 1000" is technically
> OK but msecs_to_jiffies(val) is the cleaner solution and handles all
> corner cases correctly. This is a minor API cleanup only.
> 
> Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] drivers: net: xgene: Make xgene_enet_of_match depend on CONFIG_OF
From: David Miller @ 2015-02-12  3:39 UTC (permalink / raw)
  To: geert; +Cc: isubramanian, kchudgar, fkan, netdev, linux-kernel
In-Reply-To: <1423650340-24800-1-git-send-email-geert@linux-m68k.org>

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Wed, 11 Feb 2015 11:25:40 +0100

> If CONFIG_NET_XGENE=y but CONFIG_OF=n:
> 
> drivers/net/ethernet/apm/xgene/xgene_enet_main.c:1033: warning: ‘xgene_enet_of_match’ defined but not used
> 
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>

Applied.

^ permalink raw reply

* Re: [PATCH] drivers/net: Use setup_timer and mod_timer
From: David Miller @ 2015-02-12  3:40 UTC (permalink / raw)
  To: vthakkar1994; +Cc: w-lkml, balbi, justinvanwijngaarden, netdev, linux-kernel
In-Reply-To: <20150211102950.GA23755@vaishali-Ideapad-Z570>

From: Vaishali Thakkar <vthakkar1994@gmail.com>
Date: Wed, 11 Feb 2015 15:59:50 +0530

> This patch introduces the use of functions setup_timer
> and mod_timer.
> 
> This is done using Coccinelle and semantic patch used
> for this as follows:
 ...
> Signed-off-by: Vaishali Thakkar <vthakkar1994@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH net] tg3: Hold tp->lock before calling tg3_halt() from tg3_init_one()
From: David Miller @ 2015-02-12  3:51 UTC (permalink / raw)
  To: j-nomura; +Cc: prashant, mchan, netdev
In-Reply-To: <54DC0140.6000406@ce.jp.nec.com>

From: Junichi Nomura <j-nomura@ce.jp.nec.com>
Date: Thu, 12 Feb 2015 01:26:24 +0000

> tg3_init_one() calls tg3_halt() without tp->lock despite its assumption
> and causes deadlock.
> If lockdep is enabled, a warning like this shows up before the stall:
> 
>   [ BUG: bad unlock balance detected! ]
>   3.19.0test #3 Tainted: G            E
>   -------------------------------------
>   insmod/369 is trying to release lock (&(&tp->lock)->rlock) at:
>   [<ffffffffa02d5a1d>] tg3_chip_reset+0x14d/0x780 [tg3]
>   but there are no more locks to release!
> 
> tg3_init_one() doesn't call tg3_halt() under normal situation but
> during kexec kdump I hit this problem.
> 
> Fixes: 932f19de ("tg3: Release tp->lock before invoking synchronize_irq()")
> Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>

Applied.

^ permalink raw reply

* Re: pull-request: wireless-drivers 2015-02-11
From: David Miller @ 2015-02-12  3:50 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <87iof8l252.fsf@kamboji.qca.qualcomm.com>

From: Kalle Valo <kvalo@qca.qualcomm.com>
Date: Wed, 11 Feb 2015 20:43:53 +0200

> here's one rtlwifi fix for 3.20. We have had two reports of this issue
> already, so it would be good to get this to -rc1 or -rc2.
> 
> I rebased wireless-drivers on top of net-next, so this patch applies to
> net-next. I hope that's ok.

Pulled, thanks a lot.

^ permalink raw reply

* [PATCH net] ipvlan: add a missing __percpu pcpu_stats
From: Eric Dumazet @ 2015-02-12  3:51 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Mahesh Bandewar

From: Eric Dumazet <edumazet@google.com>

Cosmetic patch to add __percpu qualifier to pcpu_stats

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 drivers/net/ipvlan/ipvlan.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 2729f64b3e7e..924ea98bd531 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -67,7 +67,7 @@ struct ipvl_dev {
 	struct list_head	addrs;
 	int			ipv4cnt;
 	int			ipv6cnt;
-	struct ipvl_pcpu_stats	*pcpu_stats;
+	struct ipvl_pcpu_stats	__percpu *pcpu_stats;
 	DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE);
 	netdev_features_t	sfeatures;
 	u32			msg_enable;

^ permalink raw reply related

* Re: [PATCH net] ipvlan: add a missing __percpu pcpu_stats
From: David Miller @ 2015-02-12  4:04 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, maheshb
In-Reply-To: <1423713106.4942.7.camel@edumazet-glaptop2.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 11 Feb 2015 19:51:46 -0800

> From: Eric Dumazet <edumazet@google.com>
> 
> Cosmetic patch to add __percpu qualifier to pcpu_stats
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied.

^ permalink raw reply

* Re: [PATCH] net: ip: Do not allow connection to remote port zero
From: Eric Dumazet @ 2015-02-12  4:06 UTC (permalink / raw)
  To: Tom Marshall; +Cc: netdev
In-Reply-To: <20150212005844.GB3829@nwwn.com>

On Wed, 2015-02-11 at 16:58 -0800, Tom Marshall wrote:
> Port zero is reserved according to IANA.
> 
> Note UDP sendto is already disallowed if dport is zero.

I have no idea why we should prevent such thing.

There is nothing wrong sending a TCP frame with dport=0, even if
practically it is not possible to setup a listener on such port using
BSD API.

Maybe some tools are actually using this already to send probes...

^ permalink raw reply

* [PATCH next v3 1/6] bonding: Verify RX LACPDU has proper dest mac-addr
From: Mahesh Bandewar @ 2015-02-12  4:24 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, Maciej Zenczykowski, netdev, Eric Dumazet

The 802.1AX standard states:
"The DA in LACPDUs is the Slow_Protocols_Multicast address."

This patch enforces that and drops LACPDUs with destination MAC
addresses other than Slow_Protocols_Multicast address

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
v1:
   Initial version
v2:
   Rebase
v3:
   Rebase

 drivers/net/bonding/bond_3ad.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index cfc4a9c1000a..9b436696b95e 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2485,6 +2485,9 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
 	if (skb->protocol != PKT_TYPE_LACPDU)
 		return RX_HANDLER_ANOTHER;
 
+	if (!MAC_ADDRESS_EQUAL(eth_hdr(skb)->h_dest, lacpdu_mcast_addr))
+		return RX_HANDLER_ANOTHER;
+
 	lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu);
 	if (!lacpdu)
 		return RX_HANDLER_ANOTHER;
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next v3 3/6] bonding: Implement port churn-machine (AD standard 43.4.17).
From: Mahesh Bandewar @ 2015-02-12  4:24 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, Maciej Zenczykowski, netdev, Eric Dumazet

The Chrun Detection machines detect the situation where a port is operable,
but the Actor and Partner have not attached the link to an Aggregator and
brought the link into operation within a bound time period. Under normal
operation of the LACP, aggrement between Actor and Partner should be reached
very rapidly. Continued failure to reach aggrement can be symptomatic of
device failure.

Actor-churn-dection state-machine
=================================

BEGIN=True + PortEnable=False
           |
           v
 +------------------------+   ActorPort.Sync=True  +------------------+
 |   ACTOR_CHURN_MONITOR  | ---------------------> |  NO_ACTOR_CHURN  |
 |========================|                        |==================|
 |    ActorChurn=False    |  ActorPort.Sync=False  | ActorChurn=False |
 | ActorChurn.Timer=Start | <--------------------- |                  |
 +------------------------+                        +------------------+
           |                                                ^
           |                                                |
  ActorChurn.Timer=Expired                                  |
           |                                       ActorPort.Sync=True
           |                                                |
           |                +-----------------+             |
           |                |   ACTOR_CHURN   |             |
           |                |=================|             |
           +--------------> | ActorChurn=True | ------------+
                            |                 |
                            +-----------------+

Similar for the Partner-churn-detection.

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
v1:
  Initial version
v2:
  Rebase
v3:
  Rebase

 drivers/net/bonding/bond_3ad.c    | 56 +++++++++++++++++++++++++++++++++++++--
 drivers/net/bonding/bond_procfs.c | 40 +++++++++++++++++++++++++---
 include/net/bond_3ad.h            | 29 ++++++++++++++++++++
 3 files changed, 119 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 14f2ebe786c5..2a69095266c1 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -38,6 +38,7 @@
 #define AD_STANDBY                 0x2
 #define AD_MAX_TX_IN_SECOND        3
 #define AD_COLLECTOR_MAX_DELAY     0
+#define AD_MONITOR_CHURNED         0x1000
 
 /* Timer definitions (43.4.4 in the 802.3ad standard) */
 #define AD_FAST_PERIODIC_TIME      1
@@ -1013,16 +1014,19 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 	/* check if state machine should change state */
 
 	/* first, check if port was reinitialized */
-	if (port->sm_vars & AD_PORT_BEGIN)
+	if (port->sm_vars & AD_PORT_BEGIN) {
 		port->sm_rx_state = AD_RX_INITIALIZE;
+		port->sm_vars |= AD_MONITOR_CHURNED;
 	/* check if port is not enabled */
-	else if (!(port->sm_vars & AD_PORT_BEGIN)
+	} else if (!(port->sm_vars & AD_PORT_BEGIN)
 		 && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED))
 		port->sm_rx_state = AD_RX_PORT_DISABLED;
 	/* check if new lacpdu arrived */
 	else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) ||
 		 (port->sm_rx_state == AD_RX_DEFAULTED) ||
 		 (port->sm_rx_state == AD_RX_CURRENT))) {
+		if (port->sm_rx_state != AD_RX_CURRENT)
+			port->sm_vars |= AD_MONITOR_CHURNED;
 		port->sm_rx_timer_counter = 0;
 		port->sm_rx_state = AD_RX_CURRENT;
 	} else {
@@ -1100,9 +1104,11 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 			 */
 			port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION;
 			port->sm_vars &= ~AD_PORT_MATCHED;
+			port->partner_oper.port_state |= AD_STATE_LACP_TIMEOUT;
 			port->partner_oper.port_state |= AD_STATE_LACP_ACTIVITY;
 			port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT));
 			port->actor_oper_port_state |= AD_STATE_EXPIRED;
+			port->sm_vars |= AD_MONITOR_CHURNED;
 			break;
 		case AD_RX_DEFAULTED:
 			__update_default_selected(port);
@@ -1131,6 +1137,44 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 	}
 }
 
+/* ad_churn_machine - handle port churn's state machine
+ * @port: the port we're looking at
+ *
+ */
+static void ad_churn_machine(struct port *port)
+{
+	if (port->sm_vars & AD_MONITOR_CHURNED) {
+		port->sm_vars &= ~AD_MONITOR_CHURNED;
+		port->sm_churn_actor_state = AD_CHURN_MONITOR;
+		port->sm_churn_partner_state = AD_CHURN_MONITOR;
+		port->sm_churn_actor_timer_counter =
+			__ad_timer_to_ticks(AD_ACTOR_CHURN_TIMER, 0);
+		 port->sm_churn_partner_timer_counter =
+			 __ad_timer_to_ticks(AD_PARTNER_CHURN_TIMER, 0);
+		return;
+	}
+	if (port->sm_churn_actor_timer_counter &&
+		!(--port->sm_churn_actor_timer_counter) &&
+		(port->sm_churn_actor_state == AD_CHURN_MONITOR)) {
+		if (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION) {
+			port->sm_churn_actor_state = AD_NO_CHURN;
+		} else {
+			port->churn_actor_count++;
+			port->sm_churn_actor_state = AD_CHURN;
+		}
+	}
+	if (port->sm_churn_partner_timer_counter &&
+		!(--port->sm_churn_partner_timer_counter) &&
+		(port->sm_churn_partner_state == AD_CHURN_MONITOR)) {
+		if (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) {
+			port->sm_churn_partner_state = AD_NO_CHURN;
+		} else {
+			port->churn_partner_count++;
+			port->sm_churn_partner_state = AD_CHURN;
+		}
+	}
+}
+
 /**
  * ad_tx_machine - handle a port's tx state machine
  * @port: the port we're looking at
@@ -1745,6 +1789,13 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
 		port->next_port_in_aggregator = NULL;
 		port->transaction_id = 0;
 
+		port->sm_churn_actor_timer_counter = 0;
+		port->sm_churn_actor_state = 0;
+		port->churn_actor_count = 0;
+		port->sm_churn_partner_timer_counter = 0;
+		port->sm_churn_partner_state = 0;
+		port->churn_partner_count = 0;
+
 		memcpy(&port->lacpdu, &lacpdu, sizeof(lacpdu));
 	}
 }
@@ -2164,6 +2215,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
 		ad_port_selection_logic(port, &update_slave_arr);
 		ad_mux_machine(port, &update_slave_arr);
 		ad_tx_machine(port);
+		ad_churn_machine(port);
 
 		/* turn off the BEGIN bit, since we already handled it */
 		if (port->sm_vars & AD_PORT_BEGIN)
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 976f5ad2a0f2..83095a0b4b90 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -178,13 +178,45 @@ static void bond_info_show_slave(struct seq_file *seq,
 	seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
 
 	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
-		const struct aggregator *agg
-			= SLAVE_AD_INFO(slave)->port.aggregator;
+		const struct port *port = &SLAVE_AD_INFO(slave)->port;
+		const struct aggregator *agg = port->aggregator;
 
-		if (agg)
+		if (agg) {
 			seq_printf(seq, "Aggregator ID: %d\n",
 				   agg->aggregator_identifier);
-		else
+			seq_printf(seq, "Actor Churn State: %s\n",
+				   bond_3ad_churn_desc(port->sm_churn_actor_state));
+			seq_printf(seq, "Partner Churn State: %s\n",
+				   bond_3ad_churn_desc(port->sm_churn_partner_state));
+			seq_printf(seq, "Actor Churned Count: %d\n",
+				   port->churn_actor_count);
+			seq_printf(seq, "Partner Churned Count: %d\n",
+				   port->churn_partner_count);
+
+			seq_puts(seq, "details actor lacp pdu:\n");
+			seq_printf(seq, "    system priority: %d\n",
+				   port->actor_system_priority);
+			seq_printf(seq, "    port key: %d\n",
+				   port->actor_oper_port_key);
+			seq_printf(seq, "    port priority: %d\n",
+				   port->actor_port_priority);
+			seq_printf(seq, "    port number: %d\n",
+				   port->actor_port_number);
+			seq_printf(seq, "    port state: %d\n",
+				   port->actor_oper_port_state);
+
+			seq_puts(seq, "details partner lacp pdu:\n");
+			seq_printf(seq, "    system priority: %d\n",
+				   port->partner_oper.system_priority);
+			seq_printf(seq, "    oper key: %d\n",
+				   port->partner_oper.key);
+			seq_printf(seq, "    port priority: %d\n",
+				   port->partner_oper.port_priority);
+			seq_printf(seq, "    port number: %d\n",
+				   port->partner_oper.port_number);
+			seq_printf(seq, "    port state: %d\n",
+				   port->partner_oper.port_state);
+		} else
 			seq_puts(seq, "Aggregator ID: N/A\n");
 	}
 	seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
index 6c455c646d61..170f8926ff66 100644
--- a/include/net/bond_3ad.h
+++ b/include/net/bond_3ad.h
@@ -82,6 +82,13 @@ typedef enum {
 	AD_TRANSMIT		/* tx Machine */
 } tx_states_t;
 
+/* churn machine states(43.4.17 in the 802.3ad standard) */
+typedef enum {
+	 AD_CHURN_MONITOR, /* monitoring for churn */
+	 AD_CHURN,         /* churn detected (error) */
+	 AD_NO_CHURN       /* no churn (no error) */
+} churn_state_t;
+
 /* rx indication types */
 typedef enum {
 	AD_TYPE_LACPDU = 1,	/* type lacpdu */
@@ -229,6 +236,12 @@ typedef struct port {
 	u16 sm_mux_timer_counter;	/* state machine mux timer counter */
 	tx_states_t sm_tx_state;	/* state machine tx state */
 	u16 sm_tx_timer_counter;	/* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */
+	u16 sm_churn_actor_timer_counter;
+	u16 sm_churn_partner_timer_counter;
+	u32 churn_actor_count;
+	u32 churn_partner_count;
+	churn_state_t sm_churn_actor_state;
+	churn_state_t sm_churn_partner_state;
 	struct slave *slave;		/* pointer to the bond slave that this port belongs to */
 	struct aggregator *aggregator;	/* pointer to an aggregator that this port related to */
 	struct port *next_port_in_aggregator;	/* Next port on the linked list of the parent aggregator */
@@ -262,6 +275,22 @@ struct ad_slave_info {
 	u16 id;
 };
 
+static inline const char *bond_3ad_churn_desc(churn_state_t state)
+{
+	static const char *const churn_description[] =
+		{ "monitoring",
+		  "churned",
+		  "none",
+		  "unknown"
+		};
+	int max_size = sizeof(churn_description) / sizeof(churn_description[0]);
+
+	if (state >= max_size)
+		state = max_size - 1;
+
+	return churn_description[state];
+}
+
 /* ========== AD Exported functions to the main bonding code ========== */
 void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
 void bond_3ad_bind_slave(struct slave *slave);
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next v3 6/6] bonding: Implement user key part of port_key in an AD system.
From: Mahesh Bandewar @ 2015-02-12  4:24 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, Maciej Zenczykowski, netdev, Eric Dumazet

The port key has three components - user-key, speed-part, and duplex-part.
The LSBit is for the duplex-part, next 5 bits are for the speed while the
remaining 10 bits are the user defined key bits. Get these 10 bits
from the user-space (through the SysFs interface) and use it to form the
admin port-key. Allowed range for the user-key is 0 - 1023 (10 bits). If
it is not provided then use zero for the user-key-bits (default).

It can set using following example code -

   # modprobe bonding mode=4
   # usr_port_key=$(( RANDOM & 0x3FF ))
   # echo $usr_port_key > /sys/class/net/bond0/bonding/ad_user_port_key
   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
   ...
   # ip link set bond0 up

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
v1:
  Initial version
v2:
  Renamed ad_actor_user_port_key ad_user_port_key
v3:
  Rebase

 Documentation/networking/bonding.txt | 62 ++++++++++++++++++++++++++++++++++++
 drivers/net/bonding/bond_3ad.c       | 14 ++++----
 drivers/net/bonding/bond_main.c      | 10 ++++++
 drivers/net/bonding/bond_options.c   | 26 +++++++++++++++
 drivers/net/bonding/bond_sysfs.c     | 15 +++++++++
 include/net/bond_options.h           |  1 +
 include/net/bonding.h                |  1 +
 7 files changed, 122 insertions(+), 7 deletions(-)

diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index f0d93c58cdb0..da22956b408f 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -51,6 +51,7 @@ Table of Contents
 3.4	Configuring Bonding Manually via Sysfs
 3.5	Configuration with Interfaces Support
 3.6	Overriding Configuration for Special Cases
+3.7 Configuring LACP for 802.3ad mode in a more secure way
 
 4. Querying Bonding Configuration
 4.1	Bonding Configuration
@@ -241,6 +242,21 @@ ad_select
 
 	This option was added in bonding version 3.4.0.
 
+ad_user_port_key
+
+	In an AD system, the port-key has three parts as shown below -
+
+	   Bits   Use
+	   00     Duplex
+	   01-05  Speed
+	   06-15  User-defined
+
+	This defines the upper 10 bits of the port key. The values can be
+	from 0 - 1023. If not given, the system defaults to 0.
+
+	This paramter has effect only in 802.3ad mode and is available through
+	SysFs interface.
+
 all_slaves_active
 
 	Specifies that duplicate frames (received on inactive ports) should be
@@ -1643,6 +1659,52 @@ output port selection.
 This feature first appeared in bonding driver version 3.7.0 and support for
 output slave selection was limited to round-robin and active-backup modes.
 
+3.7 Configuring LACP for 802.3ad mode in a more secure way
+----------------------------------------------------------
+
+When using 802.3ad bonding mode, the Actor (host) and Partner (switch)
+exchange LACPDUs.  These LACPDUs cannot be sniffed, because they are
+destined to link local mac addresses (which switches/bridges are not
+supposed to forward).  However, most of the values are easily predictable
+or are simply the machine's MAC address (which is trivially known to all
+other hosts in the same L2).  This implies that other machines in the L2
+domain can spoof LACPDU packets from other hosts to the switch and potentially
+cause mayhem by joining (from the point of view of the switch) another
+machine's aggregate, thus receiving a portion of that hosts incoming
+traffic and / or spoofing traffic from that machine themselves (potentially
+even successfully terminating some portion of flows). Though this is not
+a likely scenario, one could avoid this possibility by simply configuring
+few bonding parameters:
+
+   (a) ad_actor_system : You can set a random mac-address that can be used for
+       these LACPDU exchanges. The value can not be either NULL or Multicast.
+       Also it's preferable to set the local-admin bit. This can be done using
+       the following shell code -
+
+       # sys_mac_addr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
+                                $(( (RANDOM & 0xFE) | 0x02 )) \
+                                $(( RANDOM & 0xFF )) \
+                                $(( RANDOM & 0xFF )) \
+                                $(( RANDOM & 0xFF )) \
+                                $(( RANDOM & 0xFF )) \
+                                $(( RANDOM & 0xFF )))
+       # echo $sys_mac_addr > /sys/class/net/bond0/bonding/ad_actor_system
+
+   (b) ad_actor_sys_prio : Randomize the system priority. The default value
+       is 65535, but system can take the value from 1 - 65535. You can do this
+       this using the following shell code -
+
+       # sys_prio=$(( 1 + RANDOM + RANDOM ))
+       # echo $sys_prio > /sys/class/net/bond0/bonding/ad_actor_sys_prio
+
+   (c) ad_user_port_key : Use the user portion of the port-key. The default
+       keeps this empty. These the upper 10 bits of the port-key and value
+       ranges from 0 - 1023. You can do this using the following shell code -
+
+       # usr_port_key=$(( RANDOM & 0x3FF ))
+       # echo $usr_port_key > /sys/class/net/bond0/bonding/ad_user_port_key
+
+
 4 Querying Bonding Configuration
 =================================
 
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 4b28d8cc0e84..d39d16d7711a 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -75,10 +75,10 @@
 /* Port Key definitions
  * key is determined according to the link speed, duplex and
  * user key (which is yet not supported)
- * --------------------------------------------------------------
- * Port key :	| User key	| Speed		| Duplex	|
- * --------------------------------------------------------------
- * 16		  6		  1		  0
+ *           --------------------------------------------------------------
+ * Port key  | User key (10 bits)           | Speed (5 bits)      | Duplex|
+ *           --------------------------------------------------------------
+ *           |15                           6|5                   1|0
  */
 #define  AD_DUPLEX_KEY_MASKS    0x1
 #define  AD_SPEED_KEY_MASKS     0x3E
@@ -1955,10 +1955,10 @@ void bond_3ad_bind_slave(struct slave *slave)
 
 		port->slave = slave;
 		port->actor_port_number = SLAVE_AD_INFO(slave)->id;
-		/* key is determined according to the link speed, duplex and user key(which
-		 * is yet not supported)
+		/* key is determined according to the link speed, duplex and
+		 * user key
 		 */
-		port->actor_admin_port_key = 0;
+		port->actor_admin_port_key = bond->params.ad_user_port_key << 6;
 		port->actor_admin_port_key |= __get_duplex(port);
 		port->actor_admin_port_key |= (__get_link_speed(port) << 1);
 		port->actor_oper_port_key = port->actor_admin_port_key;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f899f3053e82..e5a9344dae26 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4139,6 +4139,7 @@ static int bond_check_params(struct bond_params *params)
 	const struct bond_opt_value *valptr;
 	int arp_all_targets_value;
 	u16 ad_actor_sys_prio = 0;
+	u16 ad_user_port_key = 0;
 
 	/* Convert string parameters. */
 	if (mode) {
@@ -4443,6 +4444,14 @@ static int bond_check_params(struct bond_params *params)
 			return -EINVAL;
 		}
 		ad_actor_sys_prio = valptr->value;
+
+		valptr = bond_opt_parse(bond_opt_get(BOND_OPT_AD_USER_PORT_KEY),
+					&newval);
+		if (!valptr) {
+			pr_err("Error: No ad_user_port_key default value");
+			return -EINVAL;
+		}
+		ad_user_port_key = valptr->value;
 	}
 
 	if (lp_interval == 0) {
@@ -4475,6 +4484,7 @@ static int bond_check_params(struct bond_params *params)
 	params->tlb_dynamic_lb = 1; /* Default value */
 	params->ad_actor_sys_prio = ad_actor_sys_prio;
 	eth_zero_addr(params->ad_actor_system);
+	params->ad_user_port_key = ad_user_port_key;
 	if (packets_per_slave > 0) {
 		params->reciprocal_packets_per_slave =
 			reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index f2c011b3ea33..eb0a8e9fafe7 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -74,6 +74,8 @@ static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
 static int bond_option_ad_actor_system_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
+static int bond_option_ad_user_port_key_set(struct bonding *bond,
+				  const struct bond_opt_value *newval);
 
 
 static const struct bond_opt_value bond_mode_tbl[] = {
@@ -196,6 +198,12 @@ static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = {
 	{ NULL,      -1,    0},
 };
 
+static const struct bond_opt_value bond_ad_user_port_key_tbl[] = {
+	{ "minval",  0,     BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT},
+	{ "maxval",  1023,  BOND_VALFLAG_MAX},
+	{ NULL,      -1,    0},
+};
+
 static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 	[BOND_OPT_MODE] = {
 		.id = BOND_OPT_MODE,
@@ -405,6 +413,14 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 		.flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
 		.set = bond_option_ad_actor_system_set,
 	},
+	[BOND_OPT_AD_USER_PORT_KEY] = {
+		.id = BOND_OPT_AD_USER_PORT_KEY,
+		.name = "ad_user_port_key",
+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+		.flags = BOND_OPTFLAG_IFDOWN,
+		.values = bond_ad_user_port_key_tbl,
+		.set = bond_option_ad_user_port_key_set,
+	}
 };
 
 /* Searches for an option by name */
@@ -1405,3 +1421,13 @@ static int bond_option_ad_actor_system_set(struct bonding *bond,
 
 	return 0;
 }
+
+static int bond_option_ad_user_port_key_set(struct bonding *bond,
+					    const struct bond_opt_value *newval)
+{
+	netdev_info(bond->dev, "Setting ad_user_port_key to (%llu)\n",
+		    newval->value);
+
+	bond->params.ad_user_port_key = newval->value;
+	return 0;
+}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index efa994243a2d..a6950647d99d 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -720,6 +720,20 @@ static ssize_t bonding_show_ad_actor_system(struct device *d,
 static DEVICE_ATTR(ad_actor_system, S_IRUGO | S_IWUSR,
 		   bonding_show_ad_actor_system, bonding_sysfs_store_option);
 
+static ssize_t bonding_show_ad_user_port_key(struct device *d,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		return sprintf(buf, "%hu\n", bond->params.ad_user_port_key);
+
+	return 0;
+}
+static DEVICE_ATTR(ad_user_port_key, S_IRUGO | S_IWUSR,
+		   bonding_show_ad_user_port_key, bonding_sysfs_store_option);
+
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
@@ -755,6 +769,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_tlb_dynamic_lb.attr,
 	&dev_attr_ad_actor_sys_prio.attr,
 	&dev_attr_ad_actor_system.attr,
+	&dev_attr_ad_user_port_key.attr,
 	NULL,
 };
 
diff --git a/include/net/bond_options.h b/include/net/bond_options.h
index eeeefa1d3cd8..c28aca25320e 100644
--- a/include/net/bond_options.h
+++ b/include/net/bond_options.h
@@ -65,6 +65,7 @@ enum {
 	BOND_OPT_TLB_DYNAMIC_LB,
 	BOND_OPT_AD_ACTOR_SYS_PRIO,
 	BOND_OPT_AD_ACTOR_SYSTEM,
+	BOND_OPT_AD_USER_PORT_KEY,
 	BOND_OPT_LAST
 };
 
diff --git a/include/net/bonding.h b/include/net/bonding.h
index f24f9862cea9..0ac45b4f7f2a 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -144,6 +144,7 @@ struct bond_params {
 	int tlb_dynamic_lb;
 	struct reciprocal_value reciprocal_packets_per_slave;
 	u16 ad_actor_sys_prio;
+	u16 ad_user_port_key;
 	u8 ad_actor_system[ETH_ALEN];
 };
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next v3 4/6] bonding: Allow userspace to set actors' system_priority in AD system
From: Mahesh Bandewar @ 2015-02-12  4:24 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, Maciej Zenczykowski, netdev, Eric Dumazet

This patch allows user to randomize the system-priority in an ad-system.
The allowed range is 1 - 0xFFFF while default value is 0xFFFF. If user
does not specify this value, the system defaults to 0xFFFF, which is
what it was before this patch.

Following example code could set the value -
    # modprobe bonding mode=4
    # sys_prio=$(( 1 + RANDOM + RANDOM ))
    # echo $sys_prio > /sys/class/net/bond0/bonding/ad_actor_sys_prio
    # echo +eth1 > /sys/class/net/bond0/bonding/slaves
    ...
    # ip link set bond0 up

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
v1:
  Initial version
v2:
  Rename ad_actor_system_priority to ad_actor_sys_prio
v3:
  Rebase

 Documentation/networking/bonding.txt |  9 +++++++++
 drivers/net/bonding/bond_3ad.c       |  5 ++++-
 drivers/net/bonding/bond_main.c      | 14 ++++++++++++++
 drivers/net/bonding/bond_options.c   | 29 ++++++++++++++++++++++++++++-
 drivers/net/bonding/bond_procfs.c    |  2 ++
 drivers/net/bonding/bond_sysfs.c     | 15 +++++++++++++++
 include/net/bond_options.h           |  1 +
 include/net/bonding.h                |  1 +
 8 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 83bf4986baea..f19d888651b8 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -178,6 +178,15 @@ active_slave
 	active slave, or the empty string if there is no active slave or
 	the current mode does not use an active slave.
 
+ad_actor_sys_prio
+
+	In an AD system, this specifies the system priority. The allowed range
+	is 1 - 65535. If the value is not specified, it takes 65535 as the
+	default value.
+
+	This paramter has effect only in 802.3ad mode and is available through
+	SysFs interface.
+
 ad_select
 
 	Specifies the 802.3ad aggregation selection logic to use.  The
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 2a69095266c1..46aa847a0132 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1912,7 +1912,8 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
 
 		BOND_AD_INFO(bond).aggregator_identifier = 0;
 
-		BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
+		BOND_AD_INFO(bond).system.sys_priority =
+			bond->params.ad_actor_sys_prio;
 		BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
 
 		/* initialize how many times this module is called in one
@@ -1963,6 +1964,8 @@ void bond_3ad_bind_slave(struct slave *slave)
 			port->sm_vars &= ~AD_PORT_LACP_ENABLED;
 		/* actor system is the bond's system */
 		port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
+		port->actor_system_priority =
+		    BOND_AD_INFO(bond).system.sys_priority;
 		/* tx timer(to verify that no more than MAX_TX_IN_SECOND
 		 * lacpdu's are sent in one second)
 		 */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8433fe464f95..f8f6a80231b6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4138,6 +4138,7 @@ static int bond_check_params(struct bond_params *params)
 	struct bond_opt_value newval;
 	const struct bond_opt_value *valptr;
 	int arp_all_targets_value;
+	u16 ad_actor_sys_prio = 0;
 
 	/* Convert string parameters. */
 	if (mode) {
@@ -4432,6 +4433,18 @@ static int bond_check_params(struct bond_params *params)
 		fail_over_mac_value = BOND_FOM_NONE;
 	}
 
+	if (bond_mode == BOND_MODE_8023AD) {
+		bond_opt_initstr(&newval, "default");
+		valptr = bond_opt_parse(
+				bond_opt_get(BOND_OPT_AD_ACTOR_SYS_PRIO),
+					     &newval);
+		if (!valptr) {
+			pr_err("Error: No ad_actor_sys_prio default value");
+			return -EINVAL;
+		}
+		ad_actor_sys_prio = valptr->value;
+	}
+
 	if (lp_interval == 0) {
 		pr_warn("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
 			INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL);
@@ -4460,6 +4473,7 @@ static int bond_check_params(struct bond_params *params)
 	params->lp_interval = lp_interval;
 	params->packets_per_slave = packets_per_slave;
 	params->tlb_dynamic_lb = 1; /* Default value */
+	params->ad_actor_sys_prio = ad_actor_sys_prio;
 	if (packets_per_slave > 0) {
 		params->reciprocal_packets_per_slave =
 			reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 4df28943d222..05d5e735eaec 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -70,6 +70,8 @@ static int bond_option_slaves_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
 static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
+static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,
+				  const struct bond_opt_value *newval);
 
 
 static const struct bond_opt_value bond_mode_tbl[] = {
@@ -186,6 +188,12 @@ static const struct bond_opt_value bond_tlb_dynamic_lb_tbl[] = {
 	{ NULL,  -1, 0}
 };
 
+static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = {
+	{ "minval",  1,     BOND_VALFLAG_MIN},
+	{ "maxval",  65535, BOND_VALFLAG_MAX | BOND_VALFLAG_DEFAULT},
+	{ NULL,      -1,    0},
+};
+
 static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 	[BOND_OPT_MODE] = {
 		.id = BOND_OPT_MODE,
@@ -379,7 +387,15 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 		.values = bond_tlb_dynamic_lb_tbl,
 		.flags = BOND_OPTFLAG_IFDOWN,
 		.set = bond_option_tlb_dynamic_lb_set,
-	}
+	},
+	[BOND_OPT_AD_ACTOR_SYS_PRIO] = {
+		.id = BOND_OPT_AD_ACTOR_SYS_PRIO,
+		.name = "ad_actor_sys_prio",
+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+		.flags = BOND_OPTFLAG_IFDOWN,
+		.values = bond_ad_actor_sys_prio_tbl,
+		.set = bond_option_ad_actor_sys_prio_set,
+	},
 };
 
 /* Searches for an option by name */
@@ -1349,3 +1365,14 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
 
 	return 0;
 }
+
+
+static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,
+					    const struct bond_opt_value *newval)
+{
+	netdev_info(bond->dev, "Setting ad_actor_sys_prio to (%llu)\n",
+		    newval->value);
+
+	bond->params.ad_actor_sys_prio = newval->value;
+	return 0;
+}
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 83095a0b4b90..9e33c48886ef 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -134,6 +134,8 @@ static void bond_info_show_master(struct seq_file *seq)
 					  bond->params.ad_select);
 		seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
 			   optval->string);
+		seq_printf(seq, "System priority: %d\n",
+				BOND_AD_INFO(bond).system.sys_priority);
 
 		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
 			seq_printf(seq, "bond %s has no active aggregator\n",
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 7e9e151d4d61..1a4a591a58c9 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -692,6 +692,20 @@ static ssize_t bonding_show_packets_per_slave(struct device *d,
 static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
 		   bonding_show_packets_per_slave, bonding_sysfs_store_option);
 
+static ssize_t bonding_show_ad_actor_sys_prio(struct device *d,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		return sprintf(buf, "%hu\n", bond->params.ad_actor_sys_prio);
+
+	return 0;
+}
+static DEVICE_ATTR(ad_actor_sys_prio, S_IRUGO | S_IWUSR,
+		   bonding_show_ad_actor_sys_prio, bonding_sysfs_store_option);
+
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
@@ -725,6 +739,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_lp_interval.attr,
 	&dev_attr_packets_per_slave.attr,
 	&dev_attr_tlb_dynamic_lb.attr,
+	&dev_attr_ad_actor_sys_prio.attr,
 	NULL,
 };
 
diff --git a/include/net/bond_options.h b/include/net/bond_options.h
index ea6546d2c946..894002a2620f 100644
--- a/include/net/bond_options.h
+++ b/include/net/bond_options.h
@@ -63,6 +63,7 @@ enum {
 	BOND_OPT_LP_INTERVAL,
 	BOND_OPT_SLAVES,
 	BOND_OPT_TLB_DYNAMIC_LB,
+	BOND_OPT_AD_ACTOR_SYS_PRIO,
 	BOND_OPT_LAST
 };
 
diff --git a/include/net/bonding.h b/include/net/bonding.h
index fda6feeb6c1f..cb4587f6516e 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -143,6 +143,7 @@ struct bond_params {
 	int packets_per_slave;
 	int tlb_dynamic_lb;
 	struct reciprocal_value reciprocal_packets_per_slave;
+	u16 ad_actor_sys_prio;
 };
 
 struct bond_parm_tbl {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH] net: ipv6: Make address flushing on ifdown optional - v3
From: David Ahern @ 2015-02-12  4:27 UTC (permalink / raw)
  To: netdev; +Cc: David Ahern, Hannes Frederic Sowa

Currently, all ipv6 addresses are flushed when the interface is configured
down, even static address:

[root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
    inet6 2000:11:1:1::1/64 scope global tentative
       valid_lft forever preferred_lft forever
[root@f20 ~]# ip link set dev eth1 up
[root@f20 ~]# ip link set dev eth1 down
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff

Add a new sysctl to make this behavior optional. The new setting defaults to
flush all addresses to maintain backwards compatibility. When the setting is
reset static addresses are not flushed:

[root@f20 ~]# echo 0 > /proc/sys/net/ipv6/conf/eth1/flush_addr_on_down
[root@f20 ~]# ip -6 addr add dev eth1 2000:11:1:1::1/64
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
    inet6 2000:11:1:1::1/64 scope global tentative
       valid_lft forever preferred_lft forever
[root@f20 ~]#  ip link set dev eth1 up
[root@f20 ~]#  ip link set dev eth1 down
[root@f20 ~]# ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether 02:04:11:22:33:01 brd ff:ff:ff:ff:ff:ff
    inet6 2000:11:1:1::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::4:11ff:fe22:3301/64 scope link
       valid_lft forever preferred_lft forever

v3:
- fix local variable ordering and comment style per Dave's comment
- consistency in DEVCONF naming per Brian Haley's comment
- added entry to Documentation/networking/ip-sysctl.txt

v2:
- only keep static addresses as suggested by Hannes
- added new managed flag to track configured addresses
- on ifdown do not remove from configured address from inet6_addr_lst
- on ifdown reset the TENTATIVE flag and set state to DAD so that DAD is
  redone when link is brought up again

Suggested-by: Hannes Frederic Sowa <hannes@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Hannes Frederic Sowa <hannes@redhat.com>
---
 Documentation/networking/ip-sysctl.txt |  6 ++++
 include/linux/ipv6.h                   |  1 +
 include/net/if_inet6.h                 |  1 +
 include/uapi/linux/ipv6.h              |  1 +
 net/ipv6/addrconf.c                    | 54 +++++++++++++++++++++++++++-------
 5 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 1b8c964b0d17..a9e06c6ccfa4 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1341,6 +1341,12 @@ dad_transmits - INTEGER
 	The amount of Duplicate Address Detection probes to send.
 	Default: 1
 
+flush_addr_on_down - BOOLEAN
+	Flush all IPv6 addresses on an interface down event. If disabled
+	static addresses are not flushed.
+
+	Default: enabled
+
 forwarding - INTEGER
 	Configure interface-specific Host/Router behaviour.
 
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 4d5169f5d7d1..92973b587be0 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -53,6 +53,7 @@ struct ipv6_devconf {
 	__s32           ndisc_notify;
 	__s32		suppress_frag_ndisc;
 	__s32		accept_ra_mtu;
+	__s32		flush_addr_on_down;
 	void		*sysctl;
 };
 
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 98e5f9578f86..3b6323111f77 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -72,6 +72,7 @@ struct inet6_ifaddr {
 	int			regen_count;
 
 	bool			tokenized;
+	bool			managed;
 
 	struct rcu_head		rcu;
 	struct in6_addr		peer_addr;
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 437a6a4b125a..9c31b90db187 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -170,6 +170,7 @@ enum {
 	DEVCONF_ACCEPT_RA_FROM_LOCAL,
 	DEVCONF_USE_OPTIMISTIC,
 	DEVCONF_ACCEPT_RA_MTU,
+	DEVCONF_FLUSH_ADDR_ON_DOWN,
 	DEVCONF_MAX
 };
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 98e4a63d72bb..939a1b37578a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -202,6 +202,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
 	.accept_dad		= 1,
 	.suppress_frag_ndisc	= 1,
 	.accept_ra_mtu		= 1,
+	.flush_addr_on_down	= 1,
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -240,6 +241,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
 	.accept_dad		= 1,
 	.suppress_frag_ndisc	= 1,
 	.accept_ra_mtu		= 1,
+	.flush_addr_on_down	= 1,
 };
 
 /* Check if a valid qdisc is available */
@@ -870,6 +872,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
 	ifa->prefered_lft = prefered_lft;
 	ifa->cstamp = ifa->tstamp = jiffies;
 	ifa->tokenized = false;
+	ifa->managed = false;
 
 	ifa->rt = rt;
 
@@ -2525,6 +2528,8 @@ static int inet6_addr_add(struct net *net, int ifindex,
 			    valid_lft, prefered_lft);
 
 	if (!IS_ERR(ifp)) {
+		ifp->managed = true;
+
 		if (!(ifa_flags & IFA_F_NOPREFIXROUTE)) {
 			addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev,
 					      expires, flags);
@@ -3046,8 +3051,9 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event)
 static int addrconf_ifdown(struct net_device *dev, int how)
 {
 	struct net *net = dev_net(dev);
+	struct inet6_ifaddr *ifa, *tmp;
+	struct list_head del_list;
 	struct inet6_dev *idev;
-	struct inet6_ifaddr *ifa;
 	int state, i;
 
 	ASSERT_RTNL();
@@ -3082,9 +3088,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
 restart:
 		hlist_for_each_entry_rcu(ifa, h, addr_lst) {
 			if (ifa->idev == idev) {
-				hlist_del_init_rcu(&ifa->addr_lst);
 				addrconf_del_dad_work(ifa);
-				goto restart;
+				if (how || idev->cnf.flush_addr_on_down ||
+				    !ifa->managed) {
+					hlist_del_init_rcu(&ifa->addr_lst);
+					goto restart;
+				}
 			}
 		}
 		spin_unlock_bh(&addrconf_hash_lock);
@@ -3118,14 +3127,34 @@ static int addrconf_ifdown(struct net_device *dev, int how)
 		write_lock_bh(&idev->lock);
 	}
 
-	while (!list_empty(&idev->addr_list)) {
-		ifa = list_first_entry(&idev->addr_list,
+	INIT_LIST_HEAD(&del_list);
+	list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) {
+		/* on NETDEV_DOWN events do not flush managed (user configured)
+		 * addresses unless configured to do so. If the address is not
+		 * deleted reset flags and state such that DAD is re-done on a
+		 * subsequent link up.
+		 */
+		if (!how && !idev->cnf.flush_addr_on_down && ifa->managed) {
+			if (!(ifa->flags & IFA_F_NODAD)) {
+				ifa->flags |= IFA_F_TENTATIVE;
+				ifa->state = INET6_IFADDR_STATE_DAD;
+			}
+		} else {
+			list_del(&ifa->if_list);
+			list_add(&ifa->if_list, &del_list);
+		}
+	}
+
+	write_unlock_bh(&idev->lock);
+
+	while (!list_empty(&del_list)) {
+		ifa = list_first_entry(&del_list,
 				       struct inet6_ifaddr, if_list);
+
 		addrconf_del_dad_work(ifa);
 
 		list_del(&ifa->if_list);
 
-		write_unlock_bh(&idev->lock);
 
 		spin_lock_bh(&ifa->state_lock);
 		state = ifa->state;
@@ -3137,12 +3166,8 @@ static int addrconf_ifdown(struct net_device *dev, int how)
 			inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
 		}
 		in6_ifa_put(ifa);
-
-		write_lock_bh(&idev->lock);
 	}
 
-	write_unlock_bh(&idev->lock);
-
 	/* Step 5: Discard anycast and multicast list */
 	if (how) {
 		ipv6_ac_destroy_dev(idev);
@@ -4398,6 +4423,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
 	array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
 	array[DEVCONF_ACCEPT_RA_FROM_LOCAL] = cnf->accept_ra_from_local;
 	array[DEVCONF_ACCEPT_RA_MTU] = cnf->accept_ra_mtu;
+	array[DEVCONF_FLUSH_ADDR_ON_DOWN] = cnf->flush_addr_on_down;
 }
 
 static inline size_t inet6_ifla6_size(void)
@@ -5300,6 +5326,14 @@ static struct addrconf_sysctl_table
 			.proc_handler	= proc_dointvec,
 		},
 		{
+			.procname       = "flush_addr_on_down",
+			.data           = &ipv6_devconf.flush_addr_on_down,
+			.maxlen         = sizeof(int),
+			.mode           = 0644,
+			.proc_handler   = proc_dointvec,
+
+		},
+		{
 			/* sentinel */
 		}
 	},
-- 
1.9.3 (Apple Git-50)

^ permalink raw reply related

* [PATCH next v3 5/6] bonding: Allow userspace to set actors' macaddr in an AD-system.
From: Mahesh Bandewar @ 2015-02-12  4:28 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, Maciej Zenczykowski, netdev, Eric Dumazet

In an AD system, the communication between actor and partner is the
business between these two entiries. In the current setup anyone on the
same L2 can "guess" the LACPDU contents and then possibly send the
spoofed LACPDUs and trick the partner causing connectivity issues for
the AD system. This patch allows to use a random mac-address obscuring
it's identity making it harder for someone in the L2 is do the same thing.

This patch allows user-space to choose the mac-address for the AD-system.
This mac-address can not be NULL or a Multicast. If the mac-address is set
from user-space; kernel will honor it and will not overwrite it. In the
absense (value from user space); the logic will default to using the
masters' mac as the mac-address for the AD-system.

It can be set using example code below -

   # modprobe bonding mode=4
   # sys_mac_addr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
                    $(( (RANDOM & 0xFE) | 0x02 )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )) \
                    $(( RANDOM & 0xFF )))
   # echo $sys_mac_addr > /sys/class/net/bond0/bonding/ad_actor_system
   # echo +eth1 > /sys/class/net/bond0/bonding/slaves
   ...
   # ip link set bond0 up

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
v1:
  Initial version
v2:
  Renamed ad_actor_system_mac_address to ad_actor_system
v3:
  Fixed commit message.

 Documentation/networking/bonding.txt | 12 ++++++++++++
 drivers/net/bonding/bond_3ad.c       |  7 ++++++-
 drivers/net/bonding/bond_main.c      |  1 +
 drivers/net/bonding/bond_options.c   | 29 +++++++++++++++++++++++++++++
 drivers/net/bonding/bond_procfs.c    |  6 ++++++
 drivers/net/bonding/bond_sysfs.c     | 15 +++++++++++++++
 include/net/bond_options.h           |  1 +
 include/net/bonding.h                |  1 +
 8 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index f19d888651b8..f0d93c58cdb0 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -187,6 +187,18 @@ ad_actor_sys_prio
 	This paramter has effect only in 802.3ad mode and is available through
 	SysFs interface.
 
+ad_actor_system
+
+	In an AD system, this specifies the mac-address for the actor in
+	protocol packet exchanges (LACPDUs). The value cannot be NULL or
+	multicast. It is preferred to have the local-admin bit set for this
+	mac but driver does not enforce it. If the value is not given then
+	system defaults to using the masters' mac address as actors' system
+	address.
+
+	This paramter has effect only in 802.3ad mode and is available through
+	SysFs interface.
+
 ad_select
 
 	Specifies the 802.3ad aggregation selection logic to use.  The
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 46aa847a0132..4b28d8cc0e84 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1914,7 +1914,12 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
 
 		BOND_AD_INFO(bond).system.sys_priority =
 			bond->params.ad_actor_sys_prio;
-		BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
+		if (is_zero_ether_addr(bond->params.ad_actor_system))
+			BOND_AD_INFO(bond).system.sys_mac_addr =
+			    *((struct mac_addr *)bond->dev->dev_addr);
+		else
+			BOND_AD_INFO(bond).system.sys_mac_addr =
+			    *((struct mac_addr *)bond->params.ad_actor_system);
 
 		/* initialize how many times this module is called in one
 		 * second (should be about every 100ms)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f8f6a80231b6..f899f3053e82 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4474,6 +4474,7 @@ static int bond_check_params(struct bond_params *params)
 	params->packets_per_slave = packets_per_slave;
 	params->tlb_dynamic_lb = 1; /* Default value */
 	params->ad_actor_sys_prio = ad_actor_sys_prio;
+	eth_zero_addr(params->ad_actor_system);
 	if (packets_per_slave > 0) {
 		params->reciprocal_packets_per_slave =
 			reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 05d5e735eaec..f2c011b3ea33 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -72,6 +72,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
 static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,
 				  const struct bond_opt_value *newval);
+static int bond_option_ad_actor_system_set(struct bonding *bond,
+				  const struct bond_opt_value *newval);
 
 
 static const struct bond_opt_value bond_mode_tbl[] = {
@@ -396,6 +398,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
 		.values = bond_ad_actor_sys_prio_tbl,
 		.set = bond_option_ad_actor_sys_prio_set,
 	},
+	[BOND_OPT_AD_ACTOR_SYSTEM] = {
+		.id = BOND_OPT_AD_ACTOR_SYSTEM,
+		.name = "ad_actor_system",
+		.unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+		.flags = BOND_OPTFLAG_RAWVAL | BOND_OPTFLAG_IFDOWN,
+		.set = bond_option_ad_actor_system_set,
+	},
 };
 
 /* Searches for an option by name */
@@ -1376,3 +1385,23 @@ static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,
 	bond->params.ad_actor_sys_prio = newval->value;
 	return 0;
 }
+
+static int bond_option_ad_actor_system_set(struct bonding *bond,
+					    const struct bond_opt_value *newval)
+{
+	u8 macaddr[ETH_ALEN];
+	int i;
+
+	i = sscanf(newval->string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+		   &macaddr[0], &macaddr[1], &macaddr[2],
+		   &macaddr[3], &macaddr[4], &macaddr[5]);
+
+	if (i != ETH_ALEN || !is_valid_ether_addr(macaddr)) {
+		netdev_err(bond->dev, "Invalid MAC address.\n");
+		return -EINVAL;
+	}
+
+	ether_addr_copy(bond->params.ad_actor_system, macaddr);
+
+	return 0;
+}
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 9e33c48886ef..81452ced852f 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -136,6 +136,8 @@ static void bond_info_show_master(struct seq_file *seq)
 			   optval->string);
 		seq_printf(seq, "System priority: %d\n",
 				BOND_AD_INFO(bond).system.sys_priority);
+		seq_printf(seq, "System MAC address: %pM\n",
+				&BOND_AD_INFO(bond).system.sys_mac_addr);
 
 		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
 			seq_printf(seq, "bond %s has no active aggregator\n",
@@ -198,6 +200,8 @@ static void bond_info_show_slave(struct seq_file *seq,
 			seq_puts(seq, "details actor lacp pdu:\n");
 			seq_printf(seq, "    system priority: %d\n",
 				   port->actor_system_priority);
+			seq_printf(seq, "    system mac address: %pM\n",
+				   &port->actor_system);
 			seq_printf(seq, "    port key: %d\n",
 				   port->actor_oper_port_key);
 			seq_printf(seq, "    port priority: %d\n",
@@ -210,6 +214,8 @@ static void bond_info_show_slave(struct seq_file *seq,
 			seq_puts(seq, "details partner lacp pdu:\n");
 			seq_printf(seq, "    system priority: %d\n",
 				   port->partner_oper.system_priority);
+			seq_printf(seq, "    system mac address: %pM\n",
+				   &port->partner_oper.system);
 			seq_printf(seq, "    oper key: %d\n",
 				   port->partner_oper.key);
 			seq_printf(seq, "    port priority: %d\n",
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 1a4a591a58c9..efa994243a2d 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -706,6 +706,20 @@ static ssize_t bonding_show_ad_actor_sys_prio(struct device *d,
 static DEVICE_ATTR(ad_actor_sys_prio, S_IRUGO | S_IWUSR,
 		   bonding_show_ad_actor_sys_prio, bonding_sysfs_store_option);
 
+static ssize_t bonding_show_ad_actor_system(struct device *d,
+						 struct device_attribute *attr,
+						 char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		return sprintf(buf, "%pM\n", bond->params.ad_actor_system);
+
+	return 0;
+}
+static DEVICE_ATTR(ad_actor_system, S_IRUGO | S_IWUSR,
+		   bonding_show_ad_actor_system, bonding_sysfs_store_option);
+
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
@@ -740,6 +754,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_packets_per_slave.attr,
 	&dev_attr_tlb_dynamic_lb.attr,
 	&dev_attr_ad_actor_sys_prio.attr,
+	&dev_attr_ad_actor_system.attr,
 	NULL,
 };
 
diff --git a/include/net/bond_options.h b/include/net/bond_options.h
index 894002a2620f..eeeefa1d3cd8 100644
--- a/include/net/bond_options.h
+++ b/include/net/bond_options.h
@@ -64,6 +64,7 @@ enum {
 	BOND_OPT_SLAVES,
 	BOND_OPT_TLB_DYNAMIC_LB,
 	BOND_OPT_AD_ACTOR_SYS_PRIO,
+	BOND_OPT_AD_ACTOR_SYSTEM,
 	BOND_OPT_LAST
 };
 
diff --git a/include/net/bonding.h b/include/net/bonding.h
index cb4587f6516e..f24f9862cea9 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -144,6 +144,7 @@ struct bond_params {
 	int tlb_dynamic_lb;
 	struct reciprocal_value reciprocal_packets_per_slave;
 	u16 ad_actor_sys_prio;
+	u8 ad_actor_system[ETH_ALEN];
 };
 
 struct bond_parm_tbl {
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH next v3 2/6] bonding: implement bond_poll_controller()
From: Mahesh Bandewar @ 2015-02-12  4:24 UTC (permalink / raw)
  To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
	Nikolay Aleksandrov, David Miller
  Cc: Mahesh Bandewar, Maciej Zenczykowski, netdev, Eric Dumazet

This patches implements the poll_controller support for all
bonding driver. If the slaves have poll_controller net_op defined,
this implementation calls them. This is mode agnostic implementation
and iterates through all slaves (based on mode) and calls respective
handler.

Signed-off-by: Mahesh Bandewar <maheshb@google.com>
---
v1:
   Initial version
v2:
   Eliminate bool variable.
v3:
   Rebase

 drivers/net/bonding/bond_3ad.c  | 24 ++++++++++++++++++++++++
 drivers/net/bonding/bond_main.c | 33 +++++++++++++++++++++++++++++++++
 include/net/bond_3ad.h          |  1 +
 3 files changed, 58 insertions(+)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 9b436696b95e..14f2ebe786c5 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2477,6 +2477,30 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
 	return ret;
 }
 
+#define BOND_3AD_PORT_OPERATIONAL \
+		(AD_STATE_DISTRIBUTING | AD_STATE_COLLECTING | \
+		 AD_STATE_SYNCHRONIZATION | AD_STATE_AGGREGATION)
+
+static int bond_3ad_port_operational(struct slave *slave)
+{
+	port_t *port = &SLAVE_AD_INFO(slave)->port;
+
+	return bond_slave_can_tx(slave) &&
+	       (port->actor_oper_port_state & port->partner_oper.port_state &
+		BOND_3AD_PORT_OPERATIONAL) == BOND_3AD_PORT_OPERATIONAL;
+}
+
+/* bond_3ad_port_is_active - check if a slave port is active or not. A port
+ * is active when it can forward traffic.
+ *
+ * @slave: slave port to check state for.
+ * Returns: 0 if not active else is active.
+ */
+int bond_3ad_port_is_active(struct slave *slave)
+{
+	return bond_3ad_port_operational(slave);
+}
+
 int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
 			 struct slave *slave)
 {
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b979c265fc51..8433fe464f95 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -928,6 +928,39 @@ static inline void slave_disable_netpoll(struct slave *slave)
 
 static void bond_poll_controller(struct net_device *bond_dev)
 {
+	struct bonding *bond = netdev_priv(bond_dev);
+	struct slave *slave = NULL;
+	struct list_head *iter;
+	struct ad_info ad_info;
+	struct netpoll_info *ni;
+	const struct net_device_ops *ops;
+
+	if (BOND_MODE(bond) == BOND_MODE_8023AD)
+		if (bond_3ad_get_active_agg_info(bond, &ad_info))
+			return;
+
+	bond_for_each_slave(bond, slave, iter) {
+		ops = slave->dev->netdev_ops;
+		if (!bond_slave_is_up(slave) || !ops->ndo_poll_controller)
+			continue;
+
+		if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+			struct aggregator *agg =
+			    SLAVE_AD_INFO(slave)->port.aggregator;
+
+			if (agg && agg->aggregator_identifier !=
+				   ad_info.aggregator_id)
+				continue;
+		    if (!bond_3ad_port_is_active(slave) || ad_info.ports != 1)
+				continue;
+		}
+
+		ni = rcu_dereference_bh(slave->dev->npinfo);
+		if (down_trylock(&ni->dev_lock))
+			continue;
+		ops->ndo_poll_controller(slave->dev);
+		up(&ni->dev_lock);
+	}
 }
 
 static void bond_netpoll_cleanup(struct net_device *bond_dev)
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
index f04cdbb7848e..6c455c646d61 100644
--- a/include/net/bond_3ad.h
+++ b/include/net/bond_3ad.h
@@ -278,5 +278,6 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
 			 struct slave *slave);
 int bond_3ad_set_carrier(struct bonding *bond);
 void bond_3ad_update_lacp_rate(struct bonding *bond);
+int bond_3ad_port_is_active(struct slave *slave);
 #endif /* _NET_BOND_3AD_H */
 
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related

* [PATCH net-next v2 0/3] net: Introducing socket mark receive socket option
From: Eyal Birger @ 2015-02-12  4:32 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, shmulik.ladkani, Eyal Birger

This patch set introduces a new socket option for fetching the mark
of skbs passed to sockets as ancillary data.

A userspace program may wish to receive the mark of packets it
receives, for example for distinguishing between different TPROXY
diversion rules to the same userspace proxy socket.

The patch set includes a minor function renaming, as well as a
change in struct sk_buff for allowing skb->mark to persist after
being queued to the socket queue.

---
Changes in v2:
- Function parameter indentation
- Commit message formatting
---

Eyal Birger (3):
  net: Rename sock_recv_ts_and_drops() to sock_cmsg_recv()
  net: use skb->priority for overloading skb->dropcount and
    skb->reserved_tailroom instead of skb->mark
  net: Introducing socket mark receive socket option

 arch/alpha/include/uapi/asm/socket.h   |  2 ++
 arch/avr32/include/uapi/asm/socket.h   |  2 ++
 arch/cris/include/uapi/asm/socket.h    |  2 ++
 arch/frv/include/uapi/asm/socket.h     |  2 ++
 arch/ia64/include/uapi/asm/socket.h    |  2 ++
 arch/m32r/include/uapi/asm/socket.h    |  2 ++
 arch/mips/include/uapi/asm/socket.h    |  2 ++
 arch/mn10300/include/uapi/asm/socket.h |  2 ++
 arch/parisc/include/uapi/asm/socket.h  |  2 ++
 arch/powerpc/include/uapi/asm/socket.h |  2 ++
 arch/s390/include/uapi/asm/socket.h    |  2 ++
 arch/sparc/include/uapi/asm/socket.h   |  2 ++
 arch/xtensa/include/uapi/asm/socket.h  |  2 ++
 include/linux/skbuff.h                 |  4 ++--
 include/net/sock.h                     | 18 ++++++++++--------
 include/uapi/asm-generic/socket.h      |  2 ++
 net/atm/common.c                       |  2 +-
 net/bluetooth/af_bluetooth.c           |  4 ++--
 net/can/bcm.c                          |  2 +-
 net/can/raw.c                          |  2 +-
 net/core/sock.c                        |  8 ++++++++
 net/ieee802154/socket.c                |  4 ++--
 net/ipv4/raw.c                         |  2 +-
 net/ipv4/udp.c                         |  2 +-
 net/ipv6/raw.c                         |  2 +-
 net/ipv6/udp.c                         |  2 +-
 net/key/af_key.c                       |  2 +-
 net/packet/af_packet.c                 |  2 +-
 net/rxrpc/ar-recvmsg.c                 |  2 +-
 net/sctp/socket.c                      |  2 +-
 net/socket.c                           | 15 ++++++++++++---
 31 files changed, 75 insertions(+), 28 deletions(-)

-- 
2.1.4

^ 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