* Re: [PATCH] netfilter: nft_osf: use enum nft_data_types for nft_validate_register_store
From: Pablo Neira Ayuso @ 2018-09-20 16:24 UTC (permalink / raw)
To: Stefan Agner
Cc: ffmancera, kadlec, fw, davem, netfilter-devel, coreteam, netdev,
linux-kernel
In-Reply-To: <20180918052136.25978-1-stefan@agner.ch>
On Mon, Sep 17, 2018 at 10:21:36PM -0700, Stefan Agner wrote:
> The function nft_validate_register_store requires a struct of type
> struct nft_data_types. NFTA_DATA_VALUE is of type enum
> nft_verdict_attributes. Pass the correct enum type.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] netfilter: conntrack: get rid of double sizeof
From: Pablo Neira Ayuso @ 2018-09-20 16:22 UTC (permalink / raw)
To: zhong jiang; +Cc: davem, kadlec, fw, netfilter-devel, netdev, linux-kernel
In-Reply-To: <1537359671-53720-1-git-send-email-zhongjiang@huawei.com>
On Wed, Sep 19, 2018 at 08:21:11PM +0800, zhong jiang wrote:
> sizeof(sizeof()) is quite strange and does not seem to be what
> is wanted here.
>
> The issue is detected with the help of Coccinelle.
Applied to nf, thanks.
^ permalink raw reply
* Re: [PATCH v7 4/4] gpiolib: Implement fast processing path in get/set array
From: Janusz Krzysztofik @ 2018-09-20 16:21 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Andrew Lunn, Ulf Hansson, linux-doc, linux-iio, Linus Walleij,
Dominik Brodowski, Peter Rosin, netdev, linux-i2c,
Peter Meerwald-Stadler, devel, Florian Fainelli, Jonathan Corbet,
Janusz Krzysztofik, Krzysztof Kozlowski, Kishon Vijay Abraham I,
Tony Lindgren, Lukas Wunner, Geert Uytterhoeven, linux-serial,
Jiri Slaby, Michael Hennerich, Uwe Kleine-König, linux-gpio
In-Reply-To: <9860023.SlBYqtbjDV@z50>
On Thursday, September 20, 2018 5:48:22 PM CEST Janusz Krzysztofik wrote:
> On Thursday, September 20, 2018 12:11:48 PM CEST Marek Szyprowski wrote:
> > Hi All,
> >
> > On 2018-09-02 14:01, Janusz Krzysztofik wrote:
> > > Certain GPIO descriptor arrays returned by gpio_get_array() may contain
> > > information on direct mapping of array members to pins of a single GPIO
> > > chip in hardware order. In such cases, bitmaps of values can be passed
> > > directly from/to the chip's .get/set_multiple() callbacks without
> > > wasting time on iterations.
> > >
> > > Add respective code to gpiod_get/set_array_bitmap_complex() functions.
> > > Pins not applicable for fast path are processed as before, skipping
> > > over the 'fast' ones.
> > >
> > > Cc: Jonathan Corbet <corbet@lwn.net>
> > > Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
> >
> > I've just noticed that this patch landed in today's linux-next. Sadly it
> > breaks booting of Exynos5250-based Samsung Snow Chromebook (ARM 32bit,
> > device-tree source arch/arm/boot/dts/exynos5250-snow.dts).
> >
> > Booting hangs after detecting MMC cards. Reverting this patch fixes the
> > boot. I will try later to add some debugs and investigate it further what
> > really happens when booting hangs.
>
> Hi Marek,
>
> Thanks for reporting. Could you please try the following fix?
Hi again,
I realized the patch was not correct, j, not i, should be updated in second
hunk. Please try the following one.
Thanks,
Janusz
>From a919c504850f6cb40e8e81267a3a37537f7c4fd4 Mon Sep 17 00:00:00 2001
From: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Date: Thu, 20 Sep 2018 17:37:21 +0200
Subject: [PATCH] gpiolib: Fix bitmap index not updated
While skipping fast path bits, bitmap index is not updated with next
found zero bit position. Fix it.
Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
---
drivers/gpio/gpiolib.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index a53d17745d21..369bdd358fcc 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2880,7 +2880,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
__set_bit(hwgpio, mask);
if (array_info)
- find_next_zero_bit(array_info->get_mask,
+ i = find_next_zero_bit(array_info->get_mask,
array_size, i);
else
i++;
@@ -2905,7 +2905,8 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
trace_gpio_value(desc_to_gpio(desc), 1, value);
if (array_info)
- find_next_zero_bit(array_info->get_mask, i, j);
+ j = find_next_zero_bit(array_info->get_mask, i,
+ j);
else
j++;
}
@@ -3192,7 +3193,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
}
if (array_info)
- find_next_zero_bit(array_info->set_mask,
+ i = find_next_zero_bit(array_info->set_mask,
array_size, i);
else
i++;
--
2.16.4
^ permalink raw reply related
* Re: [PATCH net-next v5 02/20] zinc: introduce minimal cryptography library
From: Arnd Bergmann @ 2018-09-20 16:02 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Jason A. Donenfeld, Eric Biggers, Linux Kernel Mailing List,
Networking, open list:HARDWARE RANDOM NUMBER GENERATOR CORE,
David Miller, gregkh, sneves, Andy Lutomirski,
jeanphilippe.aumasson
In-Reply-To: <CAKv+Gu-0oTBrg3T8TsNYPOdrmJSSC313-CYASO34kb_nviva6A@mail.gmail.com>
On Thu, Sep 20, 2018 at 8:41 AM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
>
> (+ Arnd, Eric)
>
> On 18 September 2018 at 09:16, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> ...
>
> > diff --git a/lib/zinc/Makefile b/lib/zinc/Makefile
> > new file mode 100644
> > index 000000000000..83dfd63988c0
> > --- /dev/null
> > +++ b/lib/zinc/Makefile
> > @@ -0,0 +1,4 @@
>
> Apologies for not spotting these before:
>
> > +ccflags-y := -O3
>
> -O3 optimization has been problematic in the past, at least on x86 but
> I think on other architectures as well. Please stick with -O2.
>
> > +ccflags-y += -Wframe-larger-than=$(if (CONFIG_KASAN),16384,8192)
>
> There is no way we can support code in the kernel with that kind of
> stack space requirements. I will let Arnd comment on what we typically
> allow, since he deals with such issues on a regular basis.
Right, if you hit a stack requirement like this, it's usually the compiler
doing something bad, not just using too much stack but also generating
rather slow object code in the process. It's better to fix the bug by
optimizing the code to not spill registers to the stack.
In the long run, I'd like to reduce the stack frame size further, so
best assume that anything over 1024 bytes (on 32-bit) or 1280 bytes
(on 64-bit) is a bug in the code, and stay below that.
For prototyping, you can just mark the broken functions individually
by setting the warning limit for a specific function that is known to
be misoptimized by the compiler (with a comment about which compiler
and architectures are affected), but not override the limit for the
entire file.
Arnd
^ permalink raw reply
* Re: [PATCH net-next v5 02/20] zinc: introduce minimal cryptography library
From: Andy Lutomirski @ 2018-09-20 16:01 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Jason A. Donenfeld, Arnd Bergmann, Eric Biggers,
Linux Kernel Mailing List, <netdev@vger.kernel.org>,
open list:HARDWARE RANDOM NUMBER GENERATOR CORE, David S. Miller,
Greg Kroah-Hartman, Samuel Neves, Andy Lutomirski,
Jean-Philippe Aumasson
In-Reply-To: <CAKv+Gu-0oTBrg3T8TsNYPOdrmJSSC313-CYASO34kb_nviva6A@mail.gmail.com>
> On Sep 20, 2018, at 8:41 AM, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
> (+ Arnd, Eric)
>
> On 18 September 2018 at 09:16, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> ...
>
>> diff --git a/lib/zinc/Makefile b/lib/zinc/Makefile
>> new file mode 100644
>> index 000000000000..83dfd63988c0
>> --- /dev/null
>> +++ b/lib/zinc/Makefile
>> @@ -0,0 +1,4 @@
>
> Apologies for not spotting these before:
>
>> +ccflags-y := -O3
>
> -O3 optimization has been problematic in the past, at least on x86 but
> I think on other architectures as well. Please stick with -O2.
>
>> +ccflags-y += -Wframe-larger-than=$(if (CONFIG_KASAN),16384,8192)
>
> There is no way we can support code in the kernel with that kind of
> stack space requirements. I will let Arnd comment on what we typically
> allow, since he deals with such issues on a regular basis.
To make matters worse, KASAN is incompatible with VMAP_STACK right now, and KASAN is not so good at detecting stack overflow.
>
>> +ccflags-y += -D'pr_fmt(fmt)="zinc: " fmt'
>> +ccflags-$(CONFIG_ZINC_DEBUG) += -DDEBUG
>> --
>> 2.19.0
>>
^ permalink raw reply
* Re: [PATCH v7 4/4] gpiolib: Implement fast processing path in get/set array
From: Linus Walleij @ 2018-09-20 15:49 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Janusz Krzysztofik, Jonathan Corbet, Miguel Ojeda Sandonis,
Peter Korsgaard, Peter Rosin, Ulf Hansson, Andrew Lunn,
Florian Fainelli, David S. Miller, Dominik Brodowski, Greg KH,
kishon, Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
Hartmut Knaack, Peter Meerwald, Jiri Slaby, Willy Tarreau,
Geert Uytterhoeven
In-Reply-To: <20180920101151eucas1p221f5a1715b8556bb9d99bf08fe09ce6f~WE-_cEf4l0754207542eucas1p27@eucas1p2.samsung.com>
On Thu, Sep 20, 2018 at 3:11 AM Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> I've just noticed that this patch landed in today's linux-next. Sadly it
> breaks booting of Exynos5250-based Samsung Snow Chromebook (ARM 32bit,
> device-tree source arch/arm/boot/dts/exynos5250-snow.dts).
Thanks for testing on this platform!
> Booting hangs after detecting MMC cards. Reverting this patch fixes the
> boot. I will try later to add some debugs and investigate it further what
> really happens when booting hangs.
How typical. I hope we can fix it, because this should mean speedups
for your platform.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v7 4/4] gpiolib: Implement fast processing path in get/set array
From: Janusz Krzysztofik @ 2018-09-20 15:48 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Linus Walleij, Jonathan Corbet, Miguel Ojeda Sandonis,
Peter Korsgaard, Peter Rosin, Ulf Hansson, Andrew Lunn,
Florian Fainelli, David S. Miller, Dominik Brodowski,
Greg Kroah-Hartman, Kishon Vijay Abraham I, Lars-Peter Clausen,
Michael Hennerich, Jonathan Cameron, Hartmut Knaack,
Peter Meerwald-Stadler, Jiri Slaby, Willy Tarreau
In-Reply-To: <20180920101151eucas1p221f5a1715b8556bb9d99bf08fe09ce6f~WE-_cEf4l0754207542eucas1p27@eucas1p2.samsung.com>
On Thursday, September 20, 2018 12:11:48 PM CEST Marek Szyprowski wrote:
> Hi All,
>
> On 2018-09-02 14:01, Janusz Krzysztofik wrote:
> > Certain GPIO descriptor arrays returned by gpio_get_array() may contain
> > information on direct mapping of array members to pins of a single GPIO
> > chip in hardware order. In such cases, bitmaps of values can be passed
> > directly from/to the chip's .get/set_multiple() callbacks without
> > wasting time on iterations.
> >
> > Add respective code to gpiod_get/set_array_bitmap_complex() functions.
> > Pins not applicable for fast path are processed as before, skipping
> > over the 'fast' ones.
> >
> > Cc: Jonathan Corbet <corbet@lwn.net>
> > Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
>
> I've just noticed that this patch landed in today's linux-next. Sadly it
> breaks booting of Exynos5250-based Samsung Snow Chromebook (ARM 32bit,
> device-tree source arch/arm/boot/dts/exynos5250-snow.dts).
>
> Booting hangs after detecting MMC cards. Reverting this patch fixes the
> boot. I will try later to add some debugs and investigate it further what
> really happens when booting hangs.
Hi Marek,
Thanks for reporting. Could you please try the following fix?
Thanks,
Janusz
>From d7ecd435bfb4972766b63ac383a43875700c7452 Mon Sep 17 00:00:00 2001
From: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Date: Thu, 20 Sep 2018 17:37:21 +0200
Subject: [PATCH] gpiolib: Fix bitmap index not updated
While skipping fast path bits, bitmap index is not updated with next
found zero bit position. Fix it.
Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
---
drivers/gpio/gpiolib.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index a53d17745d21..5bc3447949c9 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2880,7 +2880,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
__set_bit(hwgpio, mask);
if (array_info)
- find_next_zero_bit(array_info->get_mask,
+ i = find_next_zero_bit(array_info->get_mask,
array_size, i);
else
i++;
@@ -2905,7 +2905,8 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
trace_gpio_value(desc_to_gpio(desc), 1, value);
if (array_info)
- find_next_zero_bit(array_info->get_mask, i, j);
+ i = find_next_zero_bit(array_info->get_mask, i,
+ j);
else
j++;
}
@@ -3192,7 +3193,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
}
if (array_info)
- find_next_zero_bit(array_info->set_mask,
+ i = find_next_zero_bit(array_info->set_mask,
array_size, i);
else
i++;
--
2.16.4
^ permalink raw reply related
* Re: [PATCH iproute2 v2 0/3] testsuite: make alltests fixes
From: Luca Boccassi @ 2018-09-20 10:02 UTC (permalink / raw)
To: Petr Vorel, netdev; +Cc: Stephen Hemminger, Phil Sutter
In-Reply-To: <20180919233624.18494-1-petr.vorel@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 539 bytes --]
On Thu, 2018-09-20 at 01:36 +0200, Petr Vorel wrote:
> Hi,
>
> here are simply fixes to restore 'make alltests'.
> Currently it does not run.
>
> Kind regards,
> Petr
>
> Petr Vorel (3):
> testsuite: Fix missing generate_nlmsg
> testsuite: Generate generate_nlmsg when needed
> testsuite: Warn about empty $(IPVERS)
>
> testsuite/Makefile | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
Series-tested-by: Luca Boccassi <bluca@debian.org>
--
Kind regards,
Luca Boccassi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v5 02/20] zinc: introduce minimal cryptography library
From: Ard Biesheuvel @ 2018-09-20 15:41 UTC (permalink / raw)
To: Jason A. Donenfeld, Arnd Bergmann, Eric Biggers
Cc: Linux Kernel Mailing List, <netdev@vger.kernel.org>,
open list:HARDWARE RANDOM NUMBER GENERATOR CORE, David S. Miller,
Greg Kroah-Hartman, Samuel Neves, Andy Lutomirski,
Jean-Philippe Aumasson
In-Reply-To: <20180918161646.19105-3-Jason@zx2c4.com>
(+ Arnd, Eric)
On 18 September 2018 at 09:16, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
...
> diff --git a/lib/zinc/Makefile b/lib/zinc/Makefile
> new file mode 100644
> index 000000000000..83dfd63988c0
> --- /dev/null
> +++ b/lib/zinc/Makefile
> @@ -0,0 +1,4 @@
Apologies for not spotting these before:
> +ccflags-y := -O3
-O3 optimization has been problematic in the past, at least on x86 but
I think on other architectures as well. Please stick with -O2.
> +ccflags-y += -Wframe-larger-than=$(if (CONFIG_KASAN),16384,8192)
There is no way we can support code in the kernel with that kind of
stack space requirements. I will let Arnd comment on what we typically
allow, since he deals with such issues on a regular basis.
> +ccflags-y += -D'pr_fmt(fmt)="zinc: " fmt'
> +ccflags-$(CONFIG_ZINC_DEBUG) += -DDEBUG
> --
> 2.19.0
>
^ permalink raw reply
* Re: [PATCH] net: ibm: remove a redundant local variable 'k'
From: Sergei Shtylyov @ 2018-09-20 9:49 UTC (permalink / raw)
To: zhong jiang, davem; +Cc: dougmill, netdev, linux-kernel
In-Reply-To: <1537366995-59168-1-git-send-email-zhongjiang@huawei.com>
Hello!
On 9/19/2018 5:23 PM, zhong jiang wrote:
> The local variable 'k' is never used after being assigned.
> hence it should be redundant adn can be removed.
Can.
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
[...]
MBR, Sergei
^ permalink raw reply
* Re: [PATCH] netfilter: nf_tables: add SECMARK support
From: Casey Schaufler @ 2018-09-20 15:23 UTC (permalink / raw)
To: Christian Göttsche
Cc: pablo, kadlec, fw, davem, netfilter-devel, coreteam, netdev,
linux-kernel, Paul Moore, Stephen Smalley, Eric Paris, jmorris,
serge, selinux, linux-security-module
In-Reply-To: <CAJ2a_Ddd19txwUiKkOwpdWUSq9+VWFSR6Cqe4zgXKggWUPi4hw@mail.gmail.com>
On 9/20/2018 12:18 AM, Christian Göttsche wrote:
>> I've only had a cursory look at your patch, but how is it
>> different from what's in xt_SECMARK.c ?
> xt_SEXMARK.c is for xtables, use-able in iptables; this is for nftables (nft)
Thank you. I am enlightened.
^ permalink raw reply
* [PATCH net] sctp: update dst pmtu with the correct daddr
From: Xin Long @ 2018-09-20 9:27 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman
When processing pmtu update from an icmp packet, it calls .update_pmtu
with sk instead of skb in sctp_transport_update_pmtu.
However for sctp, the daddr in the transport might be different from
inet_sock->inet_daddr or sk->sk_v6_daddr, which is used to update or
create the route cache. The incorrect daddr will cause a different
route cache created for the path.
So before calling .update_pmtu, inet_sock->inet_daddr/sk->sk_v6_daddr
should be updated with the daddr in the transport, and update it back
after it's done.
The issue has existed since route exceptions introduction.
Fixes: 4895c771c7f0 ("ipv4: Add FIB nexthop exceptions.")
Reported-by: ian.periam@dialogic.com
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/transport.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 12cac85..033696e 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -260,6 +260,7 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
{
struct dst_entry *dst = sctp_transport_dst_check(t);
+ struct sock *sk = t->asoc->base.sk;
bool change = true;
if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
@@ -271,12 +272,19 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
pmtu = SCTP_TRUNC4(pmtu);
if (dst) {
- dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu);
+ struct sctp_pf *pf = sctp_get_pf_specific(dst->ops->family);
+ union sctp_addr addr;
+
+ pf->af->from_sk(&addr, sk);
+ pf->to_sk_daddr(&t->ipaddr, sk);
+ dst->ops->update_pmtu(dst, sk, NULL, pmtu);
+ pf->to_sk_daddr(&addr, sk);
+
dst = sctp_transport_dst_check(t);
}
if (!dst) {
- t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk);
+ t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
dst = t->dst;
}
--
2.1.0
^ permalink raw reply related
* Re: [PATCH bpf-next 2/2] xsk: fix bug when trying to use both copy and zero-copy on one queue id
From: Magnus Karlsson @ 2018-09-20 9:17 UTC (permalink / raw)
To: jakub.kicinski
Cc: ys114321, Karlsson, Magnus, Björn Töpel, ast,
Daniel Borkmann, Network Development
In-Reply-To: <CAJ8uoz27a-+OYxHGnXOT6pY2v0hNxvrmCW8Eb5y5JkWLG9K3hg@mail.gmail.com>
On Wed, Sep 19, 2018 at 9:18 AM Magnus Karlsson
<magnus.karlsson@gmail.com> wrote:
>
> On Wed, Sep 19, 2018 at 3:58 AM Jakub Kicinski
> <jakub.kicinski@netronome.com> wrote:
> >
> > On Tue, 18 Sep 2018 10:22:11 -0700, Y Song wrote:
> > > > +/* The umem is stored both in the _rx struct and the _tx struct as we do
> > > > + * not know if the device has more tx queues than rx, or the opposite.
> > > > + * This might also change during run time.
> > > > + */
> > > > +static void xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
> > > > + u16 queue_id)
> > > > +{
> > > > + if (queue_id < dev->real_num_rx_queues)
> > > > + dev->_rx[queue_id].umem = umem;
> > > > + if (queue_id < dev->real_num_tx_queues)
> > > > + dev->_tx[queue_id].umem = umem;
> > > > +}
> > > > +
> > > > +static struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
> > > > + u16 queue_id)
> > > > +{
> > > > + if (queue_id < dev->real_num_rx_queues)
> > > > + return dev->_rx[queue_id].umem;
> > > > + if (queue_id < dev->real_num_tx_queues)
> > > > + return dev->_tx[queue_id].umem;
> > > > +
> > > > + return NULL;
> > > > +}
> > > > +
> > > > +static void xdp_clear_umem_at_qid(struct net_device *dev, u16 queue_id)
> > > > +{
> > > > + /* Zero out the entry independent on how many queues are configured
> > > > + * at this point in time, as it might be used in the future.
> > > > + */
> > > > + if (queue_id < dev->num_rx_queues)
> > > > + dev->_rx[queue_id].umem = NULL;
> > > > + if (queue_id < dev->num_tx_queues)
> > > > + dev->_tx[queue_id].umem = NULL;
> > > > +}
> > > > +
> > >
> > > I am sure whether the following scenario can happen or not.
> > > Could you clarify?
> > > 1. suppose initially we have num_rx_queues = num_tx_queues = 10
> > > xdp_reg_umem_at_qid() set umem1 to queue_id = 8
> > > 2. num_tx_queues is changed to 5
> > > 3. xdp_clear_umem_at_qid() is called for queue_id = 8,
> > > and dev->_rx[8].umum = 0.
> > > 4. xdp_reg_umem_at_qid() is called gain to set for queue_id = 8
> > > dev->_rx[8].umem = umem2
> > > 5. num_tx_queues is changed to 10
> > > Now dev->_rx[8].umem != dev->_tx[8].umem, is this possible and is it
> > > a problem?
> >
> > Plus IIRC the check of qid vs real_num_[rt]x_queues in xsk_bind() is
> > not under rtnl_lock so it doesn't count for much. Why not do all the
> > checks against num_[rt]x_queues here, instead of real_..?
>
> You are correct, two separate rtnl_lock regions is broken. Will spin a
> v2 tomorrow when I am back in the office.
>
> Thanks Jakub for catching this. I really appreciate you reviewing my code.
Sorry, forgot to answer your question about why real_num_ instead of
num_. If we used num_ instead, we would get a behavior where we can
open a socket on a queue id, let us say 10, that will not be active if
real_num_ is below 10. So no traffic will flow on this socket until we
issue an ethtool command to state that we have 10 or more queues
configured. While this behavior is sane (and consistent), I believe it
will lead to a more complicated driver implementation, break the
current uapi (since we will return an error if you try to bind to a
queue id that is not active at the moment) and I like my suggestion
below better :-).
What I would like to suggest is that the current model at bind() is
kept, that is it will fail if you try to bind to a non-active queue
id. But we add some code in ethool_set_channels in net/core/ethtool.c
to check if you have an active af_xdp socket on a queue id and try to
make it inactive, we return an error and disallow the change. This
would IMHO be like not allowing a load module to be unloaded if
someone is using it or not allowing unmounting a file system if files
are in use. What do you think? If you think this is the right way to
go, I can implement this in a follow up patch or in this patch set if
that makes more sense, let me know. This suggestion would actually
make it simpler to implement zero-copy support in the driver. Some of
the complications we are having today is due to the fact that ethtool
can come in from the side and change things for us when an AF_XDP
socket is active on a queue id. And implementing zero copy support in
the driver needs to get simpler IMO.
Please let me know what you think.
Thanks: Magnus
> /Magnus
^ permalink raw reply
* Re: [EXT] [PATCH net] net: mvneta: fix the Rx desc buffer DMA unmapping
From: Gregory CLEMENT @ 2018-09-20 14:59 UTC (permalink / raw)
To: Antoine Tenart
Cc: Yelena Krivosheev, davem@davemloft.net, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com,
maxime.chevallier@bootlin.com, miquel.raynal@bootlin.com,
Nadav Haklai, Stefan Chulski, Yan Markman, mw@semihalf.com
In-Reply-To: <20180920112010.GB1158@kwain>
Hi Antoine,
On jeu., sept. 20 2018, Antoine Tenart <antoine.tenart@bootlin.com> wrote:
> Hi Yelena,
>
> On Thu, Sep 20, 2018 at 10:14:56AM +0000, Yelena Krivosheev wrote:
>>
>> Please, check and fix all cases of dma_unmap_single() usage.
>> See mvneta_rxq_drop_pkts()
>> ...
>> if (!data || !(rx_desc->buf_phys_addr))
>> continue;
>> dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
>> MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
>> __free_page(data);
>> ...
>
> I had a look at the one reported by CONFIG_DMA_API_DEBUG, and at DMA
> unmapping calls using PAGE_SIZE. As you pointed out there might be
> others parts, thanks!
Actually Jisheng had submitted a similar patch few weeks ago and as I
pointed at this time, the dma_unmap in mvneta_rxq_drop_pkts can be
called when the allocation is done in with HWBM in this case which use a
dma_map_single.
I though that in this case using dma_map_single is the things to do even
if in the SWBM case it is less optimal.
Gregory
>
> Antoine
>
> --
> Antoine Ténart, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com
^ permalink raw reply
* RE: [PATCH v2 1/5] netlink: remove NLA_NESTED_COMPAT
From: Johannes Berg @ 2018-09-20 14:56 UTC (permalink / raw)
To: David Laight,
linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: David Ahern, Johannes Berg
In-Reply-To: <15cc8087b97d4b8693fad397b27f4d10-1XygrNkDbNvwg4NCKwmqgw@public.gmane.org>
>> @@ -172,7 +172,6 @@ enum {
>> NLA_FLAG,
>> NLA_MSECS,
>> NLA_NESTED,
>> - NLA_NESTED_COMPAT,
>> NLA_NUL_STRING,
>> NLA_BINARY,
>> NLA_S8,
>...
>
>Is it safe to remove an item from this emun ?
I believe it is, since it's not part of uapi. At least as long as you recompile all netlink policies afterwards.
johannes
--
Sent from my phone.
^ permalink raw reply
* [PATCH 3/3] ipv4: initialize ra_mutex in inet_init_net()
From: Kirill Tkhai @ 2018-09-20 9:12 UTC (permalink / raw)
To: davem, xiyou.wangcong, yoshfuji, ktkhai, avagin, edumazet,
ebiederm, netdev
In-Reply-To: <153743451940.21312.15708795592586962785.stgit@localhost.localdomain>
From: Cong Wang <xiyou.wangcong@gmail.com>
ra_mutex is a IPv4 specific mutex, it is inside struct netns_ipv4,
but its initialization is in the generic netns code, setup_net().
Move it to IPv4 specific net init code, inet_init_net().
Fixes: d9ff3049739e ("net: Replace ip_ra_lock with per-net mutex")
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
net/core/net_namespace.c | 1 -
net/ipv4/af_inet.c | 2 ++
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 670c84b1bfc2..b272ccfcbf63 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -308,7 +308,6 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
net->user_ns = user_ns;
idr_init(&net->netns_ids);
spin_lock_init(&net->nsid_lock);
- mutex_init(&net->ipv4.ra_mutex);
list_for_each_entry(ops, &pernet_list, list) {
error = ops_init(ops, net);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index bbd3a072ffea..d4623144e237 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1818,6 +1818,8 @@ static __net_init int inet_init_net(struct net *net)
net->ipv4.sysctl_igmp_llm_reports = 1;
net->ipv4.sysctl_igmp_qrv = 2;
+ mutex_init(&net->ipv4.ra_mutex);
+
return 0;
}
^ permalink raw reply related
* [PATCH 2/3] net: Register af_inet_ops earlier
From: Kirill Tkhai @ 2018-09-20 9:12 UTC (permalink / raw)
To: davem, xiyou.wangcong, yoshfuji, ktkhai, avagin, edumazet,
ebiederm, netdev
In-Reply-To: <153743451940.21312.15708795592586962785.stgit@localhost.localdomain>
This function just initializes locks and defaults.
Let register it before other pernet operation,
since some of them potentially may relay on that.
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
net/ipv4/af_inet.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index f4ecbe0aaf1a..bbd3a072ffea 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1938,6 +1938,9 @@ static int __init inet_init(void)
for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
inet_register_protosw(q);
+ if (init_inet_pernet_ops())
+ pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__);
+
/*
* Set the ARP module up
*/
@@ -1975,9 +1978,6 @@ static int __init inet_init(void)
if (ip_mr_init())
pr_crit("%s: Cannot init ipv4 mroute\n", __func__);
#endif
-
- if (init_inet_pernet_ops())
- pr_crit("%s: Cannot init ipv4 inet pernet ops\n", __func__);
/*
* Initialise per-cpu ipv4 mibs
*/
^ permalink raw reply related
* [PATCH net-next 0/3] Refactorings on af_inet pernet initialization
From: Kirill Tkhai @ 2018-09-20 9:11 UTC (permalink / raw)
To: davem, xiyou.wangcong, yoshfuji, ktkhai, avagin, edumazet,
ebiederm, netdev
This patch set makes several cleanups around inet_init_net().
---
Cong Wang (1):
ipv4: initialize ra_mutex in inet_init_net()
Kirill Tkhai (2):
net: Remove inet_exit_net()
net: Register af_inet_ops earlier
net/core/net_namespace.c | 1 -
net/ipv4/af_inet.c | 13 +++++--------
2 files changed, 5 insertions(+), 9 deletions(-)
^ permalink raw reply
* [PATCH 1/3] net: Remove inet_exit_net()
From: Kirill Tkhai @ 2018-09-20 9:11 UTC (permalink / raw)
To: davem, xiyou.wangcong, yoshfuji, ktkhai, avagin, edumazet,
ebiederm, netdev
In-Reply-To: <153743451940.21312.15708795592586962785.stgit@localhost.localdomain>
This function does nothing, and since ops_exit_list()
checks for NULL ->exit method, we do not need stub here.
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
net/ipv4/af_inet.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 1fbe2f815474..f4ecbe0aaf1a 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1821,13 +1821,8 @@ static __net_init int inet_init_net(struct net *net)
return 0;
}
-static __net_exit void inet_exit_net(struct net *net)
-{
-}
-
static __net_initdata struct pernet_operations af_inet_ops = {
.init = inet_init_net,
- .exit = inet_exit_net,
};
static int __init init_inet_pernet_ops(void)
^ permalink raw reply related
* Re: [Patch net-next] ipv4: initialize ra_mutex in inet_init_net()
From: Kirill Tkhai @ 2018-09-20 9:04 UTC (permalink / raw)
To: Cong Wang; +Cc: Linux Kernel Network Developers
In-Reply-To: <CAM_iQpVz_bxDLPZder7L+Tm4Qqzb3PTncf7BbyQp=7v9WYuB3Q@mail.gmail.com>
On 20.09.2018 0:28, Cong Wang wrote:
> On Wed, Sep 19, 2018 at 1:25 AM Kirill Tkhai <ktkhai@virtuozzo.com> wrote:
>>
>> On 18.09.2018 23:17, Cong Wang wrote:
>>> On Mon, Sep 17, 2018 at 12:25 AM Kirill Tkhai <ktkhai@virtuozzo.com> wrote:
>>>> In inet_init() the order of registration is:
>>>>
>>>> ip_mr_init();
>>>> init_inet_pernet_ops();
>>>>
>>>> This means, ipmr_net_ops pernet operations are before af_inet_ops
>>>> in pernet_list. So, there is a theoretical probability, sometimes
>>>> in the future, we will have a problem during a fail of net initialization.
>>>>
>>>> Say,
>>>>
>>>> setup_net():
>>>> ipmr_net_ops->init() returns 0
>>>> xxx->init() returns error
>>>> and then we do:
>>>> ipmr_net_ops->exit(),
>>>>
>>>> which could touch ra_mutex (theoretically).
>>>
>>> How could ra_mutex be touched in this scenario?
>>>
>>> ra_mutex is only used in ip_ra_control() which is called
>>> only by {get,set}sockopt(). I don't see anything related
>>> to netns exit() path here.
>>
>> Currently, it is not touched. But it's an ordinary practice,
>> someone closes sockets in pernet ->exit methods. For example,
>> we close percpu icmp sockets in icmp_sk_exit(), which are
>> also of RAW type, and there is also called ip_ra_control()
>> for them. Yes, they differ by their protocol; icmp sockets
>> are of IPPROTO_ICMP protocol, while ip_ra_control() acts
>> on IPPROTO_RAW sockets, but it's not good anyway. This does
>> not look reliable for the future. In case of someone changes
>> something here, we may do not notice this for the long time,
>> while some users will meet bugs on their places.
>
> First of all, we only consider current code base. Even if you
> really planned to changed this in the future, it would be still your
> responsibility to take care of it. Why? Simple, FIFO. My patch
> comes ahead of any future changes here, obviously.
>
> Secondly, it is certainly not hard to notice. I am pretty sure
> you would get a warning/crash if this bug triggered.
>
>
>
>>
>> Problems on error paths is not easy to detect on testing,
>> while user may meet them. We had issue of same type with
>> uninitialized xfrm_policy_lock. It was introduced in 2013,
>> while the problem was found only in 2017:
>
> Been there, done that, I've fixed multiple IPv6 init code
> error path. This is not where we disagree, by the way.
>
>
>>
>> introduced by 283bc9f35bbb
>> fixed by c282222a45cb
>>
>> (Last week I met it on RH7 kernel, which still has no a fix.
>> But this talk is not about distribution kernels, just about
>> the way).
>>
>> I just want to say if someone makes some creativity on top
>> of this code, it will be to more friendly from us to him/her
>> to not force this person to think about such not obvious details,
>> but just to implement nice architecture right now.
>
> You keep saying nice architecture, how did you architect
> ipv4.ra_mutex into net/core/net_namespace.c? It is apparently
> not nice.
>
> Good luck with your future.
>
> I am tired, let's just drop it. I have no interest to fix your mess.
You added me to CC, so you probably want to know my opinion about this.
Since it's not a real problem fix, but just a refactoring, I say you
my opinion, how this refactoring may be made better. If you don't want
to know my opinion, you may consider not to CC me.
Just this, not a reason to take offense.
Thanks,
Kirill
^ permalink raw reply
* Re: [PATCH net-next 17/22] hv_netvsc: fix return type of ndo_start_xmit function
From: Haiyang Zhang via dev @ 2018-09-20 14:50 UTC (permalink / raw)
To: Stephen Hemminger, YueHaibing
Cc: dmitry.tarnyagin-0TCahj4L2NoXWF+eFR7m5Q@public.gmane.org,
madalin.bucur-3arQi8VN3Tc@public.gmane.org,
linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org,
linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org,
pantelis.antoniou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
KY Srinivasan, t.sailer-aAjG49QhEdKVRmA6MYkXiA@public.gmane.org,
dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
arvid.brodin-SVm98a2vdck@public.gmane.org,
michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org,
m-karicheri2-l0cyMroinI0@public.gmane.org,
xen-devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b@public.gmane.org,
jreuter-K7Hl1MveuGQ@public.gmane.org,
sammy-4OGMY2YDKIVeoWH0uzbU5w@public.gmane.org,
grygorii.strashko-l0cyMroinI0@public.gmane.org,
w-kwok2-l0cyMroinI0@public.gmane.org,
"steve.glendinning-nksJyM/082jR7s880joybQ@public.gmane.org" <steve.gl
In-Reply-To: <20180920074341.3acef75c@xeon-e3>
> -----Original Message-----
> From: Stephen Hemminger <stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org>
> Sent: Thursday, September 20, 2018 10:44 AM
> To: YueHaibing <yuehaibing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org; dmitry.tarnyagin-0TCahj4L2NoXWF+eFR7m5Q@public.gmane.org;
> wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org; mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org; michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org;
> hsweeten-3FF4nKcrg1dE2c76skzGb0EOCMrvLtNR@public.gmane.org; madalin.bucur-3arQi8VN3Tc@public.gmane.org;
> pantelis.antoniou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; claudiu.manoil-3arQi8VN3Tc@public.gmane.org; leoyang.li-3arQi8VN3Tc@public.gmane.org;
> linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org; sammy-4OGMY2YDKIVeoWH0uzbU5w@public.gmane.org; ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org;
> nico-vtqb6HGKxmzR7s880joybQ@public.gmane.org; steve.glendinning-nksJyM/082jR7s880joybQ@public.gmane.org; f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org;
> grygorii.strashko-l0cyMroinI0@public.gmane.org; w-kwok2-l0cyMroinI0@public.gmane.org; m-karicheri2-l0cyMroinI0@public.gmane.org;
> t.sailer-aAjG49QhEdKVRmA6MYkXiA@public.gmane.org; jreuter-K7Hl1MveuGQ@public.gmane.org; KY Srinivasan <kys-0li6OtcxBFHby3iVrkZq2A@public.gmane.org>;
> Haiyang Zhang <haiyangz-0li6OtcxBFHby3iVrkZq2A@public.gmane.org>; wei.liu2-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org;
> paul.durrant-Sxgqhf6Nn4DQT0dZR+AlfA@public.gmane.org; arvid.brodin-SVm98a2vdck@public.gmane.org; pshelar-LZ6Gd1LRuIk@public.gmane.org;
> dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org; linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org; xen-
> devel-GuqFBffKawtpuQazS67q72D2FQJk+8+b@public.gmane.org; netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
> linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-can-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
> devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X@public.gmane.org; linux-hams-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-
> omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org; linux-arm-
> kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> Subject: Re: [PATCH net-next 17/22] hv_netvsc: fix return type of
> ndo_start_xmit function
>
> On Thu, 20 Sep 2018 20:33:01 +0800
> YueHaibing <yuehaibing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org> wrote:
> > int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
> > */
> > vf_netdev = rcu_dereference_bh(net_device_ctx->vf_netdev);
> > if (vf_netdev && netif_running(vf_netdev) &&
> > - !netpoll_tx_running(net))
> > - return netvsc_vf_xmit(net, vf_netdev, skb);
> > + !netpoll_tx_running(net)) {
> > + ret = netvsc_vf_xmit(net, vf_netdev, skb);
> > + if (ret)
> > + return NETDEV_TX_BUSY;
> > + }
>
> Sorry, the new code is wrong. It will fall through if ret == 0 (NETDEV_TX_OK)
> Please review and test your patches.
Plus consideration of -- For error case, please just return NETDEV_TX_OK. We
are not sure if the error can go away after retrying, returning NETDEV_TX_BUSY
may cause infinite retry from the upper layer.
So, let's just always return NETDEV_TX_OK like this:
netvsc_vf_xmit(net, vf_netdev, skb);
return NETDEV_TX_OK;
Thanks,
- Haiyang
^ permalink raw reply
* CONGRATULATIONS:
From: WINNING AWARD @ 2018-09-20 7:55 UTC (permalink / raw)
To: Recipients
This is to inform you that you are among the Ten lucky winners of Category A. Hence we do believe with your winning prize, you will continue to be active to the Google search engine/ ancillary services. Google is now the biggest search engine worldwide and in an effort to make sure that it remains the most widely used search engine, we ran an on-line e-mail beta test which your email address won 950 thousand dollars .
You are advised to contact your Foreign Transfer Manager with the following details (Ref NO: GP/48-46GC/Q, Winning NO: GC046GP-43-11) and to avoid unnecessary delay.
Google Promotion Foreign Transfer Manager
Sir. Randy Brown
Email: ( rd4217526@gmail.com
Sincerely,
Lawrence Page
Co-founder of Google™”
^ permalink raw reply
* Re: [PATCH net-next 17/22] hv_netvsc: fix return type of ndo_start_xmit function
From: Stephen Hemminger @ 2018-09-20 14:43 UTC (permalink / raw)
To: YueHaibing
Cc: dmitry.tarnyagin, madalin.bucur, linux-mips, linux,
pantelis.antoniou, t.sailer, dev, f.fainelli, arvid.brodin,
michal.simek, pshelar, m-karicheri2, xen-devel, jreuter, sammy,
grygorii.strashko, w-kwok2, haiyangz, steve.glendinning,
linux-can, claudiu.manoil, paul.durrant, mkl, linux-hams,
linux-omap, linux-arm-kernel, wei.liu2, nico, netdev, linux-usb,
linux-kernel, ralf, leoyang.li, wg, devel, linuxppc-dev, da
In-Reply-To: <20180920123306.14772-18-yuehaibing@huawei.com>
On Thu, 20 Sep 2018 20:33:01 +0800
YueHaibing <yuehaibing@huawei.com> wrote:
> The method ndo_start_xmit() is defined as returning an 'netdev_tx_t',
> which is a typedef for an enum type, so make sure the implementation in
> this driver has returns 'netdev_tx_t' value, and change the function
> return type to netdev_tx_t.
>
> Found by coccinelle.
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> drivers/net/hyperv/netvsc_drv.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index 3af6d8d..056c472 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -511,7 +511,8 @@ static int netvsc_vf_xmit(struct net_device *net, struct net_device *vf_netdev,
> return rc;
> }
>
> -static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
> +static netdev_tx_t
> +netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
> {
> struct net_device_context *net_device_ctx = netdev_priv(net);
> struct hv_netvsc_packet *packet = NULL;
> @@ -528,8 +529,11 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
> */
> vf_netdev = rcu_dereference_bh(net_device_ctx->vf_netdev);
> if (vf_netdev && netif_running(vf_netdev) &&
> - !netpoll_tx_running(net))
> - return netvsc_vf_xmit(net, vf_netdev, skb);
> + !netpoll_tx_running(net)) {
> + ret = netvsc_vf_xmit(net, vf_netdev, skb);
> + if (ret)
> + return NETDEV_TX_BUSY;
> + }
Sorry, the new code is wrong. It will fall through if ret == 0 (NETDEV_TX_OK)
Please review and test your patches.
^ permalink raw reply
* [PATCH net-next 1/5] net: allow binding socket in a VRF when there's an unbound socket
From: Mike Manning @ 2018-09-20 8:58 UTC (permalink / raw)
To: netdev; +Cc: Robert Shearman
In-Reply-To: <20180920085848.17721-1-mmanning@vyatta.att-mail.com>
From: Robert Shearman <rshearma@vyatta.att-mail.com>
There is no easy way currently for applications that want to receive
packets in the default VRF to be isolated from packets arriving in
VRFs, which makes using VRF-unaware applications in a VRF-aware system
a potential security risk.
So change the inet socket lookup to avoid packets arriving on a device
enslaved to an l3mdev from matching unbound sockets by removing the
wildcard for non sk_bound_dev_if and instead relying on check against
the secondary device index, which will be 0 when the input device is
not enslaved to an l3mdev and so match against an unbound socket and
not match when the input device is enslaved.
The existing net.ipv4.tcp_l3mdev_accept & net.ipv4.udp_l3mdev_accept
sysctls, which are documented as allowing the working across all VRF
domains, can be used to also work in the default VRF by causing
unbound sockets to match against packets arriving on a device
enslaved to an l3mdev.
Change the socket binding to take the l3mdev into account to allow an
unbound socket to not conflict sockets bound to an l3mdev given the
datapath isolation now guaranteed.
Signed-off-by: Robert Shearman <rshearma@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
Documentation/networking/vrf.txt | 9 +++++----
include/net/inet6_hashtables.h | 5 ++---
include/net/inet_hashtables.h | 21 ++++++++++++++-------
include/net/inet_sock.h | 13 +++++++++++++
net/core/sock.c | 2 ++
net/ipv4/inet_connection_sock.c | 13 ++++++++++---
net/ipv4/inet_hashtables.c | 34 +++++++++++++++++++++-------------
net/ipv4/ip_sockglue.c | 3 +++
net/ipv4/raw.c | 4 ++--
net/ipv4/udp.c | 15 ++++++---------
net/ipv6/datagram.c | 5 ++++-
net/ipv6/inet6_hashtables.c | 14 ++++++--------
net/ipv6/ipv6_sockglue.c | 3 +++
net/ipv6/raw.c | 6 +++---
net/ipv6/udp.c | 14 +++++---------
15 files changed, 99 insertions(+), 62 deletions(-)
diff --git a/Documentation/networking/vrf.txt b/Documentation/networking/vrf.txt
index 8ff7b4c8f91b..d4b129402d57 100644
--- a/Documentation/networking/vrf.txt
+++ b/Documentation/networking/vrf.txt
@@ -103,6 +103,11 @@ VRF device:
or to specify the output device using cmsg and IP_PKTINFO.
+By default the scope of the port bindings for unbound sockets is
+limited to the default VRF. That is, it will not be matched by packets
+arriving on interfaces enslaved to an l3mdev and processes may bind to
+the same port if they bind to an l3mdev.
+
TCP & UDP services running in the default VRF context (ie., not bound
to any VRF device) can work across all VRF domains by enabling the
tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
@@ -112,10 +117,6 @@ tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
netfilter rules on the VRF device can be used to limit access to services
running in the default VRF context as well.
-The default VRF does not have limited scope with respect to port bindings.
-That is, if a process does a wildcard bind to a port in the default VRF it
-owns the port across all VRF domains within the network namespace.
-
################################################################################
Using iproute2 for VRFs
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 6e91e38a31da..9db98af46985 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -115,9 +115,8 @@ int inet6_hash(struct sock *sk);
((__sk)->sk_family == AF_INET6) && \
ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \
ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \
- (!(__sk)->sk_bound_dev_if || \
- ((__sk)->sk_bound_dev_if == (__dif)) || \
- ((__sk)->sk_bound_dev_if == (__sdif))) && \
+ (((__sk)->sk_bound_dev_if == (__dif)) || \
+ ((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#endif /* _INET6_HASHTABLES_H */
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 9141e95529e7..ec279bcd0958 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -79,6 +79,7 @@ struct inet_ehash_bucket {
struct inet_bind_bucket {
possible_net_t ib_net;
+ int l3mdev;
unsigned short port;
signed char fastreuse;
signed char fastreuseport;
@@ -188,10 +189,18 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
hashinfo->ehash_locks = NULL;
}
+static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+{
+ if (!bound_dev_if)
+ return !sdif || net->ipv4.sysctl_tcp_l3mdev_accept;
+ return bound_dev_if == dif || bound_dev_if == sdif;
+}
+
struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
struct inet_bind_hashbucket *head,
- const unsigned short snum);
+ const unsigned short snum, int l3mdev);
void inet_bind_bucket_destroy(struct kmem_cache *cachep,
struct inet_bind_bucket *tb);
@@ -282,9 +291,8 @@ static inline struct sock *inet_lookup_listener(struct net *net,
#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
(((__sk)->sk_portpair == (__ports)) && \
((__sk)->sk_addrpair == (__cookie)) && \
- (!(__sk)->sk_bound_dev_if || \
- ((__sk)->sk_bound_dev_if == (__dif)) || \
- ((__sk)->sk_bound_dev_if == (__sdif))) && \
+ (((__sk)->sk_bound_dev_if == (__dif)) || \
+ ((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
@@ -294,9 +302,8 @@ static inline struct sock *inet_lookup_listener(struct net *net,
(((__sk)->sk_portpair == (__ports)) && \
((__sk)->sk_daddr == (__saddr)) && \
((__sk)->sk_rcv_saddr == (__daddr)) && \
- (!(__sk)->sk_bound_dev_if || \
- ((__sk)->sk_bound_dev_if == (__dif)) || \
- ((__sk)->sk_bound_dev_if == (__sdif))) && \
+ (((__sk)->sk_bound_dev_if == (__dif)) || \
+ ((__sk)->sk_bound_dev_if == (__sdif))) && \
net_eq(sock_net(__sk), (__net)))
#endif /* 64-bit arch */
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index e03b93360f33..92e0aa3958f6 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -130,6 +130,19 @@ static inline int inet_request_bound_dev_if(const struct sock *sk,
return sk->sk_bound_dev_if;
}
+static inline int inet_sk_bound_l3mdev(const struct sock *sk)
+{
+#ifdef CONFIG_NET_L3_MASTER_DEV
+ struct net *net = sock_net(sk);
+
+ if (!net->ipv4.sysctl_tcp_l3mdev_accept)
+ return l3mdev_master_ifindex_by_index(net,
+ sk->sk_bound_dev_if);
+#endif
+
+ return 0;
+}
+
static inline struct ip_options_rcu *ireq_opt_deref(const struct inet_request_sock *ireq)
{
return rcu_dereference_check(ireq->ireq_opt,
diff --git a/net/core/sock.c b/net/core/sock.c
index 3730eb855095..da1cbb88a6bf 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -567,6 +567,8 @@ static int sock_setbindtodevice(struct sock *sk, char __user *optval,
lock_sock(sk);
sk->sk_bound_dev_if = index;
+ if (sk->sk_prot->rehash)
+ sk->sk_prot->rehash(sk);
sk_dst_reset(sk);
release_sock(sk);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index dfd5009f96ef..97bba5b3d69f 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -183,7 +183,9 @@ inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *
int i, low, high, attempt_half;
struct inet_bind_bucket *tb;
u32 remaining, offset;
+ int l3mdev;
+ l3mdev = inet_sk_bound_l3mdev(sk);
attempt_half = (sk->sk_reuse == SK_CAN_REUSE) ? 1 : 0;
other_half_scan:
inet_get_local_port_range(net, &low, &high);
@@ -219,7 +221,8 @@ inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *
hinfo->bhash_size)];
spin_lock_bh(&head->lock);
inet_bind_bucket_for_each(tb, &head->chain)
- if (net_eq(ib_net(tb), net) && tb->port == port) {
+ if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+ tb->port == port) {
if (!inet_csk_bind_conflict(sk, tb, false, false))
goto success;
goto next_port;
@@ -293,6 +296,9 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
struct net *net = sock_net(sk);
struct inet_bind_bucket *tb = NULL;
kuid_t uid = sock_i_uid(sk);
+ int l3mdev;
+
+ l3mdev = inet_sk_bound_l3mdev(sk);
if (!port) {
head = inet_csk_find_open_port(sk, &tb, &port);
@@ -306,11 +312,12 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
hinfo->bhash_size)];
spin_lock_bh(&head->lock);
inet_bind_bucket_for_each(tb, &head->chain)
- if (net_eq(ib_net(tb), net) && tb->port == port)
+ if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+ tb->port == port)
goto tb_found;
tb_not_found:
tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
- net, head, port);
+ net, head, port, l3mdev);
if (!tb)
goto fail_unlock;
tb_found:
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index f5c9ef2586de..2ec684057ebd 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -65,12 +65,14 @@ static u32 sk_ehashfn(const struct sock *sk)
struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
struct net *net,
struct inet_bind_hashbucket *head,
- const unsigned short snum)
+ const unsigned short snum,
+ int l3mdev)
{
struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
if (tb) {
write_pnet(&tb->ib_net, net);
+ tb->l3mdev = l3mdev;
tb->port = snum;
tb->fastreuse = 0;
tb->fastreuseport = 0;
@@ -135,6 +137,7 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
table->bhash_size);
struct inet_bind_hashbucket *head = &table->bhash[bhash];
struct inet_bind_bucket *tb;
+ int l3mdev;
spin_lock(&head->lock);
tb = inet_csk(sk)->icsk_bind_hash;
@@ -143,6 +146,8 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
return -ENOENT;
}
if (tb->port != port) {
+ l3mdev = inet_sk_bound_l3mdev(sk);
+
/* NOTE: using tproxy and redirecting skbs to a proxy
* on a different listener port breaks the assumption
* that the listener socket's icsk_bind_hash is the same
@@ -150,12 +155,13 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
* create a new bind bucket for the child here. */
inet_bind_bucket_for_each(tb, &head->chain) {
if (net_eq(ib_net(tb), sock_net(sk)) &&
- tb->port == port)
+ tb->l3mdev == l3mdev && tb->port == port)
break;
}
if (!tb) {
tb = inet_bind_bucket_create(table->bind_bucket_cachep,
- sock_net(sk), head, port);
+ sock_net(sk), head, port,
+ l3mdev);
if (!tb) {
spin_unlock(&head->lock);
return -ENOMEM;
@@ -229,6 +235,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
{
int score = -1;
struct inet_sock *inet = inet_sk(sk);
+ bool dev_match;
if (net_eq(sock_net(sk), net) && inet->inet_num == hnum &&
!ipv6_only_sock(sk)) {
@@ -239,15 +246,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
return -1;
score += 4;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
+ dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif);
+ if (!dev_match)
+ return -1;
+ score += 4;
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score += 4;
- }
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
}
@@ -675,6 +679,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
u32 remaining, offset;
int ret, i, low, high;
static u32 hint;
+ int l3mdev;
if (port) {
head = &hinfo->bhash[inet_bhashfn(net, port,
@@ -693,6 +698,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
return ret;
}
+ l3mdev = inet_sk_bound_l3mdev(sk);
+
inet_get_local_port_range(net, &low, &high);
high++; /* [32768, 60999] -> [32768, 61000[ */
remaining = high - low;
@@ -719,7 +726,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
* the established check is already unique enough.
*/
inet_bind_bucket_for_each(tb, &head->chain) {
- if (net_eq(ib_net(tb), net) && tb->port == port) {
+ if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+ tb->port == port) {
if (tb->fastreuse >= 0 ||
tb->fastreuseport >= 0)
goto next_port;
@@ -732,7 +740,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
}
tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
- net, head, port);
+ net, head, port, l3mdev);
if (!tb) {
spin_unlock_bh(&head->lock);
return -ENOMEM;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index c0fe5ad996f2..026971314c43 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -892,6 +892,9 @@ static int do_ip_setsockopt(struct sock *sk, int level,
dev_put(dev);
err = -EINVAL;
+ if (!sk->sk_bound_dev_if && midx)
+ break;
+
if (sk->sk_bound_dev_if &&
mreq.imr_ifindex != sk->sk_bound_dev_if &&
(!midx || midx != sk->sk_bound_dev_if))
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 33df4d76db2d..8a0d568d7aec 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -70,6 +70,7 @@
#include <net/snmp.h>
#include <net/tcp_states.h>
#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
#include <net/checksum.h>
#include <net/xfrm.h>
#include <linux/rtnetlink.h>
@@ -131,8 +132,7 @@ struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
!(inet->inet_daddr && inet->inet_daddr != raddr) &&
!(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
- !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
- sk->sk_bound_dev_if != sdif))
+ inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
goto found; /* gotcha */
}
sk = NULL;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f4e35b2ff8b8..3d59ab47a85d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -371,6 +371,7 @@ static int compute_score(struct sock *sk, struct net *net,
{
int score;
struct inet_sock *inet;
+ bool dev_match;
if (!net_eq(sock_net(sk), net) ||
udp_sk(sk)->udp_port_hash != hnum ||
@@ -398,15 +399,11 @@ static int compute_score(struct sock *sk, struct net *net,
score += 4;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
-
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score += 4;
- }
+ dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif);
+ if (!dev_match)
+ return -1;
+ score += 4;
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 1ede7a16a0be..4813293d4fad 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -782,7 +782,10 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
if (src_info->ipi6_ifindex) {
if (fl6->flowi6_oif &&
- src_info->ipi6_ifindex != fl6->flowi6_oif)
+ src_info->ipi6_ifindex != fl6->flowi6_oif &&
+ (sk->sk_bound_dev_if != fl6->flowi6_oif ||
+ !sk_dev_equal_l3scope(
+ sk, src_info->ipi6_ifindex)))
return -EINVAL;
fl6->flowi6_oif = src_info->ipi6_ifindex;
}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 3d7c7460a0c5..5eeeba7181a1 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -99,6 +99,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
const int dif, const int sdif, bool exact_dif)
{
int score = -1;
+ bool dev_match;
if (net_eq(sock_net(sk), net) && inet_sk(sk)->inet_num == hnum &&
sk->sk_family == PF_INET6) {
@@ -109,15 +110,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
return -1;
score++;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
+ dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif);
+ if (!dev_match)
+ return -1;
+ score++;
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score++;
- }
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
}
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index c0cac9cc3a28..7dfbc797b130 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -626,6 +626,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
rcu_read_unlock();
+ if (!sk->sk_bound_dev_if && midx)
+ goto e_inval;
+
if (sk->sk_bound_dev_if &&
sk->sk_bound_dev_if != val &&
(!midx || midx != sk->sk_bound_dev_if))
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 413d98bf24f4..2f61a9f1a2b2 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -49,6 +49,7 @@
#include <net/transp_v6.h>
#include <net/udp.h>
#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
#include <net/tcp_states.h>
#if IS_ENABLED(CONFIG_IPV6_MIP6)
#include <net/mip6.h>
@@ -86,9 +87,8 @@ struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
!ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))
continue;
- if (sk->sk_bound_dev_if &&
- sk->sk_bound_dev_if != dif &&
- sk->sk_bound_dev_if != sdif)
+ if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+ dif, sdif))
continue;
if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 83f4c77c79d8..e22b7dd78c9b 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -117,6 +117,7 @@ static int compute_score(struct sock *sk, struct net *net,
{
int score;
struct inet_sock *inet;
+ bool dev_match;
if (!net_eq(sock_net(sk), net) ||
udp_sk(sk)->udp_port_hash != hnum ||
@@ -144,15 +145,10 @@ static int compute_score(struct sock *sk, struct net *net,
score++;
}
- if (sk->sk_bound_dev_if || exact_dif) {
- bool dev_match = (sk->sk_bound_dev_if == dif ||
- sk->sk_bound_dev_if == sdif);
-
- if (!dev_match)
- return -1;
- if (sk->sk_bound_dev_if)
- score++;
- }
+ dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif);
+ if (!dev_match)
+ return -1;
+ score++;
if (sk->sk_incoming_cpu == raw_smp_processor_id())
score++;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next 4/5] ipv6: do not drop vrf udp multicast packets
From: Mike Manning @ 2018-09-20 8:58 UTC (permalink / raw)
To: netdev; +Cc: Dewi Morgan
In-Reply-To: <20180920085848.17721-1-mmanning@vyatta.att-mail.com>
From: Dewi Morgan <morgand@vyatta.att-mail.com>
For bound udp sockets in a vrf, also check the sdif to get the index
for ingress devices enslaved to an l3mdev. Verify the multicast address
against the enslaved rather than the l3mdev device.
Signed-off-by: Dewi Morgan <morgand@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
net/ipv6/ip6_input.c | 27 ++++++++++++++++++++++++---
net/ipv6/udp.c | 8 +++++---
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 108f5f88ec98..fc60f297d95b 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -325,9 +325,12 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
{
const struct inet6_protocol *ipprot;
struct inet6_dev *idev;
+ struct net_device *dev;
unsigned int nhoff;
+ int sdif = inet6_sdif(skb);
int nexthdr;
bool raw;
+ bool deliver;
bool have_final = false;
/*
@@ -371,9 +374,27 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
skb_postpull_rcsum(skb, skb_network_header(skb),
skb_network_header_len(skb));
hdr = ipv6_hdr(skb);
- if (ipv6_addr_is_multicast(&hdr->daddr) &&
- !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
- &hdr->saddr) &&
+
+ /* skb->dev passed may be master dev for vrfs. */
+ if (sdif) {
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(dev_net(skb->dev),
+ sdif);
+ if (!dev) {
+ rcu_read_unlock();
+ kfree_skb(skb);
+ return -ENODEV;
+ }
+ } else {
+ dev = skb->dev;
+ }
+
+ deliver = ipv6_chk_mcast_addr(dev, &hdr->daddr,
+ &hdr->saddr);
+ if (sdif)
+ rcu_read_unlock();
+
+ if (ipv6_addr_is_multicast(&hdr->daddr) && !deliver &&
!ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
goto discard;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e22b7dd78c9b..35f71b7a1070 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -637,7 +637,7 @@ static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
__be16 loc_port, const struct in6_addr *loc_addr,
__be16 rmt_port, const struct in6_addr *rmt_addr,
- int dif, unsigned short hnum)
+ int dif, int sdif, unsigned short hnum)
{
struct inet_sock *inet = inet_sk(sk);
@@ -649,7 +649,7 @@ static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
(inet->inet_dport && inet->inet_dport != rmt_port) ||
(!ipv6_addr_any(&sk->sk_v6_daddr) &&
!ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) ||
- (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) ||
+ !inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif) ||
(!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)))
return false;
@@ -683,6 +683,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
unsigned int offset = offsetof(typeof(*sk), sk_node);
unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10);
int dif = inet6_iif(skb);
+ int sdif = inet6_sdif(skb);
struct hlist_node *node;
struct sk_buff *nskb;
@@ -697,7 +698,8 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
sk_for_each_entry_offset_rcu(sk, node, &hslot->head, offset) {
if (!__udp_v6_is_mcast_sock(net, sk, uh->dest, daddr,
- uh->source, saddr, dif, hnum))
+ uh->source, saddr, dif, sdif,
+ hnum))
continue;
/* If zero checksum and no_check is not on for
* the socket then skip it.
--
2.11.0
^ 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