* [net-next 0/3] bnx2-cnic: Driver Version Upgrades
From: Rasesh Mody @ 2015-02-18 0:26 UTC (permalink / raw)
To: netdev, David Miller; +Cc: Dept-HSGLinuxNICDev, Sony Chacko, Rasesh Mody
Hi Dave,
This patch set includes bnx2 and cnic drivers' re-branding changes, fix for a
chip initialization issue and updates the bnx2 driver version to 2.2.6 and
cnic driver version to 2.5.21.
Please apply these patches to net-next.
Thanks,
Rasesh
Rasesh Mody (3):
bnx2-cnic: Driver Rebranding Changes
bnx2: Fix for Chip Initialization
bnx2-cnic: Driver Version Update
drivers/net/ethernet/broadcom/Kconfig | 8 ++++----
drivers/net/ethernet/broadcom/bnx2.c | 14 ++++++--------
drivers/net/ethernet/broadcom/bnx2.h | 4 ++--
drivers/net/ethernet/broadcom/bnx2_fw.h | 4 ++--
drivers/net/ethernet/broadcom/cnic.c | 6 +++---
drivers/net/ethernet/broadcom/cnic_if.h | 8 ++++----
6 files changed, 21 insertions(+), 23 deletions(-)
--
1.8.2.3
^ permalink raw reply
* [net-next 3/3] bnx2-cnic: Driver Version Update
From: Rasesh Mody @ 2015-02-18 0:26 UTC (permalink / raw)
To: netdev, David Miller; +Cc: Dept-HSGLinuxNICDev, Sony Chacko, Rasesh Mody
In-Reply-To: <1424219180-29028-1-git-send-email-rasesh.mody@qlogic.com>
This patch updates BNX2 driver version to 2.2.6 and CNIC driver version
to 2.5.21.
Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
drivers/net/ethernet/broadcom/bnx2.c | 4 ++--
drivers/net/ethernet/broadcom/cnic_if.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 4b48e21..dcd4bcc 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -58,8 +58,8 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
-#define DRV_MODULE_VERSION "2.2.5"
-#define DRV_MODULE_RELDATE "December 20, 2013"
+#define DRV_MODULE_VERSION "2.2.6"
+#define DRV_MODULE_RELDATE "January 29, 2014"
#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw"
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw"
#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw"
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 7fe0b64..ef6125b 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -15,8 +15,8 @@
#include "bnx2x/bnx2x_mfw_req.h"
-#define CNIC_MODULE_VERSION "2.5.20"
-#define CNIC_MODULE_RELDATE "March 14, 2014"
+#define CNIC_MODULE_VERSION "2.5.21"
+#define CNIC_MODULE_RELDATE "January 29, 2015"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
--
1.8.2.3
^ permalink raw reply related
* [net-next 2/3] bnx2: Fix for Chip Initialization
From: Rasesh Mody @ 2015-02-18 0:26 UTC (permalink / raw)
To: netdev, David Miller; +Cc: Dept-HSGLinuxNICDev, Sony Chacko, Rasesh Mody
In-Reply-To: <1424219180-29028-1-git-send-email-rasesh.mody@qlogic.com>
Do not enable filter SORT MODE in chip init routine. This patch addresses an
issue where BCM5716 sporadically drops packets when changing multicast list.
Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
drivers/net/ethernet/broadcom/bnx2.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 2305de2..4b48e21 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -4984,8 +4984,6 @@ bnx2_init_chip(struct bnx2 *bp)
bp->idle_chk_status_idx = 0xffff;
- bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
-
/* Set up how to generate a link change interrupt. */
BNX2_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
--
1.8.2.3
^ permalink raw reply related
* [net-next 1/3] bnx2-cnic: Driver Rebranding Changes
From: Rasesh Mody @ 2015-02-18 0:26 UTC (permalink / raw)
To: netdev, David Miller; +Cc: Dept-HSGLinuxNICDev, Sony Chacko, Rasesh Mody
In-Reply-To: <1424219180-29028-1-git-send-email-rasesh.mody@qlogic.com>
This patch provides additional changes as a part of BNX2 and CNIC driver
re-branding effort.
Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
drivers/net/ethernet/broadcom/Kconfig | 8 ++++----
drivers/net/ethernet/broadcom/bnx2.c | 8 ++++----
drivers/net/ethernet/broadcom/bnx2.h | 4 ++--
drivers/net/ethernet/broadcom/bnx2_fw.h | 4 ++--
drivers/net/ethernet/broadcom/cnic.c | 6 +++---
drivers/net/ethernet/broadcom/cnic_if.h | 4 ++--
6 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index c3e260c..7849dd1 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -72,12 +72,12 @@ config BCMGENET
Broadcom BCM7xxx Set Top Box family chipset.
config BNX2
- tristate "QLogic NetXtremeII support"
+ tristate "QLogic bnx2 support"
depends on PCI
select CRC32
select FW_LOADER
---help---
- This driver supports QLogic NetXtremeII gigabit Ethernet cards.
+ This driver supports QLogic bnx2 gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called bnx2. This is recommended.
@@ -88,8 +88,8 @@ config CNIC
select BNX2
select UIO
---help---
- This driver supports offload features of QLogic NetXtremeII
- gigabit Ethernet cards.
+ This driver supports offload features of QLogic bnx2 gigabit
+ Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called cnic. This is recommended.
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 823d01c..2305de2 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -1,7 +1,7 @@
-/* bnx2.c: QLogic NX2 network driver.
+/* bnx2.c: QLogic bnx2 network driver.
*
* Copyright (c) 2004-2014 Broadcom Corporation
- * Copyright (c) 2014 QLogic Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
*
* 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
@@ -72,10 +72,10 @@
#define TX_TIMEOUT (5*HZ)
static char version[] =
- "QLogic NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+ "QLogic " DRV_MODULE_NAME " Gigabit Ethernet Driver v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
-MODULE_DESCRIPTION("QLogic NetXtreme II BCM5706/5708/5709/5716 Driver");
+MODULE_DESCRIPTION("QLogic BCM5706/5708/5709/5716 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_FIRMWARE(FW_MIPS_FILE_06);
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h
index 28df35d..f92f76c 100644
--- a/drivers/net/ethernet/broadcom/bnx2.h
+++ b/drivers/net/ethernet/broadcom/bnx2.h
@@ -1,7 +1,7 @@
-/* bnx2.h: QLogic NX2 network driver.
+/* bnx2.h: QLogic bnx2 network driver.
*
* Copyright (c) 2004-2014 Broadcom Corporation
- * Copyright (c) 2014 QLogic Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
*
* 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
diff --git a/drivers/net/ethernet/broadcom/bnx2_fw.h b/drivers/net/ethernet/broadcom/bnx2_fw.h
index 7db79c2..b0f2cca 100644
--- a/drivers/net/ethernet/broadcom/bnx2_fw.h
+++ b/drivers/net/ethernet/broadcom/bnx2_fw.h
@@ -1,7 +1,7 @@
-/* bnx2_fw.h: QLogic NX2 network driver.
+/* bnx2_fw.h: QLogic bnx2 network driver.
*
* Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
- * Copyright (c) 2014 QLogic Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
*
* 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
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index f05fab6..17c145f 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -1,7 +1,7 @@
/* cnic.c: QLogic CNIC core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
- * Copyright (c) 2014 QLogic Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
*
* 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
@@ -58,11 +58,11 @@
#define CNIC_MODULE_NAME "cnic"
static char version[] =
- "QLogic NetXtreme II CNIC Driver " CNIC_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
+ "QLogic " CNIC_MODULE_NAME "Driver v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com> and John(Zongxi) "
"Chen (zongxi@broadcom.com");
-MODULE_DESCRIPTION("QLogic NetXtreme II CNIC Driver");
+MODULE_DESCRIPTION("QLogic cnic Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(CNIC_MODULE_VERSION);
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 8bb36c1..7fe0b64 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -1,7 +1,7 @@
-/* cnic_if.h: QLogic CNIC core network driver.
+/* cnic_if.h: QLogic cnic core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
- * Copyright (c) 2014 QLogic Corporation
+ * Copyright (c) 2014-2015 QLogic Corporation
*
* 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
--
1.8.2.3
^ permalink raw reply related
* Re: [PATCH RFC 0/2] net: dsa: integration with SWITCHDEV for HW bridging
From: Florian Fainelli @ 2015-02-18 1:09 UTC (permalink / raw)
To: Scott Feldman
Cc: Netdev, David S. Miller, vivien.didelot, jerome.oufella, linux,
andrew, cphealy
In-Reply-To: <CAE4R7bDFJn=ZMNDnDovY62eQyv4aSBR0VdhB8yoF+JLCTaS+kw@mail.gmail.com>
On 17/02/15 16:48, Scott Feldman wrote:
> On Tue, Feb 17, 2015 at 2:26 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
>> Hi all,
>>
>> This patchset is mostly to demonstrate how we could integrate with SWITCHDEV
>> to provide HW bridging support for DSA switch drivers that are currently in
>> tree. Since 'net-next' is currently closed, this gives us some time to work
>> on the abstraction we want to have in DSA to facilitate our life.
>>
>> Attached is an example of how this winds up looking like for the bcm_sf2 driver.
>
> It looks good Florian.
>
> Does bcm_sf2 do mac/vlan learning?
>
Yes, it can do that, that's next on my list of things to get working ;)
--
Florian
^ permalink raw reply
* Re: [PATCH net-next] netfilter: Remove uses of return value of seq_printf/puts/putc
From: Joe Perches @ 2015-02-18 1:19 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, LKML
In-Reply-To: <1424136309.8287.8.camel@perches.com>
On Mon, 2015-02-16 at 17:25 -0800, Joe Perches wrote:
> These functions are soon going to return void so remove the
> return value uses.
>
> Convert the return value to test seq_has_overflowed() instead.
Please do not apply.
These need conversions not to "return seq_has_
> Signed-off-by: Joe Perches <joe@perches.com>
> ---
> net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 4 +++-
> net/netfilter/nf_conntrack_acct.c | 8 +++++---
> net/netfilter/nf_conntrack_expect.c | 4 +++-
> net/netfilter/nfnetlink_log.c | 12 +++++++-----
> 4 files changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
> index a460a87..b03b801 100644
> --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
> +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
> @@ -300,7 +300,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
> __nf_ct_l3proto_find(exp->tuple.src.l3num),
> __nf_ct_l4proto_find(exp->tuple.src.l3num,
> exp->tuple.dst.protonum));
> - return seq_putc(s, '\n');
> + seq_putc(s, '\n');
> +
> + return seq_has_overflowed(s);
> }
>
> static const struct seq_operations exp_seq_ops = {
> diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
> index a4b5e2a..4d291dc 100644
> --- a/net/netfilter/nf_conntrack_acct.c
> +++ b/net/netfilter/nf_conntrack_acct.c
> @@ -47,9 +47,11 @@ seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir)
> return 0;
>
> counter = acct->counter;
> - return seq_printf(s, "packets=%llu bytes=%llu ",
> - (unsigned long long)atomic64_read(&counter[dir].packets),
> - (unsigned long long)atomic64_read(&counter[dir].bytes));
> + seq_printf(s, "packets=%llu bytes=%llu ",
> + (unsigned long long)atomic64_read(&counter[dir].packets),
> + (unsigned long long)atomic64_read(&counter[dir].bytes));
> +
> + return seq_has_overflowed(s);
> };
> EXPORT_SYMBOL_GPL(seq_print_acct);
>
> diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
> index 91a1837..1abf92f 100644
> --- a/net/netfilter/nf_conntrack_expect.c
> +++ b/net/netfilter/nf_conntrack_expect.c
> @@ -561,7 +561,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
> helper->expect_policy[expect->class].name);
> }
>
> - return seq_putc(s, '\n');
> + seq_putc(s, '\n');
> +
> + return seq_has_overflowed(s);
> }
>
> static const struct seq_operations exp_seq_ops = {
> diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
> index 11d85b3..3e016ff 100644
> --- a/net/netfilter/nfnetlink_log.c
> +++ b/net/netfilter/nfnetlink_log.c
> @@ -998,11 +998,13 @@ static int seq_show(struct seq_file *s, void *v)
> {
> const struct nfulnl_instance *inst = v;
>
> - return seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n",
> - inst->group_num,
> - inst->peer_portid, inst->qlen,
> - inst->copy_mode, inst->copy_range,
> - inst->flushtimeout, atomic_read(&inst->use));
> + seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n",
> + inst->group_num,
> + inst->peer_portid, inst->qlen,
> + inst->copy_mode, inst->copy_range,
> + inst->flushtimeout, atomic_read(&inst->use));
> +
> + return seq_has_overflowed(s);
> }
>
> static const struct seq_operations nful_seq_ops = {
>
>
> --
> 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] netfilter: Remove uses of return value of seq_printf/puts/putc
From: Joe Perches @ 2015-02-18 1:20 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, LKML
In-Reply-To: <1424136309.8287.8.camel@perches.com>
On Mon, 2015-02-16 at 17:25 -0800, Joe Perches wrote:
> These functions are soon going to return void so remove the
> return value uses.
>
> Convert the return value to test seq_has_overflowed() instead.
(sorry 'bout that, overly sensitive mouse)
Please do not apply.
These need conversions to "return 0"
not "return seq_has_overflowed()";
^ permalink raw reply
* Re: [PATCH RFC 1/2] net: dsa: integrate with SWITCHDEV for HW bridging
From: Andrew Lunn @ 2015-02-18 1:19 UTC (permalink / raw)
To: Florian Fainelli
Cc: netdev, davem, vivien.didelot, jerome.oufella, linux, cphealy
In-Reply-To: <1424201196-4901-2-git-send-email-f.fainelli@gmail.com>
> +/* Return a bitmask of all ports being currently bridged. Note that on
> + * leave, the mask will still return the bitmask of ports currently bridged,
> + * prior to port removal, and this is exactly what we want.
> + */
> +static u32 dsa_slave_br_port_mask(struct dsa_switch *ds)
> +{
> + unsigned int port;
> + u32 mask = 0;
> +
> + for (port = 0; port < DSA_MAX_PORTS; port++) {
> + if (!((1 << port) & ds->phys_port_mask))
> + continue;
> +
> + if (ds->ports[port]->priv_flags & IFF_BRIDGE_PORT)
> + mask |= 1 << port;
> + }
> +
> + return mask;
> +}
> +
> +static int dsa_slave_bridge_port_join(struct net_device *dev,
> + struct net_device *bridge)
> +{
> + struct dsa_slave_priv *p = netdev_priv(dev);
> + struct dsa_switch *ds = p->parent;
> + int ret = -EOPNOTSUPP;
> +
> + if (ds->drv->port_join_bridge)
> + ret = ds->drv->port_join_bridge(ds, p->port,
> + dsa_slave_br_port_mask(ds));
Hi Florian
Shouldn't this bridge port mask also be dependent on bridge?
I'm thinking of cases like
brctl addbr br0
brctl addif br0 lan0
brctl addif br0 lan1
brctl addbr br1
brctl addif br1 lan2
brctl addif br1 lan3
We have two software bridges, so need two masks. It does look like
your hardware and the Marvell hardware supports this, disjoint sets of
bridged ports. But with the current implementation, your going to end
up with one hardware bridge with four ports, and broken STP.
Andrew
^ permalink raw reply
* Re: [PATCH] colons are invalid characters in netdev names
From: Stephen Hemminger @ 2015-02-18 1:28 UTC (permalink / raw)
To: Matthew Thode; +Cc: davem, netdev, linux-kernel
In-Reply-To: <1424214942-17581-1-git-send-email-mthode@mthode.org>
On Tue, 17 Feb 2015 17:15:42 -0600
Matthew Thode <mthode@mthode.org> wrote:
> colons are used as a separator in netdev device lookup in dev_ioctl.c
>
> Specific functions are SIOCGIFTXQLEN SIOCETHTOOL SIOCSIFNAME
>
> Signed-off-by: Matthew Thode <mthode@mthode.org>
What is the exact sequence that causes the problem?
SIOCSIFNAME already strips of colon.
^ permalink raw reply
* Re: [PATCH] colons are invalid characters in netdev names
From: Matthew Thode @ 2015-02-18 1:33 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: davem, netdev, linux-kernel
In-Reply-To: <20150217192803.21a63afd@uryu.home.lan>
[-- Attachment #1: Type: text/plain, Size: 700 bytes --]
On 02/17/2015 07:28 PM, Stephen Hemminger wrote:
> On Tue, 17 Feb 2015 17:15:42 -0600
> Matthew Thode <mthode@mthode.org> wrote:
>
>> colons are used as a separator in netdev device lookup in dev_ioctl.c
>>
>> Specific functions are SIOCGIFTXQLEN SIOCETHTOOL SIOCSIFNAME
>>
>> Signed-off-by: Matthew Thode <mthode@mthode.org>
>
> What is the exact sequence that causes the problem?
> SIOCSIFNAME already strips of colon.
>
>
It strips the name one access, not creation. You can create a dummy
device and not access it, escaping doesn't seem to help.
ip link add name foo:asdasd type dummy
ip link del dev foo:asdasd # will not be deleted
--
Matthew Thode
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* [PATCH v2 net-next 1/2] igmp v6: add __ipv6_sock_mc_join and __ipv6_sock_mc_drop
From: Madhu Challa @ 2015-02-18 1:19 UTC (permalink / raw)
To: eric.dumazet, netdev; +Cc: Madhu Challa
Based on the igmp v4 changes from Eric Dumazet.
These changes are needed to perform igmp v6 join/leave while
RTNL is held.
Make ipv6_sock_mc_join and ipv6_sock_mc_drop wrappers around
__ipv6_sock_mc_join and __ipv6_sock_mc_drop to avoid
proliferation of work queues.
Signed-off-by: Madhu Challa <challa@noironetworks.com>
---
include/net/ipv6.h | 8 ++++++++
net/ipv6/mcast.c | 41 ++++++++++++++++++++++++++++++++---------
2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 4c9fe22..b767306 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -940,4 +940,12 @@ int ipv6_sysctl_register(void);
void ipv6_sysctl_unregister(void);
#endif
+int ipv6_sock_mc_join(struct sock *sk, int ifindex,
+ const struct in6_addr *addr);
+int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
+ const struct in6_addr *addr);
+int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+ const struct in6_addr *addr);
+int __ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+ const struct in6_addr *addr);
#endif /* _NET_IPV6_H */
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 5ce107c..f4a76b1 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -132,7 +132,7 @@ static int unsolicited_report_interval(struct inet6_dev *idev)
return iv > 0 ? iv : 1;
}
-int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
+int __ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
{
struct net_device *dev = NULL;
struct ipv6_mc_socklist *mc_lst;
@@ -140,6 +140,8 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
struct net *net = sock_net(sk);
int err;
+ ASSERT_RTNL();
+
if (!ipv6_addr_is_multicast(addr))
return -EINVAL;
@@ -161,7 +163,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
mc_lst->next = NULL;
mc_lst->addr = *addr;
- rtnl_lock();
if (ifindex == 0) {
struct rt6_info *rt;
rt = rt6_lookup(net, addr, NULL, 0, 0);
@@ -173,7 +174,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
dev = __dev_get_by_index(net, ifindex);
if (dev == NULL) {
- rtnl_unlock();
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
return -ENODEV;
}
@@ -190,7 +190,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
err = ipv6_dev_mc_inc(dev, addr);
if (err) {
- rtnl_unlock();
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
return err;
}
@@ -198,25 +197,38 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
mc_lst->next = np->ipv6_mc_list;
rcu_assign_pointer(np->ipv6_mc_list, mc_lst);
- rtnl_unlock();
return 0;
}
+EXPORT_SYMBOL(__ipv6_sock_mc_join);
+
+int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
+{
+ int ret;
+
+ rtnl_lock();
+ ret = __ipv6_sock_mc_join(sk, ifindex, addr);
+ rtnl_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(ipv6_sock_mc_join);
/*
* socket leave on multicast group
*/
-int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
+int __ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct ipv6_mc_socklist *mc_lst;
struct ipv6_mc_socklist __rcu **lnk;
struct net *net = sock_net(sk);
+ ASSERT_RTNL();
+
if (!ipv6_addr_is_multicast(addr))
return -EINVAL;
- rtnl_lock();
for (lnk = &np->ipv6_mc_list;
(mc_lst = rtnl_dereference(*lnk)) != NULL;
lnk = &mc_lst->next) {
@@ -235,17 +247,28 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
__ipv6_dev_mc_dec(idev, &mc_lst->addr);
} else
(void) ip6_mc_leave_src(sk, mc_lst, NULL);
- rtnl_unlock();
atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
kfree_rcu(mc_lst, rcu);
return 0;
}
}
- rtnl_unlock();
return -EADDRNOTAVAIL;
}
+EXPORT_SYMBOL(__ipv6_sock_mc_drop);
+
+int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
+{
+ int ret;
+
+ rtnl_lock();
+ ret = __ipv6_sock_mc_drop(sk, ifindex, addr);
+ rtnl_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(ipv6_sock_mc_drop);
/* called with rcu_read_lock() */
static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
--
1.9.1
^ permalink raw reply related
* [PATCH v2 net-next 2/2] multicast: Extend ip address command to enable multicast group join/leave on IP level.
From: Madhu Challa @ 2015-02-18 1:19 UTC (permalink / raw)
To: eric.dumazet, netdev; +Cc: Madhu Challa
In-Reply-To: <1424222346-12736-1-git-send-email-challa@noironetworks.com>
Joining multicast group on ethernet level via "ip maddr" command would
not work if we have an Ethernet switch that does igmp snooping since
the switch would not replicate multicast packets on ports that did not
have IGMP reports for the multicast addresses.
Linux vxlan interfaces created via "ip link add vxlan" have the group option
that enables then to do the required join.
By extending ip address command with option "autojoin" we can get similar
functionality for openvswitch vxlan interfaces as well as other tunneling
mechanisms that need to receive multicast traffic. The kernel code is
structured similar to how the vxlan driver does a group join / leave.
example:
ip address add 224.1.1.10/24 dev eth5 autojoin
ip address del 224.1.1.10/24 dev eth5
v2 address review comments from Eric Dumazet.
This patch applies on top of
[PATCH net-next] igmp: add __ip_mc_{join|leave}_group()
by Eric Dumazet. and
igmp v6: add __ipv6_sock_mc_join and __ipv6_sock_mc_drop
remove the work queue and call the __ip_mc_{join|leave}_group
and the ipv6 variant __ipv6_sock_mc_{join|drop}
Signed-off-by: Madhu Challa <challa@noironetworks.com>
---
include/net/netns/ipv4.h | 1 +
include/net/netns/ipv6.h | 1 +
include/uapi/linux/if_addr.h | 1 +
net/ipv4/devinet.c | 36 ++++++++++++++++++++++++++++++++++++
net/ipv4/igmp.c | 17 +++++++++++++++++
net/ipv6/addrconf.c | 35 ++++++++++++++++++++++++++++++++++-
net/ipv6/mcast.c | 20 ++++++++++++++++----
7 files changed, 106 insertions(+), 5 deletions(-)
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index dbe2254..9c1f01e 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -47,6 +47,7 @@ struct netns_ipv4 {
#endif
struct hlist_head *fib_table_hash;
struct sock *fibnl;
+ struct sock *mc_autojoin_sock;
struct sock * __percpu *icmp_sk;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 69ae41f..fd2cef8 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -67,6 +67,7 @@ struct netns_ipv6 {
struct sock *ndisc_sk;
struct sock *tcp_sk;
struct sock *igmp_sk;
+ struct sock *mc_autojoin_sock;
#ifdef CONFIG_IPV6_MROUTE
#ifndef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
struct mr6_table *mrt6;
diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h
index dea10a8..40fdfea 100644
--- a/include/uapi/linux/if_addr.h
+++ b/include/uapi/linux/if_addr.h
@@ -50,6 +50,7 @@ enum {
#define IFA_F_PERMANENT 0x80
#define IFA_F_MANAGETEMPADDR 0x100
#define IFA_F_NOPREFIXROUTE 0x200
+#define IFA_F_MCAUTOJOIN 0x400
struct ifa_cacheinfo {
__u32 ifa_prefered;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index f0b4a31..1dc5ad4 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -548,6 +548,26 @@ struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
return NULL;
}
+static int ip_mc_config(struct sock *sk, bool join, __be32 saddr, int ifindex)
+{
+ int ret;
+ struct ip_mreqn mreq = {
+ .imr_multiaddr.s_addr = saddr,
+ .imr_ifindex = ifindex,
+ };
+
+ ASSERT_RTNL();
+
+ lock_sock(sk);
+ if (join)
+ ret = __ip_mc_join_group(sk, &mreq);
+ else
+ ret = __ip_mc_leave_group(sk, &mreq);
+ release_sock(sk);
+
+ return ret;
+}
+
static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
{
struct net *net = sock_net(skb->sk);
@@ -584,6 +604,11 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
!inet_ifa_match(nla_get_be32(tb[IFA_ADDRESS]), ifa)))
continue;
+ if (ipv4_is_multicast(ifa->ifa_address)) {
+ ip_mc_config(net->ipv4.mc_autojoin_sock,
+ false, ifa->ifa_address,
+ ifa->ifa_dev->dev->ifindex);
+ }
__inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).portid);
return 0;
}
@@ -825,6 +850,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
struct in_ifaddr *ifa_existing;
__u32 valid_lft = INFINITY_LIFE_TIME;
__u32 prefered_lft = INFINITY_LIFE_TIME;
+ int ret;
ASSERT_RTNL();
@@ -838,6 +864,16 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
* userspace already relies on not having to provide this.
*/
set_ifa_lifetime(ifa, valid_lft, prefered_lft);
+ if (ifa->ifa_flags & IFA_F_MCAUTOJOIN) {
+ WARN_ON(!ipv4_is_multicast(ifa->ifa_address));
+ ret = ip_mc_config(net->ipv4.mc_autojoin_sock,
+ true, ifa->ifa_address,
+ ifa->ifa_dev->dev->ifindex);
+ if (ret < 0) {
+ inet_free_ifa(ifa);
+ return ret;
+ }
+ }
return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid);
} else {
inet_free_ifa(ifa);
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 4b1172d..1a66960 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -2740,6 +2740,8 @@ static const struct file_operations igmp_mcf_seq_fops = {
static int __net_init igmp_net_init(struct net *net)
{
struct proc_dir_entry *pde;
+ int err;
+ struct socket *sock = NULL;
pde = proc_create("igmp", S_IRUGO, net->proc_net, &igmp_mc_seq_fops);
if (!pde)
@@ -2748,8 +2750,16 @@ static int __net_init igmp_net_init(struct net *net)
&igmp_mcf_seq_fops);
if (!pde)
goto out_mcfilter;
+ err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
+ if (err < 0)
+ goto out_sock;
+ sk_change_net(sock->sk, net);
+ net->ipv4.mc_autojoin_sock = sock->sk;
+
return 0;
+out_sock:
+ remove_proc_entry("mcfilter", net->proc_net);
out_mcfilter:
remove_proc_entry("igmp", net->proc_net);
out_igmp:
@@ -2758,8 +2768,15 @@ out_igmp:
static void __net_exit igmp_net_exit(struct net *net)
{
+ struct sock *sk = net->ipv4.mc_autojoin_sock;
+
remove_proc_entry("mcfilter", net->proc_net);
remove_proc_entry("igmp", net->proc_net);
+ if (sk) {
+ kernel_sock_shutdown(sk->sk_socket, SHUT_RDWR);
+ sk_release_kernel(sk);
+ net->ipv4.mc_autojoin_sock = NULL;
+ }
}
static struct pernet_operations igmp_net_ops = {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 98e4a63..00807a7 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2464,6 +2464,23 @@ err_exit:
return err;
}
+static int ipv6_mc_config(struct sock *sk, bool join,
+ const struct in6_addr *addr, int ifindex)
+{
+ int ret;
+
+ ASSERT_RTNL();
+
+ lock_sock(sk);
+ if (join)
+ ret = __ipv6_sock_mc_join(sk, ifindex, addr);
+ else
+ ret = __ipv6_sock_mc_drop(sk, ifindex, addr);
+ release_sock(sk);
+
+ return ret;
+}
+
/*
* Manual configuration of address on an interface
*/
@@ -2480,6 +2497,7 @@ static int inet6_addr_add(struct net *net, int ifindex,
u32 flags;
clock_t expires;
unsigned long timeout;
+ int ret;
ASSERT_RTNL();
@@ -2501,6 +2519,14 @@ static int inet6_addr_add(struct net *net, int ifindex,
if (IS_ERR(idev))
return PTR_ERR(idev);
+ if (ifa_flags & IFA_F_MCAUTOJOIN) {
+ WARN_ON(!ipv6_addr_is_multicast(pfx));
+ ret = ipv6_mc_config(net->ipv6.mc_autojoin_sock,
+ true, pfx, ifindex);
+ if (ret < 0)
+ return ret;
+ }
+
scope = ipv6_addr_scope(pfx);
timeout = addrconf_timeout_fixup(valid_lft, HZ);
@@ -2542,6 +2568,9 @@ static int inet6_addr_add(struct net *net, int ifindex,
in6_ifa_put(ifp);
addrconf_verify_rtnl();
return 0;
+ } else if (ifa_flags & IFA_F_MCAUTOJOIN) {
+ ipv6_mc_config(net->ipv6.mc_autojoin_sock,
+ false, pfx, ifindex);
}
return PTR_ERR(ifp);
@@ -2578,6 +2607,10 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
jiffies);
ipv6_del_addr(ifp);
addrconf_verify_rtnl();
+ if (ipv6_addr_is_multicast(pfx)) {
+ ipv6_mc_config(net->ipv6.mc_autojoin_sock,
+ false, pfx, dev->ifindex);
+ }
return 0;
}
}
@@ -3945,7 +3978,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
/* We ignore other flags so far. */
ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR |
- IFA_F_NOPREFIXROUTE;
+ IFA_F_NOPREFIXROUTE | IFA_F_MCAUTOJOIN;
ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
if (ifa == NULL) {
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f4a76b1..5b1261f 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2930,20 +2930,32 @@ static int __net_init igmp6_net_init(struct net *net)
inet6_sk(net->ipv6.igmp_sk)->hop_limit = 1;
+ err = inet_ctl_sock_create(&net->ipv6.mc_autojoin_sock, PF_INET6,
+ SOCK_RAW, IPPROTO_ICMPV6, net);
+ if (err < 0) {
+ pr_err("Failed to initialize the IGMP6 autojoin socket (err %d)\n",
+ err);
+ goto out_sock_create;
+ }
+
err = igmp6_proc_init(net);
if (err)
- goto out_sock_create;
-out:
- return err;
+ goto out_sock_create_autojoin;
+
+ return 0;
+out_sock_create_autojoin:
+ inet_ctl_sock_destroy(net->ipv6.mc_autojoin_sock);
out_sock_create:
inet_ctl_sock_destroy(net->ipv6.igmp_sk);
- goto out;
+out:
+ return err;
}
static void __net_exit igmp6_net_exit(struct net *net)
{
inet_ctl_sock_destroy(net->ipv6.igmp_sk);
+ inet_ctl_sock_destroy(net->ipv6.mc_autojoin_sock);
igmp6_proc_exit(net);
}
--
1.9.1
^ permalink raw reply related
* Re: [PATCH RFC 1/2] net: dsa: integrate with SWITCHDEV for HW bridging
From: Florian Fainelli @ 2015-02-18 1:43 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, davem, vivien.didelot, jerome.oufella, linux, cphealy,
Scott Feldman, Jiri Pirko
In-Reply-To: <20150218011955.GA17155@lunn.ch>
On 17/02/15 17:19, Andrew Lunn wrote:
>> +/* Return a bitmask of all ports being currently bridged. Note that on
>> + * leave, the mask will still return the bitmask of ports currently bridged,
>> + * prior to port removal, and this is exactly what we want.
>> + */
>> +static u32 dsa_slave_br_port_mask(struct dsa_switch *ds)
>> +{
>> + unsigned int port;
>> + u32 mask = 0;
>> +
>> + for (port = 0; port < DSA_MAX_PORTS; port++) {
>> + if (!((1 << port) & ds->phys_port_mask))
>> + continue;
>> +
>> + if (ds->ports[port]->priv_flags & IFF_BRIDGE_PORT)
>> + mask |= 1 << port;
>> + }
>> +
>> + return mask;
>> +}
>> +
>> +static int dsa_slave_bridge_port_join(struct net_device *dev,
>> + struct net_device *bridge)
>> +{
>> + struct dsa_slave_priv *p = netdev_priv(dev);
>> + struct dsa_switch *ds = p->parent;
>> + int ret = -EOPNOTSUPP;
>> +
>> + if (ds->drv->port_join_bridge)
>> + ret = ds->drv->port_join_bridge(ds, p->port,
>> + dsa_slave_br_port_mask(ds));
>
> Hi Florian
>
> Shouldn't this bridge port mask also be dependent on bridge?
Yes, you are very right, thankfully this is a RFC patch because of that ;)
>
> I'm thinking of cases like
>
> brctl addbr br0
> brctl addif br0 lan0
> brctl addif br0 lan1
>
> brctl addbr br1
> brctl addif br1 lan2
mask = 0x4 | 0x2 | 0x1 # FAIL
> brctl addif br1 lan3
mask = 0x8 | 0x4 | 0x2 | 0x1 # FAIL
>
> We have two software bridges, so need two masks. It does look like
> your hardware and the Marvell hardware supports this, disjoint sets of
> bridged ports. But with the current implementation, your going to end
> up with one hardware bridge with four ports, and broken STP.
Yep, I will rework that patch set to address that, and I can actually
test that, which is even better, thanks!
--
Florian
^ permalink raw reply
* Re: [PATCH RFC 1/2] net: dsa: integrate with SWITCHDEV for HW bridging
From: Guenter Roeck @ 2015-02-18 3:53 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: netdev, davem, vivien.didelot, jerome.oufella, cphealy
In-Reply-To: <20150218011955.GA17155@lunn.ch>
On 02/17/2015 05:19 PM, Andrew Lunn wrote:
>> +/* Return a bitmask of all ports being currently bridged. Note that on
>> + * leave, the mask will still return the bitmask of ports currently bridged,
>> + * prior to port removal, and this is exactly what we want.
>> + */
>> +static u32 dsa_slave_br_port_mask(struct dsa_switch *ds)
>> +{
>> + unsigned int port;
>> + u32 mask = 0;
>> +
>> + for (port = 0; port < DSA_MAX_PORTS; port++) {
>> + if (!((1 << port) & ds->phys_port_mask))
>> + continue;
>> +
>> + if (ds->ports[port]->priv_flags & IFF_BRIDGE_PORT)
>> + mask |= 1 << port;
>> + }
>> +
>> + return mask;
>> +}
>> +
>> +static int dsa_slave_bridge_port_join(struct net_device *dev,
>> + struct net_device *bridge)
>> +{
>> + struct dsa_slave_priv *p = netdev_priv(dev);
>> + struct dsa_switch *ds = p->parent;
>> + int ret = -EOPNOTSUPP;
>> +
>> + if (ds->drv->port_join_bridge)
>> + ret = ds->drv->port_join_bridge(ds, p->port,
>> + dsa_slave_br_port_mask(ds));
>
> Hi Florian
>
> Shouldn't this bridge port mask also be dependent on bridge?
>
> I'm thinking of cases like
>
> brctl addbr br0
> brctl addif br0 lan0
> brctl addif br0 lan1
>
> brctl addbr br1
> brctl addif br1 lan2
> brctl addif br1 lan3
>
> We have two software bridges, so need two masks. It does look like
> your hardware and the Marvell hardware supports this, disjoint sets of
> bridged ports. But with the current implementation, your going to end
> up with one hardware bridge with four ports, and broken STP.
>
Same problem here.
With the code above I see the ports which are part of "a" bridge group,
but I can not determine which group the port is supposed to join.
I don't really see the value in providing the port mask to
port_join_bridge, but maybe I am missing something. In my
implementation I just passed on bridge * and used it to
determine which port belongs to which bridge group.
It doesn't have to be that, but maybe we can use the bridge
ifindex or anything else that lets me determine which bridge
group the port belongs to.
Guenter
^ permalink raw reply
* Re: [PATCH] vhost: support upto 509 memory regions
From: Michael S. Tsirkin @ 2015-02-18 4:27 UTC (permalink / raw)
To: Eric Northup
Cc: Paolo Bonzini, Igor Mammedov, Linux Kernel Mailing List, KVM,
netdev
In-Reply-To: <CAG7+5M1N53tXU72W1i937xZHxc7+sF=JhA6+QWmcarNnApbgiw@mail.gmail.com>
On Tue, Feb 17, 2015 at 04:53:45PM -0800, Eric Northup wrote:
> On Tue, Feb 17, 2015 at 4:32 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > On Tue, Feb 17, 2015 at 11:59:48AM +0100, Paolo Bonzini wrote:
> >>
> >>
> >> On 17/02/2015 10:02, Michael S. Tsirkin wrote:
> >> > > Increasing VHOST_MEMORY_MAX_NREGIONS from 65 to 509
> >> > > to match KVM_USER_MEM_SLOTS fixes issue for vhost-net.
> >> > >
> >> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> >> >
> >> > This scares me a bit: each region is 32byte, we are talking
> >> > a 16K allocation that userspace can trigger.
> >>
> >> What's bad with a 16K allocation?
> >
> > It fails when memory is fragmented.
> >
> >> > How does kvm handle this issue?
> >>
> >> It doesn't.
> >>
> >> Paolo
> >
> > I'm guessing kvm doesn't do memory scans on data path,
> > vhost does.
> >
> > qemu is just doing things that kernel didn't expect it to need.
> >
> > Instead, I suggest reducing number of GPA<->HVA mappings:
> >
> > you have GPA 1,5,7
> > map them at HVA 11,15,17
> > then you can have 1 slot: 1->11
> >
> > To avoid libc reusing the memory holes, reserve them with MAP_NORESERVE
> > or something like this.
>
> This works beautifully when host virtual address bits are more
> plentiful than guest physical address bits. Not all architectures
> have that property, though.
AFAIK this is pretty much a requirement for both kvm and vhost,
as we require each guest page to also be mapped in qemu memory.
> > We can discuss smarter lookup algorithms but I'd rather
> > userspace didn't do things that we then have to
> > work around in kernel.
> >
> >
> > --
> > MST
> > --
> > To unsubscribe from this list: send the line "unsubscribe kvm" 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: getting a list of naked interface names from iproute2
From: Matthew Thode @ 2015-02-18 4:45 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20150217102358.67b9d826@uryu.home.lan>
[-- Attachment #1: Type: text/plain, Size: 1287 bytes --]
On 02/17/2015 09:23 AM, Stephen Hemminger wrote:
> On Mon, 16 Feb 2015 18:07:12 -0600
> Matthew Thode <mthode@mthode.org> wrote:
>
>> iproute2 seems to like to add @ and : info to it's output. This makes
>> parsing it hard for things like neutron (openstack). I have a patch to
>> slightly update it (still missing some things, I'll link it at the end
>> if interested). Is there a better way of getting interface names from
>> iproute2 without having to strip out at characters like '@' and ':'?
>>
>> changeset in neutron: https://review.openstack.org/#/c/154128/
>> link to current code:
>> https://github.com/openstack/neutron/blob/master/neutron/agent/linux/ip_lib.py#L110-L131
>>
>> I'd appreciate your help, I'd rather not have to go through each link
>> type to pull it's delimiter, but if needed I guess it's needed.
>>
>
> Stop screenscraping, and use a real API.
> All of the above would work better:
> 1. Libc if_nameindex
> 2. Legacy ioctl(SIOCGIFCONF)
> 3. Netlink NLMMSG_REQ (RTM_GETLINK)
> 4. Sysfs /sys/class/net
>
Do you happen to know a way to request it for a specific namespace?
going over the links in /sys/class/net only gets you the current
namespace (was the easiest method to do in python2.7).
--
Matthew Thode
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH RFC 1/2] net: dsa: integrate with SWITCHDEV for HW bridging
From: Florian Fainelli @ 2015-02-18 4:53 UTC (permalink / raw)
To: Guenter Roeck
Cc: Andrew Lunn, netdev, David Miller, Vivien Didelot, jerome.oufella,
Chris Healy
In-Reply-To: <54E40CC9.2000505@roeck-us.net>
2015-02-17 19:53 GMT-08:00 Guenter Roeck <linux@roeck-us.net>:
> On 02/17/2015 05:19 PM, Andrew Lunn wrote:
>>>
>>> +/* Return a bitmask of all ports being currently bridged. Note that on
>>> + * leave, the mask will still return the bitmask of ports currently
>>> bridged,
>>> + * prior to port removal, and this is exactly what we want.
>>> + */
>>> +static u32 dsa_slave_br_port_mask(struct dsa_switch *ds)
>>> +{
>>> + unsigned int port;
>>> + u32 mask = 0;
>>> +
>>> + for (port = 0; port < DSA_MAX_PORTS; port++) {
>>> + if (!((1 << port) & ds->phys_port_mask))
>>> + continue;
>>> +
>>> + if (ds->ports[port]->priv_flags & IFF_BRIDGE_PORT)
>>> + mask |= 1 << port;
>>> + }
>>> +
>>> + return mask;
>>> +}
>>> +
>>> +static int dsa_slave_bridge_port_join(struct net_device *dev,
>>> + struct net_device *bridge)
>>> +{
>>> + struct dsa_slave_priv *p = netdev_priv(dev);
>>> + struct dsa_switch *ds = p->parent;
>>> + int ret = -EOPNOTSUPP;
>>> +
>>> + if (ds->drv->port_join_bridge)
>>> + ret = ds->drv->port_join_bridge(ds, p->port,
>>> +
>>> dsa_slave_br_port_mask(ds));
>>
>>
>> Hi Florian
>>
>> Shouldn't this bridge port mask also be dependent on bridge?
>>
>> I'm thinking of cases like
>>
>> brctl addbr br0
>> brctl addif br0 lan0
>> brctl addif br0 lan1
>>
>> brctl addbr br1
>> brctl addif br1 lan2
>> brctl addif br1 lan3
>>
>> We have two software bridges, so need two masks. It does look like
>> your hardware and the Marvell hardware supports this, disjoint sets of
>> bridged ports. But with the current implementation, your going to end
>> up with one hardware bridge with four ports, and broken STP.
>>
>
> Same problem here.
>
> With the code above I see the ports which are part of "a" bridge group,
> but I can not determine which group the port is supposed to join.
I have put a v2 here which addresses that by retaining which bridge
the port was added to and comparing that against the bridge net_device
we want to join:
https://github.com/ffainelli/linux/tree/dsa-hw-bridge-v2
>
> I don't really see the value in providing the port mask to
> port_join_bridge, but maybe I am missing something. In my
> implementation I just passed on bridge * and used it to
> determine which port belongs to which bridge group.
> It doesn't have to be that, but maybe we can use the bridge
> ifindex or anything else that lets me determine which bridge
> group the port belongs to.
As I described in the cover letter, I tend to think that resolving
this bitmask is part of the abstraction DSA should provide to its
driver, maybe it is more future proof and better to give access to the
bridge net_device pointer such that drivers can figure out the bridge
details themselves. With that in mind, maybe we can do something like
this:
- add the bridge net_device pointer to the join/leave callbacks
- provide a helper like dsa_slave_br_port_mask that drivers use or not
--
Florian
^ permalink raw reply
* Re: [PATCH net v2] ematch: Fix auto-loading of ematch modules.
From: Cong Wang @ 2015-02-18 5:17 UTC (permalink / raw)
To: Ignacy Gawędzki, netdev
In-Reply-To: <20150217191520.GA15405@zenon.in.qult.net>
On Tue, Feb 17, 2015 at 11:15 AM, Ignacy Gawędzki
<ignacy.gawedzki@green-communications.fr> wrote:
> In tcf_em_validate(), after calling request_module() to load the
> kind-specific module, set em->ops to NULL before returning -EAGAIN, so
> that module_put() is not called again by tcf_em_tree_destroy().
>
> Signed-off-by: Ignacy Gawędzki <ignacy.gawedzki@green-communications.fr>
Acked-by: Cong Wang <cwang@twopensource.com>
^ permalink raw reply
* Re: [PATCH RFC 1/2] net: dsa: integrate with SWITCHDEV for HW bridging
From: Guenter Roeck @ 2015-02-18 6:14 UTC (permalink / raw)
To: Florian Fainelli
Cc: Andrew Lunn, netdev, David Miller, Vivien Didelot, jerome.oufella,
Chris Healy
In-Reply-To: <CAGVrzcZNEz6+peBAaSfadFf+wf9p=8EJ0yqBVZqAmnfEaPDFPA@mail.gmail.com>
On 02/17/2015 08:53 PM, Florian Fainelli wrote:
> 2015-02-17 19:53 GMT-08:00 Guenter Roeck <linux@roeck-us.net>:
[...]
>
> I have put a v2 here which addresses that by retaining which bridge
> the port was added to and comparing that against the bridge net_device
> we want to join:
>
> https://github.com/ffainelli/linux/tree/dsa-hw-bridge-v2
>
>>
>> I don't really see the value in providing the port mask to
>> port_join_bridge, but maybe I am missing something. In my
>> implementation I just passed on bridge * and used it to
>> determine which port belongs to which bridge group.
>> It doesn't have to be that, but maybe we can use the bridge
>> ifindex or anything else that lets me determine which bridge
>> group the port belongs to.
>
> As I described in the cover letter, I tend to think that resolving
> this bitmask is part of the abstraction DSA should provide to its
> driver, maybe it is more future proof and better to give access to the
> bridge net_device pointer such that drivers can figure out the bridge
> details themselves. With that in mind, maybe we can do something like
> this:
>
> - add the bridge net_device pointer to the join/leave callbacks
> - provide a helper like dsa_slave_br_port_mask that drivers use or not
>
Not sure if that is needed.
At first glance v2 should do it. I only use the bridge pointer
to create a set of bit masks, one for each bridge group. This is
pretty much what you do now. So I should have the information I need,
and it should actually simplify my code to some degree.
Unfortunately I won't be able to work on this for the next few days,
since I'll be at the Linux Collaboration Summit in Santa Rosa.
Guenter
^ permalink raw reply
* Setting RPS affinities from network driver
From: Sunil Kovvuri @ 2015-02-18 6:16 UTC (permalink / raw)
To: netdev, David S. Miller
Hi,
I am writing a network driver for a multicore SOC with a on-board
network interface and would like to set RPS affinities from driver by
default. So that the network performance is good with whatever driver
supplied. Ofcourse these can be further adjusted from userspace
anyways.
Is there a way to set RPS settings from driver itself ?
The only issue i am seeing is while setting 'rps_needed' key.
static_key_slow_inc(&rps_needed);
Currently this is not exported, so having issues while compiling
driver as module.
If i export this symbol, will it be acceptable ?
Thanks,
Sunil.
^ permalink raw reply
* [PATCH next v4 1/6] bonding: Verify RX LACPDU has proper dest mac-addr
From: Mahesh Bandewar @ 2015-02-18 7:17 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-v4:
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 v4 3/6] bonding: Implement port churn-machine (AD standard 43.4.17).
From: Mahesh Bandewar @ 2015-02-18 7:17 UTC (permalink / raw)
To: Jay Vosburgh, Andy Gospodarek, Veaceslav Falico,
Nikolay Aleksandrov, David Miller
Cc: Mahesh Bandewar, Maciej Zenczykowski, netdev, Eric Dumazet
The Churn 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, agreement between Actor and Partner should be reached
very rapidly. Continued failure to reach agreement can be symptomatic of
device failure.
Actor-churn-detection 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-v4:
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 9b436696b95e..c728ece78154 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 f04cdbb7848e..22ac75dd8bd5 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 v4 4/6] bonding: Allow userspace to set actors' system_priority in AD system
From: Mahesh Bandewar @ 2015-02-18 7:17 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-v4:
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 c728ece78154..d847e6951e71 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 f6bdaae7519d..c7aa1e4d5ccc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4136,6 +4136,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) {
@@ -4430,6 +4431,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);
@@ -4458,6 +4471,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 next v4 5/6] bonding: Allow userspace to set actors' macaddr in an AD-system.
From: Mahesh Bandewar @ 2015-02-18 7:17 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 entities. 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
absence (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.
v4:
Rebase
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 d847e6951e71..d5eacac7daba 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 c7aa1e4d5ccc..45c148431595 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4472,6 +4472,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 v4 6/6] bonding: Implement user key part of port_key in an AD system.
From: Mahesh Bandewar @ 2015-02-18 7:17 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-v4:
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 d5eacac7daba..cac1aa249626 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 45c148431595..ce543df28eee 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4137,6 +4137,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) {
@@ -4441,6 +4442,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) {
@@ -4473,6 +4482,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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox