Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next-2.6] netns: net_identifiers should be read_mostly
From: Eric Dumazet @ 2009-11-17 20:42 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Netdev List

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 drivers/net/bonding/bond_main.c         |    2 +-
 drivers/net/ppp_generic.c               |    2 +-
 drivers/net/pppoe.c                     |    2 +-
 drivers/net/pppol2tp.c                  |    2 +-
 net/8021q/vlan.c                        |    2 +-
 net/ipv4/ip_gre.c                       |    2 +-
 net/ipv4/ipip.c                         |    2 +-
 net/ipv6/ip6_tunnel.c                   |    2 +-
 net/ipv6/sit.c                          |    2 +-
 net/key/af_key.c                        |    2 +-
 net/netfilter/nf_conntrack_proto_dccp.c |    2 +-
 net/netfilter/nf_conntrack_proto_gre.c  |    2 +-
 net/phonet/pn_dev.c                     |    2 +-
 13 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ecea6c2..726bd75 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -158,7 +158,7 @@ MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the
 static const char * const version =
 	DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
-int bond_net_id;
+int bond_net_id __read_mostly;
 
 static __be32 arp_target[BOND_MAX_ARP_TARGETS];
 static int arp_ip_count;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 9bf2a6b..de64f64 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -184,7 +184,7 @@ static atomic_t ppp_unit_count = ATOMIC_INIT(0);
 static atomic_t channel_count = ATOMIC_INIT(0);
 
 /* per-net private data for this module */
