* [RFC PATCH net-next v2 5/5] rtnl/ipv4: add support of RTM_GETNETCONF
From: Nicolas Dichtel @ 2012-10-24 16:02 UTC (permalink / raw)
To: davem; +Cc: netdev, Nicolas Dichtel
In-Reply-To: <1351094579-3911-1-git-send-email-nicolas.dichtel@6wind.com>
This message allows to get the devconf for an interface.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
net/ipv4/devinet.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 845fe48..2f522970 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1448,7 +1448,8 @@ static inline int inet_netconf_msgsize_devconf(int type)
int size = NLMSG_ALIGN(sizeof(struct netconfmsg))
+ nla_total_size(4); /* NETCONFA_IFINDEX */
- if (type == NETCONFA_FORWARDING)
+ /* type -1 is used for ALL */
+ if (type == -1 || type == NETCONFA_FORWARDING)
size += nla_total_size(4);
return size;
@@ -1473,7 +1474,8 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
if (nla_put_s32(skb, NETCONFA_IFINDEX, ifindex) < 0)
goto nla_put_failure;
- if (type == NETCONFA_FORWARDING &&
+ /* type -1 is used for ALL */
+ if ((type == -1 || type == NETCONFA_FORWARDING) &&
nla_put_s32(skb, NETCONFA_FORWARDING,
IPV4_DEVCONF(*devconf, FORWARDING)) < 0)
goto nla_put_failure;
@@ -1510,6 +1512,73 @@ errout:
rtnl_set_sk_err(net, RTNLGRP_IPV4_NETCONF, err);
}
+static const struct nla_policy devconf_ipv4_policy[NETCONFA_MAX+1] = {
+ [NETCONFA_IFINDEX] = { .len = sizeof(int) },
+ [NETCONFA_FORWARDING] = { .len = sizeof(int) },
+};
+
+static int inet_netconf_get_devconf(struct sk_buff *in_skb,
+ struct nlmsghdr *nlh,
+ void *arg)
+{
+ struct net *net = sock_net(in_skb->sk);
+ struct nlattr *tb[NETCONFA_MAX+1];
+ struct netconfmsg *ncm;
+ struct sk_buff *skb;
+ struct ipv4_devconf *devconf;
+ struct in_device *in_dev;
+ struct net_device *dev;
+ int ifindex;
+ int err;
+
+ err = nlmsg_parse(nlh, sizeof(*ncm), tb, NETCONFA_MAX,
+ devconf_ipv4_policy);
+ if (err < 0)
+ goto errout;
+
+ err = EINVAL;
+ if (!tb[NETCONFA_IFINDEX])
+ goto errout;
+
+ ifindex = nla_get_s32(tb[NETCONFA_IFINDEX]);
+ switch (ifindex) {
+ case NETCONFA_IFINDEX_ALL:
+ devconf = net->ipv4.devconf_all;
+ break;
+ case NETCONFA_IFINDEX_DEFAULT:
+ devconf = net->ipv4.devconf_dflt;
+ break;
+ default:
+ dev = __dev_get_by_index(net, ifindex);
+ if (dev == NULL)
+ goto errout;
+ in_dev = __in_dev_get_rtnl(dev);
+ if (in_dev == NULL)
+ goto errout;
+ devconf = &in_dev->cnf;
+ break;
+ }
+
+ err = -ENOBUFS;
+ skb = nlmsg_new(inet_netconf_msgsize_devconf(-1), GFP_ATOMIC);
+ if (skb == NULL)
+ goto errout;
+
+ err = inet_netconf_fill_devconf(skb, ifindex, devconf,
+ NETLINK_CB(in_skb).portid,
+ nlh->nlmsg_seq, RTM_NEWNETCONF, 0,
+ -1);
+ if (err < 0) {
+ /* -EMSGSIZE implies BUG in inet_netconf_msgsize_devconf() */
+ WARN_ON(err == -EMSGSIZE);
+ kfree_skb(skb);
+ goto errout;
+ }
+ err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
+errout:
+ return err;
+}
+
#ifdef CONFIG_SYSCTL
static void devinet_copy_dflt_conf(struct net *net, int i)
@@ -1894,5 +1963,7 @@ void __init devinet_init(void)
rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL, NULL);
rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, NULL);
rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, NULL);
+ rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf,
+ NULL, NULL);
}
--
1.7.12
^ permalink raw reply related
* Re: [PATCH] Make hmac algorithm selection for cookie generation dynamic
From: Neil Horman @ 2012-10-24 16:01 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: linux-sctp, David S. Miller, netdev
In-Reply-To: <5087FBE0.1020005@gmail.com>
On Wed, Oct 24, 2012 at 10:32:00AM -0400, Vlad Yasevich wrote:
> On 10/19/2012 11:52 AM, Neil Horman wrote:
> >Currently sctp allows for the optional use of md5 of sha1 hmac algorithms to
> >generate cookie values when establishing new connections via two build time
> >config options. Theres no real reason to make this a static selection. We can
> >add a sysctl that allows for the dynamic selection of these algorithms at run
> >time, with the default value determined by the corresponding crypto library
> >config options. It saves us two needless configuration settings and enables the
> >freedom for administrators to select which algorithm a particular system uses.
> >This comes in handy when, for example running a system in FIPS mode, where use
> >of md5 is disallowed, but SHA1 is permitted.
> >
> >Note: This new sysctl has no corresponding socket option to select the cookie
> >hmac algorithm. I chose not to implement that intentionally, as RFC 6458
> >contains no option for this value, and I opted not to pollute the socket option
> >namespace.
> >
> >Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >CC: Vlad Yasevich <vyasevich@gmail.com>
> >CC: "David S. Miller" <davem@davemloft.net>
> >CC: netdev@vger.kernel.org
> >---
> > Documentation/networking/ip-sysctl.txt | 14 ++++++++
> > include/net/netns/sctp.h | 3 ++
> > include/net/sctp/constants.h | 8 -----
> > include/net/sctp/structs.h | 1 +
> > net/sctp/Kconfig | 30 -----------------
> > net/sctp/protocol.c | 9 ++++++
> > net/sctp/socket.c | 11 ++++---
> > net/sctp/sysctl.c | 59 ++++++++++++++++++++++++++++++++++
> > 8 files changed, 93 insertions(+), 42 deletions(-)
> >
> >diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
> >index c7fc107..98ac0d7 100644
> >--- a/Documentation/networking/ip-sysctl.txt
> >+++ b/Documentation/networking/ip-sysctl.txt
> >@@ -1514,6 +1514,20 @@ cookie_preserve_enable - BOOLEAN
> >
> > Default: 1
> >
> >+cookie_hmac_alg - STRING
> >+ Select the hmac algorithm used when generating the cookie value sent by
> >+ a listening sctp socket to a connecting client in the INIT-ACK chunk.
> >+ Valid values are:
> >+ * md5
> >+ * sha1
> >+ * none
> >+ Ability to assign md5 or sha1 as the selected alg is predicated on the
> >+ configuarion of those algorithms at build time (CONFIG_CRYPTO_MD5 and
> >+ CONFIG_CRYPTO_SHA1).
> >+
> >+ Default: Dependent on configuration. MD5 if available, else SHA1 if
> >+ available, else none.
> >+
> > rcvbuf_policy - INTEGER
> > Determines if the receive buffer is attributed to the socket or to
> > association. SCTP supports the capability to create multiple
> >diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h
> >index 5e5eb1f..3573a81 100644
> >--- a/include/net/netns/sctp.h
> >+++ b/include/net/netns/sctp.h
> >@@ -62,6 +62,9 @@ struct netns_sctp {
> > /* Whether Cookie Preservative is enabled(1) or not(0) */
> > int cookie_preserve_enable;
> >
> >+ /* The namespace default hmac alg */
> >+ char *sctp_hmac_alg;
> >+
> > /* Valid.Cookie.Life - 60 seconds */
> > unsigned int valid_cookie_life;
> >
> >diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
> >index d053d2e..c29707d 100644
> >--- a/include/net/sctp/constants.h
> >+++ b/include/net/sctp/constants.h
> >@@ -312,14 +312,6 @@ enum { SCTP_MAX_GABS = 16 };
> > * functions simpler to write.
> > */
> >
> >-#if defined (CONFIG_SCTP_HMAC_MD5)
> >-#define SCTP_COOKIE_HMAC_ALG "hmac(md5)"
> >-#elif defined (CONFIG_SCTP_HMAC_SHA1)
> >-#define SCTP_COOKIE_HMAC_ALG "hmac(sha1)"
> >-#else
> >-#define SCTP_COOKIE_HMAC_ALG NULL
> >-#endif
> >-
> > /* These return values describe the success or failure of a number of
> > * routines which form the lower interface to SCTP_outqueue.
> > */
> >diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> >index 0fef00f..ce5f957 100644
> >--- a/include/net/sctp/structs.h
> >+++ b/include/net/sctp/structs.h
> >@@ -177,6 +177,7 @@ struct sctp_sock {
> >
> > /* Access to HMAC transform. */
> > struct crypto_hash *hmac;
> >+ char *sctp_hmac_alg;
> >
> > /* What is our base endpointer? */
> > struct sctp_endpoint *ep;
> >diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
> >index 126b014..44ffd3e 100644
> >--- a/net/sctp/Kconfig
> >+++ b/net/sctp/Kconfig
> >@@ -9,7 +9,6 @@ menuconfig IP_SCTP
> > select CRYPTO
> > select CRYPTO_HMAC
> > select CRYPTO_SHA1
> >- select CRYPTO_MD5 if SCTP_HMAC_MD5
> > select LIBCRC32C
> > ---help---
> > Stream Control Transmission Protocol
> >@@ -68,33 +67,4 @@ config SCTP_DBG_OBJCNT
> >
> > If unsure, say N
> >
> >-choice
> >- prompt "SCTP: Cookie HMAC Algorithm"
> >- default SCTP_HMAC_MD5
>
> Did you intend to change the default algorithm to SHA1? Seems a bit
> unintended and undocumented.
>
Thats not what I did (or at least not my intention). The sctp_net_init code
checks teh crypto options and if md5 is selcted as on, it uses that as a
default, only if its not selected, does sha1 become the default. In my testing
this worked properly, and the sysctl for the init_net came up as md5, even
though I had both md5 and sha1 configured. Is there something else here I'm
missing?
> Would it make more sense to to change from a choice to sub-menu and
> allow selection of multiple algorithms? Then use the interface you
> have to change the default.
>
Not sure I follow. You mean create a sub-menu allowing us to choose the default
value at compile time, and allow overriding from there via sysctl? I'm fine with
such a change, although given that everyone seems used to the idea of md5 being
the default when configured, as well as the idea of needing to override default
sysctl values, I'm not sure is necessecary.
Let me know about the default, and if I'm on the same page as you regarding the
config option, and I can repost this.
Thanks!
Neil
^ permalink raw reply
* Re: [PATCH] Make hmac algorithm selection for cookie generation dynamic
From: Vlad Yasevich @ 2012-10-24 16:17 UTC (permalink / raw)
To: Neil Horman; +Cc: linux-sctp, David S. Miller, netdev
In-Reply-To: <20121024160157.GA26433@hmsreliant.think-freely.org>
On 10/24/2012 12:01 PM, Neil Horman wrote:
> On Wed, Oct 24, 2012 at 10:32:00AM -0400, Vlad Yasevich wrote:
>> On 10/19/2012 11:52 AM, Neil Horman wrote:
>>> Currently sctp allows for the optional use of md5 of sha1 hmac algorithms to
>>> generate cookie values when establishing new connections via two build time
>>> config options. Theres no real reason to make this a static selection. We can
>>> add a sysctl that allows for the dynamic selection of these algorithms at run
>>> time, with the default value determined by the corresponding crypto library
>>> config options. It saves us two needless configuration settings and enables the
>>> freedom for administrators to select which algorithm a particular system uses.
>>> This comes in handy when, for example running a system in FIPS mode, where use
>>> of md5 is disallowed, but SHA1 is permitted.
>>>
>>> Note: This new sysctl has no corresponding socket option to select the cookie
>>> hmac algorithm. I chose not to implement that intentionally, as RFC 6458
>>> contains no option for this value, and I opted not to pollute the socket option
>>> namespace.
>>>
>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>> CC: Vlad Yasevich <vyasevich@gmail.com>
>>> CC: "David S. Miller" <davem@davemloft.net>
>>> CC: netdev@vger.kernel.org
>>> ---
>>> Documentation/networking/ip-sysctl.txt | 14 ++++++++
>>> include/net/netns/sctp.h | 3 ++
>>> include/net/sctp/constants.h | 8 -----
>>> include/net/sctp/structs.h | 1 +
>>> net/sctp/Kconfig | 30 -----------------
>>> net/sctp/protocol.c | 9 ++++++
>>> net/sctp/socket.c | 11 ++++---
>>> net/sctp/sysctl.c | 59 ++++++++++++++++++++++++++++++++++
>>> 8 files changed, 93 insertions(+), 42 deletions(-)
>>>
>>> diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
>>> index c7fc107..98ac0d7 100644
>>> --- a/Documentation/networking/ip-sysctl.txt
>>> +++ b/Documentation/networking/ip-sysctl.txt
>>> @@ -1514,6 +1514,20 @@ cookie_preserve_enable - BOOLEAN
>>>
>>> Default: 1
>>>
>>> +cookie_hmac_alg - STRING
>>> + Select the hmac algorithm used when generating the cookie value sent by
>>> + a listening sctp socket to a connecting client in the INIT-ACK chunk.
>>> + Valid values are:
>>> + * md5
>>> + * sha1
>>> + * none
>>> + Ability to assign md5 or sha1 as the selected alg is predicated on the
>>> + configuarion of those algorithms at build time (CONFIG_CRYPTO_MD5 and
>>> + CONFIG_CRYPTO_SHA1).
>>> +
>>> + Default: Dependent on configuration. MD5 if available, else SHA1 if
>>> + available, else none.
>>> +
>>> rcvbuf_policy - INTEGER
>>> Determines if the receive buffer is attributed to the socket or to
>>> association. SCTP supports the capability to create multiple
>>> diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h
>>> index 5e5eb1f..3573a81 100644
>>> --- a/include/net/netns/sctp.h
>>> +++ b/include/net/netns/sctp.h
>>> @@ -62,6 +62,9 @@ struct netns_sctp {
>>> /* Whether Cookie Preservative is enabled(1) or not(0) */
>>> int cookie_preserve_enable;
>>>
>>> + /* The namespace default hmac alg */
>>> + char *sctp_hmac_alg;
>>> +
>>> /* Valid.Cookie.Life - 60 seconds */
>>> unsigned int valid_cookie_life;
>>>
>>> diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
>>> index d053d2e..c29707d 100644
>>> --- a/include/net/sctp/constants.h
>>> +++ b/include/net/sctp/constants.h
>>> @@ -312,14 +312,6 @@ enum { SCTP_MAX_GABS = 16 };
>>> * functions simpler to write.
>>> */
>>>
>>> -#if defined (CONFIG_SCTP_HMAC_MD5)
>>> -#define SCTP_COOKIE_HMAC_ALG "hmac(md5)"
>>> -#elif defined (CONFIG_SCTP_HMAC_SHA1)
>>> -#define SCTP_COOKIE_HMAC_ALG "hmac(sha1)"
>>> -#else
>>> -#define SCTP_COOKIE_HMAC_ALG NULL
>>> -#endif
>>> -
>>> /* These return values describe the success or failure of a number of
>>> * routines which form the lower interface to SCTP_outqueue.
>>> */
>>> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
>>> index 0fef00f..ce5f957 100644
>>> --- a/include/net/sctp/structs.h
>>> +++ b/include/net/sctp/structs.h
>>> @@ -177,6 +177,7 @@ struct sctp_sock {
>>>
>>> /* Access to HMAC transform. */
>>> struct crypto_hash *hmac;
>>> + char *sctp_hmac_alg;
>>>
>>> /* What is our base endpointer? */
>>> struct sctp_endpoint *ep;
>>> diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
>>> index 126b014..44ffd3e 100644
>>> --- a/net/sctp/Kconfig
>>> +++ b/net/sctp/Kconfig
>>> @@ -9,7 +9,6 @@ menuconfig IP_SCTP
>>> select CRYPTO
>>> select CRYPTO_HMAC
>>> select CRYPTO_SHA1
>>> - select CRYPTO_MD5 if SCTP_HMAC_MD5
>>> select LIBCRC32C
>>> ---help---
>>> Stream Control Transmission Protocol
>>> @@ -68,33 +67,4 @@ config SCTP_DBG_OBJCNT
>>>
>>> If unsure, say N
>>>
>>> -choice
>>> - prompt "SCTP: Cookie HMAC Algorithm"
>>> - default SCTP_HMAC_MD5
>>
>> Did you intend to change the default algorithm to SHA1? Seems a bit
>> unintended and undocumented.
>>
> Thats not what I did (or at least not my intention). The sctp_net_init code
> checks teh crypto options and if md5 is selcted as on, it uses that as a
> default, only if its not selected, does sha1 become the default. In my testing
> this worked properly, and the sysctl for the init_net came up as md5, even
> though I had both md5 and sha1 configured. Is there something else here I'm
> missing?
Yes, if you turn on MD5 in the config, it stays the default. However,
if you do a brand new config, MD5 may be disabled (if nothing else in
the config needs it) and then your default will change seemingly
unintentionally. You always get SHA1 because it is needed for SCTP AUTH.
>
>> Would it make more sense to to change from a choice to sub-menu and
>> allow selection of multiple algorithms? Then use the interface you
>> have to change the default.
>>
> Not sure I follow. You mean create a sub-menu allowing us to choose the default
> value at compile time, and allow overriding from there via sysctl? I'm fine with
> such a change, although given that everyone seems used to the idea of md5 being
> the default when configured, as well as the idea of needing to override default
> sysctl values, I'm not sure is necessecary.
>
>
> Let me know about the default, and if I'm on the same page as you regarding the
> config option, and I can repost this.
>
What I am not sure I like is that there is no longer any tie in between
the HMACs needed for cookie signing and the HMAC module selections in
SCTP. You just happen to get lucky with SHA1 because it is always there
for AUTH. Before, to disable cookie signing, it was an explicit
configuration choice to turn it off in the SCTP section. Now, it might
be an unintended side-effect for not turning on the right modules.
See what I am getting at?
A solution might be to have a sub-menu that allows you to turn on a set
of signing algorithms and may be even choose the default one. This way
it's clear that there is a dependency relationship between SCTP and
signing algorithms.
-vlad
> Thanks!
> Neil
>
^ permalink raw reply
* Re: [PATCH] net: allow configuration of the size of page in __netdev_alloc_frag
From: Ian Campbell @ 2012-10-24 16:22 UTC (permalink / raw)
To: Eric Dumazet
Cc: netdev@vger.kernel.org, Eric Dumazet, Konrad Rzeszutek Wilk,
xen-devel@lists.xen.org
In-Reply-To: <1351092068.6537.107.camel@edumazet-glaptop>
On Wed, 2012-10-24 at 16:21 +0100, Eric Dumazet wrote:
> On Wed, 2012-10-24 at 15:02 +0100, Ian Campbell wrote:
> > On Wed, 2012-10-24 at 14:30 +0100, Eric Dumazet wrote:
> > > It seems to me its a driver issue, for example
> > > drivers/net/xen-netfront.c has assumptions that can be easily fixed.
> >
> > The netfront ->head thing is a separate (although perhaps related)
> > issue, I intended to fix along the same lines as the previous netback
> > except for some unfathomable reason I haven't been able to reproduce the
> > problem with netfront -- I've no idea why though since it seems like it
> > should be a no brainer!
> >
> > > Why skb->head can be on order-1 or order-2 pages and this is working ?
> >
> > skb->head being order 1 or 2 isn't working for me. The driver I'm having
> > issues with which caused me to create this particular patch is the tg3
> > driver (although I don't think this is by any means specific to tg3).
> >
> > For the ->head the tg3 driver does:
> > mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
> > while for the frags it does:
> > mapping = skb_frag_dma_map(&tp->pdev->dev, frag, 0, len, DMA_TO_DEVICE);
> >
> > This ought to do the Right Thing but doesn't seem to be working. Konrad
> > suspected an issue with the swiotlb's handling of order>0 pages in some
> > cases. As I said in the commit message he is looking into this issue.
> >
> > My concern however was that even once the swiotlb is fixed to work right
> > the effect of pci_map_single on a order>0 page is going to be that the
> > data gets bounced into contiguous memory -- that is a memcpy which would
> > undo the benefit of having allocating large pages to start with. So I
> > figured that in such cases we'd be better off just using order 0
> > allocations to start with.
>
> I am really confused.
>
> If you really have such problems, why locally generated TCP traffic
> doesnt also have it ?
I think it does. The reason I noticed the original problem was that ssh
to the machine was virtually (no pun intended) unusable.
> Your patch doesnt touch sk_page_frag_refill(), does it ?
That's right. It doesn't. When is (sk->sk_allocation & __GFP_WAIT) true?
Is it possible I'm just not hitting that case?
Is it possible that this only affects certain traffic patterns (I only
really tried ssh/scp and ping)? Or perhaps its just that the swiotlb is
only broken in one corner case and not the other.
Ian.
^ permalink raw reply
* Re: [PATCH for-3.7] vhost: fix mergeable bufs on BE hosts
From: Michael S. Tsirkin @ 2012-10-24 16:24 UTC (permalink / raw)
To: David Miller; +Cc: netdev, stable, kvm, virtualization
In-Reply-To: <20121021.192402.1010682456837361393.davem@davemloft.net>
On Sun, Oct 21, 2012 at 07:24:02PM -0400, David Miller wrote:
> From: "Michael S. Tsirkin" <mst@redhat.com>
> Date: Sun, 21 Oct 2012 14:49:01 +0200
>
> > On Mon, Oct 15, 2012 at 07:55:34PM +0200, Michael S. Tsirkin wrote:
> >> We copy head count to a 16 bit field,
> >> this works by chance on LE but on BE
> >> guest gets 0. Fix it up.
> >>
> >> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> >> Tested-by: Alexander Graf <agraf@suse.de>
> >> Cc: stable@kernel.org
> >
> > Ping. Dave, could you apply this to -net please?
>
> Pinging me but not cc:'ing me? That's really strange.
>
> What if I operate by just mass deleting things that I'm
> not explicitly on the To: or CC: when I'm very backlogged?
Yes, that was silly. Would you like me to repost the patch?
--
MST
^ permalink raw reply
* Re: [PATCH] net: allow configuration of the size of page in __netdev_alloc_frag
From: Eric Dumazet @ 2012-10-24 16:43 UTC (permalink / raw)
To: Ian Campbell
Cc: netdev@vger.kernel.org, Eric Dumazet, Konrad Rzeszutek Wilk,
xen-devel@lists.xen.org
In-Reply-To: <1351095739.18035.83.camel@zakaz.uk.xensource.com>
On Wed, 2012-10-24 at 17:22 +0100, Ian Campbell wrote:
> On Wed, 2012-10-24 at 16:21 +0100, Eric Dumazet wrote:
> > If you really have such problems, why locally generated TCP traffic
> > doesnt also have it ?
>
> I think it does. The reason I noticed the original problem was that ssh
> to the machine was virtually (no pun intended) unusable.
>
> > Your patch doesnt touch sk_page_frag_refill(), does it ?
>
> That's right. It doesn't. When is (sk->sk_allocation & __GFP_WAIT) true?
> Is it possible I'm just not hitting that case?
>
I hope not. GFP_KERNEL has __GFP_WAIT.
> Is it possible that this only affects certain traffic patterns (I only
> really tried ssh/scp and ping)? Or perhaps its just that the swiotlb is
> only broken in one corner case and not the other.
Could you try a netperf -t TCP_STREAM ?
Because ssh use small packets, and small TCP packets dont use frags but
skb->head.
You mentioned a 70% drop of performance, but what test have you used
exactly ?
^ permalink raw reply
* [net-next PATCH v1 0/3] extend set/get netlink for embedded
From: John Fastabend @ 2012-10-24 16:50 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
This extends the PF_BRIDGE setlink and getlink so that they can be
used generically outside of the Linux bridge module. Doing this
allows embedded devices to use the same netlink interface that
the software bridge is currently using.
In this patchset I opted to create two new ndo ops ndo_bridge_setlink
and ndo_bridge_getlink. These ops pass the nlmsghdr to the device
for handling. The netlink message is extended to support nested
IFLA_AF_SPEC attributes. A IFLA_BRIDGE_FLAGS attribute is used to
determine the target of the message either a master netdev is the
target or the target is "self" indicating the target is the netdev.
In this way we can send netlink msg to an embedded device or the
linux sw bridge or both. If the set completes sucessfully the flag
is cleared in this way we can learn what failed in the both case.
This scheme is similar to how FDB updates are handled. If no flag
attribute is present the message is sent to the master device to
support the existing messages.
An initial IFLA_BRIDGE_MODE attribute is added to indicate if the
bridge is in a VEPA mode or VEB mode. This is most useful for
SR-IOV device and can be used to indicate support for VF to VF or
VF to PF traffic. Without this we have no way of knowing this
other then trial and error because not all hardware supports
this.
In the future additional attributes can be added to handle other
attributes. We could for example move some of the linux bridge
sysfs attributes here if we want a netlink interface for them.
This should also allow DSA switches to use the bridging tools.
See RFC patch from Lennert
http://patchwork.ozlabs.org/patch/16578/
I could have simply added the VEPA attribute handling to the
rtnl_setlink() routine but it seemed like a good feature to have
all the bridging events and configuration on the same type. Also
this should allow more powerful offloaded switches like the
hardware supported via DSA access to the bridge control
interface.
Also I think this interface should allow Vlad to add his port based
VLAN interface here as well.
Any feedback/criticism appreciated thanks!
---
John Fastabend (3):
ixgbe: add setlink, getlink support to ixgbe and ixgbevf
net: set and query VEB/VEPA bridge mode via PF_BRIDGE
net: create generic bridge ops
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 59 ++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 3
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 10 +
include/linux/netdevice.h | 10 +
include/linux/rtnetlink.h | 3
include/uapi/linux/if_bridge.h | 18 ++
net/bridge/br_device.c | 2
net/bridge/br_netlink.c | 75 +-------
net/bridge/br_private.h | 7 +
net/core/rtnetlink.c | 207 +++++++++++++++++++++
10 files changed, 328 insertions(+), 66 deletions(-)
--
Signature
^ permalink raw reply
* [net-next PATCH v1 1/3] net: create generic bridge ops
From: John Fastabend @ 2012-10-24 16:51 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
In-Reply-To: <20121024164906.14221.45341.stgit@jf-dev1-dcblab>
The PF_BRIDGE:RTM_{GET|SET}LINK nlmsg family and type are
currently embedded in the ./net/bridge module. This prohibits
them from being used by other bridging devices. One example
of this being hardware that has embedded bridging components.
In order to use these nlmsg types more generically this patch
adds two net_device_ops hooks. One to set link bridge attributes
and another to dump the current bride attributes.
ndo_bridge_setlink()
ndo_bridge_getlink()
CC: Lennert Buytenhek <buytenh@wantstofly.org>
CC: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/linux/netdevice.h | 10 ++++++
net/bridge/br_device.c | 2 +
net/bridge/br_netlink.c | 73 +++++++----------------------------------
net/bridge/br_private.h | 3 ++
net/core/rtnetlink.c | 80 +++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 108 insertions(+), 60 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f8eda02..7bf867c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -887,6 +887,10 @@ struct netdev_fcoe_hbainfo {
* struct net_device *dev, int idx)
* Used to add FDB entries to dump requests. Implementers should add
* entries to skb and update idx with the number of entries.
+ *
+ * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh)
+ * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
+ * struct net_device *dev)
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
@@ -998,6 +1002,12 @@ struct net_device_ops {
struct netlink_callback *cb,
struct net_device *dev,
int idx);
+
+ int (*ndo_bridge_setlink)(struct net_device *dev,
+ struct nlmsghdr *nlh);
+ int (*ndo_bridge_getlink)(struct sk_buff *skb,
+ u32 pid, u32 seq,
+ struct net_device *dev);
};
/*
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 070e8a6..63b5b08 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -313,6 +313,8 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_fdb_add = br_fdb_add,
.ndo_fdb_del = br_fdb_delete,
.ndo_fdb_dump = br_fdb_dump,
+ .ndo_bridge_getlink = br_getlink,
+ .ndo_bridge_setlink = br_setlink,
};
static void br_dev_free(struct net_device *dev)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 093f527..743511b 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -111,54 +111,33 @@ errout:
/*
* Dump information about all ports, in response to GETLINK
*/
-static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev)
{
- struct net *net = sock_net(skb->sk);
- struct net_device *dev;
- int idx;
-
- idx = 0;
- rcu_read_lock();
- for_each_netdev_rcu(net, dev) {
- struct net_bridge_port *port = br_port_get_rcu(dev);
-
- /* not a bridge port */
- if (!port || idx < cb->args[0])
- goto skip;
-
- if (br_fill_ifinfo(skb, port,
- NETLINK_CB(cb->skb).portid,
- cb->nlh->nlmsg_seq, RTM_NEWLINK,
- NLM_F_MULTI) < 0)
- break;
-skip:
- ++idx;
- }
- rcu_read_unlock();
- cb->args[0] = idx;
+ int err = 0;
+ struct net_bridge_port *port = br_port_get_rcu(dev);
+
+ /* not a bridge port */
+ if (!port)
+ goto out;
- return skb->len;
+ err = br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, NLM_F_MULTI);
+out:
+ return err;
}
/*
* Change state of port (ie from forwarding to blocking etc)
* Used by spanning tree in user space.
*/
-static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
{
- struct net *net = sock_net(skb->sk);
struct ifinfomsg *ifm;
struct nlattr *protinfo;
- struct net_device *dev;
struct net_bridge_port *p;
u8 new_state;
- if (nlmsg_len(nlh) < sizeof(*ifm))
- return -EINVAL;
-
ifm = nlmsg_data(nlh);
- if (ifm->ifi_family != AF_BRIDGE)
- return -EPFNOSUPPORT;
protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO);
if (!protinfo || nla_len(protinfo) < sizeof(u8))
@@ -168,10 +147,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if (new_state > BR_STATE_BLOCKING)
return -EINVAL;
- dev = __dev_get_by_index(net, ifm->ifi_index);
- if (!dev)
- return -ENODEV;
-
p = br_port_get_rtnl(dev);
if (!p)
return -EINVAL;
@@ -218,29 +193,7 @@ struct rtnl_link_ops br_link_ops __read_mostly = {
int __init br_netlink_init(void)
{
- int err;
-
- err = rtnl_link_register(&br_link_ops);
- if (err < 0)
- goto err1;
-
- err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL,
- br_dump_ifinfo, NULL);
- if (err)
- goto err2;
- err = __rtnl_register(PF_BRIDGE, RTM_SETLINK,
- br_rtm_setlink, NULL, NULL);
- if (err)
- goto err3;
-
- return 0;
-
-err3:
- rtnl_unregister_all(PF_BRIDGE);
-err2:
- rtnl_link_unregister(&br_link_ops);
-err1:
- return err;
+ return rtnl_link_register(&br_link_ops);
}
void __exit br_netlink_fini(void)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 9b278c4..fdcd5f6 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -553,6 +553,9 @@ extern struct rtnl_link_ops br_link_ops;
extern int br_netlink_init(void);
extern void br_netlink_fini(void);
extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
+extern int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg);
+extern int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev);
#ifdef CONFIG_SYSFS
/* br_sysfs_if.c */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 64fe3cc..a068666 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2252,6 +2252,83 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *dev;
+ int idx = 0;
+ u32 portid = NETLINK_CB(cb->skb).portid;
+ u32 seq = cb->nlh->nlmsg_seq;
+
+ rcu_read_lock();
+ for_each_netdev_rcu(net, dev) {
+ const struct net_device_ops *ops = dev->netdev_ops;
+ struct net_device *master = dev->master;
+
+ if (idx < cb->args[0])
+ continue;
+
+ if (master && master->netdev_ops->ndo_bridge_getlink) {
+ const struct net_device_ops *bops = master->netdev_ops;
+ int err = bops->ndo_bridge_getlink(skb, portid,
+ seq, dev);
+
+ if (err < 0)
+ break;
+ else
+ idx++;
+ }
+
+ if (ops->ndo_bridge_getlink) {
+ int err = ops->ndo_bridge_getlink(skb, portid,
+ seq, dev);
+
+ if (err < 0)
+ break;
+ else
+ idx++;
+ }
+ }
+ rcu_read_unlock();
+ cb->args[0] = idx;
+
+ return skb->len;
+}
+
+static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
+ void *arg)
+{
+ struct net *net = sock_net(skb->sk);
+ struct ifinfomsg *ifm;
+ struct net_device *dev;
+ int err = -EINVAL;
+
+ if (nlmsg_len(nlh) < sizeof(*ifm))
+ return -EINVAL;
+
+ ifm = nlmsg_data(nlh);
+ if (ifm->ifi_family != AF_BRIDGE)
+ return -EPFNOSUPPORT;
+
+ dev = __dev_get_by_index(net, ifm->ifi_index);
+ if (!dev) {
+ pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n");
+ return -ENODEV;
+ }
+
+ if (dev->master && dev->master->netdev_ops->ndo_bridge_setlink) {
+ err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh);
+ if (err)
+ goto out;
+ }
+
+ if (dev->netdev_ops->ndo_bridge_setlink)
+ err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
+
+out:
+ return err;
+}
+
/* Protected by RTNL sempahore. */
static struct rtattr **rta_buf;
static int rtattr_max;
@@ -2433,5 +2510,8 @@ void __init rtnetlink_init(void)
rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL);
rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL);
rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL);
+
+ rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL);
+ rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL);
}
^ permalink raw reply related
* [net-next PATCH v1 3/3] ixgbe: add setlink, getlink support to ixgbe and ixgbevf
From: John Fastabend @ 2012-10-24 16:51 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
In-Reply-To: <20121024164906.14221.45341.stgit@jf-dev1-dcblab>
This adds support for the net device ops to manage the embedded
hardware bridge on ixgbe devices. With this patch the bridge
mode can be toggled between VEB and VEPA to support stacking
macvlan devices or using the embedded switch without any SW
component in 802.1Qbg/br environments.
Additionally, this adds source address pruning to the ixgbevf
driver to prune any frames sent back from a reflective relay on
the switch. This is required because the existing hardware does
not support this. Without it frames get pushed into the stack
with its own src mac which is invalid per 802.1Qbg VEPA
definition.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 59 ++++++++++++++++++++-
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 3 +
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 10 ++++
include/linux/rtnetlink.h | 3 +
net/core/rtnetlink.c | 50 ++++++++++++++++++
5 files changed, 122 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 88d636a..9a88e01 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -44,6 +44,7 @@
#include <linux/ethtool.h>
#include <linux/if.h>
#include <linux/if_vlan.h>
+#include <linux/if_bridge.h>
#include <linux/prefetch.h>
#include <scsi/fc/fc_fcoe.h>
@@ -3224,7 +3225,6 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), reg_offset - 1);
IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (~0) << vf_shift);
IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), reg_offset - 1);
- IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
/* Map PF MAC address in RAR Entry 0 to first pool following VFs */
hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0));
@@ -3247,8 +3247,6 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
- /* enable Tx loopback for VF/PF communication */
- IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
/* Enable MAC Anti-Spoofing */
hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0),
@@ -7025,6 +7023,59 @@ static int ixgbe_ndo_fdb_dump(struct sk_buff *skb,
return idx;
}
+static int ixgbe_ndo_bridge_setlink(struct net_device *dev,
+ struct nlmsghdr *nlh)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ struct nlattr *attr, *br_spec;
+ int rem;
+
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return -EOPNOTSUPP;
+
+ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
+
+ nla_for_each_nested(attr, br_spec, rem) {
+ __u16 mode;
+ u32 reg = 0;
+
+ if (nla_type(attr) != IFLA_BRIDGE_MODE)
+ continue;
+
+ mode = nla_get_u16(attr);
+ if (mode == BRIDGE_MODE_VEPA)
+ reg = 0;
+ else if (mode == BRIDGE_MODE_VEB)
+ reg = IXGBE_PFDTXGSWC_VT_LBEN;
+ else
+ return -EINVAL;
+
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_PFDTXGSWC, reg);
+
+ e_info(drv, "enabling bridge mode: %s\n",
+ mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
+ }
+
+ return 0;
+}
+
+static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ u16 mode;
+
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return 0;
+
+ if (IXGBE_READ_REG(&adapter->hw, IXGBE_PFDTXGSWC) & 1)
+ mode = BRIDGE_MODE_VEB;
+ else
+ mode = BRIDGE_MODE_VEPA;
+
+ return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode);
+}
+
static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
@@ -7064,6 +7115,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_fdb_add = ixgbe_ndo_fdb_add,
.ndo_fdb_del = ixgbe_ndo_fdb_del,
.ndo_fdb_dump = ixgbe_ndo_fdb_dump,
+ .ndo_bridge_setlink = ixgbe_ndo_bridge_setlink,
+ .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
};
/**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 96876b7..7e3ac28 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -117,6 +117,9 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
}
}
+ /* Initialize default switching mode VEB */
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+
/* If call to enable VFs succeeded then allocate memory
* for per VF control structures.
*/
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 07d7eab..ac6a76d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -478,6 +478,16 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
}
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
+ /* Workaround hardware that can't do proper VEPA multicast
+ * source pruning.
+ */
+ if ((skb->pkt_type & (PACKET_BROADCAST | PACKET_MULTICAST)) &&
+ !(compare_ether_addr(adapter->netdev->dev_addr,
+ eth_hdr(skb)->h_source))) {
+ dev_kfree_skb_irq(skb);
+ goto next_desc;
+ }
+
ixgbevf_receive_skb(q_vector, skb, staterr, rx_desc);
next_desc:
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 7002bbf..489dd7bb 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -69,4 +69,7 @@ extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
int idx);
+
+extern int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev, u16 mode);
#endif /* __LINUX_RTNETLINK_H */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 8d2af0f..51dc58f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2252,6 +2252,56 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev, u16 mode)
+{
+ struct nlmsghdr *nlh;
+ struct ifinfomsg *ifm;
+ struct nlattr *br_afspec;
+ u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
+
+ nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), NLM_F_MULTI);
+ if (nlh == NULL)
+ return -EMSGSIZE;
+
+ ifm = nlmsg_data(nlh);
+ ifm->ifi_family = AF_BRIDGE;
+ ifm->__ifi_pad = 0;
+ ifm->ifi_type = dev->type;
+ ifm->ifi_index = dev->ifindex;
+ ifm->ifi_flags = dev_get_flags(dev);
+ ifm->ifi_change = 0;
+
+
+ if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
+ nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
+ nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
+ (dev->master &&
+ nla_put_u32(skb, IFLA_MASTER, dev->master->ifindex)) ||
+ (dev->addr_len &&
+ nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
+ (dev->ifindex != dev->iflink &&
+ nla_put_u32(skb, IFLA_LINK, dev->iflink)))
+ goto nla_put_failure;
+
+ br_afspec = nla_nest_start(skb, IFLA_AF_SPEC);
+ if (!br_afspec)
+ goto nla_put_failure;
+
+ if (nla_put_u16(skb, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF) ||
+ nla_put_u16(skb, IFLA_BRIDGE_MODE, mode)) {
+ nla_nest_cancel(skb, br_afspec);
+ goto nla_put_failure;
+ }
+ nla_nest_end(skb, br_afspec);
+
+ return nlmsg_end(skb, nlh);
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
+}
+EXPORT_SYMBOL(ndo_dflt_bridge_getlink);
+
static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
^ permalink raw reply related
* Re: [PATCH] Make hmac algorithm selection for cookie generation dynamic
From: Neil Horman @ 2012-10-24 17:18 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: linux-sctp, David S. Miller, netdev
In-Reply-To: <508814AC.8030005@gmail.com>
On Wed, Oct 24, 2012 at 12:17:48PM -0400, Vlad Yasevich wrote:
> On 10/24/2012 12:01 PM, Neil Horman wrote:
> >On Wed, Oct 24, 2012 at 10:32:00AM -0400, Vlad Yasevich wrote:
> >>On 10/19/2012 11:52 AM, Neil Horman wrote:
> >>>Currently sctp allows for the optional use of md5 of sha1 hmac algorithms to
> >>>generate cookie values when establishing new connections via two build time
> >>>config options. Theres no real reason to make this a static selection. We can
> >>>add a sysctl that allows for the dynamic selection of these algorithms at run
> >>>time, with the default value determined by the corresponding crypto library
> >>>config options. It saves us two needless configuration settings and enables the
> >>>freedom for administrators to select which algorithm a particular system uses.
> >>>This comes in handy when, for example running a system in FIPS mode, where use
> >>>of md5 is disallowed, but SHA1 is permitted.
> >>>
> >>>Note: This new sysctl has no corresponding socket option to select the cookie
> >>>hmac algorithm. I chose not to implement that intentionally, as RFC 6458
> >>>contains no option for this value, and I opted not to pollute the socket option
> >>>namespace.
> >>>
> >>>Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >>>CC: Vlad Yasevich <vyasevich@gmail.com>
> >>>CC: "David S. Miller" <davem@davemloft.net>
> >>>CC: netdev@vger.kernel.org
> >>>---
> >>> Documentation/networking/ip-sysctl.txt | 14 ++++++++
> >>> include/net/netns/sctp.h | 3 ++
> >>> include/net/sctp/constants.h | 8 -----
> >>> include/net/sctp/structs.h | 1 +
> >>> net/sctp/Kconfig | 30 -----------------
> >>> net/sctp/protocol.c | 9 ++++++
> >>> net/sctp/socket.c | 11 ++++---
> >>> net/sctp/sysctl.c | 59 ++++++++++++++++++++++++++++++++++
> >>> 8 files changed, 93 insertions(+), 42 deletions(-)
> >>>
> >>>diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
> >>>index c7fc107..98ac0d7 100644
> >>>--- a/Documentation/networking/ip-sysctl.txt
> >>>+++ b/Documentation/networking/ip-sysctl.txt
> >>>@@ -1514,6 +1514,20 @@ cookie_preserve_enable - BOOLEAN
> >>>
> >>> Default: 1
> >>>
> >>>+cookie_hmac_alg - STRING
> >>>+ Select the hmac algorithm used when generating the cookie value sent by
> >>>+ a listening sctp socket to a connecting client in the INIT-ACK chunk.
> >>>+ Valid values are:
> >>>+ * md5
> >>>+ * sha1
> >>>+ * none
> >>>+ Ability to assign md5 or sha1 as the selected alg is predicated on the
> >>>+ configuarion of those algorithms at build time (CONFIG_CRYPTO_MD5 and
> >>>+ CONFIG_CRYPTO_SHA1).
> >>>+
> >>>+ Default: Dependent on configuration. MD5 if available, else SHA1 if
> >>>+ available, else none.
> >>>+
> >>> rcvbuf_policy - INTEGER
> >>> Determines if the receive buffer is attributed to the socket or to
> >>> association. SCTP supports the capability to create multiple
> >>>diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h
> >>>index 5e5eb1f..3573a81 100644
> >>>--- a/include/net/netns/sctp.h
> >>>+++ b/include/net/netns/sctp.h
> >>>@@ -62,6 +62,9 @@ struct netns_sctp {
> >>> /* Whether Cookie Preservative is enabled(1) or not(0) */
> >>> int cookie_preserve_enable;
> >>>
> >>>+ /* The namespace default hmac alg */
> >>>+ char *sctp_hmac_alg;
> >>>+
> >>> /* Valid.Cookie.Life - 60 seconds */
> >>> unsigned int valid_cookie_life;
> >>>
> >>>diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
> >>>index d053d2e..c29707d 100644
> >>>--- a/include/net/sctp/constants.h
> >>>+++ b/include/net/sctp/constants.h
> >>>@@ -312,14 +312,6 @@ enum { SCTP_MAX_GABS = 16 };
> >>> * functions simpler to write.
> >>> */
> >>>
> >>>-#if defined (CONFIG_SCTP_HMAC_MD5)
> >>>-#define SCTP_COOKIE_HMAC_ALG "hmac(md5)"
> >>>-#elif defined (CONFIG_SCTP_HMAC_SHA1)
> >>>-#define SCTP_COOKIE_HMAC_ALG "hmac(sha1)"
> >>>-#else
> >>>-#define SCTP_COOKIE_HMAC_ALG NULL
> >>>-#endif
> >>>-
> >>> /* These return values describe the success or failure of a number of
> >>> * routines which form the lower interface to SCTP_outqueue.
> >>> */
> >>>diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> >>>index 0fef00f..ce5f957 100644
> >>>--- a/include/net/sctp/structs.h
> >>>+++ b/include/net/sctp/structs.h
> >>>@@ -177,6 +177,7 @@ struct sctp_sock {
> >>>
> >>> /* Access to HMAC transform. */
> >>> struct crypto_hash *hmac;
> >>>+ char *sctp_hmac_alg;
> >>>
> >>> /* What is our base endpointer? */
> >>> struct sctp_endpoint *ep;
> >>>diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
> >>>index 126b014..44ffd3e 100644
> >>>--- a/net/sctp/Kconfig
> >>>+++ b/net/sctp/Kconfig
> >>>@@ -9,7 +9,6 @@ menuconfig IP_SCTP
> >>> select CRYPTO
> >>> select CRYPTO_HMAC
> >>> select CRYPTO_SHA1
> >>>- select CRYPTO_MD5 if SCTP_HMAC_MD5
> >>> select LIBCRC32C
> >>> ---help---
> >>> Stream Control Transmission Protocol
> >>>@@ -68,33 +67,4 @@ config SCTP_DBG_OBJCNT
> >>>
> >>> If unsure, say N
> >>>
> >>>-choice
> >>>- prompt "SCTP: Cookie HMAC Algorithm"
> >>>- default SCTP_HMAC_MD5
> >>
> >>Did you intend to change the default algorithm to SHA1? Seems a bit
> >>unintended and undocumented.
> >>
> >Thats not what I did (or at least not my intention). The sctp_net_init code
> >checks teh crypto options and if md5 is selcted as on, it uses that as a
> >default, only if its not selected, does sha1 become the default. In my testing
> >this worked properly, and the sysctl for the init_net came up as md5, even
> >though I had both md5 and sha1 configured. Is there something else here I'm
> >missing?
>
> Yes, if you turn on MD5 in the config, it stays the default.
> However, if you do a brand new config, MD5 may be disabled (if
> nothing else in the config needs it) and then your default will
> change seemingly unintentionally. You always get SHA1 because it is
> needed for SCTP AUTH.
>
> >
> >>Would it make more sense to to change from a choice to sub-menu and
> >>allow selection of multiple algorithms? Then use the interface you
> >>have to change the default.
> >>
> >Not sure I follow. You mean create a sub-menu allowing us to choose the default
> >value at compile time, and allow overriding from there via sysctl? I'm fine with
> >such a change, although given that everyone seems used to the idea of md5 being
> >the default when configured, as well as the idea of needing to override default
> >sysctl values, I'm not sure is necessecary.
> >
> >
> >Let me know about the default, and if I'm on the same page as you regarding the
> >config option, and I can repost this.
> >
>
> What I am not sure I like is that there is no longer any tie in
> between the HMACs needed for cookie signing and the HMAC module
> selections in SCTP. You just happen to get lucky with SHA1 because
> it is always there for AUTH. Before, to disable cookie signing, it
> was an explicit configuration choice to turn it off in the SCTP
> section. Now, it might be an unintended side-effect for not turning
> on the right modules.
> See what I am getting at?
>
> A solution might be to have a sub-menu that allows you to turn on a set
> of signing algorithms and may be even choose the default one. This
> way it's clear that there is a dependency relationship between SCTP
> and signing algorithms.
>
> -vlad
>
Ah, I see, you would rather just there be a way to explicitly indicate what the
default hmac_algorithm is, rather than have it be implicitly decided upon by the
crypto options. I can see the value there. We can do something like what
selinux does in its kconfig where we off a choice of cookie hmac options from a
set of {none,md5,sha1} and set the default value based on that. I'll reroll
this in just a bit
Thanks!
Neil
> >Thanks!
> >Neil
> >
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" 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: [net-next 2/8] maintainers: update with official intel support link, new maintainer
From: Rick Jones @ 2012-10-24 17:31 UTC (permalink / raw)
To: jeffrey.t.kirsher
Cc: Joe Perches, Tushar Dave, davem, Jesse Brandeburg, netdev, gospo,
sassmann
In-Reply-To: <1351053166.2252.39.camel@jtkirshe-mobl>
On 10/23/2012 09:32 PM, Jeff Kirsher wrote:
> So how do we go about giving this spider web of complex coverage to some
> clear concise coverage in the MAINTAINERS?
I happen to like seeing "real" names. Is it possible to leverage email
conventions to allow a comment of sorts with each email:
INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
M: Jeff Kirsher (den mother) <jeffrey.t.kirsher@intel.com>
M: Jesse Brandeburg (performance focus) <jesse.brandeburg@intel.com>
M: Bruce Allan (e1000e focus) <bruce.w.allan@intel.com>
M: Carolyn Wyborny (igb focus) <carolyn.wyborny@intel.com>
M: Don Skidmore (omnibus) <donald.c.skidmore@intel.com>
M: Greg Rose (omnibus) <gregory.v.rose@intel.com>
M: Peter P Waskiewicz Jr (omnibus) <peter.p.waskiewicz.jr@intel.com>
M: Alex Duyck (omnibus) <alexander.h.duyck@intel.com>
M: John Ronciak (omnibus) <john.ronciak@intel.com>
M: Tushar Dave (omnibus and rca) <tushar.n.dave@intel.com>
perhaps "any" or "all" rather than omnibus if that is too much a
fifty-cent word. Everyone is still in one place, but with some
indication of specialization/generalization. If the parenthesis form
cannot be used, (I've not seen it elsewhere in MAINTAINERS) then perhaps
the quoted form.
rick jones
(And yes, "den mother" was meant as a bit of levity :)
^ permalink raw reply
* Re: [PATCH] gianfar_ptp: use iomem, not ioports resource tree in probe
From: Tabi Timur-B04825 @ 2012-10-24 17:59 UTC (permalink / raw)
To: Paul Gortmaker
Cc: netdev@vger.kernel.org, Wei Yang, Manoil Claudiu-B08782,
Tabi Timur-B04825
In-Reply-To: <1351092096-14811-1-git-send-email-paul.gortmaker@windriver.com>
On Wed, Oct 24, 2012 at 10:21 AM, Paul Gortmaker
<paul.gortmaker@windriver.com> wrote:
> From: Wei Yang <Wei.Yang@windriver.com>
>
> When using a 36 bit dtb file, the driver complains "resource busy".
>
> Investigating the source of the message leads one to the
> gianfar_ptp_probe function.
>
> Since the type of the device resource requested in this function
> is IORESOURCE_MEM, it should use "iomem_resource" instead of
> "ioports_resource".
I can't comment on this patch, since I didn't write the driver, but I
am confused on one thing. Why is the driver using platform_xxx calls
to get data? Why isn't it using of_xxx calls to read properties from
the device tree? For example, why is it using
etsects->irq = platform_get_irq(dev, 0);
to get the IRQ? Shouldn't it do this instead:
etsects->irq = irq_of_parse_and_map(node, 0);
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: [PATCH for-3.7] vhost: fix mergeable bufs on BE hosts
From: David Miller @ 2012-10-24 18:11 UTC (permalink / raw)
To: mst; +Cc: netdev, stable, kvm, virtualization
In-Reply-To: <20121024162437.GA10764@redhat.com>
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Wed, 24 Oct 2012 18:24:38 +0200
> Would you like me to repost the patch?
This question is almost retorical.
I said I don't reliably read things I'm not explicitly CC:'d
on, therefore it's possible (and in fact, likely) I don't have
the patch in my inbox.
What do you think you should do?
^ permalink raw reply
* Re: [net-next PATCH v1 0/3] extend set/get netlink for embedded
From: David Miller @ 2012-10-24 18:13 UTC (permalink / raw)
To: john.r.fastabend
Cc: shemminger, buytenh, vyasevic, jhs, chrisw, krkumar2, samudrala,
peter.p.waskiewicz.jr, jeffrey.t.kirsher, netdev, bhutchings,
gregory.v.rose, eilong
In-Reply-To: <20121024164906.14221.45341.stgit@jf-dev1-dcblab>
Where is patch #2?
^ permalink raw reply
* Re: [PATCH] net: allow configuration of the size of page in __netdev_alloc_frag
From: David Miller @ 2012-10-24 18:19 UTC (permalink / raw)
To: ian.campbell; +Cc: netdev, edumazet, konrad.wilk, xen-devel
In-Reply-To: <1351078936-14159-1-git-send-email-ian.campbell@citrix.com>
I'm not applying this.
Fix your drivers and the infrastructure they use, don't paper
around it.
^ permalink raw reply
* RE: [net-next PATCH v1 0/3] extend set/get netlink for embedded
From: Rose, Gregory V @ 2012-10-24 18:26 UTC (permalink / raw)
To: David Miller, Fastabend, John R
Cc: shemminger@vyatta.com, buytenh@wantstofly.org,
vyasevic@redhat.com, jhs@mojatatu.com, chrisw@redhat.com,
krkumar2@in.ibm.com, samudrala@us.ibm.com, Waskiewicz Jr, Peter P,
Kirsher, Jeffrey T, netdev@vger.kernel.org,
bhutchings@solarflare.com, eilong@broadcom.com
In-Reply-To: <20121024.141325.2109103383062843556.davem@davemloft.net>
> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Wednesday, October 24, 2012 11:13 AM
> To: Fastabend, John R
> Cc: shemminger@vyatta.com; buytenh@wantstofly.org; vyasevic@redhat.com;
> jhs@mojatatu.com; chrisw@redhat.com; krkumar2@in.ibm.com;
> samudrala@us.ibm.com; Waskiewicz Jr, Peter P; Kirsher, Jeffrey T;
> netdev@vger.kernel.org; bhutchings@solarflare.com; Rose, Gregory V;
> eilong@broadcom.com
> Subject: Re: [net-next PATCH v1 0/3] extend set/get netlink for embedded
>
>
> Where is patch #2?
I received it and I saw netdev on the address list. Maybe it suffered some misadventure while traveling along the intertubes.
- Greg
^ permalink raw reply
* [net-next PATCH v2 0/3] extend set/get netlink for embedded
From: John Fastabend @ 2012-10-24 18:12 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
This extends the PF_BRIDGE setlink and getlink so that they can be
used generically outside of the Linux bridge module. Doing this
allows embedded devices to use the same netlink interface that
the software bridge is currently using.
In this patchset I opted to create two new ndo ops ndo_bridge_setlink
and ndo_bridge_getlink. These ops pass the nlmsghdr to the device
for handling. The netlink message is extended to support nested
IFLA_AF_SPEC attributes. A IFLA_BRIDGE_FLAGS attribute is used to
determine the target of the message either a master netdev is the
target or the target is "self" indicating the target is the netdev.
In this way we can send netlink msg to an embedded device or the
linux sw bridge or both. If the set completes sucessfully the flag
is cleared in this way we can learn what failed in the both case.
This scheme is similar to how FDB updates are handled. If no flag
attribute is present the message is sent to the master device to
support the existing messages.
An initial IFLA_BRIDGE_MODE attribute is added to indicate if the
bridge is in a VEPA mode or VEB mode. This is most useful for
SR-IOV device and can be used to indicate support for VF to VF or
VF to PF traffic. Without this we have no way of knowing this
other then trial and error because not all hardware supports
this.
In the future additional attributes can be added to handle other
attributes. We could for example move some of the linux bridge
sysfs attributes here if we want a netlink interface for them.
This should also allow DSA switches to use the bridging tools.
See RFC patch from Lennert
http://patchwork.ozlabs.org/patch/16578/
I could have simply added the VEPA attribute handling to the
rtnl_setlink() routine but it seemed like a good feature to have
all the bridging events and configuration on the same type. Also
this should allow more powerful offloaded switches like the
hardware supported via DSA access to the bridge control
interface.
Also I think this interface should allow Vlad to add his port based
VLAN interface here as well.
Any feedback/criticism appreciated thanks!
---
John Fastabend (3):
ixgbe: add setlink, getlink support to ixgbe and ixgbevf
net: set and query VEB/VEPA bridge mode via PF_BRIDGE
net: create generic bridge ops
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 59 ++++++
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 3
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 10 +
include/linux/netdevice.h | 10 +
include/linux/rtnetlink.h | 3
include/uapi/linux/if_bridge.h | 18 ++
net/bridge/br_device.c | 2
net/bridge/br_netlink.c | 75 +-------
net/bridge/br_private.h | 7 +
net/core/rtnetlink.c | 207 +++++++++++++++++++++
10 files changed, 328 insertions(+), 66 deletions(-)
--
Signature
^ permalink raw reply
* [net-next PATCH v2 1/3] net: create generic bridge ops
From: John Fastabend @ 2012-10-24 18:12 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
In-Reply-To: <20121024181033.14378.33097.stgit@jf-dev1-dcblab>
The PF_BRIDGE:RTM_{GET|SET}LINK nlmsg family and type are
currently embedded in the ./net/bridge module. This prohibits
them from being used by other bridging devices. One example
of this being hardware that has embedded bridging components.
In order to use these nlmsg types more generically this patch
adds two net_device_ops hooks. One to set link bridge attributes
and another to dump the current bride attributes.
ndo_bridge_setlink()
ndo_bridge_getlink()
CC: Lennert Buytenhek <buytenh@wantstofly.org>
CC: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/linux/netdevice.h | 10 ++++++
net/bridge/br_device.c | 2 +
net/bridge/br_netlink.c | 73 +++++++----------------------------------
net/bridge/br_private.h | 3 ++
net/core/rtnetlink.c | 80 +++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 108 insertions(+), 60 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f8eda02..7bf867c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -887,6 +887,10 @@ struct netdev_fcoe_hbainfo {
* struct net_device *dev, int idx)
* Used to add FDB entries to dump requests. Implementers should add
* entries to skb and update idx with the number of entries.
+ *
+ * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh)
+ * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
+ * struct net_device *dev)
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
@@ -998,6 +1002,12 @@ struct net_device_ops {
struct netlink_callback *cb,
struct net_device *dev,
int idx);
+
+ int (*ndo_bridge_setlink)(struct net_device *dev,
+ struct nlmsghdr *nlh);
+ int (*ndo_bridge_getlink)(struct sk_buff *skb,
+ u32 pid, u32 seq,
+ struct net_device *dev);
};
/*
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 070e8a6..63b5b08 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -313,6 +313,8 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_fdb_add = br_fdb_add,
.ndo_fdb_del = br_fdb_delete,
.ndo_fdb_dump = br_fdb_dump,
+ .ndo_bridge_getlink = br_getlink,
+ .ndo_bridge_setlink = br_setlink,
};
static void br_dev_free(struct net_device *dev)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 093f527..743511b 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -111,54 +111,33 @@ errout:
/*
* Dump information about all ports, in response to GETLINK
*/
-static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev)
{
- struct net *net = sock_net(skb->sk);
- struct net_device *dev;
- int idx;
-
- idx = 0;
- rcu_read_lock();
- for_each_netdev_rcu(net, dev) {
- struct net_bridge_port *port = br_port_get_rcu(dev);
-
- /* not a bridge port */
- if (!port || idx < cb->args[0])
- goto skip;
-
- if (br_fill_ifinfo(skb, port,
- NETLINK_CB(cb->skb).portid,
- cb->nlh->nlmsg_seq, RTM_NEWLINK,
- NLM_F_MULTI) < 0)
- break;
-skip:
- ++idx;
- }
- rcu_read_unlock();
- cb->args[0] = idx;
+ int err = 0;
+ struct net_bridge_port *port = br_port_get_rcu(dev);
+
+ /* not a bridge port */
+ if (!port)
+ goto out;
- return skb->len;
+ err = br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, NLM_F_MULTI);
+out:
+ return err;
}
/*
* Change state of port (ie from forwarding to blocking etc)
* Used by spanning tree in user space.
*/
-static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
{
- struct net *net = sock_net(skb->sk);
struct ifinfomsg *ifm;
struct nlattr *protinfo;
- struct net_device *dev;
struct net_bridge_port *p;
u8 new_state;
- if (nlmsg_len(nlh) < sizeof(*ifm))
- return -EINVAL;
-
ifm = nlmsg_data(nlh);
- if (ifm->ifi_family != AF_BRIDGE)
- return -EPFNOSUPPORT;
protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO);
if (!protinfo || nla_len(protinfo) < sizeof(u8))
@@ -168,10 +147,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if (new_state > BR_STATE_BLOCKING)
return -EINVAL;
- dev = __dev_get_by_index(net, ifm->ifi_index);
- if (!dev)
- return -ENODEV;
-
p = br_port_get_rtnl(dev);
if (!p)
return -EINVAL;
@@ -218,29 +193,7 @@ struct rtnl_link_ops br_link_ops __read_mostly = {
int __init br_netlink_init(void)
{
- int err;
-
- err = rtnl_link_register(&br_link_ops);
- if (err < 0)
- goto err1;
-
- err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL,
- br_dump_ifinfo, NULL);
- if (err)
- goto err2;
- err = __rtnl_register(PF_BRIDGE, RTM_SETLINK,
- br_rtm_setlink, NULL, NULL);
- if (err)
- goto err3;
-
- return 0;
-
-err3:
- rtnl_unregister_all(PF_BRIDGE);
-err2:
- rtnl_link_unregister(&br_link_ops);
-err1:
- return err;
+ return rtnl_link_register(&br_link_ops);
}
void __exit br_netlink_fini(void)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 9b278c4..fdcd5f6 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -553,6 +553,9 @@ extern struct rtnl_link_ops br_link_ops;
extern int br_netlink_init(void);
extern void br_netlink_fini(void);
extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
+extern int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg);
+extern int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev);
#ifdef CONFIG_SYSFS
/* br_sysfs_if.c */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 64fe3cc..a068666 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2252,6 +2252,83 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *dev;
+ int idx = 0;
+ u32 portid = NETLINK_CB(cb->skb).portid;
+ u32 seq = cb->nlh->nlmsg_seq;
+
+ rcu_read_lock();
+ for_each_netdev_rcu(net, dev) {
+ const struct net_device_ops *ops = dev->netdev_ops;
+ struct net_device *master = dev->master;
+
+ if (idx < cb->args[0])
+ continue;
+
+ if (master && master->netdev_ops->ndo_bridge_getlink) {
+ const struct net_device_ops *bops = master->netdev_ops;
+ int err = bops->ndo_bridge_getlink(skb, portid,
+ seq, dev);
+
+ if (err < 0)
+ break;
+ else
+ idx++;
+ }
+
+ if (ops->ndo_bridge_getlink) {
+ int err = ops->ndo_bridge_getlink(skb, portid,
+ seq, dev);
+
+ if (err < 0)
+ break;
+ else
+ idx++;
+ }
+ }
+ rcu_read_unlock();
+ cb->args[0] = idx;
+
+ return skb->len;
+}
+
+static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
+ void *arg)
+{
+ struct net *net = sock_net(skb->sk);
+ struct ifinfomsg *ifm;
+ struct net_device *dev;
+ int err = -EINVAL;
+
+ if (nlmsg_len(nlh) < sizeof(*ifm))
+ return -EINVAL;
+
+ ifm = nlmsg_data(nlh);
+ if (ifm->ifi_family != AF_BRIDGE)
+ return -EPFNOSUPPORT;
+
+ dev = __dev_get_by_index(net, ifm->ifi_index);
+ if (!dev) {
+ pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n");
+ return -ENODEV;
+ }
+
+ if (dev->master && dev->master->netdev_ops->ndo_bridge_setlink) {
+ err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh);
+ if (err)
+ goto out;
+ }
+
+ if (dev->netdev_ops->ndo_bridge_setlink)
+ err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
+
+out:
+ return err;
+}
+
/* Protected by RTNL sempahore. */
static struct rtattr **rta_buf;
static int rtattr_max;
@@ -2433,5 +2510,8 @@ void __init rtnetlink_init(void)
rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL);
rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL);
rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL);
+
+ rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL);
+ rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL);
}
^ permalink raw reply related
* [net-next PATCH v2 2/3] net: set and query VEB/VEPA bridge mode via PF_BRIDGE
From: John Fastabend @ 2012-10-24 18:13 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
In-Reply-To: <20121024181033.14378.33097.stgit@jf-dev1-dcblab>
Hardware switches may support enabling and disabling the
loopback switch which puts the device in a VEPA mode defined
in the IEEE 802.1Qbg specification. In this mode frames are
not switched in the hardware but sent directly to the switch.
SR-IOV capable NICs will likely support this mode I am
aware of at least two such devices. Also I am told (but don't
have any of this hardware available) that there are devices
that only support VEPA modes. In these cases it is important
at a minimum to be able to query these attributes.
This patch adds an additional IFLA_BRIDGE_MODE attribute that can be
set and dumped via the PF_BRIDGE:{SET|GET}LINK operations. Also
anticipating bridge attributes that may be common for both embedded
bridges and software bridges this adds a flags attribute
IFLA_BRIDGE_FLAGS currently used to determine if the command or event
is being generated to/from an embedded bridge or software bridge.
Finally, the event generation is pulled out of the bridge module and
into rtnetlink proper.
For example using the macvlan driver in VEPA mode on top of
an embedded switch requires putting the embedded switch into
a VEPA mode to get the expected results.
-------- --------
| VEPA | | VEPA | <-- macvlan vepa edge relays
-------- --------
| |
| |
------------------
| VEPA | <-- embedded switch in NIC
------------------
|
|
-------------------
| external switch | <-- shiny new physical
------------------- switch with VEPA support
A packet sent from the macvlan VEPA at the top could be
loopbacked on the embedded switch and never seen by the
external switch. So in order for this to work the embedded
switch needs to be set in the VEPA state via the above
described commands.
By making these attributes nested in IFLA_AF_SPEC we allow
future extensions to be made as needed.
CC: Lennert Buytenhek <buytenh@wantstofly.org>
CC: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/uapi/linux/if_bridge.h | 18 ++++++++
net/bridge/br_netlink.c | 2 -
net/bridge/br_private.h | 4 +-
net/core/rtnetlink.c | 85 ++++++++++++++++++++++++++++++++++++++--
4 files changed, 102 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index a8fe954..b388579 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -97,5 +97,23 @@ struct __fdb_entry {
__u16 unused;
};
+/* Bridge Flags */
+#define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */
+#define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */
+#define BRIDGE_MODE_VEB 0 /* Default loopback mode */
+#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */
+
+/* Bridge management nested attributes
+ * [IFLA_AF_SPEC] = {
+ * [IFLA_BRIDGE_FLAGS]
+ * [IFLA_BRIDGE_MODE]
+ * }
+ */
+enum {
+ IFLA_BRIDGE_FLAGS,
+ IFLA_BRIDGE_MODE,
+ __IFLA_BRIDGE_MAX,
+};
+#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
#endif /* _UAPI_LINUX_IF_BRIDGE_H */
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 743511b..14b065c 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -166,8 +166,6 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
br_port_state_selection(p->br);
spin_unlock_bh(&p->br->lock);
- br_ifinfo_notify(RTM_NEWLINK, p);
-
return 0;
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index fdcd5f6..6f40c14 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -158,7 +158,9 @@ struct net_bridge_port
static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
{
- struct net_bridge_port *port = rcu_dereference(dev->rx_handler_data);
+ struct net_bridge_port *port =
+ rcu_dereference_rtnl(dev->rx_handler_data);
+
return br_port_exists(dev) ? port : NULL;
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a068666..8d2af0f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2295,13 +2295,60 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+static inline size_t bridge_nlmsg_size(void)
+{
+ return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
+ + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
+ + nla_total_size(sizeof(u32)) /* IFLA_MASTER */
+ + nla_total_size(sizeof(u32)) /* IFLA_MTU */
+ + nla_total_size(sizeof(u32)) /* IFLA_LINK */
+ + nla_total_size(sizeof(u32)) /* IFLA_OPERSTATE */
+ + nla_total_size(sizeof(u8)) /* IFLA_PROTINFO */
+ + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */
+ + nla_total_size(sizeof(u16)) /* IFLA_BRIDGE_FLAGS */
+ + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */
+}
+
+static int rtnl_bridge_notify(struct net_device *dev, u16 flags)
+{
+ struct net *net = dev_net(dev);
+ struct net_device *master = dev->master;
+ struct sk_buff *skb;
+ int err = -EOPNOTSUPP;
+
+ skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC);
+ if (!skb) {
+ err = -ENOMEM;
+ goto errout;
+ }
+
+ if (!flags && master && master->netdev_ops->ndo_bridge_getlink)
+ err = master->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev);
+ else if (dev->netdev_ops->ndo_bridge_getlink)
+ err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev);
+
+ if (err < 0)
+ goto errout;
+
+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+ return 0;
+errout:
+ WARN_ON(err == -EMSGSIZE);
+ kfree_skb(skb);
+ rtnl_set_sk_err(net, RTNLGRP_LINK, err);
+ return err;
+}
+
static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
void *arg)
{
struct net *net = sock_net(skb->sk);
struct ifinfomsg *ifm;
struct net_device *dev;
- int err = -EINVAL;
+ struct nlattr *br_spec, *attr = NULL;
+ int rem, err = -EOPNOTSUPP;
+ u16 flags = 0;
if (nlmsg_len(nlh) < sizeof(*ifm))
return -EINVAL;
@@ -2316,15 +2363,45 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
return -ENODEV;
}
- if (dev->master && dev->master->netdev_ops->ndo_bridge_setlink) {
+ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
+ if (br_spec) {
+ nla_for_each_nested(attr, br_spec, rem) {
+ if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
+ flags = nla_get_u16(attr);
+ break;
+ }
+ }
+ }
+
+ if (!flags || (flags & BRIDGE_FLAGS_MASTER)) {
+ if (!dev->master ||
+ !dev->master->netdev_ops->ndo_bridge_setlink) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh);
if (err)
goto out;
+
+ flags &= ~BRIDGE_FLAGS_MASTER;
}
- if (dev->netdev_ops->ndo_bridge_setlink)
- err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
+ if ((flags & BRIDGE_FLAGS_SELF)) {
+ if (!dev->netdev_ops->ndo_bridge_setlink)
+ err = -EOPNOTSUPP;
+ else
+ err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
+
+ if (!err)
+ flags &= ~BRIDGE_FLAGS_SELF;
+ }
+ if (attr && nla_type(attr) == IFLA_BRIDGE_FLAGS)
+ memcpy(nla_data(attr), &flags, sizeof(flags));
+ /* Generate event to notify upper layer of bridge change */
+ if (!err)
+ err = rtnl_bridge_notify(dev, flags);
out:
return err;
}
^ permalink raw reply related
* Re: [net-next PATCH v1 0/3] extend set/get netlink for embedded
From: John Fastabend @ 2012-10-24 18:30 UTC (permalink / raw)
To: David Miller
Cc: shemminger, buytenh, vyasevic, jhs, chrisw, krkumar2, samudrala,
peter.p.waskiewicz.jr, jeffrey.t.kirsher, netdev, bhutchings,
gregory.v.rose, eilong
In-Reply-To: <20121024.141325.2109103383062843556.davem@davemloft.net>
On 10/24/2012 11:13 AM, David Miller wrote:
>
> Where is patch #2?
>
Apparently lost in the ether I was hoping it would show up. Sending
a v2 sorry for the hassle hope it works this time.
.John
^ permalink raw reply
* [net-next PATCH v2 3/3] ixgbe: add setlink, getlink support to ixgbe and ixgbevf
From: John Fastabend @ 2012-10-24 18:13 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
In-Reply-To: <20121024181033.14378.33097.stgit@jf-dev1-dcblab>
This adds support for the net device ops to manage the embedded
hardware bridge on ixgbe devices. With this patch the bridge
mode can be toggled between VEB and VEPA to support stacking
macvlan devices or using the embedded switch without any SW
component in 802.1Qbg/br environments.
Additionally, this adds source address pruning to the ixgbevf
driver to prune any frames sent back from a reflective relay on
the switch. This is required because the existing hardware does
not support this. Without it frames get pushed into the stack
with its own src mac which is invalid per 802.1Qbg VEPA
definition.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 59 ++++++++++++++++++++-
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 3 +
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 10 ++++
include/linux/rtnetlink.h | 3 +
net/core/rtnetlink.c | 50 ++++++++++++++++++
5 files changed, 122 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 88d636a..9a88e01 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -44,6 +44,7 @@
#include <linux/ethtool.h>
#include <linux/if.h>
#include <linux/if_vlan.h>
+#include <linux/if_bridge.h>
#include <linux/prefetch.h>
#include <scsi/fc/fc_fcoe.h>
@@ -3224,7 +3225,6 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), reg_offset - 1);
IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (~0) << vf_shift);
IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), reg_offset - 1);
- IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
/* Map PF MAC address in RAR Entry 0 to first pool following VFs */
hw->mac.ops.set_vmdq(hw, 0, VMDQ_P(0));
@@ -3247,8 +3247,6 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
- /* enable Tx loopback for VF/PF communication */
- IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
/* Enable MAC Anti-Spoofing */
hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0),
@@ -7025,6 +7023,59 @@ static int ixgbe_ndo_fdb_dump(struct sk_buff *skb,
return idx;
}
+static int ixgbe_ndo_bridge_setlink(struct net_device *dev,
+ struct nlmsghdr *nlh)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ struct nlattr *attr, *br_spec;
+ int rem;
+
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return -EOPNOTSUPP;
+
+ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
+
+ nla_for_each_nested(attr, br_spec, rem) {
+ __u16 mode;
+ u32 reg = 0;
+
+ if (nla_type(attr) != IFLA_BRIDGE_MODE)
+ continue;
+
+ mode = nla_get_u16(attr);
+ if (mode == BRIDGE_MODE_VEPA)
+ reg = 0;
+ else if (mode == BRIDGE_MODE_VEB)
+ reg = IXGBE_PFDTXGSWC_VT_LBEN;
+ else
+ return -EINVAL;
+
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_PFDTXGSWC, reg);
+
+ e_info(drv, "enabling bridge mode: %s\n",
+ mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
+ }
+
+ return 0;
+}
+
+static int ixgbe_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ u16 mode;
+
+ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
+ return 0;
+
+ if (IXGBE_READ_REG(&adapter->hw, IXGBE_PFDTXGSWC) & 1)
+ mode = BRIDGE_MODE_VEB;
+ else
+ mode = BRIDGE_MODE_VEPA;
+
+ return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode);
+}
+
static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
@@ -7064,6 +7115,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_fdb_add = ixgbe_ndo_fdb_add,
.ndo_fdb_del = ixgbe_ndo_fdb_del,
.ndo_fdb_dump = ixgbe_ndo_fdb_dump,
+ .ndo_bridge_setlink = ixgbe_ndo_bridge_setlink,
+ .ndo_bridge_getlink = ixgbe_ndo_bridge_getlink,
};
/**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 96876b7..7e3ac28 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -117,6 +117,9 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
}
}
+ /* Initialize default switching mode VEB */
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+
/* If call to enable VFs succeeded then allocate memory
* for per VF control structures.
*/
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 07d7eab..ac6a76d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -478,6 +478,16 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
}
skb->protocol = eth_type_trans(skb, rx_ring->netdev);
+ /* Workaround hardware that can't do proper VEPA multicast
+ * source pruning.
+ */
+ if ((skb->pkt_type & (PACKET_BROADCAST | PACKET_MULTICAST)) &&
+ !(compare_ether_addr(adapter->netdev->dev_addr,
+ eth_hdr(skb)->h_source))) {
+ dev_kfree_skb_irq(skb);
+ goto next_desc;
+ }
+
ixgbevf_receive_skb(q_vector, skb, staterr, rx_desc);
next_desc:
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 7002bbf..489dd7bb 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -69,4 +69,7 @@ extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
int idx);
+
+extern int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev, u16 mode);
#endif /* __LINUX_RTNETLINK_H */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 8d2af0f..51dc58f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2252,6 +2252,56 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ struct net_device *dev, u16 mode)
+{
+ struct nlmsghdr *nlh;
+ struct ifinfomsg *ifm;
+ struct nlattr *br_afspec;
+ u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
+
+ nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), NLM_F_MULTI);
+ if (nlh == NULL)
+ return -EMSGSIZE;
+
+ ifm = nlmsg_data(nlh);
+ ifm->ifi_family = AF_BRIDGE;
+ ifm->__ifi_pad = 0;
+ ifm->ifi_type = dev->type;
+ ifm->ifi_index = dev->ifindex;
+ ifm->ifi_flags = dev_get_flags(dev);
+ ifm->ifi_change = 0;
+
+
+ if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
+ nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
+ nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
+ (dev->master &&
+ nla_put_u32(skb, IFLA_MASTER, dev->master->ifindex)) ||
+ (dev->addr_len &&
+ nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
+ (dev->ifindex != dev->iflink &&
+ nla_put_u32(skb, IFLA_LINK, dev->iflink)))
+ goto nla_put_failure;
+
+ br_afspec = nla_nest_start(skb, IFLA_AF_SPEC);
+ if (!br_afspec)
+ goto nla_put_failure;
+
+ if (nla_put_u16(skb, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF) ||
+ nla_put_u16(skb, IFLA_BRIDGE_MODE, mode)) {
+ nla_nest_cancel(skb, br_afspec);
+ goto nla_put_failure;
+ }
+ nla_nest_end(skb, br_afspec);
+
+ return nlmsg_end(skb, nlh);
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
+}
+EXPORT_SYMBOL(ndo_dflt_bridge_getlink);
+
static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
^ permalink raw reply related
* Re: [net-next PATCH v1 0/3] extend set/get netlink for embedded
From: John Fastabend @ 2012-10-24 18:33 UTC (permalink / raw)
To: Rose, Gregory V
Cc: David Miller, shemminger@vyatta.com, buytenh@wantstofly.org,
vyasevic@redhat.com, jhs@mojatatu.com, chrisw@redhat.com,
krkumar2@in.ibm.com, samudrala@us.ibm.com, Waskiewicz Jr, Peter P,
Kirsher, Jeffrey T, netdev@vger.kernel.org,
bhutchings@solarflare.com, eilong@broadcom.com
In-Reply-To: <C5551D9AAB213A418B7FD5E4A6F30A072D53669F@ORSMSX106.amr.corp.intel.com>
On 10/24/2012 11:26 AM, Rose, Gregory V wrote:
>> -----Original Message-----
>> From: David Miller [mailto:davem@davemloft.net]
>> Sent: Wednesday, October 24, 2012 11:13 AM
>> To: Fastabend, John R
>> Cc: shemminger@vyatta.com; buytenh@wantstofly.org; vyasevic@redhat.com;
>> jhs@mojatatu.com; chrisw@redhat.com; krkumar2@in.ibm.com;
>> samudrala@us.ibm.com; Waskiewicz Jr, Peter P; Kirsher, Jeffrey T;
>> netdev@vger.kernel.org; bhutchings@solarflare.com; Rose, Gregory V;
>> eilong@broadcom.com
>> Subject: Re: [net-next PATCH v1 0/3] extend set/get netlink for embedded
>>
>>
>> Where is patch #2?
>
> I received it and I saw netdev on the address list. Maybe it suffered some misadventure while traveling along the intertubes.
>
> - Greg
>
Sorry I have no idea what happened to it. Anyways I see v2 on patchworks
and netdev now. Thanks.
^ permalink raw reply
* [PATCH repost for-3.7] vhost: fix mergeable bufs on BE hosts
From: Michael S. Tsirkin @ 2012-10-24 18:37 UTC (permalink / raw)
To: David Miller; +Cc: netdev, stable, kvm, virtualization
We copy head count to a 16 bit field, this works by chance on LE but on
BE guest gets 0. Fix it up.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Alexander Graf <agraf@suse.de>
Cc: stable@vger.kernel.org
---
Repost fixing up To/Cc list.
drivers/vhost/net.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 9ab6d47..2bb463c 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -448,7 +448,8 @@ static void handle_rx(struct vhost_net *net)
.hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE
};
size_t total_len = 0;
- int err, headcount, mergeable;
+ int err, mergeable;
+ s16 headcount;
size_t vhost_hlen, sock_hlen;
size_t vhost_len, sock_len;
/* TODO: check that we are running from vhost_worker? */
--
MST
^ permalink raw reply related
* [net-next PATCH v1 2/3] net: set and query VEB/VEPA bridge mode via PF_BRIDGE
From: John Fastabend @ 2012-10-24 16:51 UTC (permalink / raw)
To: shemminger, buytenh, davem, vyasevic
Cc: jhs, chrisw, krkumar2, samudrala, peter.p.waskiewicz.jr,
jeffrey.t.kirsher, netdev, bhutchings, gregory.v.rose, eilong
In-Reply-To: <20121024164906.14221.45341.stgit@jf-dev1-dcblab>
Hardware switches may support enabling and disabling the
loopback switch which puts the device in a VEPA mode defined
in the IEEE 802.1Qbg specification. In this mode frames are
not switched in the hardware but sent directly to the switch.
SR-IOV capable NICs will likely support this mode I am
aware of at least two such devices. Also I am told (but don't
have any of this hardware available) that there are devices
that only support VEPA modes. In these cases it is important
at a minimum to be able to query these attributes.
This patch adds an additional IFLA_BRIDGE_MODE attribute that can be
set and dumped via the PF_BRIDGE:{SET|GET}LINK operations. Also
anticipating bridge attributes that may be common for both embedded
bridges and software bridges this adds a flags attribute
IFLA_BRIDGE_FLAGS currently used to determine if the command or event
is being generated to/from an embedded bridge or software bridge.
Finally, the event generation is pulled out of the bridge module and
into rtnetlink proper.
For example using the macvlan driver in VEPA mode on top of
an embedded switch requires putting the embedded switch into
a VEPA mode to get the expected results.
-------- --------
| VEPA | | VEPA | <-- macvlan vepa edge relays
-------- --------
| |
| |
------------------
| VEPA | <-- embedded switch in NIC
------------------
|
|
-------------------
| external switch | <-- shiny new physical
------------------- switch with VEPA support
A packet sent from the macvlan VEPA at the top could be
loopbacked on the embedded switch and never seen by the
external switch. So in order for this to work the embedded
switch needs to be set in the VEPA state via the above
described commands.
By making these attributes nested in IFLA_AF_SPEC we allow
future extensions to be made as needed.
CC: Lennert Buytenhek <buytenh@wantstofly.org>
CC: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
include/uapi/linux/if_bridge.h | 18 ++++++++
net/bridge/br_netlink.c | 2 -
net/bridge/br_private.h | 4 +-
net/core/rtnetlink.c | 85 ++++++++++++++++++++++++++++++++++++++--
4 files changed, 102 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index a8fe954..b388579 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -97,5 +97,23 @@ struct __fdb_entry {
__u16 unused;
};
+/* Bridge Flags */
+#define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */
+#define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */
+#define BRIDGE_MODE_VEB 0 /* Default loopback mode */
+#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */
+
+/* Bridge management nested attributes
+ * [IFLA_AF_SPEC] = {
+ * [IFLA_BRIDGE_FLAGS]
+ * [IFLA_BRIDGE_MODE]
+ * }
+ */
+enum {
+ IFLA_BRIDGE_FLAGS,
+ IFLA_BRIDGE_MODE,
+ __IFLA_BRIDGE_MAX,
+};
+#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
#endif /* _UAPI_LINUX_IF_BRIDGE_H */
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 743511b..14b065c 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -166,8 +166,6 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
br_port_state_selection(p->br);
spin_unlock_bh(&p->br->lock);
- br_ifinfo_notify(RTM_NEWLINK, p);
-
return 0;
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index fdcd5f6..6f40c14 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -158,7 +158,9 @@ struct net_bridge_port
static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
{
- struct net_bridge_port *port = rcu_dereference(dev->rx_handler_data);
+ struct net_bridge_port *port =
+ rcu_dereference_rtnl(dev->rx_handler_data);
+
return br_port_exists(dev) ? port : NULL;
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a068666..8d2af0f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2295,13 +2295,60 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+static inline size_t bridge_nlmsg_size(void)
+{
+ return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
+ + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
+ + nla_total_size(sizeof(u32)) /* IFLA_MASTER */
+ + nla_total_size(sizeof(u32)) /* IFLA_MTU */
+ + nla_total_size(sizeof(u32)) /* IFLA_LINK */
+ + nla_total_size(sizeof(u32)) /* IFLA_OPERSTATE */
+ + nla_total_size(sizeof(u8)) /* IFLA_PROTINFO */
+ + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */
+ + nla_total_size(sizeof(u16)) /* IFLA_BRIDGE_FLAGS */
+ + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */
+}
+
+static int rtnl_bridge_notify(struct net_device *dev, u16 flags)
+{
+ struct net *net = dev_net(dev);
+ struct net_device *master = dev->master;
+ struct sk_buff *skb;
+ int err = -EOPNOTSUPP;
+
+ skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC);
+ if (!skb) {
+ err = -ENOMEM;
+ goto errout;
+ }
+
+ if (!flags && master && master->netdev_ops->ndo_bridge_getlink)
+ err = master->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev);
+ else if (dev->netdev_ops->ndo_bridge_getlink)
+ err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev);
+
+ if (err < 0)
+ goto errout;
+
+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+ return 0;
+errout:
+ WARN_ON(err == -EMSGSIZE);
+ kfree_skb(skb);
+ rtnl_set_sk_err(net, RTNLGRP_LINK, err);
+ return err;
+}
+
static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
void *arg)
{
struct net *net = sock_net(skb->sk);
struct ifinfomsg *ifm;
struct net_device *dev;
- int err = -EINVAL;
+ struct nlattr *br_spec, *attr = NULL;
+ int rem, err = -EOPNOTSUPP;
+ u16 flags = 0;
if (nlmsg_len(nlh) < sizeof(*ifm))
return -EINVAL;
@@ -2316,15 +2363,45 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
return -ENODEV;
}
- if (dev->master && dev->master->netdev_ops->ndo_bridge_setlink) {
+ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
+ if (br_spec) {
+ nla_for_each_nested(attr, br_spec, rem) {
+ if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
+ flags = nla_get_u16(attr);
+ break;
+ }
+ }
+ }
+
+ if (!flags || (flags & BRIDGE_FLAGS_MASTER)) {
+ if (!dev->master ||
+ !dev->master->netdev_ops->ndo_bridge_setlink) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh);
if (err)
goto out;
+
+ flags &= ~BRIDGE_FLAGS_MASTER;
}
- if (dev->netdev_ops->ndo_bridge_setlink)
- err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
+ if ((flags & BRIDGE_FLAGS_SELF)) {
+ if (!dev->netdev_ops->ndo_bridge_setlink)
+ err = -EOPNOTSUPP;
+ else
+ err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
+
+ if (!err)
+ flags &= ~BRIDGE_FLAGS_SELF;
+ }
+ if (attr && nla_type(attr) == IFLA_BRIDGE_FLAGS)
+ memcpy(nla_data(attr), &flags, sizeof(flags));
+ /* Generate event to notify upper layer of bridge change */
+ if (!err)
+ err = rtnl_bridge_notify(dev, flags);
out:
return err;
}
^ permalink raw reply related
* [PATCH] bas_gigaset: fix pre_reset handling
From: Tilman Schmidt @ 2012-10-24 18:44 UTC (permalink / raw)
To: Karsten Keil, David Miller
Cc: Oliver Neukum,
gigaset307x-common-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Hansjoerg Lipp,
i4ldeveloper-JX7+OpRa80SjiSfgN6Y1Ib39b6g2fGNp
The delayed work function int_in_work() may call usb_reset_device()
and thus, indirectly, the driver's pre_reset method. Trying to
cancel the work synchronously in that situation would deadlock.
Fix by avoiding cancel_work_sync() in the pre_reset method.
If the reset was NOT initiated by int_in_work() this might cause
int_in_work() to run after the post_reset method, with urb_int_in
already resubmitted, so handle that case gracefully.
Signed-off-by: Tilman Schmidt <tilman-ZTO5kqT2PaM@public.gmane.org>
---
drivers/isdn/gigaset/bas-gigaset.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 5275887..c44950d 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -617,7 +617,13 @@ static void int_in_work(struct work_struct *work)
if (rc == 0)
/* success, resubmit interrupt read URB */
rc = usb_submit_urb(urb, GFP_ATOMIC);
- if (rc != 0 && rc != -ENODEV) {
+
+ switch (rc) {
+ case 0: /* success */
+ case -ENODEV: /* device gone */
+ case -EINVAL: /* URB already resubmitted, or terminal badness */
+ break;
+ default: /* failure: try to recover by resetting the device */
dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc));
rc = usb_lock_device_for_reset(ucs->udev, ucs->interface);
if (rc == 0) {
@@ -2442,7 +2448,9 @@ static void gigaset_disconnect(struct usb_interface *interface)
}
/* gigaset_suspend
- * This function is called before the USB connection is suspended.
+ * This function is called before the USB connection is suspended
+ * or before the USB device is reset.
+ * In the latter case, message == PMSG_ON.
*/
static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
{
@@ -2498,7 +2506,12 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
del_timer_sync(&ucs->timer_atrdy);
del_timer_sync(&ucs->timer_cmd_in);
del_timer_sync(&ucs->timer_int_in);
- cancel_work_sync(&ucs->int_in_wq);
+
+ /* don't try to cancel int_in_wq from within reset as it
+ * might be the one requesting the reset
+ */
+ if (message.event != PM_EVENT_ON)
+ cancel_work_sync(&ucs->int_in_wq);
gig_dbg(DEBUG_SUSPEND, "suspend complete");
return 0;
--
1.7.3.4
^ 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