* Re: [RFC PATCH iproute2] Drop capabilities if not running ip exec vrf with libcap
From: Luca Boccassi @ 2018-03-27 17:05 UTC (permalink / raw)
To: David Ahern, netdev; +Cc: luto, stephen
In-Reply-To: <4f03183a-3373-62b7-06ea-b1198299c8d5@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3757 bytes --]
On Tue, 2018-03-27 at 10:40 -0600, David Ahern wrote:
> On 3/27/18 10:24 AM, Luca Boccassi wrote:
> > ip vrf exec requires root or CAP_NET_ADMIN, CAP_SYS_ADMIN and
> > CAP_DAC_OVERRIDE. It is not possible to run unprivileged commands
> > like
> > ping as non-root or non-cap-enabled due to this requirement.
> > To allow users and administrators to safely add the required
> > capabilities to the binary, drop all capabilities on start if not
> > invoked with "vrf exec".
> > Update the manpage with the requirements.
> >
> > Signed-off-by: Luca Boccassi <bluca@debian.org>
> > ---
> >
> > I'd like to be able to run ip vrf exec as a normal user, does this
> > approach
> > sound sensible? Any concerns? Are there any other alternatives?
> > It would be up to each user/admin/whatever to make sure the program
> > is
> > built with libcap and to add the capabilities manually, so nothing
> > will be
> > there by default.
>
> This is very similar to a change I recently made for our
> distribution. I
> created a separate 'runvrf' command so as to not contaminate 'ip'
> (the
> runvrf command has the limitation it can not configure the VRF cgroup
> so
> that needs to be done before runvrf).
Great, thanks for the feedback!
> >
> > configure | 17 +++++++++++++++++
> > ip/ip.c | 34 ++++++++++++++++++++++++++++++++++
> > man/man8/ip-vrf.8 | 8 ++++++++
> > 3 files changed, 59 insertions(+)
> >
> > diff --git a/configure b/configure
> > index f7c2d7a7..5ef5cd4c 100755
> > --- a/configure
> > +++ b/configure
> > @@ -336,6 +336,20 @@ EOF
> > rm -f $TMPDIR/strtest.c $TMPDIR/strtest
> > }
> >
> > +check_cap()
> > +{
> > + if ${PKG_CONFIG} libcap --exists
> > + then
> > + echo "HAVE_CAP:=y" >>$CONFIG
> > + echo "yes"
> > +
> > + echo 'CFLAGS += -DHAVE_LIBCAP' `${PKG_CONFIG}
> > libcap --cflags` >>$CONFIG
> > + echo 'LDLIBS +=' `${PKG_CONFIG} libcap --libs` >>
> > $CONFIG
> > + else
> > + echo "no"
> > + fi
> > +}
> > +
> > quiet_config()
> > {
> > cat <<EOF
> > @@ -410,6 +424,9 @@ check_berkeley_db
> > echo -n "need for strlcpy: "
> > check_strlcpy
> >
> > +echo -n "libcap support: "
> > +check_cap
> > +
> > echo >> $CONFIG
> > echo "%.o: %.c" >> $CONFIG
> > echo ' $(QUIET_CC)$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@
> > $<' >> $CONFIG
> > diff --git a/ip/ip.c b/ip/ip.c
> > index e0cd96cb..49739571 100644
> > --- a/ip/ip.c
> > +++ b/ip/ip.c
> > @@ -17,6 +17,10 @@
> > #include <netinet/in.h>
> > #include <string.h>
> > #include <errno.h>
> > +#include <sys/types.h>
> > +#ifdef HAVE_LIBCAP
> > +#include <sys/capability.h>
> > +#endif
> >
> > #include "SNAPSHOT.h"
> > #include "utils.h"
> > @@ -68,6 +72,24 @@ static int do_help(int argc, char **argv)
> > return 0;
> > }
> >
> > +static void drop_cap(void)
> > +{
> > +#ifdef HAVE_LIBCAP
> > + /* don't harmstring root/sudo */
> > + if (getuid() != 0 && geteuid() != 0) {
> > + cap_t capabilities;
> > + capabilities = cap_get_proc();
> > + if (!capabilities)
> > + exit(EXIT_FAILURE);
> > + if (cap_clear(capabilities) != 0)
> > + exit(EXIT_FAILURE);
> > + if (cap_set_proc(capabilities) != 0)
> > + exit(EXIT_FAILURE);
> > + cap_free(capabilities);
> > + }
> > +#endif
> > +}
>
> You don't need the capabilities after the cgroup has been changed, so
> you can add a call to drop_cap at the end of vrf_switch.
Ok, if Stephen finds the approach correct I'll send a v1 with that
change (it shouldn't be strictly necessary as execvp which is ran just
after vrf_switch drops caps, but it won't hurt either).
--
Kind regards,
Luca Boccassi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* [PATCH net-next 0/2] do not allow to add routes if disable_ipv6 is enabled
From: Lorenzo Bianconi @ 2018-03-27 17:11 UTC (permalink / raw)
To: davem; +Cc: netdev
Do not allow userspace to add static ipv6 routes if disable_ipv6 is enabled.
Update disable_ipv6 documentation according to that change
Lorenzo Bianconi (2):
ipv6: do not set routes if disable_ipv6 has been enabled
Documentation: ip-sysctl.txt: clarify disable_ipv6
Documentation/networking/ip-sysctl.txt | 4 +++-
net/ipv6/route.c | 5 +++++
2 files changed, 8 insertions(+), 1 deletion(-)
--
2.14.3
^ permalink raw reply
* [PATCH net-next 1/2] ipv6: do not set routes if disable_ipv6 has been enabled
From: Lorenzo Bianconi @ 2018-03-27 17:11 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1522166051.git.lorenzo.bianconi@redhat.com>
Do not allow to set ipv6 routes from userspace if disable_ipv6 has been
enabled. The issue can be triggered using the following reproducer:
- sysctl net.ipv6.conf.all.disable_ipv6=1
- ip -6 route add a:b:c:d::/64 dev em1
- ip -6 route show
a:b:c:d::/64 dev em1 metric 1024 pref medium
Fix it checking disable_ipv6 value in ip6_route_info_create routine
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
net/ipv6/route.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1d0eaa69874d..672fd7fdb037 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2917,6 +2917,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
if (!dev)
goto out;
+ if (idev->cnf.disable_ipv6) {
+ err = -EACCES;
+ goto out;
+ }
+
if (!(dev->flags & IFF_UP)) {
NL_SET_ERR_MSG(extack, "Nexthop device is not up");
err = -ENETDOWN;
--
2.14.3
^ permalink raw reply related
* [PATCH net-next 2/2] Documentation: ip-sysctl.txt: clarify disable_ipv6
From: Lorenzo Bianconi @ 2018-03-27 17:11 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1522166051.git.lorenzo.bianconi@redhat.com>
Clarify that when disable_ipv6 is enabled even the ipv6 routes
are deleted for the selected interface and from now it will not
be possible to add addresses/routes to that interface
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
Documentation/networking/ip-sysctl.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 1d1120753ae8..33f35f049ad5 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1703,7 +1703,9 @@ disable_ipv6 - BOOLEAN
interface and start Duplicate Address Detection, if necessary.
When this value is changed from 0 to 1 (IPv6 is being disabled),
- it will dynamically delete all address on the given interface.
+ it will dynamically delete all addresses and routes on the given
+ interface. From now on it will not possible to add addresses/routes
+ to the selected interface.
accept_dad - INTEGER
Whether to accept DAD (Duplicate Address Detection).
--
2.14.3
^ permalink raw reply related
* Re: [PATCH v6 bpf-next 08/11] bpf: introduce BPF_RAW_TRACEPOINT
From: Steven Rostedt @ 2018-03-27 17:11 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: davem, daniel, torvalds, peterz, netdev, kernel-team, linux-api,
Mathieu Desnoyers, Kees Cook
In-Reply-To: <20180327130211.284c8924@gandalf.local.home>
On Tue, 27 Mar 2018 13:02:11 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> Honestly, I think this is too much of a short cut and a hack. I know
> you want to keep it "simple" and save space, but you really should do
> it the same way ftrace and perf do it. That is, create a section and
> have all tracepoints create a structure that holds a pointer to the
> tracepoint and to the bpf probe function. Then you don't even need the
> kernel_tracepoint_find_by_name(), you just iterate over your table and
> you get the tracepoint and the bpf function associated to it.
Also, if you do it the perf/ftrace way, you get support for module
tracepoints pretty much for free. Which would include tracepoints in
networking code that is loaded by a module.
-- Steve
^ permalink raw reply
* Re: [PATCH v2 net 1/1] qede: Fix barrier usage after tx doorbell write.
From: David Miller @ 2018-03-27 17:12 UTC (permalink / raw)
To: manish.chopra; +Cc: netdev, ariel.elior, michal.kalderon
In-Reply-To: <20180327133441.15949-1-manish.chopra@cavium.com>
From: Manish Chopra <manish.chopra@cavium.com>
Date: Tue, 27 Mar 2018 06:34:41 -0700
> Since commit c5ad119fb6c09b0297446be05bd66602fa564758
> ("net: sched: pfifo_fast use skb_array") driver is exposed
> to an issue where it is hitting NULL skbs while handling TX
> completions. Driver uses mmiowb() to flush the writes to the
> doorbell bar which is a write-combined bar, however on x86
> mmiowb() does not flush the write combined buffer.
>
> This patch fixes this problem by replacing mmiowb() with wmb()
> after the write combined doorbell write so that writes are
> flushed and synchronized from more than one processor.
>
> V1->V2:
> -------
> This patch was marked as "superseded" in patchwork.
> (Not really sure for what reason).Resending it as v2.
>
> Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
> Signed-off-by: Manish Chopra <manish.chopra@cavium.com>
Applied, thank you.
^ permalink raw reply
* Re: [Patch net] llc: properly handle dev_queue_xmit() return value
From: David Miller @ 2018-03-27 17:13 UTC (permalink / raw)
To: noamr; +Cc: netdev, xiyou.wangcong
In-Reply-To: <CAHqykcSHSdN5At7-EUOCxxUVxd7-o7jH93FOJGR7o_75BdHazg@mail.gmail.com>
From: Noam Rathaus <noamr@beyondsecurity.com>
Date: Tue, 27 Mar 2018 16:27:49 +0000
> Guys please fill me in on the next step?
>
> If it’s applied it means it’s part of the official code of the kernel now?
It means it is in my networking GIT tree and will make it's way to Linus
in the not so distant future.
^ permalink raw reply
* Re: [net-next PATCH v2 03/10] net: netcp: ethss: make call to gbe_sgmii_config() conditional
From: Andrew Lunn @ 2018-03-27 17:13 UTC (permalink / raw)
To: Murali Karicheri
Cc: robh+dt, mark.rutland, ssantosh, malat, w-kwok2, devicetree,
linux-kernel, linux-arm-kernel, davem, netdev
In-Reply-To: <1522168309-12338-4-git-send-email-m-karicheri2@ti.com>
On Tue, Mar 27, 2018 at 12:31:42PM -0400, Murali Karicheri wrote:
> As a preparatory patch to add support for 2u cpsw hardware found on
> K2G SoC, make call to gbe_sgmii_config() conditional. This is required
> since 2u uses RGMII interface instead of SGMII and to allow for driver
> re-use.
>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> ---
> drivers/net/ethernet/ti/netcp_ethss.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c
> index 56dbc0b..1dea891 100644
> --- a/drivers/net/ethernet/ti/netcp_ethss.c
> +++ b/drivers/net/ethernet/ti/netcp_ethss.c
> @@ -2271,7 +2271,8 @@ static int gbe_slave_open(struct gbe_intf *gbe_intf)
>
> void (*hndlr)(struct net_device *) = gbe_adjust_link;
>
> - gbe_sgmii_config(priv, slave);
> + if ((priv->ss_version == GBE_SS_VERSION_14) || IS_SS_ID_NU(priv))
> + gbe_sgmii_config(priv, slave);
Hi Murali
So you have:
#define IS_SS_ID_NU(d) \
(GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU)
Does version 14 have a name? Could you add another IS_SS_ID_XX(d)
macro for it? That would make these statements more consistent.
Andrew
^ permalink raw reply
* Re: [RFC PATCH iproute2] Drop capabilities if not running ip exec vrf with libcap
From: Stephen Hemminger @ 2018-03-27 17:15 UTC (permalink / raw)
To: Luca Boccassi; +Cc: netdev, dsahern, luto
In-Reply-To: <20180327162419.8962-1-bluca@debian.org>
On Tue, 27 Mar 2018 17:24:19 +0100
Luca Boccassi <bluca@debian.org> wrote:
> ip vrf exec requires root or CAP_NET_ADMIN, CAP_SYS_ADMIN and
> CAP_DAC_OVERRIDE. It is not possible to run unprivileged commands like
> ping as non-root or non-cap-enabled due to this requirement.
> To allow users and administrators to safely add the required
> capabilities to the binary, drop all capabilities on start if not
> invoked with "vrf exec".
> Update the manpage with the requirements.
>
> Signed-off-by: Luca Boccassi <bluca@debian.org>
Gets a little messy, but don't have a better answer.
When a command like iproute gets involved in security policy things
I become concerned that it may have unexpected consequences.
^ permalink raw reply
* Re: [PATCH net-next] net: mvpp2: Use relaxed I/O in data path
From: David Miller @ 2018-03-27 17:16 UTC (permalink / raw)
To: maxime.chevallier
Cc: ymarkman, netdev, linux-kernel, antoine.tenart, thomas.petazzoni,
gregory.clement, miquel.raynal, nadavh, stefanc, mw
In-Reply-To: <20180327144905.23499-1-maxime.chevallier@bootlin.com>
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
Date: Tue, 27 Mar 2018 16:49:05 +0200
> From: Yan Markman <ymarkman@marvell.com>
>
> Use relaxed I/O on the hot path. This achieves significant performance
> improvements. On a 10G link, this makes a basic iperf TCP test go from
> an average of 4.5 Gbits/sec to about 9.40 Gbits/sec.
>
> Signed-off-by: Yan Markman <ymarkman@marvell.com>
> [Maxime: Commit message, cosmetic changes]
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> ---
> David, this patch should not conflict with other the pending PPv2 series I sent
> earlier ("[PATCH net-next 0/2] net: mvpp2: Remove unnecessary dynamic allocs")
Applied, but it is up to you to make sure the correct barriers are in place
such that undesirable memory and IOMEM operation reordering does not occur.
Said another way, you get to keep the pieces if this breaks things :-)
^ permalink raw reply
* RE: [EXT] Re: [PATCH net-next] net: mvpp2: Use relaxed I/O in data path
From: Yan Markman @ 2018-03-27 17:18 UTC (permalink / raw)
To: David Miller, maxime.chevallier@bootlin.com
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
antoine.tenart@bootlin.com, thomas.petazzoni@bootlin.com,
gregory.clement@bootlin.com, miquel.raynal@bootlin.com,
Nadav Haklai, Stefan Chulski, mw@semihalf.com
In-Reply-To: <20180327.131624.64497520832369981.davem@davemloft.net>
Thanks David
We are aware and it is working properly
Yan Markman
-----Original Message-----
From: David Miller [mailto:davem@davemloft.net]
Sent: Tuesday, March 27, 2018 8:16 PM
To: maxime.chevallier@bootlin.com
Cc: Yan Markman <ymarkman@marvell.com>; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; antoine.tenart@bootlin.com; thomas.petazzoni@bootlin.com; gregory.clement@bootlin.com; miquel.raynal@bootlin.com; Nadav Haklai <nadavh@marvell.com>; Stefan Chulski <stefanc@marvell.com>; mw@semihalf.com
Subject: [EXT] Re: [PATCH net-next] net: mvpp2: Use relaxed I/O in data path
External Email
----------------------------------------------------------------------
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
Date: Tue, 27 Mar 2018 16:49:05 +0200
> From: Yan Markman <ymarkman@marvell.com>
>
> Use relaxed I/O on the hot path. This achieves significant performance
> improvements. On a 10G link, this makes a basic iperf TCP test go from
> an average of 4.5 Gbits/sec to about 9.40 Gbits/sec.
>
> Signed-off-by: Yan Markman <ymarkman@marvell.com>
> [Maxime: Commit message, cosmetic changes]
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> ---
> David, this patch should not conflict with other the pending PPv2
> series I sent earlier ("[PATCH net-next 0/2] net: mvpp2: Remove
> unnecessary dynamic allocs")
Applied, but it is up to you to make sure the correct barriers are in place such that undesirable memory and IOMEM operation reordering does not occur.
Said another way, you get to keep the pieces if this breaks things :-)
^ permalink raw reply
* Re: [net-next PATCH v2 03/10] net: netcp: ethss: make call to gbe_sgmii_config() conditional
From: Andrew Lunn @ 2018-03-27 17:18 UTC (permalink / raw)
To: Murali Karicheri
Cc: mark.rutland, devicetree, malat, netdev, linux-kernel, w-kwok2,
robh+dt, ssantosh, davem, linux-arm-kernel
In-Reply-To: <1522168309-12338-4-git-send-email-m-karicheri2@ti.com>
On Tue, Mar 27, 2018 at 12:31:42PM -0400, Murali Karicheri wrote:
> As a preparatory patch to add support for 2u cpsw hardware found on
> K2G SoC, make call to gbe_sgmii_config() conditional. This is required
> since 2u uses RGMII interface instead of SGMII and to allow for driver
> re-use.
>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> ---
> drivers/net/ethernet/ti/netcp_ethss.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c
> index 56dbc0b..1dea891 100644
> --- a/drivers/net/ethernet/ti/netcp_ethss.c
> +++ b/drivers/net/ethernet/ti/netcp_ethss.c
> @@ -2271,7 +2271,8 @@ static int gbe_slave_open(struct gbe_intf *gbe_intf)
>
> void (*hndlr)(struct net_device *) = gbe_adjust_link;
>
> - gbe_sgmii_config(priv, slave);
> + if ((priv->ss_version == GBE_SS_VERSION_14) || IS_SS_ID_NU(priv))
> + gbe_sgmii_config(priv, slave);
Or maybe:
if (slave->phy_node == PHY_INTERFACE_MODE_SGMII)
gbe_sgmii_config(priv, slave);
Andrew
^ permalink raw reply
* Re: [PATCH net-next 0/5] Make pernet_operations always read locked
From: David Miller @ 2018-03-27 17:18 UTC (permalink / raw)
To: ktkhai
Cc: nicolas.dichtel, vyasevic, paulmck, vyasevich, mark.rutland,
leonro, avagin, fw, ebiederm, roman.kapl, dsahern, netdev,
bfields
In-Reply-To: <152216238129.1634.4807322431520445566.stgit@localhost.localdomain>
From: Kirill Tkhai <ktkhai@virtuozzo.com>
Date: Tue, 27 Mar 2018 18:01:42 +0300
> All the pernet_operations are converted, and the last one
> is in this patchset (nfsd_net_ops acked by J. Bruce Fields).
> So, it's the time to kill pernet_operations::async field,
> and make setup_net() and cleanup_net() always require
> the rwsem only read locked.
>
> All further pernet_operations have to be developed to fit
> this rule. Some of previous patches added a comment to
> struct pernet_operations about that.
>
> Also, this patchset renames net_sem to pernet_ops_rwsem
> to make the target area of the rwsem is more clear visible,
> and adds more comments.
Amazing work, series applied, thanks!
^ permalink raw reply
* [bpf-next PATCH v2 0/4] bpf, sockmap BPF_F_INGRESS support
From: John Fastabend @ 2018-03-27 17:23 UTC (permalink / raw)
To: ast, daniel; +Cc: netdev, davem
This series adds the BPF_F_INGRESS flag support to the redirect APIs.
Bringing the sockmap API in-line with the cls_bpf redirect APIs.
We add it to both variants of sockmap programs, the first patch adds
support for tx ulp hooks and the third patch adds support for the recv
skb hooks. Patches two and four add tests for the corresponding
ingress redirect hooks.
Follow on patches can address busy polling support, but next series
from me will move the sockmap sample program into selftests.
v2: added static to function definition caught by kbuild bot
---
John Fastabend (4):
bpf: sockmap redirect ingress support
bpf: sockmap, add BPF_F_INGRESS tests
bpf: sockmap, BPF_F_INGRESS flag for BPF_SK_SKB_STREAM_VERDICT:
bpf: sockmap, more BPF_SK_SKB_STREAM_VERDICT tests
include/linux/filter.h | 2
include/net/sock.h | 1
kernel/bpf/sockmap.c | 290 ++++++++++++++++++++++++++++++++++++---
net/core/filter.c | 4 -
net/ipv4/tcp.c | 10 +
samples/sockmap/sockmap_kern.c | 62 +++++++-
samples/sockmap/sockmap_test.sh | 40 +++++
samples/sockmap/sockmap_user.c | 58 ++++++++
8 files changed, 430 insertions(+), 37 deletions(-)
^ permalink raw reply
* [bpf-next PATCH v2 1/4] bpf: sockmap redirect ingress support
From: John Fastabend @ 2018-03-27 17:23 UTC (permalink / raw)
To: ast, daniel; +Cc: netdev, davem
In-Reply-To: <20180327172042.11354.81872.stgit@john-Precision-Tower-5810>
Add support for the BPF_F_INGRESS flag in sk_msg redirect helper.
To do this add a scatterlist ring for receiving socks to check
before calling into regular recvmsg call path. Additionally, because
the poll wakeup logic only checked the skb recv queue we need to
add a hook in TCP stack (similar to write side) so that we have
a way to wake up polling socks when a scatterlist is redirected
to that sock.
After this all that is needed is for the redirect helper to
push the scatterlist into the psock receive queue.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
include/linux/filter.h | 1
include/net/sock.h | 1
kernel/bpf/sockmap.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++-
net/core/filter.c | 2
net/ipv4/tcp.c | 10 ++
5 files changed, 207 insertions(+), 5 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 109d05c..d0e207f 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -521,6 +521,7 @@ struct sk_msg_buff {
__u32 key;
__u32 flags;
struct bpf_map *map;
+ struct list_head list;
};
/* Compute the linear packet data range [data, data_end) which
diff --git a/include/net/sock.h b/include/net/sock.h
index 7093111..b8ff435 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1085,6 +1085,7 @@ struct proto {
#endif
bool (*stream_memory_free)(const struct sock *sk);
+ bool (*stream_memory_read)(const struct sock *sk);
/* Memory pressure */
void (*enter_memory_pressure)(struct sock *sk);
void (*leave_memory_pressure)(struct sock *sk);
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
index 69c5bcc..b30bada 100644
--- a/kernel/bpf/sockmap.c
+++ b/kernel/bpf/sockmap.c
@@ -41,6 +41,8 @@
#include <linux/mm.h>
#include <net/strparser.h>
#include <net/tcp.h>
+#include <linux/ptr_ring.h>
+#include <net/inet_common.h>
#define SOCK_CREATE_FLAG_MASK \
(BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY)
@@ -82,6 +84,7 @@ struct smap_psock {
int sg_size;
int eval;
struct sk_msg_buff *cork;
+ struct list_head ingress;
struct strparser strp;
struct bpf_prog *bpf_tx_msg;
@@ -103,6 +106,8 @@ struct smap_psock {
};
static void smap_release_sock(struct smap_psock *psock, struct sock *sock);
+static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+ int nonblock, int flags, int *addr_len);
static int bpf_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
static int bpf_tcp_sendpage(struct sock *sk, struct page *page,
int offset, size_t size, int flags);
@@ -112,6 +117,21 @@ static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
return rcu_dereference_sk_user_data(sk);
}
+static bool bpf_tcp_stream_read(const struct sock *sk)
+{
+ struct smap_psock *psock;
+ bool empty = true;
+
+ rcu_read_lock();
+ psock = smap_psock_sk(sk);
+ if (unlikely(!psock))
+ goto out;
+ empty = list_empty(&psock->ingress);
+out:
+ rcu_read_unlock();
+ return !empty;
+}
+
static struct proto tcp_bpf_proto;
static int bpf_tcp_init(struct sock *sk)
{
@@ -135,6 +155,8 @@ static int bpf_tcp_init(struct sock *sk)
if (psock->bpf_tx_msg) {
tcp_bpf_proto.sendmsg = bpf_tcp_sendmsg;
tcp_bpf_proto.sendpage = bpf_tcp_sendpage;
+ tcp_bpf_proto.recvmsg = bpf_tcp_recvmsg;
+ tcp_bpf_proto.stream_memory_read = bpf_tcp_stream_read;
}
sk->sk_prot = &tcp_bpf_proto;
@@ -170,6 +192,7 @@ static void bpf_tcp_close(struct sock *sk, long timeout)
{
void (*close_fun)(struct sock *sk, long timeout);
struct smap_psock_map_entry *e, *tmp;
+ struct sk_msg_buff *md, *mtmp;
struct smap_psock *psock;
struct sock *osk;
@@ -188,6 +211,12 @@ static void bpf_tcp_close(struct sock *sk, long timeout)
close_fun = psock->save_close;
write_lock_bh(&sk->sk_callback_lock);
+ list_for_each_entry_safe(md, mtmp, &psock->ingress, list) {
+ list_del(&md->list);
+ free_start_sg(psock->sock, md);
+ kfree(md);
+ }
+
list_for_each_entry_safe(e, tmp, &psock->maps, list) {
osk = cmpxchg(e->entry, sk, NULL);
if (osk == sk) {
@@ -468,6 +497,72 @@ static unsigned int smap_do_tx_msg(struct sock *sk,
return _rc;
}
+static int bpf_tcp_ingress(struct sock *sk, int apply_bytes,
+ struct smap_psock *psock,
+ struct sk_msg_buff *md, int flags)
+{
+ bool apply = apply_bytes;
+ size_t size, copied = 0;
+ struct sk_msg_buff *r;
+ int err = 0, i;
+
+ r = kzalloc(sizeof(struct sk_msg_buff), __GFP_NOWARN | GFP_KERNEL);
+ if (unlikely(!r))
+ return -ENOMEM;
+
+ lock_sock(sk);
+ r->sg_start = md->sg_start;
+ i = md->sg_start;
+
+ do {
+ r->sg_data[i] = md->sg_data[i];
+
+ size = (apply && apply_bytes < md->sg_data[i].length) ?
+ apply_bytes : md->sg_data[i].length;
+
+ if (!sk_wmem_schedule(sk, size)) {
+ if (!copied)
+ err = -ENOMEM;
+ break;
+ }
+
+ sk_mem_charge(sk, size);
+ r->sg_data[i].length = size;
+ md->sg_data[i].length -= size;
+ md->sg_data[i].offset += size;
+ copied += size;
+
+ if (md->sg_data[i].length) {
+ get_page(sg_page(&r->sg_data[i]));
+ r->sg_end = (i + 1) == MAX_SKB_FRAGS ? 0 : i + 1;
+ } else {
+ i++;
+ if (i == MAX_SKB_FRAGS)
+ i = 0;
+ r->sg_end = i;
+ }
+
+ if (apply) {
+ apply_bytes -= size;
+ if (!apply_bytes)
+ break;
+ }
+ } while (i != md->sg_end);
+
+ md->sg_start = i;
+
+ if (!err) {
+ list_add_tail(&r->list, &psock->ingress);
+ sk->sk_data_ready(sk);
+ } else {
+ free_start_sg(sk, r);
+ kfree(r);
+ }
+
+ release_sock(sk);
+ return err;
+}
+
static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send,
struct sk_msg_buff *md,
int flags)
@@ -475,6 +570,7 @@ static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send,
struct smap_psock *psock;
struct scatterlist *sg;
int i, err, free = 0;
+ bool ingress = !!(md->flags & BPF_F_INGRESS);
sg = md->sg_data;
@@ -487,9 +583,14 @@ static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send,
goto out_rcu;
rcu_read_unlock();
- lock_sock(sk);
- err = bpf_tcp_push(sk, send, md, flags, false);
- release_sock(sk);
+
+ if (ingress) {
+ err = bpf_tcp_ingress(sk, send, psock, md, flags);
+ } else {
+ lock_sock(sk);
+ err = bpf_tcp_push(sk, send, md, flags, false);
+ release_sock(sk);
+ }
smap_release_sock(psock, sk);
if (unlikely(err))
goto out;
@@ -623,6 +724,89 @@ static int bpf_exec_tx_verdict(struct smap_psock *psock,
return err;
}
+static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+ int nonblock, int flags, int *addr_len)
+{
+ struct iov_iter *iter = &msg->msg_iter;
+ struct smap_psock *psock;
+ int copied = 0;
+
+ if (unlikely(flags & MSG_ERRQUEUE))
+ return inet_recv_error(sk, msg, len, addr_len);
+
+ rcu_read_lock();
+ psock = smap_psock_sk(sk);
+ if (unlikely(!psock))
+ goto out;
+
+ if (unlikely(!refcount_inc_not_zero(&psock->refcnt)))
+ goto out;
+
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ goto out;
+ rcu_read_unlock();
+
+ lock_sock(sk);
+ while (copied != len) {
+ struct scatterlist *sg;
+ struct sk_msg_buff *md;
+ int i;
+
+ md = list_first_entry_or_null(&psock->ingress,
+ struct sk_msg_buff, list);
+ if (unlikely(!md))
+ break;
+ i = md->sg_start;
+ do {
+ struct page *page;
+ int n, copy;
+
+ sg = &md->sg_data[i];
+ copy = sg->length;
+ page = sg_page(sg);
+
+ if (copied + copy > len)
+ copy = len - copied;
+
+ n = copy_page_to_iter(page, sg->offset, copy, iter);
+ if (n != copy) {
+ md->sg_start = i;
+ release_sock(sk);
+ smap_release_sock(psock, sk);
+ return -EFAULT;
+ }
+
+ copied += copy;
+ sg->offset += copy;
+ sg->length -= copy;
+ sk_mem_uncharge(sk, copy);
+
+ if (!sg->length) {
+ i++;
+ if (i == MAX_SKB_FRAGS)
+ i = 0;
+ put_page(page);
+ }
+ if (copied == len)
+ break;
+ } while (i != md->sg_end);
+ md->sg_start = i;
+
+ if (!sg->length && md->sg_start == md->sg_end) {
+ list_del(&md->list);
+ kfree(md);
+ }
+ }
+
+ release_sock(sk);
+ smap_release_sock(psock, sk);
+ return copied;
+out:
+ rcu_read_unlock();
+ return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
+}
+
+
static int bpf_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
{
int flags = msg->msg_flags | MSG_NO_SHARED_FRAGS;
@@ -1107,6 +1291,7 @@ static void sock_map_remove_complete(struct bpf_stab *stab)
static void smap_gc_work(struct work_struct *w)
{
struct smap_psock_map_entry *e, *tmp;
+ struct sk_msg_buff *md, *mtmp;
struct smap_psock *psock;
psock = container_of(w, struct smap_psock, gc_work);
@@ -1131,6 +1316,12 @@ static void smap_gc_work(struct work_struct *w)
kfree(psock->cork);
}
+ list_for_each_entry_safe(md, mtmp, &psock->ingress, list) {
+ list_del(&md->list);
+ free_start_sg(psock->sock, md);
+ kfree(md);
+ }
+
list_for_each_entry_safe(e, tmp, &psock->maps, list) {
list_del(&e->list);
kfree(e);
@@ -1160,6 +1351,7 @@ static struct smap_psock *smap_init_psock(struct sock *sock,
INIT_WORK(&psock->tx_work, smap_tx_work);
INIT_WORK(&psock->gc_work, smap_gc_work);
INIT_LIST_HEAD(&psock->maps);
+ INIT_LIST_HEAD(&psock->ingress);
refcount_set(&psock->refcnt, 1);
rcu_assign_sk_user_data(sock, psock);
diff --git a/net/core/filter.c b/net/core/filter.c
index 00c711c..11b1f16 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1894,7 +1894,7 @@ struct sock *do_sk_redirect_map(struct sk_buff *skb)
struct bpf_map *, map, u32, key, u64, flags)
{
/* If user passes invalid input drop the packet. */
- if (unlikely(flags))
+ if (unlikely(flags & ~(BPF_F_INGRESS)))
return SK_DROP;
msg->key = key;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0c31be3..bccc4c2 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -485,6 +485,14 @@ static void tcp_tx_timestamp(struct sock *sk, u16 tsflags)
}
}
+static inline bool tcp_stream_is_readable(const struct tcp_sock *tp,
+ int target, struct sock *sk)
+{
+ return (tp->rcv_nxt - tp->copied_seq >= target) ||
+ (sk->sk_prot->stream_memory_read ?
+ sk->sk_prot->stream_memory_read(sk) : false);
+}
+
/*
* Wait for a TCP event.
*
@@ -554,7 +562,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
tp->urg_data)
target++;
- if (tp->rcv_nxt - tp->copied_seq >= target)
+ if (tcp_stream_is_readable(tp, target, sk))
mask |= EPOLLIN | EPOLLRDNORM;
if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
^ permalink raw reply related
* [bpf-next PATCH v2 2/4] bpf: sockmap, add BPF_F_INGRESS tests
From: John Fastabend @ 2018-03-27 17:23 UTC (permalink / raw)
To: ast, daniel; +Cc: netdev, davem
In-Reply-To: <20180327172042.11354.81872.stgit@john-Precision-Tower-5810>
Add a set of tests to verify ingress flag in redirect helpers
works correctly with various msg sizes.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_kern.c | 41 +++++++++++++++++++++++++++++----------
samples/sockmap/sockmap_test.sh | 22 ++++++++++++++++++++-
samples/sockmap/sockmap_user.c | 35 +++++++++++++++++++++++++++++++++
3 files changed, 87 insertions(+), 11 deletions(-)
diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c
index 9ad5ba7..ca28722 100644
--- a/samples/sockmap/sockmap_kern.c
+++ b/samples/sockmap/sockmap_kern.c
@@ -54,7 +54,7 @@ struct bpf_map_def SEC("maps") sock_map_redir = {
.type = BPF_MAP_TYPE_SOCKMAP,
.key_size = sizeof(int),
.value_size = sizeof(int),
- .max_entries = 1,
+ .max_entries = 20,
};
struct bpf_map_def SEC("maps") sock_apply_bytes = {
@@ -78,6 +78,13 @@ struct bpf_map_def SEC("maps") sock_pull_bytes = {
.max_entries = 2
};
+struct bpf_map_def SEC("maps") sock_redir_flags = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(int),
+ .value_size = sizeof(int),
+ .max_entries = 1
+};
+
SEC("sk_skb1")
int bpf_prog1(struct __sk_buff *skb)
@@ -197,8 +204,9 @@ int bpf_prog5(struct sk_msg_md *msg)
SEC("sk_msg3")
int bpf_prog6(struct sk_msg_md *msg)
{
- int *bytes, zero = 0, one = 1;
- int *start, *end;
+ int *bytes, zero = 0, one = 1, key = 0;
+ int *start, *end, *f;
+ __u64 flags = 0;
bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
if (bytes)
@@ -210,15 +218,22 @@ int bpf_prog6(struct sk_msg_md *msg)
end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
if (start && end)
bpf_msg_pull_data(msg, *start, *end, 0);
- return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
+ f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
+ if (f && *f) {
+ key = 2;
+ flags = *f;
+ }
+ return bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
}
SEC("sk_msg4")
int bpf_prog7(struct sk_msg_md *msg)
{
- int err1 = 0, err2 = 0, zero = 0, one = 1;
- int *bytes, *start, *end, len1, len2;
+ int err1 = 0, err2 = 0, zero = 0, one = 1, key = 0;
+ int *f, *bytes, *start, *end, len1, len2;
+ __u64 flags = 0;
+ int err;
bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
if (bytes)
err1 = bpf_msg_apply_bytes(msg, *bytes);
@@ -229,7 +244,6 @@ int bpf_prog7(struct sk_msg_md *msg)
start = bpf_map_lookup_elem(&sock_pull_bytes, &zero);
end = bpf_map_lookup_elem(&sock_pull_bytes, &one);
if (start && end) {
- int err;
bpf_printk("sk_msg2: pull(%i:%i)\n",
start ? *start : 0, end ? *end : 0);
@@ -241,9 +255,16 @@ int bpf_prog7(struct sk_msg_md *msg)
bpf_printk("sk_msg2: length update %i->%i\n",
len1, len2);
}
- bpf_printk("sk_msg3: redirect(%iB) err1=%i err2=%i\n",
- len1, err1, err2);
- return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
+ f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
+ if (f && *f) {
+ key = 2;
+ flags = *f;
+ }
+ bpf_printk("sk_msg3: redirect(%iB) flags=%i err=%i\n",
+ len1, flags, err1 ? err1 : err2);
+ err = bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
+ bpf_printk("sk_msg3: err %i\n", err);
+ return err;
}
SEC("sk_msg5")
diff --git a/samples/sockmap/sockmap_test.sh b/samples/sockmap/sockmap_test.sh
index 6d8cc40..13b205f 100755
--- a/samples/sockmap/sockmap_test.sh
+++ b/samples/sockmap/sockmap_test.sh
@@ -1,5 +1,5 @@
#Test a bunch of positive cases to verify basic functionality
-for prog in "--txmsg" "--txmsg_redir" "--txmsg_drop"; do
+for prog in "--txmsg_redir --txmsg_ingress" "--txmsg" "--txmsg_redir" "--txmsg_redir --txmsg_ingress" "--txmsg_drop"; do
for t in "sendmsg" "sendpage"; do
for r in 1 10 100; do
for i in 1 10 100; do
@@ -100,6 +100,16 @@ for t in "sendmsg" "sendpage"; do
sleep 2
done
+prog="--txmsg_redir --txmsg_apply 1 --txmsg_ingress"
+
+for t in "sendmsg" "sendpage"; do
+ TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
+ echo $TEST
+ $TEST
+ sleep 2
+done
+
+
# Test apply and redirect with larger value than send
r=1
i=8
@@ -113,6 +123,16 @@ for t in "sendmsg" "sendpage"; do
sleep 2
done
+prog="--txmsg_redir --txmsg_apply 2048 --txmsg_ingress"
+
+for t in "sendmsg" "sendpage"; do
+ TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
+ echo $TEST
+ $TEST
+ sleep 2
+done
+
+
# Test apply and redirect with apply that never reaches limit
r=1024
i=1
diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c
index 07aa237..f7503f4 100644
--- a/samples/sockmap/sockmap_user.c
+++ b/samples/sockmap/sockmap_user.c
@@ -64,6 +64,7 @@
int txmsg_cork;
int txmsg_start;
int txmsg_end;
+int txmsg_ingress;
static const struct option long_options[] = {
{"help", no_argument, NULL, 'h' },
@@ -83,6 +84,7 @@
{"txmsg_cork", required_argument, NULL, 'k'},
{"txmsg_start", required_argument, NULL, 's'},
{"txmsg_end", required_argument, NULL, 'e'},
+ {"txmsg_ingress", no_argument, &txmsg_ingress, 1 },
{0, 0, NULL, 0 }
};
@@ -793,6 +795,39 @@ int main(int argc, char **argv)
return err;
}
}
+
+ if (txmsg_ingress) {
+ int in = BPF_F_INGRESS;
+
+ i = 0;
+ err = bpf_map_update_elem(map_fd[6], &i, &in, BPF_ANY);
+ if (err) {
+ fprintf(stderr,
+ "ERROR: bpf_map_update_elem (txmsg_ingress): %d (%s)\n",
+ err, strerror(errno));
+ }
+ i = 1;
+ err = bpf_map_update_elem(map_fd[1], &i, &p1, BPF_ANY);
+ if (err) {
+ fprintf(stderr,
+ "ERROR: bpf_map_update_elem (p1 txmsg): %d (%s)\n",
+ err, strerror(errno));
+ }
+ err = bpf_map_update_elem(map_fd[2], &i, &p1, BPF_ANY);
+ if (err) {
+ fprintf(stderr,
+ "ERROR: bpf_map_update_elem (p1 redir): %d (%s)\n",
+ err, strerror(errno));
+ }
+
+ i = 2;
+ err = bpf_map_update_elem(map_fd[2], &i, &p2, BPF_ANY);
+ if (err) {
+ fprintf(stderr,
+ "ERROR: bpf_map_update_elem (p2 txmsg): %d (%s)\n",
+ err, strerror(errno));
+ }
+ }
}
if (txmsg_drop)
^ permalink raw reply related
* [bpf-next PATCH v2 3/4] bpf: sockmap, BPF_F_INGRESS flag for BPF_SK_SKB_STREAM_VERDICT:
From: John Fastabend @ 2018-03-27 17:23 UTC (permalink / raw)
To: ast, daniel; +Cc: netdev, davem
In-Reply-To: <20180327172042.11354.81872.stgit@john-Precision-Tower-5810>
Add support for the BPF_F_INGRESS flag in skb redirect helper. To
do this convert skb into a scatterlist and push into ingress queue.
This is the same logic that is used in the sk_msg redirect helper
so it should feel familiar.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
include/linux/filter.h | 1 +
kernel/bpf/sockmap.c | 94 +++++++++++++++++++++++++++++++++++++++---------
net/core/filter.c | 2 +
3 files changed, 78 insertions(+), 19 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h
index d0e207f..7de778a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -521,6 +521,7 @@ struct sk_msg_buff {
__u32 key;
__u32 flags;
struct bpf_map *map;
+ struct sk_buff *skb;
struct list_head list;
};
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
index b30bada..b52e1c4 100644
--- a/kernel/bpf/sockmap.c
+++ b/kernel/bpf/sockmap.c
@@ -785,7 +785,8 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
i++;
if (i == MAX_SKB_FRAGS)
i = 0;
- put_page(page);
+ if (!md->skb)
+ put_page(page);
}
if (copied == len)
break;
@@ -794,6 +795,8 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
if (!sg->length && md->sg_start == md->sg_end) {
list_del(&md->list);
+ if (md->skb)
+ consume_skb(md->skb);
kfree(md);
}
}
@@ -1045,27 +1048,72 @@ static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
__SK_DROP;
}
+static int smap_do_ingress(struct smap_psock *psock, struct sk_buff *skb)
+{
+ struct sock *sk = psock->sock;
+ int copied = 0, num_sg;
+ struct sk_msg_buff *r;
+
+ r = kzalloc(sizeof(struct sk_msg_buff), __GFP_NOWARN | GFP_ATOMIC);
+ if (unlikely(!r))
+ return -EAGAIN;
+
+ if (!sk_rmem_schedule(sk, skb, skb->len)) {
+ kfree(r);
+ return -EAGAIN;
+ }
+ sk_mem_charge(sk, skb->len);
+
+ sg_init_table(r->sg_data, MAX_SKB_FRAGS);
+ num_sg = skb_to_sgvec(skb, r->sg_data, 0, skb->len);
+ if (unlikely(num_sg < 0)) {
+ kfree(r);
+ return num_sg;
+ }
+ copied = skb->len;
+ r->sg_start = 0;
+ r->sg_end = num_sg == MAX_SKB_FRAGS ? 0 : num_sg;
+ r->skb = skb;
+ list_add_tail(&r->list, &psock->ingress);
+ sk->sk_data_ready(sk);
+ return copied;
+}
+
static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
{
+ struct smap_psock *peer;
struct sock *sk;
+ __u32 in;
int rc;
rc = smap_verdict_func(psock, skb);
switch (rc) {
case __SK_REDIRECT:
sk = do_sk_redirect_map(skb);
- if (likely(sk)) {
- struct smap_psock *peer = smap_psock_sk(sk);
-
- if (likely(peer &&
- test_bit(SMAP_TX_RUNNING, &peer->state) &&
- !sock_flag(sk, SOCK_DEAD) &&
- sock_writeable(sk))) {
- skb_set_owner_w(skb, sk);
- skb_queue_tail(&peer->rxqueue, skb);
- schedule_work(&peer->tx_work);
- break;
- }
+ if (!sk) {
+ kfree_skb(skb);
+ break;
+ }
+
+ peer = smap_psock_sk(sk);
+ in = (TCP_SKB_CB(skb)->bpf.flags) & BPF_F_INGRESS;
+
+ if (unlikely(!peer || sock_flag(sk, SOCK_DEAD) ||
+ !test_bit(SMAP_TX_RUNNING, &peer->state))) {
+ kfree_skb(skb);
+ break;
+ }
+
+ if (!in && sock_writeable(sk)) {
+ skb_set_owner_w(skb, sk);
+ skb_queue_tail(&peer->rxqueue, skb);
+ schedule_work(&peer->tx_work);
+ break;
+ } else if (in &&
+ atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) {
+ skb_queue_tail(&peer->rxqueue, skb);
+ schedule_work(&peer->tx_work);
+ break;
}
/* Fall through and free skb otherwise */
case __SK_DROP:
@@ -1127,15 +1175,23 @@ static void smap_tx_work(struct work_struct *w)
}
while ((skb = skb_dequeue(&psock->rxqueue))) {
+ __u32 flags;
+
rem = skb->len;
off = 0;
start:
+ flags = (TCP_SKB_CB(skb)->bpf.flags) & BPF_F_INGRESS;
do {
- if (likely(psock->sock->sk_socket))
- n = skb_send_sock_locked(psock->sock,
- skb, off, rem);
- else
+ if (likely(psock->sock->sk_socket)) {
+ if (flags)
+ n = smap_do_ingress(psock, skb);
+ else
+ n = skb_send_sock_locked(psock->sock,
+ skb, off, rem);
+ } else {
n = -EINVAL;
+ }
+
if (n <= 0) {
if (n == -EAGAIN) {
/* Retry when space is available */
@@ -1153,7 +1209,9 @@ static void smap_tx_work(struct work_struct *w)
rem -= n;
off += n;
} while (rem);
- kfree_skb(skb);
+
+ if (!flags)
+ kfree_skb(skb);
}
out:
release_sock(psock->sock);
diff --git a/net/core/filter.c b/net/core/filter.c
index 11b1f16..b46916d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1855,7 +1855,7 @@ int skb_do_redirect(struct sk_buff *skb)
struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
/* If user passes invalid input drop the packet. */
- if (unlikely(flags))
+ if (unlikely(flags & ~(BPF_F_INGRESS)))
return SK_DROP;
tcb->bpf.key = key;
^ permalink raw reply related
* [bpf-next PATCH v2 4/4] bpf: sockmap, more BPF_SK_SKB_STREAM_VERDICT tests
From: John Fastabend @ 2018-03-27 17:23 UTC (permalink / raw)
To: ast, daniel; +Cc: netdev, davem
In-Reply-To: <20180327172042.11354.81872.stgit@john-Precision-Tower-5810>
Add BPF_SK_SKB_STREAM_VERDICT tests for ingress hook. While
we do this also bring stream tests in-line with MSG based
testing.
A map for skb options is added for userland to push options
at BPF programs.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_kern.c | 21 ++++++++++++++++++---
samples/sockmap/sockmap_test.sh | 20 +++++++++++++++++++-
samples/sockmap/sockmap_user.c | 23 +++++++++++++++++++++++
3 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c
index ca28722..9ff8bc5 100644
--- a/samples/sockmap/sockmap_kern.c
+++ b/samples/sockmap/sockmap_kern.c
@@ -85,6 +85,12 @@ struct bpf_map_def SEC("maps") sock_redir_flags = {
.max_entries = 1
};
+struct bpf_map_def SEC("maps") sock_skb_opts = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(int),
+ .value_size = sizeof(int),
+ .max_entries = 1
+};
SEC("sk_skb1")
int bpf_prog1(struct __sk_buff *skb)
@@ -97,15 +103,24 @@ int bpf_prog2(struct __sk_buff *skb)
{
__u32 lport = skb->local_port;
__u32 rport = skb->remote_port;
- int ret = 0;
+ int len, *f, ret, zero = 0;
+ __u64 flags = 0;
if (lport == 10000)
ret = 10;
else
ret = 1;
- bpf_printk("sockmap: %d -> %d @ %d\n", lport, bpf_ntohl(rport), ret);
- return bpf_sk_redirect_map(skb, &sock_map, ret, 0);
+ len = (__u32)skb->data_end - (__u32)skb->data;
+ f = bpf_map_lookup_elem(&sock_skb_opts, &zero);
+ if (f && *f) {
+ ret = 3;
+ flags = *f;
+ }
+
+ bpf_printk("sk_skb2: redirect(%iB) flags=%i\n",
+ len, flags);
+ return bpf_sk_redirect_map(skb, &sock_map, ret, flags);
}
SEC("sockops")
diff --git a/samples/sockmap/sockmap_test.sh b/samples/sockmap/sockmap_test.sh
index 13b205f..ace75f0 100755
--- a/samples/sockmap/sockmap_test.sh
+++ b/samples/sockmap/sockmap_test.sh
@@ -1,5 +1,5 @@
#Test a bunch of positive cases to verify basic functionality
-for prog in "--txmsg_redir --txmsg_ingress" "--txmsg" "--txmsg_redir" "--txmsg_redir --txmsg_ingress" "--txmsg_drop"; do
+for prog in "--txmsg_redir --txmsg_skb" "--txmsg_redir --txmsg_ingress" "--txmsg" "--txmsg_redir" "--txmsg_redir --txmsg_ingress" "--txmsg_drop"; do
for t in "sendmsg" "sendpage"; do
for r in 1 10 100; do
for i in 1 10 100; do
@@ -109,6 +109,15 @@ for t in "sendmsg" "sendpage"; do
sleep 2
done
+prog="--txmsg_redir --txmsg_apply 1 --txmsg_skb"
+
+for t in "sendmsg" "sendpage"; do
+ TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
+ echo $TEST
+ $TEST
+ sleep 2
+done
+
# Test apply and redirect with larger value than send
r=1
@@ -132,6 +141,15 @@ for t in "sendmsg" "sendpage"; do
sleep 2
done
+prog="--txmsg_redir --txmsg_apply 2048 --txmsg_skb"
+
+for t in "sendmsg" "sendpage"; do
+ TEST="./sockmap --cgroup /mnt/cgroup2/ -t $t -r $r -i $i -l $l $prog"
+ echo $TEST
+ $TEST
+ sleep 2
+done
+
# Test apply and redirect with apply that never reaches limit
r=1024
diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c
index f7503f4..6f23349 100644
--- a/samples/sockmap/sockmap_user.c
+++ b/samples/sockmap/sockmap_user.c
@@ -65,6 +65,7 @@
int txmsg_start;
int txmsg_end;
int txmsg_ingress;
+int txmsg_skb;
static const struct option long_options[] = {
{"help", no_argument, NULL, 'h' },
@@ -85,6 +86,7 @@
{"txmsg_start", required_argument, NULL, 's'},
{"txmsg_end", required_argument, NULL, 'e'},
{"txmsg_ingress", no_argument, &txmsg_ingress, 1 },
+ {"txmsg_skb", no_argument, &txmsg_skb, 1 },
{0, 0, NULL, 0 }
};
@@ -828,6 +830,27 @@ int main(int argc, char **argv)
err, strerror(errno));
}
}
+
+ if (txmsg_skb) {
+ int skb_fd = (test == SENDMSG || test == SENDPAGE) ? p2 : p1;
+ int ingress = BPF_F_INGRESS;
+
+ i = 0;
+ err = bpf_map_update_elem(map_fd[7], &i, &ingress, BPF_ANY);
+ if (err) {
+ fprintf(stderr,
+ "ERROR: bpf_map_update_elem (txmsg_ingress): %d (%s)\n",
+ err, strerror(errno));
+ }
+
+ i = 3;
+ err = bpf_map_update_elem(map_fd[0], &i, &skb_fd, BPF_ANY);
+ if (err) {
+ fprintf(stderr,
+ "ERROR: bpf_map_update_elem (c1 sockmap): %d (%s)\n",
+ err, strerror(errno));
+ }
+ }
}
if (txmsg_drop)
^ permalink raw reply related
* Re: linux-next: manual merge of the ipsec tree with the net tree
From: Stefano Brivio @ 2018-03-27 17:23 UTC (permalink / raw)
To: Petr Machata, Stephen Rothwell, Steffen Klassert
Cc: David Miller, Networking, Linux-Next Mailing List,
Linux Kernel Mailing List
In-Reply-To: <wih7epx8u60.fsf@dev-r-vrt-156.mtr.labs.mlnx>
On Tue, 27 Mar 2018 17:33:43 +0300
Petr Machata <petrm@mellanox.com> wrote:
> Hi, this conflict needs to be resolved differently. Below I'm adding a
> patch on top of linux-next. Squash or apply as you see fit.
Petr, thanks for spotting this. Stephen, you can carry these tags for
Petr's patch:
Fixes: adab890d00dc ("Merge remote-tracking branch 'ipsec/master'")
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Tested-by: Stefano Brivio <sbrivio@redhat.com>
> What's the right way to proceed from here? It looks to me like Stefano
> or Steffen should take this into the ipsec tree (possibly just squash to
> the clamping fix), as they'll hit this conflict the next time they
> rebase on top of net...? Let me know what to do, please.
Steffen, please let me know if you want me to submit anything for the
ipsec tree on top of my previous patches.
I guess another alternative would be that David fixes the conflict the
way Petr solved it, when merging to net?
--
Stefano
^ permalink raw reply
* Re: [PATCH 0/7] net: thunderx: implement DMAC filtering support
From: David Miller @ 2018-03-27 17:28 UTC (permalink / raw)
To: Vadim.Lomovtsev
Cc: sgoutham, sunil.kovvuri, robert.richter, linux-arm-kernel, netdev,
linux-kernel, dnelson, Vadim.Lomovtsev
In-Reply-To: <20180327150736.10718-1-Vadim.Lomovtsev@caviumnetworks.com>
From: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
Date: Tue, 27 Mar 2018 08:07:29 -0700
> From: Vadim Lomovtsev <Vadim.Lomovtsev@cavium.com>
>
> By default CN88XX BGX accepts all incoming multicast and broadcast
> packets and filtering is disabled. The nic driver doesn't provide
> an ability to change such behaviour.
>
> This series is to implement DMAC filtering management for CN88XX
> nic driver allowing user to enable/disable filtering and configure
> specific MAC addresses to filter traffic.
This doesn't even compile:
drivers/net/ethernet/cavium/thunder/thunder_bgx.c: In function ‘bgx_lmac_save_filter’:
drivers/net/ethernet/cavium/thunder/thunder_bgx.c:286:3: warning: ‘return’ with no value, in function returning non-void [-Wreturn-type]
return;
^~~~~~
drivers/net/ethernet/cavium/thunder/thunder_bgx.c:281:12: note: declared here
static int bgx_lmac_save_filter(struct lmac *lmac, u64 dmac, u8 vf_id)
^~~~~~~~~~~~~~~~~~~~
In file included from drivers/net/ethernet/cavium/thunder/nic.h:15:0,
from drivers/net/ethernet/cavium/thunder/thunder_bgx.c:21:
drivers/net/ethernet/cavium/thunder/thunder_bgx.c: In function ‘bgx_set_dmac_cam_filter_mac’:
drivers/net/ethernet/cavium/thunder/thunder_bgx.h:61:38: warning: left shift count >= width of type [-Wshift-count-overflow]
#define RX_DMACX_CAM_LMACID(x) (x << 49)
^
drivers/net/ethernet/cavium/thunder/thunder_bgx.c:324:8: note: in expansion of macro ‘RX_DMACX_CAM_LMACID’
cfg = RX_DMACX_CAM_LMACID(lmacid & LMAC_ID_MASK) |
^~~~~~~~~~~~~~~~~~~
^ permalink raw reply
* Re: [PATCH v2 net] strparser: Fix sign of err codes
From: David Miller @ 2018-03-27 17:29 UTC (permalink / raw)
To: davejwatson; +Cc: tom, netdev
In-Reply-To: <20180327152352.GA35552@davejwatson-mba.local>
From: Dave Watson <davejwatson@fb.com>
Date: Tue, 27 Mar 2018 08:23:52 -0700
> strp_parser_err is called with a negative code everywhere, which then
> calls abort_parser with a negative code. strp_msg_timeout calls
> abort_parser directly with a positive code. Negate ETIMEDOUT
> to match signed-ness of other calls.
>
> The default abort_parser callback, strp_abort_strp, sets
> sk->sk_err to err. Also negate the error here so sk_err always
> holds a positive value, as the rest of the net code expects. Currently
> a negative sk_err can result in endless loops, or user code that
> thinks it actually sent/received err bytes.
>
> Found while testing net/tls_sw recv path.
>
> Fixes: 43a0c6751a322847 ("strparser: Stream parser for messages")
> Signed-off-by: Dave Watson <davejwatson@fb.com>
Your v1 patch was already applied to my net tree, so you'll have to
send any further changes as a relative patch.
^ permalink raw reply
* Re: [net-next PATCH v2 05/10] net: netcp: ethss: use rgmii link status for 2u cpsw hardware
From: Andrew Lunn @ 2018-03-27 17:29 UTC (permalink / raw)
To: Murali Karicheri
Cc: robh+dt, mark.rutland, ssantosh, malat, w-kwok2, devicetree,
linux-kernel, linux-arm-kernel, davem, netdev
In-Reply-To: <1522168309-12338-6-git-send-email-m-karicheri2@ti.com>
On Tue, Mar 27, 2018 at 12:31:44PM -0400, Murali Karicheri wrote:
> Introduce rgmii link status to handle link state events for 2u
> cpsw hardware on K2G.
>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> ---
> drivers/net/ethernet/ti/netcp_ethss.c | 27 +++++++++++++++++++++++----
> 1 file changed, 23 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c
> index ab9d369..078a1b8 100644
> --- a/drivers/net/ethernet/ti/netcp_ethss.c
> +++ b/drivers/net/ethernet/ti/netcp_ethss.c
> @@ -552,6 +552,7 @@ struct gbe_ss_regs {
> struct gbe_ss_regs_ofs {
> u16 id_ver;
> u16 control;
> + u16 rgmii_status; /* 2U */
> };
>
> struct gbe_switch_regs {
> @@ -2120,23 +2121,39 @@ static bool gbe_phy_link_status(struct gbe_slave *slave)
> return !slave->phy || slave->phy->link;
> }
>
> +#define RGMII_REG_STATUS_LINK BIT(0)
> +
> +static void netcp_2u_rgmii_get_port_link(struct gbe_priv *gbe_dev, bool *status)
> +{
> + u32 val = 0;
> +
> + val = readl(GBE_REG_ADDR(gbe_dev, ss_regs, rgmii_status));
> + *status = false;
> + if ((val & RGMII_REG_STATUS_LINK) != 0)
> + *status = true;
*status = !!(val & RGMII_REG_STATUS_LINK);
> +}
> +
> static void netcp_ethss_update_link_state(struct gbe_priv *gbe_dev,
> struct gbe_slave *slave,
> struct net_device *ndev)
> {
> - int sp = slave->slave_num;
> - int phy_link_state, sgmii_link_state = 1, link_state;
> + bool sw_link_state = true, phy_link_state;
> + int sp = slave->slave_num, link_state;
>
> if (!slave->open)
> return;
>
> if (!SLAVE_LINK_IS_XGMII(slave)) {
> - sgmii_link_state =
> + if (SLAVE_LINK_IS_RGMII(slave))
> + netcp_2u_rgmii_get_port_link(gbe_dev,
> + &sw_link_state);
> + else
> + sw_link_state =
> netcp_sgmii_get_port_link(SGMII_BASE(gbe_dev, sp), sp);
This would be more readable as
if (SLAVE_LINK_IS_RGMII(slave))
netcp_2u_rgmii_get_port_link(gbe_dev,
&sw_link_state);
if (SLAVE_LINK_IS_SGMII(slave))
sw_link_state = netcp_sgmii_get_port_link(
SGMII_BASE(gbe_dev, sp), sp);
Andrew
^ permalink raw reply
* Re: [PATCH v7 0/7] netdev: intel: Eliminate duplicate barriers on weakly-ordered archs
From: Sinan Kaya @ 2018-03-27 17:33 UTC (permalink / raw)
To: jeffrey.t.kirsher
Cc: Alexander Duyck, intel-wired-lan, Netdev, Timur Tabi, sulrich,
linux-arm-msm, linux-arm-kernel
In-Reply-To: <1522169657.6503.1.camel@intel.com>
On 3/27/2018 12:54 PM, Jeff Kirsher wrote:
> On Tue, 2018-03-27 at 08:42 -0400, Sinan Kaya wrote:
>> On 3/23/2018 10:34 PM, okaya@codeaurora.org wrote:
>>> On 2018-03-23 19:58, Jeff Kirsher wrote:
>>>> On Fri, 2018-03-23 at 14:53 -0700, Alexander Duyck wrote:
>>>>> On Fri, Mar 23, 2018 at 11:52 AM, Sinan Kaya <okaya@codeaurora.
>>>>> org>
>>>>> wrote:
>>>>>> Code includes wmb() followed by writel() in multiple places.
>>>>>> writel()
>>>>>> already has a barrier on some architectures like arm64.
>>>>>>
>>>>>> This ends up CPU observing two barriers back to back before
>>>>>> executing
>>>>>> the
>>>>>> register write.
>>>>>>
>>>>>> Since code already has an explicit barrier call, changing
>>>>>> writel() to
>>>>>> writel_relaxed().
>>>>>>
>>>>>> I did a regex search for wmb() followed by writel() in each
>>>>>> drivers
>>>>>> directory.
>>>>>> I scrubbed the ones I care about in this series.
>>>>>>
>>>>>> I considered "ease of change", "popular usage" and
>>>>>> "performance
>>>>>> critical
>>>>>> path" as the determining criteria for my filtering.
>>>>>>
>>>>>> We used relaxed API heavily on ARM for a long time but
>>>>>> it did not exist on other architectures. For this reason,
>>>>>> relaxed
>>>>>> architectures have been paying double penalty in order to use
>>>>>> the
>>>>>> common
>>>>>> drivers.
>>>>>>
>>>>>> Now that relaxed API is present on all architectures, we can
>>>>>> go and
>>>>>> scrub
>>>>>> all drivers to see what needs to change and what can remain.
>>>>>>
>>>>>> We start with mostly used ones and hope to increase the
>>>>>> coverage over
>>>>>> time.
>>>>>> It will take a while to cover all drivers.
>>>>>>
>>>>>> Feel free to apply patches individually.
>>>>>
>>>>> I looked over the set and they seem good.
>>>>>
>>>>> Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com>
>>>>
>>>> Grrr, patch 1 does not apply cleanly to my next-queue tree (dev-
>>>> queue
>>>> branch). I will deal with this series in a day or two, after I
>>>> have dealt
>>>> with my driver pull requests.
>>>
>>> Sorry, you will have to replace the ones you took from me.
>>
>> Double sorry now.
>>
>> I don't know if you have been following "RFC on writel and
>> writel_relaxed" thread
>> or not but there are some new developments about wmb() requirement.
>>
>> Basically, wmb() should never be used before writel() as writel()
>> seem to
>> provide coherency and observability guarantee.
>>
>> wmb()+writel_relaxed() is slower on some architectures than plain
>> writel()
>>
>> I'll have to rework these patches to have writel() only.
>>
>> Are you able to drop the applied ones so that I can post V8 or is it
>> too late?
>
> Currently I do not have any of your patches applied to my next-queue
> tree (dev-queue branch). So feel free to do any revisions you need to
> do and to re-submit to intel-wired-lan@lists.osuosl.org (IWL) mailing
> list.
>
Thanks, Good to know.
I'm waiting for the discussion to settle. I'll update as soon as I get
a clear direction.
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* Re: [PATCH net-next 0/5] Make pernet_operations always read locked
From: Kirill Tkhai @ 2018-03-27 17:34 UTC (permalink / raw)
To: David Miller
Cc: nicolas.dichtel, vyasevic, paulmck, vyasevich, mark.rutland,
leonro, avagin, fw, ebiederm, roman.kapl, dsahern, netdev,
bfields
In-Reply-To: <20180327.131826.868714983333063962.davem@davemloft.net>
On 27.03.2018 20:18, David Miller wrote:
> From: Kirill Tkhai <ktkhai@virtuozzo.com>
> Date: Tue, 27 Mar 2018 18:01:42 +0300
>
>> All the pernet_operations are converted, and the last one
>> is in this patchset (nfsd_net_ops acked by J. Bruce Fields).
>> So, it's the time to kill pernet_operations::async field,
>> and make setup_net() and cleanup_net() always require
>> the rwsem only read locked.
>>
>> All further pernet_operations have to be developed to fit
>> this rule. Some of previous patches added a comment to
>> struct pernet_operations about that.
>>
>> Also, this patchset renames net_sem to pernet_ops_rwsem
>> to make the target area of the rwsem is more clear visible,
>> and adds more comments.
>
> Amazing work, series applied, thanks!
Thanks a lot, David!
Kirill
^ permalink raw reply
* Re: [PATCH net-next 0/6] sfc: rework locking around filter management
From: David Miller @ 2018-03-27 17:34 UTC (permalink / raw)
To: ecree; +Cc: linux-net-drivers, netdev
In-Reply-To: <7a932be7-0335-a7f3-4fb4-408ccb191737@solarflare.com>
From: Edward Cree <ecree@solarflare.com>
Date: Tue, 27 Mar 2018 17:40:11 +0100
> The use of a spinlock to protect filter state combined with the need for a
> sleeping operation (MCDI) to apply that state to the NIC (on EF10) led to
> unfixable race conditions, around the handling of filter restoration after
> an MC reboot.
> So, this patch series removes the requirement to be able to modify the SW
> filter table from atomic context, by using a workqueue to request
> asynchronous filter operations (which are needed for ARFS). Then, the
> filter table locks are changed to mutexes, replacing the dance of spinlocks
> and 'busy' flags. Also, a mutex is added to protect the RSS context state,
> since otherwise a similar race is possible around restoring that after an
> MC reboot. While we're at it, fix a couple of other related bugs.
Series applied, thank you.
^ permalink raw reply
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