-static int ppp_net_id;
+static int ppp_net_id __read_mostly;
 struct ppp_net {
 	/* units to ppp mapping */
 	struct idr units_idr;
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 60c8d23..a1dcba2 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -97,7 +97,7 @@ static const struct proto_ops pppoe_ops;
 static struct ppp_channel_ops pppoe_chan_ops;
 
 /* per-net private data for this module */
-static int pppoe_net_id;
+static int pppoe_net_id __read_mostly;
 struct pppoe_net {
 	/*
 	 * we could use _single_ hash table for all
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 849cc9c..442c382 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -232,7 +232,7 @@ static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
 static const struct proto_ops pppol2tp_ops;
 
 /* per-net private data for this module */
-static int pppol2tp_net_id;
+static int pppol2tp_net_id __read_mostly;
 struct pppol2tp_net {
 	struct list_head pppol2tp_tunnel_list;
 	rwlock_t pppol2tp_tunnel_list_lock;
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 39f8d01..d9cb020 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -41,7 +41,7 @@
 
 /* Global VLAN variables */
 
-int vlan_net_id;
+int vlan_net_id __read_mostly;
 
 /* Our listing of VLAN group(s) */
 static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index a7de9e3..c5f6af5 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -125,7 +125,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev);
 
 #define HASH_SIZE  16
 
-static int ipgre_net_id;
+static int ipgre_net_id __read_mostly;
 struct ipgre_net {
 	struct ip_tunnel *tunnels[4][HASH_SIZE];
 
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index c5b1f71..7242ffc 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -119,7 +119,7 @@
 #define HASH_SIZE  16
 #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
 
-static int ipip_net_id;
+static int ipip_net_id __read_mostly;
 struct ipip_net {
 	struct ip_tunnel *tunnels_r_l[HASH_SIZE];
 	struct ip_tunnel *tunnels_r[HASH_SIZE];
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 1d61411..e5c0f6b 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -78,7 +78,7 @@ static void ip6_fb_tnl_dev_init(struct net_device *dev);
 static void ip6_tnl_dev_init(struct net_device *dev);
 static void ip6_tnl_dev_setup(struct net_device *dev);
 
-static int ip6_tnl_net_id;
+static int ip6_tnl_net_id __read_mostly;
 struct ip6_tnl_net {
 	/* the IPv6 tunnel fallback device */
 	struct net_device *fb_tnl_dev;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b6e145a..d9deaa7 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -66,7 +66,7 @@ static void ipip6_fb_tunnel_init(struct net_device *dev);
 static void ipip6_tunnel_init(struct net_device *dev);
 static void ipip6_tunnel_setup(struct net_device *dev);
 
-static int sit_net_id;
+static int sit_net_id __read_mostly;
 struct sit_net {
 	struct ip_tunnel *tunnels_r_l[HASH_SIZE];
 	struct ip_tunnel *tunnels_r[HASH_SIZE];
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 86b2c22..478c8b3 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -35,7 +35,7 @@
 #define _X2KEY(x) ((x) == XFRM_INF ? 0 : (x))
 #define _KEY2X(x) ((x) == 0 ? XFRM_INF : (x))
 
-static int pfkey_net_id;
+static int pfkey_net_id __read_mostly;
 struct netns_pfkey {
 	/* List of all pfkey sockets. */
 	struct hlist_head table;
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 1b816a2..80abdf2 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -384,7 +384,7 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
 };
 
 /* this module per-net specifics */
-static int dccp_net_id;
+static int dccp_net_id __read_mostly;
 struct dccp_net {
 	int dccp_loose;
 	unsigned int dccp_timeout[CT_DCCP_MAX + 1];
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index a54a0af..91d0e71 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -43,7 +43,7 @@
 #define GRE_TIMEOUT		(30 * HZ)
 #define GRE_STREAM_TIMEOUT	(180 * HZ)
 
-static int proto_gre_net_id;
+static int proto_gre_net_id __read_mostly;
 struct netns_proto_gre {
 	rwlock_t		keymap_lock;
 	struct list_head	keymap_list;
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 3287f8f..d5ad794 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -43,7 +43,7 @@ struct phonet_net {
 	struct phonet_routes routes;
 };
 
-int phonet_net_id;
+int phonet_net_id __read_mostly;
 
 struct phonet_device_list *phonet_device_list(struct net *net)
 {

^ permalink raw reply related

* [RFC v2] mac80211: disallow bridging managed/adhoc interfaces
From: Johannes Berg @ 2009-11-17 20:48 UTC (permalink / raw)
  To: netdev; +Cc: linux-wireless, Stephen Hemminger, Felix Fietkau
In-Reply-To: <1258465585.3682.7.camel@johannes.local>

A number of people have tried to add a wireless interface
(in managed mode) to a bridge and then complained that it
doesn't work. It cannot work, however, because in 802.11
networks all packets need to be acknowledged and as such
need to be sent to the right address. Promiscuous doesn't
help here. The wireless address format used for these
links has only space for three addresses, the
 * transmitter, which must be equal to the sender (origin)
 * receiver (on the wireless medium), which is the AP in
   the case of managed mode
 * the recipient (destination), which is on the APs local
   network segment

In an IBSS, it is similar, but the receiver and recipient
must match and the third address is used as the BSSID.

To avoid such mistakes in the future, disallow adding a
wireless interface to a bridge.

Felix has recently added a four-address mode to the AP
and client side that can be used (after negotiating that
it is possible, which must happen out-of-band by setting
up both sides) for bridging, so allow that case.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
v2: * change error code as requested by Michael
    * disallow changing wireless mode on a bridged iface

Should more (all?) of this be in cfg80211?

 include/linux/if.h   |    1 +
 net/bridge/br_if.c   |    4 ++++
 net/mac80211/cfg.c   |    9 ++++++++-
 net/mac80211/iface.c |   22 ++++++++++++++++++++--
 4 files changed, 33 insertions(+), 3 deletions(-)

--- wireless-testing.orig/include/linux/if.h	2009-11-17 14:18:36.000000000 +0100
+++ wireless-testing/include/linux/if.h	2009-11-17 14:19:04.000000000 +0100
@@ -70,6 +70,7 @@
 #define IFF_XMIT_DST_RELEASE 0x400	/* dev_hard_start_xmit() is allowed to
 					 * release skb->dst
 					 */
+#define IFF_DONT_BRIDGE 0x800		/* disallow bridging this ether dev */
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- wireless-testing.orig/net/bridge/br_if.c	2009-11-17 14:19:17.000000000 +0100
+++ wireless-testing/net/bridge/br_if.c	2009-11-17 15:07:59.000000000 +0100
@@ -390,6 +390,10 @@ int br_add_if(struct net_bridge *br, str
 	if (dev->br_port != NULL)
 		return -EBUSY;
 
+	/* No bridging devices that dislike that (e.g. wireless) */
+	if (dev->priv_flags & IFF_DONT_BRIDGE)
+		return -EOPNOTSUPP;
+
 	p = new_nbp(br, dev);
 	if (IS_ERR(p))
 		return PTR_ERR(p);
--- wireless-testing.orig/net/mac80211/cfg.c	2009-11-17 14:21:24.000000000 +0100
+++ wireless-testing/net/mac80211/cfg.c	2009-11-17 14:37:13.000000000 +0100
@@ -106,8 +106,15 @@ static int ieee80211_change_iface(struct
 					    params->mesh_id_len,
 					    params->mesh_id);
 
-	if (params->use_4addr >= 0)
+	if (params->use_4addr >= 0) {
 		sdata->use_4addr = !!params->use_4addr;
+		sdata->dev->priv_flags &= ~IFF_DONT_BRIDGE;
+
+		if ((sdata->vif.type == NL80211_IFTYPE_STATION ||
+		     sdata->vif.type == NL80211_IFTYPE_ADHOC) &&
+		    !sdata->use_4addr)
+			sdata->dev->priv_flags |= IFF_DONT_BRIDGE;
+	}
 
 	if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
 		return 0;
--- wireless-testing.orig/net/mac80211/iface.c	2009-11-17 14:20:19.000000000 +0100
+++ wireless-testing/net/mac80211/iface.c	2009-11-17 17:56:08.000000000 +0100
@@ -745,6 +745,11 @@ int ieee80211_if_change_type(struct ieee
 	if (type == sdata->vif.type)
 		return 0;
 
+	/* if it's part of a bridge, reject changing type to station/ibss */
+	if (sdata->dev->br_port && (type == NL80211_IFTYPE_ADHOC ||
+				    type == NL80211_IFTYPE_STATION))
+		return -EBUSY;
+
 	/* Setting ad-hoc mode on non-IBSS channel is not supported. */
 	if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS &&
 	    type == NL80211_IFTYPE_ADHOC)
@@ -769,6 +774,11 @@ int ieee80211_if_change_type(struct ieee
 			sdata->local->hw.conf.channel->band);
 	sdata->drop_unencrypted = 0;
 	sdata->use_4addr = 0;
+	if (sdata->vif.type == NL80211_IFTYPE_STATION ||
+	    sdata->vif.type == NL80211_IFTYPE_ADHOC)
+		sdata->dev->priv_flags |= IFF_DONT_BRIDGE;
+	else
+		sdata->dev->priv_flags &= ~IFF_DONT_BRIDGE;
 
 	return 0;
 }
@@ -843,8 +853,16 @@ int ieee80211_if_add(struct ieee80211_lo
 					    params->mesh_id_len,
 					    params->mesh_id);
 
-	if (params && params->use_4addr >= 0)
-		sdata->use_4addr = !!params->use_4addr;
+	if (sdata->vif.type == NL80211_IFTYPE_STATION ||
+	    sdata->vif.type == NL80211_IFTYPE_ADHOC)
+		sdata->dev->priv_flags |= IFF_DONT_BRIDGE;
+	else
+		sdata->dev->priv_flags &= ~IFF_DONT_BRIDGE;
+
+	if (params && params->use_4addr > 0) {
+		sdata->use_4addr = true;
+		sdata->dev->priv_flags &= ~IFF_DONT_BRIDGE;
+	}
 
 	mutex_lock(&local->iflist_mtx);
 	list_add_tail_rcu(&sdata->list, &local->interfaces);



^ permalink raw reply

* Re: Shared i2c adapter locking
From: Stephen Rothwell @ 2009-11-17 20:59 UTC (permalink / raw)
  To: Jean Delvare
  Cc: Ben Hutchings, David Miller, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-next-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mika Kuoppala, Linux I2C
In-Reply-To: <20091117103554.03971b2f-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>

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

Hi Jean,

On Tue, 17 Nov 2009 10:35:54 +0100 Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org> wrote:
>
> Haven't you read this:
> http://www.spinics.net/lists/linux-next/msg07839.html
> 
> and the 3 following posts?

Somehow I missed that, sorry :-(

> If you did and something is still not clear, please let me know. My
> understanding is that the action token is in David's hands now.

OK, I will await developments :-)

-- 
Cheers,
Stephen Rothwell                    sfr-3FnU+UHB4dNDw9hX6IcOSA@public.gmane.org
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* [net-next PATCH 1/1] qlge: Bonding fix for mode 6.
From: Ron Mercer @ 2009-11-17 21:10 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer

Allow MAC address to be changed even if device is not up.

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 drivers/net/qlge/qlge_main.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index e2ee47d..7692299 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3951,9 +3951,6 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
 	struct sockaddr *addr = p;
 	int status;
 
-	if (netif_running(ndev))
-		return -EBUSY;
-
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 	memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
-- 
1.6.0.2


^ permalink raw reply related

* RE: [PATCH] e1000e: Fix usage under kexec
From: Tantilov, Emil S @ 2009-11-17 21:28 UTC (permalink / raw)
  To: Stefan Assmann, Sven Anders; +Cc: netdev
In-Reply-To: <4B026B24.5040108@redhat.com>

Stefan Assmann wrote:
> On 09.11.2009 21:25, Sven Anders wrote:
>> Hello!
>> 
>> We're experiencing the following problem:
>> 
>> We start a minimal linux system, prepare the system and start the
>> final system via kexec. On two different systems (one with a 82573
>> and one with a 82574), the driver cannot initialize the network
>> hardware, because the PHY is not recognized. 
>> 
>> We get the following error:
>>   e1000e: probe of 0000:02:00.0 failed with error -2
> 
> Hi Sven,
> 
> have a look at the following thread, it seems very similar.
> http://kerneltrap.org/mailarchive/linux-netdev/2009/3/7/5114394
> 
>   Stefan
> --
> Stefan Assmann         | Red Hat GmbH
> Software Engineer      | Otto-Hahn-Strasse 20, 85609 Dornach
>                        | HR: Amtsgericht Muenchen HRB 153243
>                        | GF: Brendan Lane, Charlie Peters,
> sassmann at redhat.com |     Michael Cunningham, Charles Cachera

But there is already similar code in e1000e:
http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=4f9de721ab73a5271a79b126f7b5140b01a05c99

^ permalink raw reply

* Re: [PATCH 1/2] rps: core implementation
From: Jarek Poplawski @ 2009-11-17 21:32 UTC (permalink / raw)
  To: Tom Herbert; +Cc: David Miller, netdev
In-Reply-To: <65634d660911102253o2b4f7a19kfed5849e5c88bfe1@mail.gmail.com>

Tom Herbert wrote, On 11/11/2009 07:53 AM:

> Third version of RPS.
> 
> Signed-off-by: Tom Herbert <therbert@google.com>
...
> +static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb)
> +{
> +	u32 addr1, addr2, ports;
> +	struct ipv6hdr *ip6;
> +	struct iphdr *ip;
> +	u32 hash, ihl;
> +	u8 ip_proto;
> +	int cpu;
> +	struct rps_map *map = NULL;
> +
> +	if (dev->rps_num_maps) {
> +		/*
> +		 * Locate the map corresponding to the NAPI queue that
> +		 * the packet was received on.
> +		 */
> +		int index = skb_get_rx_queue(skb);
> +		if (index < 0 || index >= dev->rps_num_maps)

skb_get_rx_queue() returns u16, so 'index < 0' seems wrong here.

Jarek P.

^ permalink raw reply

* RE: [PATCH] e1000e: Fix usage under kexec
From: Tantilov, Emil S @ 2009-11-17 21:34 UTC (permalink / raw)
  To: Stefan Assmann, Sven Anders; +Cc: netdev
In-Reply-To: <4B026B24.5040108@redhat.com>

Stefan Assmann wrote:
> On 09.11.2009 21:25, Sven Anders wrote:
>> Hello!
>> 
>> We're experiencing the following problem:
>> 
>> We start a minimal linux system, prepare the system and start the
>> final system via kexec. On two different systems (one with a 82573
>> and one with a 82574), the driver cannot initialize the network
>> hardware, because the PHY is not recognized. 
>> 
>> We get the following error:
>>   e1000e: probe of 0000:02:00.0 failed with error -2
> 
> Hi Sven,
> 
> have a look at the following thread, it seems very similar.
> http://kerneltrap.org/mailarchive/linux-netdev/2009/3/7/5114394
> 
>   Stefan
> --
> Stefan Assmann         | Red Hat GmbH
> Software Engineer      | Otto-Hahn-Strasse 20, 85609 Dornach
>                        | HR: Amtsgericht Muenchen HRB 153243
>                        | GF: Brendan Lane, Charlie Peters,
> sassmann at redhat.com |     Michael Cunningham, Charles Cachera

Ignore my previous email - wrong click sent it sooner than intended.

There is already similar code in e1000e:
http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=4f9de721ab73a5271a79b126f7b5140b01a05c99


Sven, could you provide some additional information about your system and kernel/driver verison you used when the issue occurred?

I have not been able to reproduce it on my setup.

Thanks,
Emil

^ permalink raw reply

* [RFC PATCH 1/4] net: Add support to netdev ops for changing hardware queue MAC and VLAN filters
From: Jeff Kirsher @ 2009-11-17 21:50 UTC (permalink / raw)
  To: davem, shemminger; +Cc: netdev, gospo, Mitch Williams, Jeff Kirsher

From: Williams, Mitch A <mitch.a.williams@intel.com>

Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 include/linux/netdevice.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7043f85..6a70365 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -610,6 +610,8 @@ struct netdev_queue {
  *	this function is called when a VLAN id is unregistered.
  *
  * void (*ndo_poll_controller)(struct net_device *dev);
+ * int (*ndo_set_queue_mac)(struct net_device *dev, int queue, u8* mac);
+ * int (*ndo_set_queue_vlan)(struct net_device *dev, int queue, u16 vlan);
  */
 #define HAVE_NET_DEVICE_OPS
 struct net_device_ops {
@@ -659,6 +661,10 @@ struct net_device_ops {
 #define HAVE_NETDEV_POLL
 	void                    (*ndo_poll_controller)(struct net_device *dev);
 #endif
+	int			(*ndo_set_queue_mac)(struct net_device *dev,
+						     int queue, u8 *mac);
+	int			(*ndo_set_queue_vlan)(struct net_device *dev,
+						      int queue, u16 vlan);
 #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
 	int			(*ndo_fcoe_enable)(struct net_device *dev);
 	int			(*ndo_fcoe_disable)(struct net_device *dev);


^ permalink raw reply related

* [RFC PATCH 2/4] rtnetlink: Add support to rtnetlink for setting hardware queue MAC and VLAN filters
From: Jeff Kirsher @ 2009-11-17 21:50 UTC (permalink / raw)
  To: davem, shemminger; +Cc: netdev, gospo, Mitch Williams, Jeff Kirsher
In-Reply-To: <20091117214923.15119.98918.stgit@localhost.localdomain>

From: Williams, Mitch A <mitch.a.williams@intel.com>

Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 include/linux/if_link.h |   14 ++++++++++++++
 net/core/rtnetlink.c    |   27 +++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 1d3b242..44d3726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum {
 #define IFLA_LINKINFO IFLA_LINKINFO
 	IFLA_NET_NS_PID,
 	IFLA_IFALIAS,
+	IFLA_QUEUE_MAC,		/* Hardware queue specific attributes */
+	IFLA_QUEUE_VLAN,
 	__IFLA_MAX
 };
 
@@ -181,4 +183,16 @@ struct ifla_vlan_qos_mapping {
 	__u32 to;
 };
 
+/* subqueue managment section */
+
+struct ifla_queue_mac {
+	__u32 queue;
+	__u8 mac[32];	/* MAX_ADDR_LEN */
+};
+
+struct ifla_queue_vlan {
+	__u32 queue;
+	__u32 vlan;
+};
+
 #endif /* _LINUX_IF_LINK_H */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 33148a5..ad65683 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -725,6 +725,10 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
 	[IFLA_LINKINFO]		= { .type = NLA_NESTED },
 	[IFLA_NET_NS_PID]	= { .type = NLA_U32 },
 	[IFLA_IFALIAS]	        = { .type = NLA_STRING, .len = IFALIASZ-1 },
+	[IFLA_QUEUE_MAC]	= { .type = NLA_BINARY,
+				    .len = sizeof(struct ifla_queue_mac) },
+	[IFLA_QUEUE_VLAN]	= { .type = NLA_BINARY,
+				    .len = sizeof(struct ifla_queue_vlan) },
 };
 EXPORT_SYMBOL(ifla_policy);
 
@@ -898,6 +902,29 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
 		write_unlock_bh(&dev_base_lock);
 	}
 
+	if (tb[IFLA_QUEUE_MAC]) {
+		struct ifla_queue_mac *iqm;
+		iqm = nla_data(tb[IFLA_QUEUE_MAC]);
+		write_lock_bh(&dev_base_lock);
+		if (ops->ndo_set_queue_mac)
+			err = ops->ndo_set_queue_mac(dev, iqm->queue, iqm->mac);
+		write_unlock_bh(&dev_base_lock);
+		if (err < 0)
+			goto errout;
+		modified = 1;
+	}
+
+	if (tb[IFLA_QUEUE_VLAN]) {
+		struct ifla_queue_vlan *iqv;
+		iqv = nla_data(tb[IFLA_QUEUE_VLAN]);
+		write_lock_bh(&dev_base_lock);
+		if (ops->ndo_set_queue_vlan)
+			ops->ndo_set_queue_vlan(dev, iqv->queue, iqv->vlan);
+		write_unlock_bh(&dev_base_lock);
+		if (err < 0)
+			goto errout;
+		modified = 1;
+	}
 	err = 0;
 
 errout:


^ permalink raw reply related

* [RFC PATCH 3/4] igb: Add support to igb for setting MAC and VLAN filters to hardware queues
From: Jeff Kirsher @ 2009-11-17 21:50 UTC (permalink / raw)
  To: davem, shemminger; +Cc: netdev, gospo, Mitch Williams, Jeff Kirsher
In-Reply-To: <20091117214923.15119.98918.stgit@localhost.localdomain>

From: Williams, Mitch A <mitch.a.williams@intel.com>

This is currently only supported in SR-IOV mode.

Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.h |    3 +
 drivers/net/igb/e1000_regs.h  |    1 
 drivers/net/igb/igb.h         |    2 +
 drivers/net/igb/igb_main.c    |   90 ++++++++++++++++++++++++++++++++++++-----
 4 files changed, 86 insertions(+), 10 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index b3808ca..c2d2b33 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -214,6 +214,9 @@ struct e1000_adv_tx_context_desc {
 #define E1000_VLVF_LVLAN          0x00100000
 #define E1000_VLVF_VLANID_ENABLE  0x80000000
 
+#define E1000_VMVIR_VLANA_DEFAULT	0x40000000 /* Always use default VLAN */
+#define E1000_VMVIR_VLANA_NEVER		0x80000000 /* Never insert VLAN tag */
+
 #define E1000_IOVCTL 0x05BBC
 #define E1000_IOVCTL_REUSE_VFQ 0x00000001
 
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index 934e03b..42e8528 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -307,6 +307,7 @@
 #define E1000_VMOLR(_n)        (0x05AD0 + (4 * (_n)))
 #define E1000_VLVF(_n)         (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
                                                        * Filter - RW */
+#define E1000_VMVIR(_n)        (0x03700 + (4 * (_n)))
 
 #define wr32(reg, value) (writel(value, hw->hw_addr + reg))
 #define rd32(reg) (readl(hw->hw_addr + reg))
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 63abd1c..0a55cd2 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -75,11 +75,13 @@ struct vf_data_storage {
 	u16 vlans_enabled;
 	u32 flags;
 	unsigned long last_nack;
+	u16 pf_vlan; /* When set, guest VLAN config not allowed. */
 };
 
 #define IGB_VF_FLAG_CTS            0x00000001 /* VF is clear to send data */
 #define IGB_VF_FLAG_UNI_PROMISC    0x00000002 /* VF has unicast promisc */
 #define IGB_VF_FLAG_MULTI_PROMISC  0x00000004 /* VF has multicast promisc */
+#define IGB_VF_FLAG_PF_SET_MAC     0x00000008 /* PF has set MAC address */
 
 /* RX descriptor control thresholds.
  * PTHRESH - MAC will consider prefetch if it has fewer than this number of
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 0cab5e2..67773e3 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -128,6 +128,9 @@ static void igb_msg_task(struct igb_adapter *);
 static void igb_vmm_control(struct igb_adapter *);
 static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *);
 static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
+static int igb_set_queue_mac(struct net_device *netdev, int queue, u8 *mac);
+static int igb_set_queue_vlan(struct net_device *netdev, int queue, u16 vlan);
+
 
 #ifdef CONFIG_PM
 static int igb_suspend(struct pci_dev *, pm_message_t);
@@ -1302,6 +1305,8 @@ static const struct net_device_ops igb_netdev_ops = {
 	.ndo_vlan_rx_register	= igb_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= igb_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= igb_vlan_rx_kill_vid,
+	.ndo_set_queue_mac	= igb_set_queue_mac,
+	.ndo_set_queue_vlan	= igb_set_queue_vlan,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= igb_netpoll,
 #endif
@@ -2379,7 +2384,8 @@ static void igb_rlpml_set(struct igb_adapter *adapter)
 	wr32(E1000_RLPML, max_frame_size);
 }
 
-static inline void igb_set_vmolr(struct igb_adapter *adapter, int vfn)
+static inline void igb_set_vmolr(struct igb_adapter *adapter,
+				 int vfn, bool aupe)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 vmolr;
@@ -2392,8 +2398,11 @@ static inline void igb_set_vmolr(struct igb_adapter *adapter, int vfn)
 		return;
 
 	vmolr = rd32(E1000_VMOLR(vfn));
-	vmolr |= E1000_VMOLR_AUPE |        /* Accept untagged packets */
-	         E1000_VMOLR_STRVLAN;      /* Strip vlan tags */
+	vmolr |= E1000_VMOLR_STRVLAN;      /* Strip vlan tags */
+	if (aupe)
+		vmolr |= E1000_VMOLR_AUPE;   /* Accept untagged packets */
+	else
+		vmolr &= ~(E1000_VMOLR_AUPE); /* Tagged packets ONLY */
 
 	/* clear all bits that might not be set */
 	vmolr &= ~(E1000_VMOLR_BAM | E1000_VMOLR_RSSE);
@@ -2464,7 +2473,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
 	wr32(E1000_SRRCTL(reg_idx), srrctl);
 
 	/* set filtering for VMDQ pools */
-	igb_set_vmolr(adapter, reg_idx & 0x7);
+	igb_set_vmolr(adapter, reg_idx & 0x7, true);
 
 	/* enable receive descriptor fetching */
 	rxdctl = rd32(E1000_RXDCTL(reg_idx));
@@ -4352,6 +4361,49 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
 	return -1;
 }
 
+static void igb_set_vmvir(struct igb_adapter *adapter, u32 vid, u32 vf)
+{
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (vid)
+		wr32(E1000_VMVIR(vf), (vid | E1000_VMVIR_VLANA_DEFAULT));
+	else
+		wr32(E1000_VMVIR(vf), 0);
+}
+
+static int igb_pf_set_vf_vlan(struct igb_adapter *adapter, int vf, u16 vlan)
+{
+	int err = 0;
+
+	if (vlan) {
+		err = igb_vlvf_set(adapter, vlan, true, vf);
+		if (err)
+			goto out;
+		igb_set_vmvir(adapter, vlan, vf);
+		igb_set_vmolr(adapter, vf, false);
+		adapter->vf_data[vf].pf_vlan = vlan;
+	} else if (adapter->vf_data[vf].pf_vlan) {
+		err = igb_vlvf_set(adapter, adapter->vf_data[vf].pf_vlan,
+				   false, vf);
+		if (err)
+			goto out;
+		igb_set_vmvir(adapter, vlan, vf);
+		igb_set_vmolr(adapter, vf, true);
+		adapter->vf_data[vf].pf_vlan = 0;
+	}
+out:
+	return err;
+}
+
+static int igb_set_queue_vlan(struct net_device *netdev, int queue, u16 vlan)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	if ((queue > adapter->vfs_allocated_count) ||
+	    (queue == 0) || (vlan > 4095))
+		return -EINVAL;
+	return igb_pf_set_vf_vlan(adapter, queue - 1, vlan);
+}
+
 static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
 {
 	int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
@@ -4362,15 +4414,18 @@ static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
 
 static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
 {
-	/* clear all flags */
-	adapter->vf_data[vf].flags = 0;
+	/* clear flags */
+	adapter->vf_data[vf].flags &= ~(IGB_VF_FLAG_PF_SET_MAC);
 	adapter->vf_data[vf].last_nack = jiffies;
 
 	/* reset offloads to defaults */
-	igb_set_vmolr(adapter, vf);
+	igb_set_vmolr(adapter, vf, true);
 
 	/* reset vlans for device */
-	igb_clear_vf_vfta(adapter, vf);
+	if (adapter->vf_data[vf].pf_vlan)
+		igb_pf_set_vf_vlan(adapter, adapter->vf_data[vf].pf_vlan, vf);
+	else
+		igb_clear_vf_vfta(adapter, vf);
 
 	/* reset multicast table array for vf */
 	adapter->vf_data[vf].num_vf_mc_hashes = 0;
@@ -4384,7 +4439,8 @@ static void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
 	unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
 
 	/* generate a new mac address as we were hotplug removed/added */
-	random_ether_addr(vf_mac);
+	if (!(adapter->vf_data[vf].flags & IGB_VF_FLAG_PF_SET_MAC))
+		random_ether_addr(vf_mac);
 
 	/* process remaining reset events */
 	igb_vf_reset(adapter, vf);
@@ -4493,7 +4549,10 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
 		retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf);
 		break;
 	case E1000_VF_SET_VLAN:
-		retval = igb_set_vf_vlan(adapter, msgbuf, vf);
+		if (adapter->vf_data[vf].pf_vlan)
+			retval = -1;
+		else
+			retval = igb_set_vf_vlan(adapter, msgbuf, vf);
 		break;
 	default:
 		dev_err(&pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
@@ -5843,6 +5902,17 @@ static int igb_set_vf_mac(struct igb_adapter *adapter,
 	return 0;
 }
 
+static int igb_set_queue_mac(struct net_device *netdev, int queue, u8 *mac)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	if (!is_valid_ether_addr(mac) ||
+	    (queue > adapter->vfs_allocated_count) ||
+	    (queue == 0))
+		return -EINVAL;
+	adapter->vf_data[queue - 1].flags |= IGB_VF_FLAG_PF_SET_MAC;
+	return igb_set_vf_mac(adapter, queue - 1, mac);
+}
+
 static void igb_vmm_control(struct igb_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;


^ permalink raw reply related

* [RFC PATCH 4/4] igbvf: Make error message more enlightening
From: Jeff Kirsher @ 2009-11-17 21:51 UTC (permalink / raw)
  To: davem, shemminger; +Cc: netdev, gospo, Mitch Williams, Jeff Kirsher
In-Reply-To: <20091117214923.15119.98918.stgit@localhost.localdomain>

From: Williams, Mitch A <mitch.a.williams@intel.com>

The most likely cause of this error is that the PF interface is not up,
so let's make that very explicit.

Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igbvf/netdev.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index fad7f34..a3c706c 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -2720,7 +2720,8 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
 	err = hw->mac.ops.reset_hw(hw);
 	if (err) {
 		dev_info(&pdev->dev,
-		         "PF still in reset state, assigning new address\n");
+			 "PF still in reset state, assigning new address. "
+			 "Is the PF interface up?\n");
 		random_ether_addr(hw->mac.addr);
 	} else {
 		err = hw->mac.ops.read_mac_addr(hw);


^ permalink raw reply related

* [RFC PATCH iproute2] ip: Add support for setting MAC and VLAN on hardware queues
From: Jeff Kirsher @ 2009-11-17 21:55 UTC (permalink / raw)
  To: davem, shemminger; +Cc: netdev, gospo, Mitch Williams, Jeff Kirsher

From: Williams, Mitch A <mitch.a.williams@intel.com>

This patch adds support to the "ip" tool for setting the MAC address and
VLAN filter for hardware device queues. This is most immediately useful for
SR-IOV; for VF devices to be usable in the real world, the hypervisor or VM
manager must be able to set these parameters before the VF device is
assigned to any VM.

Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 include/linux/if_link.h |   16 ++++++++++++++++
 ip/iplink.c             |   29 +++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index b0b9e8a..a458d63 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -81,6 +81,8 @@ enum
 #define IFLA_LINKINFO IFLA_LINKINFO
 	IFLA_NET_NS_PID,
 	IFLA_IFALIAS,
+	IFLA_QUEUE_MAC,		/* Hardware queue specific attributes */
+	IFLA_QUEUE_VLAN,
 	__IFLA_MAX
 };
 
@@ -188,4 +190,18 @@ struct ifla_vlan_qos_mapping
 	__u32 to;
 };
 
+/* subqueue managment section */
+
+struct ifla_queue_mac
+{
+	__u32 queue;
+	__u8 mac[32]; /* MAX_ADDR_LEN */
+};
+
+struct ifla_queue_vlan
+{
+	__u32 queue;
+	__u32 vlan;
+};
+
 #endif /* _LINUX_IF_LINK_H */
diff --git a/ip/iplink.c b/ip/iplink.c
index 32cce24..9542d62 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -68,7 +68,9 @@ void iplink_usage(void)
 	fprintf(stderr, "	                  [ mtu MTU ]\n");
 	fprintf(stderr, "	                  [ netns PID ]\n");
 	fprintf(stderr, "			  [ alias NAME ]\n");
-	fprintf(stderr, "       ip link show [ DEVICE ]\n");
+	fprintf(stderr, "	                  [ queue NUM [ mac LLADDR ]\n");
+	fprintf(stderr, "				      [ vlan VLANID ] ] \n");
+	fprintf(stderr, "       ip link show [ DEVICE [ queue NUM] ]\n");
 
 	if (iplink_have_newlink()) {
 		fprintf(stderr, "\n");
@@ -176,7 +178,7 @@ struct iplink_req {
 int iplink_parse(int argc, char **argv, struct iplink_req *req,
 		char **name, char **type, char **link, char **dev)
 {
-	int ret, len;
+	int ret, len, qnum;
 	char abuf[32];
 	int qlen = -1;
 	int mtu = -1;
@@ -278,6 +280,29 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
 				req->i.ifi_flags |= IFF_NOARP;
 			} else
 				return on_off("noarp");
+		} else if (strcmp(*argv, "queue") == 0) {
+			NEXT_ARG();
+			if (get_integer(&qnum,  *argv, 0)) {
+				invarg("Invalid \"queue\" value\n", *argv);
+			}
+			NEXT_ARG();
+			if (matches(*argv, "mac") == 0) {
+				struct ifla_queue_mac iqm;
+				NEXT_ARG();
+				iqm.queue = qnum;
+				len = ll_addr_a2n((char *)iqm.mac, 32, *argv);
+				if (len < 0)
+					return -1;
+				addattr_l(&req->n, sizeof(*req), IFLA_QUEUE_MAC, &iqm, sizeof(iqm));
+			} else if (matches(*argv, "vlan") == 0) {
+				struct ifla_queue_vlan iqv;
+				NEXT_ARG();
+				if (get_unsigned(&iqv.vlan, *argv, 0)) {
+					invarg("Invalid \"vlan\" value\n", *argv);
+				}
+				iqv.queue = qnum;
+				addattr_l(&req->n, sizeof(*req), IFLA_QUEUE_VLAN, &iqv, sizeof(iqv));
+			}
 #ifdef IFF_DYNAMIC
 		} else if (matches(*argv, "dynamic") == 0) {
 			NEXT_ARG();


^ permalink raw reply related

* Re: [RFC PATCH iproute2] ip: Add support for setting MAC and VLAN on hardware queues
From: Stephen Hemminger @ 2009-11-17 22:06 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: davem, netdev, gospo, Mitch Williams, Jeff Kirsher
In-Reply-To: <20091117215432.15195.94504.stgit@localhost.localdomain>

On Tue, 17 Nov 2009 13:55:07 -0800
Jeff Kirsher <jeffrey.t.kirsher@intel.com> wrote:

> From: Williams, Mitch A <mitch.a.williams@intel.com>
> 
> This patch adds support to the "ip" tool for setting the MAC address and
> VLAN filter for hardware device queues. This is most immediately useful for
> SR-IOV; for VF devices to be usable in the real world, the hypervisor or VM
> manager must be able to set these parameters before the VF device is
> assigned to any VM.
> 
> Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Is there anything to avoid prevent this from being misused by users who
are doing multiqueue. Maybe we need equivalent of "mounted" flag that block
devices have?

^ permalink raw reply

* [PATCH 3/3] macvlan: export macvlan mode through netlink
From: Arnd Bergmann @ 2009-11-17 22:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, David Miller, Stephen Hemminger, Herbert Xu,
	Patrick McHardy, Patrick Mullaney, Eric W. Biederman,
	Edge Virtual Bridging, Anna Fischer, bridge, virtualization,
	Jens Osterkamp, Gerhard Stenzel, Arnd Bergmann
In-Reply-To: <1258497551-25959-1-git-send-email-arnd@arndb.de>

In order to support all three modes of macvlan at
runtime, extend the existing netlink protocol
to allow choosing the mode per macvlan slave
interface.

This depends on a matching patch to iproute2
in order to become accessible in user land.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/macvlan.c   |   67 +++++++++++++++++++++++++++++++++++++++++-----
 include/linux/if_link.h |   15 ++++++++++
 2 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index fa8b568..731017e 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -33,12 +33,6 @@
 
 #define MACVLAN_HASH_SIZE	(1 << BITS_PER_BYTE)
 
-enum macvlan_type {
-	MACVLAN_PRIVATE		= 1,
-	MACVLAN_VEPA		= 2,
-	MACVLAN_BRIDGE		= 4,
-};
-
 struct macvlan_port {
 	struct net_device	*dev;
 	struct hlist_head	vlan_hash[MACVLAN_HASH_SIZE];
@@ -51,7 +45,7 @@ struct macvlan_dev {
 	struct hlist_node	hlist;
 	struct macvlan_port	*port;
 	struct net_device	*lowerdev;
-	enum macvlan_mode	mode;
+	enum ifla_macvlan_mode	mode;
 };
 
 
@@ -112,7 +106,7 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
 static void macvlan_broadcast(struct sk_buff *skb,
 			      const struct macvlan_port *port,
 			      struct net_device *src,
-			      enum macvlan_mode mode)
+			      enum ifla_macvlan_mode mode)
 {
 	const struct ethhdr *eth = eth_hdr(skb);
 	const struct macvlan_dev *vlan;
@@ -553,6 +547,18 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
 			return -EADDRNOTAVAIL;
 	}
+
+	if (data && data[IFLA_MACVLAN_MODE]) {
+		u32 mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+		switch (mode) {
+		case MACVLAN_MODE_PRIVATE:
+		case MACVLAN_MODE_VEPA:
+		case MACVLAN_MODE_BRIDGE:
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
 	return 0;
 }
 
@@ -617,6 +623,13 @@ static int macvlan_newlink(struct net_device *dev,
 	vlan->dev      = dev;
 	vlan->port     = port;
 
+	vlan->mode     = MACVLAN_MODE_VEPA;
+	if (data && data[IFLA_MACVLAN_MODE]) {
+		u32 mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+
+		vlan->mode     = mode;
+	}
+
 	err = register_netdevice(dev);
 	if (err < 0)
 		return err;
@@ -638,6 +651,39 @@ static void macvlan_dellink(struct net_device *dev)
 		macvlan_port_destroy(port->dev);
 }
 
+static int macvlan_changelink(struct net_device *dev,
+		struct nlattr *tb[], struct nlattr *data[])
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	if (data && data[IFLA_MACVLAN_MODE]) {
+		u32 mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+		vlan->mode     = mode;
+	}
+
+	return 0;
+}
+
+static size_t macvlan_get_size(const struct net_device *dev)
+{
+	return nla_total_size(4);
+}
+
+static int macvlan_fill_info(struct sk_buff *skb,
+				const struct net_device *dev)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+
+	NLA_PUT_U32(skb, IFLA_MACVLAN_MODE, vlan->mode);	
+	return 0;
+
+nla_put_failure:
+	return -EMSGSIZE;
+}
+
+static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
+	[IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
+};
+
 static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
 	.kind		= "macvlan",
 	.priv_size	= sizeof(struct macvlan_dev),
@@ -646,6 +692,11 @@ static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
 	.validate	= macvlan_validate,
 	.newlink	= macvlan_newlink,
 	.dellink	= macvlan_dellink,
+	.maxtype	= IFLA_MACVLAN_MAX,
+	.policy		= macvlan_policy,
+	.changelink	= macvlan_changelink,
+	.get_size	= macvlan_get_size,
+	.fill_info	= macvlan_fill_info,
 };
 
 static int macvlan_device_event(struct notifier_block *unused,
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 176c518..ef70ebc 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -190,4 +190,19 @@ struct ifla_vlan_qos_mapping
 	__u32 to;
 };
 
+/* MACVLAN section */
+enum {
+	IFLA_MACVLAN_UNSPEC,
+	IFLA_MACVLAN_MODE,
+	__IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum ifla_macvlan_mode {
+	MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
+	MACVLAN_MODE_VEPA    = 2, /* talk to other ports through ext bridge */
+	MACVLAN_MODE_BRIDGE  = 4, /* talk to bridge ports directly */
+};
+
 #endif /* _LINUX_IF_LINK_H */
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH] iplink: add macvlan options for bridge mode
From: Arnd Bergmann @ 2009-11-17 22:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, David Miller, Stephen Hemminger, Herbert Xu,
	Patrick McHardy, Patrick Mullaney, Eric W. Biederman,
	Edge Virtual Bridging, Anna Fischer, bridge, virtualization,
	Jens Osterkamp, Gerhard Stenzel, Arnd Bergmann
In-Reply-To: <1258497551-25959-1-git-send-email-arnd@arndb.de>

Macvlan can now optionally support forwarding between its
ports, if they are in "bridge" mode. This adds support
for this option to "ip link add", "ip link set" and "ip
-d link show".

The default mode in the kernel is now "vepa" mode, meaning
"virtual ethernet port aggregator". This mode is used
together with the "hairpin" mode of an ethernet bridge
that the parent of the macvlan device is connected to.
All frames still get sent out to the external interface,
but the adjacent bridge is able to send them back on
the same wire in hairpin mode, so the macvlan ports
are able to see each other, which the bridge can be
configured to monitor and control traffic between
all macvlan instances. Multicast traffic coming in
from the external interface is checked for the source
MAC address and only delivered to ports that have not
yet seen it.

In bridge mode, macvlan will send all multicast traffic
to other interfaces that are also in bridge mode but
not to those in vepa mode, which get them on the way
back from the hairpin.

The third supported mode is "private", which prevents
communication between macvlans even if the adjacent
bridge is in hairpin mode. This behavior is closer to
the original implementation of macvlan but stricly
maintains isolation.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 include/linux/if_link.h |   15 ++++++++
 ip/Makefile             |    3 +-
 ip/iplink_macvlan.c     |   93 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+), 1 deletions(-)
 create mode 100644 ip/iplink_macvlan.c

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index b0b9e8a..425c489 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -188,4 +188,19 @@ struct ifla_vlan_qos_mapping
 	__u32 to;
 };
 
+/* MACVLAN section */
+enum {
+	IFLA_MACVLAN_UNSPEC,
+	IFLA_MACVLAN_MODE,
+	__IFLA_MACVLAN_MAX,
+};
+
+enum ifla_macvlan_mode {
+	MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
+	MACVLAN_MODE_VEPA    = 2, /* talk to other ports through ext bridge */
+	MACVLAN_MODE_BRIDGE  = 4, /* talk to bridge ports directly */
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
 #endif /* _LINUX_IF_LINK_H */
diff --git a/ip/Makefile b/ip/Makefile
index 51914e8..46a9836 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -2,7 +2,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o \
     rtm_map.o iptunnel.o ip6tunnel.o tunnel.o ipneigh.o ipntable.o iplink.o \
     ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o \
     ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o \
-    iplink_vlan.o link_veth.o link_gre.o iplink_can.o
+    iplink_vlan.o link_veth.o link_gre.o iplink_can.o \
+    iplink_macvlan.o
 
 RTMONOBJ=rtmon.o
 
diff --git a/ip/iplink_macvlan.c b/ip/iplink_macvlan.c
new file mode 100644
index 0000000..307f559
--- /dev/null
+++ b/ip/iplink_macvlan.c
@@ -0,0 +1,93 @@
+/*
+ * iplink_vlan.c	VLAN device support
+ *
+ *              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 the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Patrick McHardy <kaber@trash.net>
+ *		Arnd Bergmann <arnd@arndb.de>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <linux/if_link.h>
+
+#include "rt_names.h"
+#include "utils.h"
+#include "ip_common.h"
+
+static void explain(void)
+{
+	fprintf(stderr,
+		"Usage: ... macvlan mode { private | vepa | bridge }\n"
+	);
+}
+
+static int mode_arg(void)
+{
+        fprintf(stderr, "Error: argument of \"mode\" must be \"private\", "
+		"\"vepa\" or \"bridge\"\n");
+        return -1;
+}
+
+static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
+			  struct nlmsghdr *n)
+{
+	while (argc > 0) {
+		if (matches(*argv, "mode") == 0) {
+			__u32 mode = 0;
+			NEXT_ARG();
+
+			if (strcmp(*argv, "private") == 0)
+				mode = MACVLAN_MODE_PRIVATE;
+			else if (strcmp(*argv, "vepa") == 0)
+				mode = MACVLAN_MODE_VEPA;
+			else if (strcmp(*argv, "bridge") == 0)
+				mode = MACVLAN_MODE_BRIDGE;
+			else 
+				return mode_arg();
+
+			addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);
+		} else if (matches(*argv, "help") == 0) {
+			explain();
+			return -1;
+		} else {
+			fprintf(stderr, "macvlan: what is \"%s\"?\n", *argv);
+			explain();
+			return -1;
+		}
+		argc--, argv++;
+	}
+
+	return 0;
+}
+
+static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
+{
+	__u32 mode;
+
+	if (!tb)
+		return;
+
+	if (!tb[IFLA_MACVLAN_MODE] ||
+	    RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
+		return;
+
+	mode = *(__u32 *)RTA_DATA(tb[IFLA_VLAN_ID]);
+	fprintf(f, " mode %s ",
+		  mode == MACVLAN_MODE_PRIVATE ? "private"
+		: mode == MACVLAN_MODE_VEPA    ? "vepa"
+		: mode == MACVLAN_MODE_BRIDGE  ? "bridge"
+		:				 "unknown");
+}
+
+struct link_util macvlan_link_util = {
+	.id		= "macvlan",
+	.maxattr	= IFLA_MACVLAN_MAX,
+	.parse_opt	= macvlan_parse_opt,
+	.print_opt	= macvlan_print_opt,
+};
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 2/3] macvlan: implement VEPA and private mode
From: Arnd Bergmann @ 2009-11-17 22:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, David Miller, Stephen Hemminger, Herbert Xu,
	Patrick McHardy, Patrick Mullaney, Eric W. Biederman,
	Edge Virtual Bridging, Anna Fischer, bridge, virtualization,
	Jens Osterkamp, Gerhard Stenzel, Arnd Bergmann
In-Reply-To: <1258497551-25959-1-git-send-email-arnd@arndb.de>

This allows each macvlan slave device to be in one
of three modes, depending on the use case:

MACVLAN_MODE_PRIVATE:
  The device never communicates with any other device
  on the same upper_dev. This even includes frames
  coming back from a reflective relay, where supported
  by the adjacent bridge.

MACVLAN_MODE_VEPA:
  The new Virtual Ethernet Port Aggregator (VEPA) mode,
  we assume that the adjacent bridge returns all frames
  where both source and destination are local to the
  macvlan port, i.e. the bridge is set up as a reflective
  relay.
  Broadcast frames coming in from the upper_dev get
  flooded to all macvlan interfaces in VEPA mode.
  We never deliver any frames locally.

MACVLAN_MODE_BRIDGE:
  We provide the behavior of a simple bridge between
  different macvlan interfaces on the same port. Frames
  from one interface to another one get delivered directly
  and are not sent out externally. Broadcast frames get
  flooded to all other bridge ports and to the external
  interface, but when they come back from a reflective
  relay, we don't deliver them again.
  Since we know all the MAC addresses, the macvlan bridge
  mode does not require learning or STP like the bridge
  module does.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/macvlan.c |   46 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 406b8b5..fa8b568 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -33,6 +33,12 @@
 
 #define MACVLAN_HASH_SIZE	(1 << BITS_PER_BYTE)
 
+enum macvlan_type {
+	MACVLAN_PRIVATE		= 1,
+	MACVLAN_VEPA		= 2,
+	MACVLAN_BRIDGE		= 4,
+};
+
 struct macvlan_port {
 	struct net_device	*dev;
 	struct hlist_head	vlan_hash[MACVLAN_HASH_SIZE];
@@ -45,6 +51,7 @@ struct macvlan_dev {
 	struct hlist_node	hlist;
 	struct macvlan_port	*port;
 	struct net_device	*lowerdev;
+	enum macvlan_mode	mode;
 };
 
 
@@ -104,7 +111,8 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
 
 static void macvlan_broadcast(struct sk_buff *skb,
 			      const struct macvlan_port *port,
-			      struct net_device *src)
+			      struct net_device *src,
+			      enum macvlan_mode mode)
 {
 	const struct ethhdr *eth = eth_hdr(skb);
 	const struct macvlan_dev *vlan;
@@ -123,6 +131,9 @@ static void macvlan_broadcast(struct sk_buff *skb,
 			if (dev == src)
 				continue;
 
+			if (!(vlan->mode & mode))
+				continue;
+
 			nskb = skb_clone(skb, GFP_ATOMIC);
 			if (nskb == NULL) {
 				dev->stats.rx_errors++;
@@ -177,13 +188,27 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
 	const struct ethhdr *eth = eth_hdr(skb);
 	const struct macvlan_port *port;
 	const struct macvlan_dev *vlan;
+	const struct macvlan_dev *src;
 
 	port = rcu_dereference(skb->dev->macvlan_port);
 	if (port == NULL)
 		return skb;
 
 	if (is_multicast_ether_addr(eth->h_dest)) {
-		macvlan_broadcast(skb, port, NULL);
+		src = macvlan_hash_lookup(port, eth->h_source);
+		if (!src)
+			/* frame comes from an external address */
+			macvlan_broadcast(skb, port, NULL, MACVLAN_MODE_VEPA
+				| MACVLAN_MODE_VEPA | MACVLAN_MODE_BRIDGE);
+		else if (src->mode == MACVLAN_MODE_VEPA)
+			/* flood to everyone except source */
+			macvlan_broadcast(skb, port, src->dev,
+				MACVLAN_MODE_VEPA | MACVLAN_MODE_BRIDGE);
+		else if (src->mode == MACVLAN_MODE_BRIDGE)
+			/* flood only to VEPA ports, bridge ports
+			   already saw the frame */
+			macvlan_broadcast(skb, port, src->dev,
+				MACVLAN_MODE_VEPA);
 		return skb;
 	}
 
@@ -218,14 +243,17 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 	secpath_reset(skb);
 	nf_reset(skb);
 
-	if (is_multicast_ether_addr(eth->h_dest)) {
-		macvlan_broadcast(skb, port, dev);
-		return macvlan_xmit_world(skb, dev);
-	}
+	if (vlan->mode == MACVLAN_MODE_BRIDGE) {
+		/* send to other bridge ports directly */
+		if (is_multicast_ether_addr(eth->h_dest)) {
+			macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE);
+			return macvlan_xmit_world(skb, dev);
+		}
 
-	dest = macvlan_hash_lookup(port, eth->h_dest);
-	if (dest)
-		return macvlan_unicast(skb, dest);
+		dest = macvlan_hash_lookup(port, eth->h_dest);
+		if (dest && dest->mode == MACVLAN_MODE_BRIDGE)
+			return macvlan_unicast(skb, dest);
+	}
 
 	return macvlan_xmit_world(skb, dev);
 }
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 1/3] macvlan: Reflect macvlan packets meant for other macvlan devices
From: Arnd Bergmann @ 2009-11-17 22:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, David Miller, Stephen Hemminger, Herbert Xu,
	Patrick McHardy, Patrick Mullaney, Eric W. Biederman,
	Edge Virtual Bridging, Anna Fischer, bridge, virtualization,
	Jens Osterkamp, Gerhard Stenzel, Arnd Bergmann
In-Reply-To: <1258497551-25959-1-git-send-email-arnd@arndb.de>

From: Eric Biederman <ebiederm@xmission.com>

Switch ports do not send packets back out the same port they came
in on.	This causes problems when using a macvlan device inside
of a network namespace as it becomes impossible to talk to
other macvlan devices.

Signed-off-by: Eric Biederman <ebiederm@xmission.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/macvlan.c |   91 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 67 insertions(+), 24 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3aabfd9..406b8b5 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -29,6 +29,7 @@
 #include <linux/if_link.h>
 #include <linux/if_macvlan.h>
 #include <net/rtnetlink.h>
+#include <net/xfrm.h>
 
 #define MACVLAN_HASH_SIZE	(1 << BITS_PER_BYTE)
 
@@ -102,7 +103,8 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
 }
 
 static void macvlan_broadcast(struct sk_buff *skb,
-			      const struct macvlan_port *port)
+			      const struct macvlan_port *port,
+			      struct net_device *src)
 {
 	const struct ethhdr *eth = eth_hdr(skb);
 	const struct macvlan_dev *vlan;
@@ -118,6 +120,9 @@ static void macvlan_broadcast(struct sk_buff *skb,
 		hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) {
 			dev = vlan->dev;
 
+			if (dev == src)
+				continue;
+
 			nskb = skb_clone(skb, GFP_ATOMIC);
 			if (nskb == NULL) {
 				dev->stats.rx_errors++;
@@ -140,20 +145,45 @@ static void macvlan_broadcast(struct sk_buff *skb,
 	}
 }
 
+static int macvlan_unicast(struct sk_buff *skb, const struct macvlan_dev *dest)
+{
+	struct net_device *dev = dest->dev;
+
+	if (unlikely(!dev->flags & IFF_UP)) {
+		kfree_skb(skb);
+		return NET_XMIT_DROP;
+	}
+
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb) {
+		dev->stats.rx_errors++;
+		dev->stats.rx_dropped++;
+		return NET_XMIT_DROP;
+	}
+
+	dev->stats.rx_bytes += skb->len + ETH_HLEN;
+	dev->stats.rx_packets++;
+
+	skb->dev = dev;
+	skb->pkt_type = PACKET_HOST;
+	netif_rx(skb);
+	return NET_XMIT_SUCCESS;
+}
+
+
 /* called under rcu_read_lock() from netif_receive_skb */
 static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
 {
 	const struct ethhdr *eth = eth_hdr(skb);
 	const struct macvlan_port *port;
 	const struct macvlan_dev *vlan;
-	struct net_device *dev;
 
 	port = rcu_dereference(skb->dev->macvlan_port);
 	if (port == NULL)
 		return skb;
 
 	if (is_multicast_ether_addr(eth->h_dest)) {
-		macvlan_broadcast(skb, port);
+		macvlan_broadcast(skb, port, NULL);
 		return skb;
 	}
 
@@ -161,27 +191,43 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
 	if (vlan == NULL)
 		return skb;
 
-	dev = vlan->dev;
-	if (unlikely(!(dev->flags & IFF_UP))) {
-		kfree_skb(skb);
-		return NULL;
-	}
+	macvlan_unicast(skb, vlan);
+	return NULL;
+}
 
-	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (skb == NULL) {
-		dev->stats.rx_errors++;
-		dev->stats.rx_dropped++;
-		return NULL;
-	}
+static int macvlan_xmit_world(struct sk_buff *skb, struct net_device *dev)
+{
+	const struct macvlan_dev *vlan = netdev_priv(dev);
+	__skb_push(skb, skb->data - skb_mac_header(skb));
+	skb->dev = vlan->lowerdev;
+	return dev_queue_xmit(skb);
+}
 
-	dev->stats.rx_bytes += skb->len + ETH_HLEN;
-	dev->stats.rx_packets++;
+static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	const struct macvlan_dev *vlan = netdev_priv(dev);
+	const struct macvlan_port *port = vlan->port;
+	const struct macvlan_dev *dest;
+	const struct ethhdr *eth;
 
-	skb->dev = dev;
-	skb->pkt_type = PACKET_HOST;
+	skb->protocol = eth_type_trans(skb, dev);
+	eth = eth_hdr(skb);
 
-	netif_rx(skb);
-	return NULL;
+	skb_dst_drop(skb);
+	skb->mark = 0;
+	secpath_reset(skb);
+	nf_reset(skb);
+
+	if (is_multicast_ether_addr(eth->h_dest)) {
+		macvlan_broadcast(skb, port, dev);
+		return macvlan_xmit_world(skb, dev);
+	}
+
+	dest = macvlan_hash_lookup(port, eth->h_dest);
+	if (dest)
+		return macvlan_unicast(skb, dest);
+
+	return macvlan_xmit_world(skb, dev);
 }
 
 static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
@@ -189,13 +235,10 @@ static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
 {
 	int i = skb_get_queue_mapping(skb);
 	struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
-	const struct macvlan_dev *vlan = netdev_priv(dev);
 	unsigned int len = skb->len;
 	int ret;
 
-	skb->dev = vlan->lowerdev;
-	ret = dev_queue_xmit(skb);
-
+	ret = macvlan_queue_xmit(skb, dev);
 	if (likely(ret == NET_XMIT_SUCCESS)) {
 		txq->tx_packets++;
 		txq->tx_bytes += len;
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 0/3] macvlan: add vepa and bridge mode
From: Arnd Bergmann @ 2009-11-17 22:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: netdev, David Miller, Stephen Hemminger, Herbert Xu,
	Patrick McHardy, Patrick Mullaney, Eric W. Biederman,
	Edge Virtual Bridging, Anna Fischer, bridge, virtualization,
	Jens Osterkamp, Gerhard Stenzel, Arnd Bergmann

This is based on an earlier patch from Eric Biederman adding
forwarding between macvlans. I extended his approach to
allow the administrator to choose the mode for each macvlan,
and to implement a functional VEPA between macvlan.

Still missing from this is support for communication between
the lower device that the macvlans are based on. This would
be extremely useful but as others have found out before me
requires significant changes not only to macvlan but also
to the common transmit path.

I've seen one panic during testing this that I still need
to track down, but it generally does what is advertised.
I've tested VEPA operation with the hairpin support
added to the bridge driver by Anna Fischer.

My current plan is to submit this for inclusion in 2.6.33
when people are happy with it and I tracked down any
remaining bugs, and possibly to do the communication with
the lower device one release later.

	Arnd <><

---

Arnd Bergmann (3):
  macvlan: implement VEPA and private mode
  macvlan: export macvlan mode through netlink
  iplink: add macvlan options for bridge mode

Eric Biederman (1):
  macvlan: Reflect macvlan packets meant for other macvlan devices

 linux/drivers/net/macvlan.c   |  170 +++++++++++++++++++++++++++++++++-----
 linux/include/linux/if_link.h |   15 +++
 2 files changed, 161 insertions(+), 24 deletions(-)

 iproute2/include/linux/if_link.h |   15 +++
 iproute2/ip/Makefile             |    3 +-
 iproute2/ip/iplink_macvlan.c     |   93 ++++++++++++++++++
 3 files changed, 110 insertions(+), 1 deletions(-)
 create mode 100644 ip/iplink_macvlan.c

^ permalink raw reply

* Re: [RFC v2] mac80211: disallow bridging managed/adhoc interfaces
From: Julian Calaby @ 2009-11-17 22:42 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev, linux-wireless, Stephen Hemminger, Felix Fietkau
In-Reply-To: <1258490898.21197.42.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>

On Wed, Nov 18, 2009 at 07:48, Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
> --- wireless-testing.orig/net/mac80211/iface.c  2009-11-17 14:20:19.000000000 +0100
> +++ wireless-testing/net/mac80211/iface.c       2009-11-17 17:56:08.000000000 +0100
> @@ -745,6 +745,11 @@ int ieee80211_if_change_type(struct ieee
>        if (type == sdata->vif.type)
>                return 0;
>
> +       /* if it's part of a bridge, reject changing type to station/ibss */
> +       if (sdata->dev->br_port && (type == NL80211_IFTYPE_ADHOC ||
> +                                   type == NL80211_IFTYPE_STATION))
> +               return -EBUSY;

Busy doesn't seem like the right error here ... maybe use -EOPNOTSUPP
like the next test?

Thanks,

-- 

Julian Calaby

Email: julian.calaby-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
.Plan: http://sites.google.com/site/juliancalaby/
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC v2] mac80211: disallow bridging managed/adhoc interfaces
From: Stephen Hemminger @ 2009-11-17 22:42 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev, linux-wireless, Felix Fietkau
In-Reply-To: <1258490898.21197.42.camel@johannes.local>

On Tue, 17 Nov 2009 21:48:18 +0100
Johannes Berg <johannes@sipsolutions.net> wrote:

> A number of people have tried to add a wireless interface
> (in managed mode) to a bridge and then complained that it
> doesn't work. It cannot work, however, because in 802.11
> networks all packets need to be acknowledged and as such
> need to be sent to the right address. Promiscuous doesn't
> help here. The wireless address format used for these
> links has only space for three addresses, the
>  * transmitter, which must be equal to the sender (origin)
>  * receiver (on the wireless medium), which is the AP in
>    the case of managed mode
>  * the recipient (destination), which is on the APs local
>    network segment
> 
> In an IBSS, it is similar, but the receiver and recipient
> must match and the third address is used as the BSSID.
> 
> To avoid such mistakes in the future, disallow adding a
> wireless interface to a bridge.
> 
> Felix has recently added a four-address mode to the AP
> and client side that can be used (after negotiating that
> it is possible, which must happen out-of-band by setting
> up both sides) for bridging, so allow that case.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

Looks good, maybe true four-address mode support will be available
more widely, and this will no longer be an issue.

Acked-by: Stephen Hemminger <shemminger@vyatta.com>

^ permalink raw reply

* Re: [RFC v2] mac80211: disallow bridging managed/adhoc interfaces
From: Johannes Berg @ 2009-11-17 22:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, linux-wireless, Felix Fietkau
In-Reply-To: <20091117144239.47930866@nehalam>

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

On Tue, 2009-11-17 at 14:42 -0800, Stephen Hemminger wrote:

> > Felix has recently added a four-address mode to the AP
> > and client side that can be used (after negotiating that
> > it is possible, which must happen out-of-band by setting
> > up both sides) for bridging, so allow that case.

> Looks good, maybe true four-address mode support will be available
> more widely, and this will no longer be an issue.

Doubt it, it breaks the current 802.11 standard, and I think 802.1X too
if you use WPA/RSN. Anyway, thanks.

I'll take a look tomorrow if we can do this generically in cfg80211, and
then send a [PATCH] either way.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: [RFC v2] mac80211: disallow bridging managed/adhoc interfaces
From: Johannes Berg @ 2009-11-17 22:46 UTC (permalink / raw)
  To: Julian Calaby; +Cc: netdev, linux-wireless, Stephen Hemminger, Felix Fietkau
In-Reply-To: <646765f40911171442m467efbc8ped7abc9d529ed095@mail.gmail.com>

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

On Wed, 2009-11-18 at 09:42 +1100, Julian Calaby wrote:
> On Wed, Nov 18, 2009 at 07:48, Johannes Berg <johannes@sipsolutions.net> wrote:
> > --- wireless-testing.orig/net/mac80211/iface.c  2009-11-17 14:20:19.000000000 +0100
> > +++ wireless-testing/net/mac80211/iface.c       2009-11-17 17:56:08.000000000 +0100
> > @@ -745,6 +745,11 @@ int ieee80211_if_change_type(struct ieee
> >        if (type == sdata->vif.type)
> >                return 0;
> >
> > +       /* if it's part of a bridge, reject changing type to station/ibss */
> > +       if (sdata->dev->br_port && (type == NL80211_IFTYPE_ADHOC ||
> > +                                   type == NL80211_IFTYPE_STATION))
> > +               return -EBUSY;
> 
> Busy doesn't seem like the right error here ... maybe use -EOPNOTSUPP
> like the next test?

Not sure, it's a temporary error and you can fix it by removing it from
the bridge, so it's "busy" in the sense that it is fixed to the current
mode or any other bridging mode by being in the bridge ... it's not that
it doesn't support the mode.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* [patch 1/1] drivers/atm/solos-pci.c: fix warning/bug, clean up code
From: akpm @ 2009-11-17 22:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, akpm, David.Woodhouse, chas, nathan

From: Andrew Morton <akpm@linux-foundation.org>

drivers/atm/solos-pci.c: In function 'flash_upgrade':
drivers/atm/solos-pci.c:528: warning: 'fw_name' may be used uninitialized in this function

Cc: Chas Williams <chas@cmf.nrl.navy.mil>
Cc: David Woodhouse <David.Woodhouse@intel.com>
Cc: Nathan Williams <nathan@traverse.com.au>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 drivers/atm/solos-pci.c |   29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff -puN drivers/atm/solos-pci.c~drivers-atm-solos-pcic-fix-warning-bug-clean-up-code drivers/atm/solos-pci.c
--- a/drivers/atm/solos-pci.c~drivers-atm-solos-pcic-fix-warning-bug-clean-up-code
+++ a/drivers/atm/solos-pci.c
@@ -531,34 +531,37 @@ static int flash_upgrade(struct solos_ca
 	int numblocks = 0;
 	int offset;
 
-	if (chip == 0) {
+	switch (chip) {
+	case 0:
 		fw_name = "solos-FPGA.bin";
 		blocksize = FPGA_BLOCK;
-	} 
-	
-	if (chip == 1) {
+		break;
+	case 1:
 		fw_name = "solos-Firmware.bin";
 		blocksize = SOLOS_BLOCK;
-	}
-	
-	if (chip == 2){
+		break;
+	case 2:
 		if (card->fpga_version > LEGACY_BUFFERS){
 			fw_name = "solos-db-FPGA.bin";
 			blocksize = FPGA_BLOCK;
 		} else {
-			dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n");
+			dev_info(&card->dev->dev, "FPGA version doesn't support"
+					" daughter board upgrades\n");
 			return -EPERM;
 		}
-	}
-	
-	if (chip == 3){
+		break;
+	case 3:
 		if (card->fpga_version > LEGACY_BUFFERS){
 			fw_name = "solos-Firmware.bin";
 			blocksize = SOLOS_BLOCK;
 		} else {
-		dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n");
-		return -EPERM;
+			dev_info(&card->dev->dev, "FPGA version doesn't support"
+					" daughter board upgrades\n");
+			return -EPERM;
 		}
+		break;
+	default:
+		return -ENODEV;
 	}
 
 	if (request_firmware(&fw, fw_name, &card->dev->dev))
_

^ permalink raw reply

* [patch for 2.6.32? 1/2] hso: fix debug routines
From: akpm @ 2009-11-17 22:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, akpm, antti.kaijanmaki, greg, randy.dunlap

From: Antti Kaijanmäki <antti.kaijanmaki@nomovok.com>

Signed-off-by: Antti Kaijanmäki <antti.kaijanmaki@nomovok.com>
Cc: Greg KH <greg@kroah.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 drivers/net/usb/hso.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff -puN drivers/net/usb/hso.c~hso-fix-debug-routines drivers/net/usb/hso.c
--- a/drivers/net/usb/hso.c~hso-fix-debug-routines
+++ a/drivers/net/usb/hso.c
@@ -378,7 +378,7 @@ static void dbg_dump(int line_count, con
 }
 
 #define DUMP(buf_, len_)	\
-	dbg_dump(__LINE__, __func__, buf_, len_)
+	dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_)
 
 #define DUMP1(buf_, len_)			\
 	do {					\
@@ -1527,7 +1527,7 @@ static void tiocmget_intr_callback(struc
 		dev_warn(&usb->dev,
 			 "hso received invalid serial state notification\n");
 		DUMP(serial_state_notification,
-		     sizeof(hso_serial_state_notifation))
+		     sizeof(struct hso_serial_state_notification));
 	} else {
 
 		UART_state_bitmap = le16_to_cpu(serial_state_notification->
_

^ permalink raw reply

* Re: [RFC v2] mac80211: disallow bridging managed/adhoc interfaces
From: Julian Calaby @ 2009-11-17 22:50 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev, linux-wireless, Stephen Hemminger, Felix Fietkau
In-Reply-To: <1258498005.30511.3.camel@johannes.local>

On Wed, Nov 18, 2009 at 09:46, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Wed, 2009-11-18 at 09:42 +1100, Julian Calaby wrote:
>> On Wed, Nov 18, 2009 at 07:48, Johannes Berg <johannes@sipsolutions.net> wrote:
>> > --- wireless-testing.orig/net/mac80211/iface.c  2009-11-17 14:20:19.000000000 +0100
>> > +++ wireless-testing/net/mac80211/iface.c       2009-11-17 17:56:08.000000000 +0100
>> > @@ -745,6 +745,11 @@ int ieee80211_if_change_type(struct ieee
>> >        if (type == sdata->vif.type)
>> >                return 0;
>> >
>> > +       /* if it's part of a bridge, reject changing type to station/ibss */
>> > +       if (sdata->dev->br_port && (type == NL80211_IFTYPE_ADHOC ||
>> > +                                   type == NL80211_IFTYPE_STATION))
>> > +               return -EBUSY;
>>
>> Busy doesn't seem like the right error here ... maybe use -EOPNOTSUPP
>> like the next test?
>
> Not sure, it's a temporary error and you can fix it by removing it from
> the bridge, so it's "busy" in the sense that it is fixed to the current
> mode or any other bridging mode by being in the bridge ... it's not that
> it doesn't support the mode.

Arguably the test following this (ensuring that we don't set ad-hoc
mode on a non-ad-hoc channel) is equally temporary - i.e. both actions
require the user to do something before they'll work again.

But then, the test after that - for whether the interface is running -
returns -EBUSY - and is just as easy to remedy, so........

Thanks,

-- 

Julian Calaby

Email: julian.calaby@gmail.com
.Plan: http://sites.google.com/site/juliancalaby/

^ 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