* [PATCH AUTOSEL 5.2 24/94] netfilter: xt_nfacct: Fix alignment mismatch in xt_nfacct_match_info
From: Sasha Levin @ 2019-09-04 15:56 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Juliana Rodrigueiro, Florian Westphal, Pablo Neira Ayuso,
Sasha Levin, netfilter-devel, coreteam, netdev
In-Reply-To: <20190904155739.2816-1-sashal@kernel.org>
From: Juliana Rodrigueiro <juliana.rodrigueiro@intra2net.com>
[ Upstream commit 89a26cd4b501e9511d3cd3d22327fc76a75a38b3 ]
When running a 64-bit kernel with a 32-bit iptables binary, the size of
the xt_nfacct_match_info struct diverges.
kernel: sizeof(struct xt_nfacct_match_info) : 40
iptables: sizeof(struct xt_nfacct_match_info)) : 36
Trying to append nfacct related rules results in an unhelpful message.
Although it is suggested to look for more information in dmesg, nothing
can be found there.
# iptables -A <chain> -m nfacct --nfacct-name <acct-object>
iptables: Invalid argument. Run `dmesg' for more information.
This patch fixes the memory misalignment by enforcing 8-byte alignment
within the struct's first revision. This solution is often used in many
other uapi netfilter headers.
Signed-off-by: Juliana Rodrigueiro <juliana.rodrigueiro@intra2net.com>
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/uapi/linux/netfilter/xt_nfacct.h | 5 ++++
net/netfilter/xt_nfacct.c | 36 ++++++++++++++++--------
2 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_nfacct.h b/include/uapi/linux/netfilter/xt_nfacct.h
index 5c8a4d760ee34..b5123ab8d54a8 100644
--- a/include/uapi/linux/netfilter/xt_nfacct.h
+++ b/include/uapi/linux/netfilter/xt_nfacct.h
@@ -11,4 +11,9 @@ struct xt_nfacct_match_info {
struct nf_acct *nfacct;
};
+struct xt_nfacct_match_info_v1 {
+ char name[NFACCT_NAME_MAX];
+ struct nf_acct *nfacct __attribute__((aligned(8)));
+};
+
#endif /* _XT_NFACCT_MATCH_H */
diff --git a/net/netfilter/xt_nfacct.c b/net/netfilter/xt_nfacct.c
index d0ab1adf5bff8..5aab6df74e0f2 100644
--- a/net/netfilter/xt_nfacct.c
+++ b/net/netfilter/xt_nfacct.c
@@ -54,25 +54,39 @@ nfacct_mt_destroy(const struct xt_mtdtor_param *par)
nfnl_acct_put(info->nfacct);
}
-static struct xt_match nfacct_mt_reg __read_mostly = {
- .name = "nfacct",
- .family = NFPROTO_UNSPEC,
- .checkentry = nfacct_mt_checkentry,
- .match = nfacct_mt,
- .destroy = nfacct_mt_destroy,
- .matchsize = sizeof(struct xt_nfacct_match_info),
- .usersize = offsetof(struct xt_nfacct_match_info, nfacct),
- .me = THIS_MODULE,
+static struct xt_match nfacct_mt_reg[] __read_mostly = {
+ {
+ .name = "nfacct",
+ .revision = 0,
+ .family = NFPROTO_UNSPEC,
+ .checkentry = nfacct_mt_checkentry,
+ .match = nfacct_mt,
+ .destroy = nfacct_mt_destroy,
+ .matchsize = sizeof(struct xt_nfacct_match_info),
+ .usersize = offsetof(struct xt_nfacct_match_info, nfacct),
+ .me = THIS_MODULE,
+ },
+ {
+ .name = "nfacct",
+ .revision = 1,
+ .family = NFPROTO_UNSPEC,
+ .checkentry = nfacct_mt_checkentry,
+ .match = nfacct_mt,
+ .destroy = nfacct_mt_destroy,
+ .matchsize = sizeof(struct xt_nfacct_match_info_v1),
+ .usersize = offsetof(struct xt_nfacct_match_info_v1, nfacct),
+ .me = THIS_MODULE,
+ },
};
static int __init nfacct_mt_init(void)
{
- return xt_register_match(&nfacct_mt_reg);
+ return xt_register_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
}
static void __exit nfacct_mt_exit(void)
{
- xt_unregister_match(&nfacct_mt_reg);
+ xt_unregister_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
}
module_init(nfacct_mt_init);
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.2 22/94] netfilter: ebtables: Fix argument order to ADD_COUNTER
From: Sasha Levin @ 2019-09-04 15:56 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Todd Seidelmann, Pablo Neira Ayuso, Sasha Levin, netfilter-devel,
coreteam, netdev
In-Reply-To: <20190904155739.2816-1-sashal@kernel.org>
From: Todd Seidelmann <tseidelmann@linode.com>
[ Upstream commit f20faa06d83de440bec8e200870784c3458793c4 ]
The ordering of arguments to the x_tables ADD_COUNTER macro
appears to be wrong in ebtables (cf. ip_tables.c, ip6_tables.c,
and arp_tables.c).
This causes data corruption in the ebtables userspace tools
because they get incorrect packet & byte counts from the kernel.
Fixes: d72133e628803 ("netfilter: ebtables: use ADD_COUNTER macro")
Signed-off-by: Todd Seidelmann <tseidelmann@linode.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bridge/netfilter/ebtables.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index c8177a89f52c3..4096d8a74a2bd 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -221,7 +221,7 @@ unsigned int ebt_do_table(struct sk_buff *skb,
return NF_DROP;
}
- ADD_COUNTER(*(counter_base + i), 1, skb->len);
+ ADD_COUNTER(*(counter_base + i), skb->len, 1);
/* these should only watch: not modify, nor tell us
* what to do with the packet
@@ -959,8 +959,8 @@ static void get_counters(const struct ebt_counter *oldcounters,
continue;
counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
for (i = 0; i < nentries; i++)
- ADD_COUNTER(counters[i], counter_base[i].pcnt,
- counter_base[i].bcnt);
+ ADD_COUNTER(counters[i], counter_base[i].bcnt,
+ counter_base[i].pcnt);
}
}
@@ -1280,7 +1280,7 @@ static int do_update_counters(struct net *net, const char *name,
/* we add to the counters of the first cpu */
for (i = 0; i < num_counters; i++)
- ADD_COUNTER(t->private->counters[i], tmp[i].pcnt, tmp[i].bcnt);
+ ADD_COUNTER(t->private->counters[i], tmp[i].bcnt, tmp[i].pcnt);
write_unlock_bh(&t->lock);
ret = 0;
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.2 20/94] tools: bpftool: close prog FD before exit on showing a single program
From: Sasha Levin @ 2019-09-04 15:56 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Quentin Monnet, Jakub Kicinski, Andrii Nakryiko,
Alexei Starovoitov, Sasha Levin, netdev, bpf
In-Reply-To: <20190904155739.2816-1-sashal@kernel.org>
From: Quentin Monnet <quentin.monnet@netronome.com>
[ Upstream commit d34b044038bfb0e19caa8b019910efc465f41d5f ]
When showing metadata about a single program by invoking
"bpftool prog show PROG", the file descriptor referring to the program
is not closed before returning from the function. Let's close it.
Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool")
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/bpf/bpftool/prog.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 7a4e21a315236..d41651afe5f64 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -362,7 +362,9 @@ static int do_show(int argc, char **argv)
if (fd < 0)
return -1;
- return show_prog(fd);
+ err = show_prog(fd);
+ close(fd);
+ return err;
}
if (argc)
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.2 19/94] selftests/bpf: fix "bind{4, 6} deny specific IP & port" on s390
From: Sasha Levin @ 2019-09-04 15:56 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ilya Leoshkevich, Daniel Borkmann, Sasha Levin, linux-kselftest,
netdev, bpf
In-Reply-To: <20190904155739.2816-1-sashal@kernel.org>
From: Ilya Leoshkevich <iii@linux.ibm.com>
[ Upstream commit 27df5c7068bf23cab282dc64b1c9894429b3b8a0 ]
"bind4 allow specific IP & port" and "bind6 deny specific IP & port"
fail on s390 because of endianness issue: the 4 IP address bytes are
loaded as a word and compared with a constant, but the value of this
constant should be different on big- and little- endian machines, which
is not the case right now.
Use __bpf_constant_ntohl to generate proper value based on machine
endianness.
Fixes: 1d436885b23b ("selftests/bpf: Selftest for sys_bind post-hooks.")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/bpf/test_sock.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_sock.c b/tools/testing/selftests/bpf/test_sock.c
index fb679ac3d4b07..0e66527334623 100644
--- a/tools/testing/selftests/bpf/test_sock.c
+++ b/tools/testing/selftests/bpf/test_sock.c
@@ -13,6 +13,7 @@
#include <bpf/bpf.h>
#include "cgroup_helpers.h"
+#include "bpf_endian.h"
#include "bpf_rlimit.h"
#include "bpf_util.h"
@@ -232,7 +233,8 @@ static struct sock_test tests[] = {
/* if (ip == expected && port == expected) */
BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
offsetof(struct bpf_sock, src_ip6[3])),
- BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x01000000, 4),
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7,
+ __bpf_constant_ntohl(0x00000001), 4),
BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
offsetof(struct bpf_sock, src_port)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x2001, 2),
@@ -261,7 +263,8 @@ static struct sock_test tests[] = {
/* if (ip == expected && port == expected) */
BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
offsetof(struct bpf_sock, src_ip4)),
- BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x0100007F, 4),
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7,
+ __bpf_constant_ntohl(0x7F000001), 4),
BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
offsetof(struct bpf_sock, src_port)),
BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x1002, 2),
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.2 02/94] ieee802154: hwsim: unregister hw while hwsim_subscribe_all_others fails
From: Sasha Levin @ 2019-09-04 15:56 UTC (permalink / raw)
To: linux-kernel, stable
Cc: YueHaibing, Hulk Robot, Alexander Aring, Stefan Schmidt,
Sasha Levin, linux-wpan, netdev
In-Reply-To: <20190904155739.2816-1-sashal@kernel.org>
From: YueHaibing <yuehaibing@huawei.com>
[ Upstream commit de166bbe861738c8bc3e5dad5b03f45d7d6ef914 ]
KASAN report this:
kernel BUG at net/mac802154/main.c:130!
invalid opcode: 0000 [#1] PREEMPT SMP
CPU: 0 PID: 19932 Comm: modprobe Not tainted 5.1.0-rc6+ #22
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
RIP: 0010:ieee802154_free_hw+0x2a/0x30 [mac802154]
Code: 55 48 8d 57 38 48 89 e5 53 48 89 fb 48 8b 47 38 48 39 c2 75 15 48 8d 7f 48 e8 82 85 16 e1 48 8b 7b 28 e8 f9 ef 83 e2 5b 5d c3 <0f> 0b 0f 1f 40 00 55 48 89 e5 53 48 89 fb 0f b6 86 80 00 00 00 88
RSP: 0018:ffffc90001c7b9f0 EFLAGS: 00010206
RAX: ffff88822df3aa80 RBX: ffff88823143d5c0 RCX: 0000000000000002
RDX: ffff88823143d5f8 RSI: ffff88822b1fabc0 RDI: ffff88823143d5c0
RBP: ffffc90001c7b9f8 R08: 0000000000000000 R09: 0000000000000001
R10: 0000000000000000 R11: 0000000000000000 R12: 00000000fffffff4
R13: ffff88822dea4f50 R14: ffff88823143d7c0 R15: 00000000fffffff4
FS: 00007ff52e999540(0000) GS:ffff888237a00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fdc06dba768 CR3: 000000023160a000 CR4: 00000000000006f0
Call Trace:
hwsim_add_one+0x2dd/0x540 [mac802154_hwsim]
hwsim_probe+0x2f/0xb0 [mac802154_hwsim]
platform_drv_probe+0x3a/0x90
? driver_sysfs_add+0x79/0xb0
really_probe+0x1d4/0x2d0
driver_probe_device+0x50/0xf0
device_driver_attach+0x54/0x60
__driver_attach+0x7e/0xd0
? device_driver_attach+0x60/0x60
bus_for_each_dev+0x68/0xc0
driver_attach+0x19/0x20
bus_add_driver+0x15e/0x200
driver_register+0x5b/0xf0
__platform_driver_register+0x31/0x40
hwsim_init_module+0x74/0x1000 [mac802154_hwsim]
? 0xffffffffa00e9000
do_one_initcall+0x6c/0x3cc
? kmem_cache_alloc_trace+0x248/0x3b0
do_init_module+0x5b/0x1f1
load_module+0x1db1/0x2690
? m_show+0x1d0/0x1d0
__do_sys_finit_module+0xc5/0xd0
__x64_sys_finit_module+0x15/0x20
do_syscall_64+0x6b/0x1d0
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x7ff52e4a2839
Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 1f f6 2c 00 f7 d8 64 89 01 48
RSP: 002b:00007ffffa7b3c08 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
RAX: ffffffffffffffda RBX: 00005647560a2a00 RCX: 00007ff52e4a2839
RDX: 0000000000000000 RSI: 00005647547f3c2e RDI: 0000000000000003
RBP: 00005647547f3c2e R08: 0000000000000000 R09: 00005647560a2a00
R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000
R13: 00005647560a2c10 R14: 0000000000040000 R15: 00005647560a2a00
Modules linked in: mac802154_hwsim(+) mac802154 [last unloaded: mac802154_hwsim]
In hwsim_add_one, if hwsim_subscribe_all_others fails, we
should call ieee802154_unregister_hw to free resources.
Reported-by: Hulk Robot <hulkci@huawei.com>
Fixes: f25da51fdc38 ("ieee802154: hwsim: add replacement for fakelb")
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Acked-by: Alexander Aring <aring@mojatatu.com>
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ieee802154/mac802154_hwsim.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
index 94b9e9d775e40..c20e7ef18bc95 100644
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -802,7 +802,7 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
err = hwsim_subscribe_all_others(phy);
if (err < 0) {
mutex_unlock(&hwsim_phys_lock);
- goto err_reg;
+ goto err_subscribe;
}
}
list_add_tail(&phy->list, &hwsim_phys);
@@ -812,6 +812,8 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
return idx;
+err_subscribe:
+ ieee802154_unregister_hw(phy->hw);
err_reg:
kfree(pib);
err_pib:
--
2.20.1
^ permalink raw reply related
* [PATCH bpf-next 0/6] selftests/bpf: move sockopt tests under test_progs
From: Stanislav Fomichev @ 2019-09-04 16:25 UTC (permalink / raw)
To: netdev, bpf; +Cc: davem, ast, daniel, Stanislav Fomichev
Now that test_progs is shaping into more generic test framework,
let's convert sockopt tests to it. This requires adding
a helper to create and join a cgroup first (test__join_cgroup).
Since we already hijack stdout/stderr that shouldn't be
a problem (cgroup helpers log to stderr).
The rest of the patches just move sockopt tests files under prog_tests/
and do the required small adjustments.
Stanislav Fomichev (6):
selftests/bpf: test_progs: add test__join_cgroup helper
selftests/bpf: test_progs: convert test_sockopt
selftests/bpf: test_progs: convert test_sockopt_sk
selftests/bpf: test_progs: convert test_sockopt_multi
selftests/bpf: test_progs: convert test_sockopt_inherit
selftests/bpf: test_progs: convert test_tcp_rtt
tools/testing/selftests/bpf/.gitignore | 5 -
tools/testing/selftests/bpf/Makefile | 12 +--
.../{test_sockopt.c => prog_tests/sockopt.c} | 50 ++-------
.../sockopt_inherit.c} | 102 ++++++++----------
.../sockopt_multi.c} | 62 ++---------
.../sockopt_sk.c} | 60 +++--------
.../{test_tcp_rtt.c => prog_tests/tcp_rtt.c} | 83 +++++---------
tools/testing/selftests/bpf/test_progs.c | 38 +++++++
tools/testing/selftests/bpf/test_progs.h | 4 +-
9 files changed, 142 insertions(+), 274 deletions(-)
rename tools/testing/selftests/bpf/{test_sockopt.c => prog_tests/sockopt.c} (96%)
rename tools/testing/selftests/bpf/{test_sockopt_inherit.c => prog_tests/sockopt_inherit.c} (72%)
rename tools/testing/selftests/bpf/{test_sockopt_multi.c => prog_tests/sockopt_multi.c} (83%)
rename tools/testing/selftests/bpf/{test_sockopt_sk.c => prog_tests/sockopt_sk.c} (79%)
rename tools/testing/selftests/bpf/{test_tcp_rtt.c => prog_tests/tcp_rtt.c} (76%)
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply
* [PATCH bpf-next 1/6] selftests/bpf: test_progs: add test__join_cgroup helper
From: Stanislav Fomichev @ 2019-09-04 16:25 UTC (permalink / raw)
To: netdev, bpf; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190904162509.199561-1-sdf@google.com>
test__join_cgroup() combines the following operations that usually
go hand in hand and returns cgroup fd:
* setup cgroup environment (make sure cgroupfs is mounted)
* mkdir cgroup
* join cgroup
It also marks a test as a "cgroup cleanup needed" and removes cgroup
state after the test is done.
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
tools/testing/selftests/bpf/Makefile | 4 +--
tools/testing/selftests/bpf/test_progs.c | 38 ++++++++++++++++++++++++
tools/testing/selftests/bpf/test_progs.h | 1 +
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index c7595b4ed55d..e145954d3765 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -102,7 +102,7 @@ $(OUTPUT)/test_socket_cookie: cgroup_helpers.c
$(OUTPUT)/test_sockmap: cgroup_helpers.c
$(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c
$(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c
-$(OUTPUT)/test_progs: trace_helpers.c
+$(OUTPUT)/test_progs: cgroup_helpers.c trace_helpers.c
$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c
$(OUTPUT)/test_cgroup_storage: cgroup_helpers.c
$(OUTPUT)/test_netcnt: cgroup_helpers.c
@@ -196,7 +196,7 @@ $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\
| $(ALU32_BUILD_DIR)
$(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \
-o $(ALU32_BUILD_DIR)/test_progs_32 \
- test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \
+ test_progs.c test_stub.c cgroup_helpers.c trace_helpers.c prog_tests/*.c \
$(OUTPUT)/libbpf.a $(LDLIBS)
$(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index e8616e778cb5..af75a1c7a458 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -2,6 +2,7 @@
/* Copyright (c) 2017 Facebook
*/
#include "test_progs.h"
+#include "cgroup_helpers.h"
#include "bpf_rlimit.h"
#include <argp.h>
#include <string.h>
@@ -17,6 +18,7 @@ struct prog_test_def {
int error_cnt;
int skip_cnt;
bool tested;
+ bool need_cgroup_cleanup;
const char *subtest_name;
int subtest_num;
@@ -122,6 +124,39 @@ void test__fail(void)
env.test->error_cnt++;
}
+int test__join_cgroup(const char *path)
+{
+ int fd;
+
+ if (!env.test->need_cgroup_cleanup) {
+ if (setup_cgroup_environment()) {
+ fprintf(stderr,
+ "#%d %s: Failed to setup cgroup environment\n",
+ env.test->test_num, env.test->test_name);
+ return -1;
+ }
+
+ env.test->need_cgroup_cleanup = true;
+ }
+
+ fd = create_and_get_cgroup(path);
+ if (fd < 0) {
+ fprintf(stderr,
+ "#%d %s: Failed to create cgroup '%s' (errno=%d)\n",
+ env.test->test_num, env.test->test_name, path, errno);
+ return fd;
+ }
+
+ if (join_cgroup(path)) {
+ fprintf(stderr,
+ "#%d %s: Failed to join cgroup '%s' (errno=%d)\n",
+ env.test->test_num, env.test->test_name, path, errno);
+ return -1;
+ }
+
+ return fd;
+}
+
struct ipv4_packet pkt_v4 = {
.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
.iph.ihl = 5,
@@ -530,6 +565,9 @@ int main(int argc, char **argv)
fprintf(env.stdout, "#%d %s:%s\n",
test->test_num, test->test_name,
test->error_cnt ? "FAIL" : "OK");
+
+ if (test->need_cgroup_cleanup)
+ cleanup_cgroup_environment();
}
stdio_restore();
printf("Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n",
diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h
index c8edb9464ba6..e518bd5da3e2 100644
--- a/tools/testing/selftests/bpf/test_progs.h
+++ b/tools/testing/selftests/bpf/test_progs.h
@@ -71,6 +71,7 @@ extern void test__force_log();
extern bool test__start_subtest(const char *name);
extern void test__skip(void);
extern void test__fail(void);
+extern int test__join_cgroup(const char *path);
#define MAGIC_BYTES 123
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply related
* [PATCH bpf-next 2/6] selftests/bpf: test_progs: convert test_sockopt
From: Stanislav Fomichev @ 2019-09-04 16:25 UTC (permalink / raw)
To: netdev, bpf; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190904162509.199561-1-sdf@google.com>
Move the files, adjust includes, remove entry from Makefile & .gitignore
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
tools/testing/selftests/bpf/.gitignore | 1 -
tools/testing/selftests/bpf/Makefile | 3 +-
.../{test_sockopt.c => prog_tests/sockopt.c} | 50 +++----------------
3 files changed, 8 insertions(+), 46 deletions(-)
rename tools/testing/selftests/bpf/{test_sockopt.c => prog_tests/sockopt.c} (96%)
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 60c9338cd9b4..0315120eac8f 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -39,7 +39,6 @@ libbpf.so.*
test_hashmap
test_btf_dump
xdping
-test_sockopt
test_sockopt_sk
test_sockopt_multi
test_sockopt_inherit
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index e145954d3765..08e2183974d5 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
test_cgroup_storage test_select_reuseport test_section_names \
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
- test_btf_dump test_cgroup_attach xdping test_sockopt test_sockopt_sk \
+ test_btf_dump test_cgroup_attach xdping test_sockopt_sk \
test_sockopt_multi test_sockopt_inherit test_tcp_rtt
BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
@@ -109,7 +109,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c
$(OUTPUT)/test_sock_fields: cgroup_helpers.c
$(OUTPUT)/test_sysctl: cgroup_helpers.c
$(OUTPUT)/test_cgroup_attach: cgroup_helpers.c
-$(OUTPUT)/test_sockopt: cgroup_helpers.c
$(OUTPUT)/test_sockopt_sk: cgroup_helpers.c
$(OUTPUT)/test_sockopt_multi: cgroup_helpers.c
$(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c
diff --git a/tools/testing/selftests/bpf/test_sockopt.c b/tools/testing/selftests/bpf/prog_tests/sockopt.c
similarity index 96%
rename from tools/testing/selftests/bpf/test_sockopt.c
rename to tools/testing/selftests/bpf/prog_tests/sockopt.c
index 23bd0819382d..3e8517a8395a 100644
--- a/tools/testing/selftests/bpf/test_sockopt.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt.c
@@ -1,22 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <linux/filter.h>
-#include <bpf/bpf.h>
-#include <bpf/libbpf.h>
-
-#include "bpf_rlimit.h"
-#include "bpf_util.h"
+#include <test_progs.h>
#include "cgroup_helpers.h"
-#define CG_PATH "/sockopt"
-
static char bpf_log_buf[4096];
static bool verbose;
@@ -983,39 +968,18 @@ static int run_test(int cgroup_fd, struct sockopt_test *test)
return ret;
}
-int main(int args, char **argv)
+void test_sockopt(void)
{
- int err = EXIT_FAILURE, error_cnt = 0;
int cgroup_fd, i;
- if (setup_cgroup_environment())
- goto cleanup_obj;
-
- cgroup_fd = create_and_get_cgroup(CG_PATH);
- if (cgroup_fd < 0)
- goto cleanup_cgroup_env;
-
- if (join_cgroup(CG_PATH))
- goto cleanup_cgroup;
+ cgroup_fd = test__join_cgroup("/sockopt");
+ if (CHECK_FAIL(cgroup_fd < 0))
+ return;
for (i = 0; i < ARRAY_SIZE(tests); i++) {
- int err = run_test(cgroup_fd, &tests[i]);
-
- if (err)
- error_cnt++;
-
- printf("#%d %s: %s\n", i, err ? "FAIL" : "PASS",
- tests[i].descr);
+ test__start_subtest(tests[i].descr);
+ CHECK_FAIL(run_test(cgroup_fd, &tests[i]));
}
- printf("Summary: %ld PASSED, %d FAILED\n",
- ARRAY_SIZE(tests) - error_cnt, error_cnt);
- err = error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
-
-cleanup_cgroup:
close(cgroup_fd);
-cleanup_cgroup_env:
- cleanup_cgroup_environment();
-cleanup_obj:
- return err;
}
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply related
* [PATCH bpf-next 3/6] selftests/bpf: test_progs: convert test_sockopt_sk
From: Stanislav Fomichev @ 2019-09-04 16:25 UTC (permalink / raw)
To: netdev, bpf; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190904162509.199561-1-sdf@google.com>
Move the files, adjust includes, remove entry from Makefile & .gitignore
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
tools/testing/selftests/bpf/.gitignore | 1 -
tools/testing/selftests/bpf/Makefile | 3 +-
.../sockopt_sk.c} | 60 ++++---------------
tools/testing/selftests/bpf/test_progs.h | 3 +-
4 files changed, 15 insertions(+), 52 deletions(-)
rename tools/testing/selftests/bpf/{test_sockopt_sk.c => prog_tests/sockopt_sk.c} (79%)
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 0315120eac8f..bc83c1a7ea1b 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -39,7 +39,6 @@ libbpf.so.*
test_hashmap
test_btf_dump
xdping
-test_sockopt_sk
test_sockopt_multi
test_sockopt_inherit
test_tcp_rtt
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 08e2183974d5..ea790901297c 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
test_cgroup_storage test_select_reuseport test_section_names \
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
- test_btf_dump test_cgroup_attach xdping test_sockopt_sk \
+ test_btf_dump test_cgroup_attach xdping \
test_sockopt_multi test_sockopt_inherit test_tcp_rtt
BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
@@ -109,7 +109,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c
$(OUTPUT)/test_sock_fields: cgroup_helpers.c
$(OUTPUT)/test_sysctl: cgroup_helpers.c
$(OUTPUT)/test_cgroup_attach: cgroup_helpers.c
-$(OUTPUT)/test_sockopt_sk: cgroup_helpers.c
$(OUTPUT)/test_sockopt_multi: cgroup_helpers.c
$(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c
$(OUTPUT)/test_tcp_rtt: cgroup_helpers.c
diff --git a/tools/testing/selftests/bpf/test_sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
similarity index 79%
rename from tools/testing/selftests/bpf/test_sockopt_sk.c
rename to tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
index e4f6055d92e9..2061a6beac0f 100644
--- a/tools/testing/selftests/bpf/test_sockopt_sk.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
@@ -1,23 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <linux/filter.h>
-#include <bpf/bpf.h>
-#include <bpf/libbpf.h>
-
-#include "bpf_rlimit.h"
-#include "bpf_util.h"
+#include <test_progs.h>
#include "cgroup_helpers.h"
-#define CG_PATH "/sockopt"
-
#define SOL_CUSTOM 0xdeadbeef
static int getsetsockopt(void)
@@ -176,7 +160,7 @@ static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)
return 0;
}
-static int run_test(int cgroup_fd)
+static void run_test(int cgroup_fd)
{
struct bpf_prog_load_attr attr = {
.file = "./sockopt_sk.o",
@@ -186,51 +170,31 @@ static int run_test(int cgroup_fd)
int err;
err = bpf_prog_load_xattr(&attr, &obj, &ignored);
- if (err) {
- log_err("Failed to load BPF object");
- return -1;
- }
+ if (CHECK_FAIL(err))
+ return;
err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt");
- if (err)
+ if (CHECK_FAIL(err))
goto close_bpf_object;
err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt");
- if (err)
+ if (CHECK_FAIL(err))
goto close_bpf_object;
- err = getsetsockopt();
+ CHECK_FAIL(getsetsockopt());
close_bpf_object:
bpf_object__close(obj);
- return err;
}
-int main(int args, char **argv)
+void test_sockopt_sk(void)
{
int cgroup_fd;
- int err = EXIT_SUCCESS;
-
- if (setup_cgroup_environment())
- goto cleanup_obj;
-
- cgroup_fd = create_and_get_cgroup(CG_PATH);
- if (cgroup_fd < 0)
- goto cleanup_cgroup_env;
-
- if (join_cgroup(CG_PATH))
- goto cleanup_cgroup;
-
- if (run_test(cgroup_fd))
- err = EXIT_FAILURE;
- printf("test_sockopt_sk: %s\n",
- err == EXIT_SUCCESS ? "PASSED" : "FAILED");
+ cgroup_fd = test__join_cgroup("/sockopt_sk");
+ if (CHECK_FAIL(cgroup_fd < 0))
+ return;
-cleanup_cgroup:
+ run_test(cgroup_fd);
close(cgroup_fd);
-cleanup_cgroup_env:
- cleanup_cgroup_environment();
-cleanup_obj:
- return err;
}
diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h
index e518bd5da3e2..0c48f64f732b 100644
--- a/tools/testing/selftests/bpf/test_progs.h
+++ b/tools/testing/selftests/bpf/test_progs.h
@@ -16,9 +16,10 @@ typedef __u16 __sum16;
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
-#include <linux/tcp.h>
+#include <netinet/tcp.h>
#include <linux/filter.h>
#include <linux/perf_event.h>
+#include <linux/socket.h>
#include <linux/unistd.h>
#include <sys/ioctl.h>
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply related
* [PATCH bpf-next 4/6] selftests/bpf: test_progs: convert test_sockopt_multi
From: Stanislav Fomichev @ 2019-09-04 16:25 UTC (permalink / raw)
To: netdev, bpf; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190904162509.199561-1-sdf@google.com>
Move the files, adjust includes, remove entry from Makefile & .gitignore
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
tools/testing/selftests/bpf/.gitignore | 1 -
tools/testing/selftests/bpf/Makefile | 3 +-
.../sockopt_multi.c} | 62 +++----------------
3 files changed, 11 insertions(+), 55 deletions(-)
rename tools/testing/selftests/bpf/{test_sockopt_multi.c => prog_tests/sockopt_multi.c} (83%)
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index bc83c1a7ea1b..4143add5a11e 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -39,6 +39,5 @@ libbpf.so.*
test_hashmap
test_btf_dump
xdping
-test_sockopt_multi
test_sockopt_inherit
test_tcp_rtt
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index ea790901297c..271f8ce89c97 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -29,7 +29,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
test_cgroup_storage test_select_reuseport test_section_names \
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
test_btf_dump test_cgroup_attach xdping \
- test_sockopt_multi test_sockopt_inherit test_tcp_rtt
+ test_sockopt_inherit test_tcp_rtt
BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
TEST_GEN_FILES = $(BPF_OBJ_FILES)
@@ -109,7 +109,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c
$(OUTPUT)/test_sock_fields: cgroup_helpers.c
$(OUTPUT)/test_sysctl: cgroup_helpers.c
$(OUTPUT)/test_cgroup_attach: cgroup_helpers.c
-$(OUTPUT)/test_sockopt_multi: cgroup_helpers.c
$(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c
$(OUTPUT)/test_tcp_rtt: cgroup_helpers.c
diff --git a/tools/testing/selftests/bpf/test_sockopt_multi.c b/tools/testing/selftests/bpf/prog_tests/sockopt_multi.c
similarity index 83%
rename from tools/testing/selftests/bpf/test_sockopt_multi.c
rename to tools/testing/selftests/bpf/prog_tests/sockopt_multi.c
index 4be3441db867..29188d6f5c8d 100644
--- a/tools/testing/selftests/bpf/test_sockopt_multi.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt_multi.c
@@ -1,19 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-
-#include <error.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <linux/filter.h>
-#include <bpf/bpf.h>
-#include <bpf/libbpf.h>
-
-#include "bpf_rlimit.h"
-#include "bpf_util.h"
+#include <test_progs.h>
#include "cgroup_helpers.h"
static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)
@@ -308,7 +294,7 @@ static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
return err;
}
-int main(int argc, char **argv)
+void test_sockopt_multi(void)
{
struct bpf_prog_load_attr attr = {
.file = "./sockopt_multi.o",
@@ -319,56 +305,28 @@ int main(int argc, char **argv)
int err = -1;
int ignored;
- if (setup_cgroup_environment()) {
- log_err("Failed to setup cgroup environment\n");
- goto out;
- }
-
- cg_parent = create_and_get_cgroup("/parent");
- if (cg_parent < 0) {
- log_err("Failed to create cgroup /parent\n");
- goto out;
- }
-
- cg_child = create_and_get_cgroup("/parent/child");
- if (cg_child < 0) {
- log_err("Failed to create cgroup /parent/child\n");
+ cg_parent = test__join_cgroup("/parent");
+ if (CHECK_FAIL(cg_parent < 0))
goto out;
- }
- if (join_cgroup("/parent/child")) {
- log_err("Failed to join cgroup /parent/child\n");
+ cg_child = test__join_cgroup("/parent/child");
+ if (CHECK_FAIL(cg_child < 0))
goto out;
- }
err = bpf_prog_load_xattr(&attr, &obj, &ignored);
- if (err) {
- log_err("Failed to load BPF object");
+ if (CHECK_FAIL(err))
goto out;
- }
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (sock_fd < 0) {
- log_err("Failed to create socket");
+ if (CHECK_FAIL(sock_fd < 0))
goto out;
- }
- if (run_getsockopt_test(obj, cg_parent, cg_child, sock_fd))
- err = -1;
- printf("test_sockopt_multi: getsockopt %s\n",
- err ? "FAILED" : "PASSED");
-
- if (run_setsockopt_test(obj, cg_parent, cg_child, sock_fd))
- err = -1;
- printf("test_sockopt_multi: setsockopt %s\n",
- err ? "FAILED" : "PASSED");
+ CHECK_FAIL(run_getsockopt_test(obj, cg_parent, cg_child, sock_fd));
+ CHECK_FAIL(run_setsockopt_test(obj, cg_parent, cg_child, sock_fd));
out:
close(sock_fd);
bpf_object__close(obj);
close(cg_child);
close(cg_parent);
-
- printf("test_sockopt_multi: %s\n", err ? "FAILED" : "PASSED");
- return err ? EXIT_FAILURE : EXIT_SUCCESS;
}
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply related
* [PATCH bpf-next 5/6] selftests/bpf: test_progs: convert test_sockopt_inherit
From: Stanislav Fomichev @ 2019-09-04 16:25 UTC (permalink / raw)
To: netdev, bpf; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190904162509.199561-1-sdf@google.com>
Move the files, adjust includes, remove entry from Makefile & .gitignore
I also added pthread_cond_wait for the server thread startup. We don't
want to connect to the server that's not yet up (for some reason
this existing race is now more prominent with test_progs).
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
tools/testing/selftests/bpf/.gitignore | 1 -
tools/testing/selftests/bpf/Makefile | 4 +-
.../sockopt_inherit.c} | 102 ++++++++----------
3 files changed, 43 insertions(+), 64 deletions(-)
rename tools/testing/selftests/bpf/{test_sockopt_inherit.c => prog_tests/sockopt_inherit.c} (72%)
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 4143add5a11e..5b06bb45b500 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -39,5 +39,4 @@ libbpf.so.*
test_hashmap
test_btf_dump
xdping
-test_sockopt_inherit
test_tcp_rtt
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 271f8ce89c97..fe786df1174b 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -28,8 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
test_cgroup_storage test_select_reuseport test_section_names \
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
- test_btf_dump test_cgroup_attach xdping \
- test_sockopt_inherit test_tcp_rtt
+ test_btf_dump test_cgroup_attach xdping test_tcp_rtt
BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
TEST_GEN_FILES = $(BPF_OBJ_FILES)
@@ -109,7 +108,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c
$(OUTPUT)/test_sock_fields: cgroup_helpers.c
$(OUTPUT)/test_sysctl: cgroup_helpers.c
$(OUTPUT)/test_cgroup_attach: cgroup_helpers.c
-$(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c
$(OUTPUT)/test_tcp_rtt: cgroup_helpers.c
.PHONY: force
diff --git a/tools/testing/selftests/bpf/test_sockopt_inherit.c b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c
similarity index 72%
rename from tools/testing/selftests/bpf/test_sockopt_inherit.c
rename to tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c
index 1bf699815b9b..6cbeea7b4bf1 100644
--- a/tools/testing/selftests/bpf/test_sockopt_inherit.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c
@@ -1,22 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-#include <error.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <pthread.h>
-
-#include <linux/filter.h>
-#include <bpf/bpf.h>
-#include <bpf/libbpf.h>
-
-#include "bpf_rlimit.h"
-#include "bpf_util.h"
+#include <test_progs.h>
#include "cgroup_helpers.h"
-#define CG_PATH "/sockopt_inherit"
#define SOL_CUSTOM 0xdeadbeef
#define CUSTOM_INHERIT1 0
#define CUSTOM_INHERIT2 1
@@ -74,6 +59,9 @@ static int verify_sockopt(int fd, int optname, const char *msg, char expected)
return 0;
}
+static pthread_mutex_t server_started_mtx = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t server_started = PTHREAD_COND_INITIALIZER;
+
static void *server_thread(void *arg)
{
struct sockaddr_storage addr;
@@ -82,16 +70,26 @@ static void *server_thread(void *arg)
int client_fd;
int err = 0;
- if (listen(fd, 1) < 0)
- error(1, errno, "Failed to listed on socket");
+ err = listen(fd, 1);
+
+ pthread_mutex_lock(&server_started_mtx);
+ pthread_cond_signal(&server_started);
+ pthread_mutex_unlock(&server_started_mtx);
+
+ if (CHECK_FAIL(err < 0)) {
+ perror("Failed to listed on socket");
+ return NULL;
+ }
err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1);
err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1);
err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1);
client_fd = accept(fd, (struct sockaddr *)&addr, &len);
- if (client_fd < 0)
- error(1, errno, "Failed to accept client");
+ if (CHECK_FAIL(client_fd < 0)) {
+ perror("Failed to accept client");
+ return NULL;
+ }
err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1);
err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1);
@@ -167,7 +165,7 @@ static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)
return 0;
}
-static int run_test(int cgroup_fd)
+static void run_test(int cgroup_fd)
{
struct bpf_prog_load_attr attr = {
.file = "./sockopt_inherit.o",
@@ -180,40 +178,41 @@ static int run_test(int cgroup_fd)
int err;
err = bpf_prog_load_xattr(&attr, &obj, &ignored);
- if (err) {
- log_err("Failed to load BPF object");
- return -1;
- }
+ if (CHECK_FAIL(err))
+ return;
err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt");
- if (err)
+ if (CHECK_FAIL(err))
goto close_bpf_object;
err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt");
- if (err)
+ if (CHECK_FAIL(err))
goto close_bpf_object;
server_fd = start_server();
- if (server_fd < 0) {
- err = -1;
+ if (CHECK_FAIL(server_fd < 0))
+ goto close_bpf_object;
+
+ if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread,
+ (void *)&server_fd)))
goto close_bpf_object;
- }
- pthread_create(&tid, NULL, server_thread, (void *)&server_fd);
+ pthread_mutex_lock(&server_started_mtx);
+ pthread_cond_wait(&server_started, &server_started_mtx);
+ pthread_mutex_unlock(&server_started_mtx);
client_fd = connect_to_server(server_fd);
- if (client_fd < 0) {
- err = -1;
+ if (CHECK_FAIL(client_fd < 0))
goto close_server_fd;
- }
- err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0);
- err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0);
- err += verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0);
+ CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0));
+ CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0));
+ CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0));
pthread_join(tid, &server_err);
- err += (int)(long)server_err;
+ err = (int)(long)server_err;
+ CHECK_FAIL(err);
close(client_fd);
@@ -221,33 +220,16 @@ static int run_test(int cgroup_fd)
close(server_fd);
close_bpf_object:
bpf_object__close(obj);
- return err;
}
-int main(int args, char **argv)
+void test_sockopt_inherit(void)
{
int cgroup_fd;
- int err = EXIT_SUCCESS;
-
- if (setup_cgroup_environment())
- return err;
-
- cgroup_fd = create_and_get_cgroup(CG_PATH);
- if (cgroup_fd < 0)
- goto cleanup_cgroup_env;
-
- if (join_cgroup(CG_PATH))
- goto cleanup_cgroup;
-
- if (run_test(cgroup_fd))
- err = EXIT_FAILURE;
- printf("test_sockopt_inherit: %s\n",
- err == EXIT_SUCCESS ? "PASSED" : "FAILED");
+ cgroup_fd = test__join_cgroup("/sockopt_inherit");
+ if (CHECK_FAIL(cgroup_fd < 0))
+ return;
-cleanup_cgroup:
+ run_test(cgroup_fd);
close(cgroup_fd);
-cleanup_cgroup_env:
- cleanup_cgroup_environment();
- return err;
}
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply related
* [PATCH bpf-next 6/6] selftests/bpf: test_progs: convert test_tcp_rtt
From: Stanislav Fomichev @ 2019-09-04 16:25 UTC (permalink / raw)
To: netdev, bpf; +Cc: davem, ast, daniel, Stanislav Fomichev
In-Reply-To: <20190904162509.199561-1-sdf@google.com>
Move the files, adjust includes, remove entry from Makefile & .gitignore
Signed-off-by: Stanislav Fomichev <sdf@google.com>
---
tools/testing/selftests/bpf/.gitignore | 1 -
tools/testing/selftests/bpf/Makefile | 3 +-
.../{test_tcp_rtt.c => prog_tests/tcp_rtt.c} | 83 ++++++-------------
3 files changed, 28 insertions(+), 59 deletions(-)
rename tools/testing/selftests/bpf/{test_tcp_rtt.c => prog_tests/tcp_rtt.c} (76%)
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 5b06bb45b500..7470327edcfe 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -39,4 +39,3 @@ libbpf.so.*
test_hashmap
test_btf_dump
xdping
-test_tcp_rtt
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index fe786df1174b..811f1b24d02b 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
test_cgroup_storage test_select_reuseport test_section_names \
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
- test_btf_dump test_cgroup_attach xdping test_tcp_rtt
+ test_btf_dump test_cgroup_attach xdping
BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
TEST_GEN_FILES = $(BPF_OBJ_FILES)
@@ -108,7 +108,6 @@ $(OUTPUT)/test_netcnt: cgroup_helpers.c
$(OUTPUT)/test_sock_fields: cgroup_helpers.c
$(OUTPUT)/test_sysctl: cgroup_helpers.c
$(OUTPUT)/test_cgroup_attach: cgroup_helpers.c
-$(OUTPUT)/test_tcp_rtt: cgroup_helpers.c
.PHONY: force
diff --git a/tools/testing/selftests/bpf/test_tcp_rtt.c b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c
similarity index 76%
rename from tools/testing/selftests/bpf/test_tcp_rtt.c
rename to tools/testing/selftests/bpf/prog_tests/tcp_rtt.c
index 93916a69823e..fdc0b3614a9e 100644
--- a/tools/testing/selftests/bpf/test_tcp_rtt.c
+++ b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c
@@ -1,24 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
-#include <error.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <pthread.h>
-
-#include <linux/filter.h>
-#include <bpf/bpf.h>
-#include <bpf/libbpf.h>
-
-#include "bpf_rlimit.h"
-#include "bpf_util.h"
+#include <test_progs.h>
#include "cgroup_helpers.h"
-#define CG_PATH "/tcp_rtt"
-
struct tcp_rtt_storage {
__u32 invoked;
__u32 dsack_dups;
@@ -31,8 +14,8 @@ static void send_byte(int fd)
{
char b = 0x55;
- if (write(fd, &b, sizeof(b)) != 1)
- error(1, errno, "Failed to send single byte");
+ if (CHECK_FAIL(write(fd, &b, sizeof(b)) != 1))
+ perror("Failed to send single byte");
}
static int wait_for_ack(int fd, int retries)
@@ -66,8 +49,10 @@ static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 invoked,
int err = 0;
struct tcp_rtt_storage val;
- if (bpf_map_lookup_elem(map_fd, &client_fd, &val) < 0)
- error(1, errno, "Failed to read socket storage");
+ if (CHECK_FAIL(bpf_map_lookup_elem(map_fd, &client_fd, &val) < 0)) {
+ perror("Failed to read socket storage");
+ return -1;
+ }
if (val.invoked != invoked) {
log_err("%s: unexpected bpf_tcp_sock.invoked %d != %d",
@@ -225,61 +210,47 @@ static void *server_thread(void *arg)
int fd = *(int *)arg;
int client_fd;
- if (listen(fd, 1) < 0)
- error(1, errno, "Failed to listed on socket");
+ if (CHECK_FAIL(listen(fd, 1)) < 0) {
+ perror("Failed to listed on socket");
+ return NULL;
+ }
client_fd = accept(fd, (struct sockaddr *)&addr, &len);
- if (client_fd < 0)
- error(1, errno, "Failed to accept client");
+ if (CHECK_FAIL(client_fd < 0)) {
+ perror("Failed to accept client");
+ return NULL;
+ }
/* Wait for the next connection (that never arrives)
* to keep this thread alive to prevent calling
* close() on client_fd.
*/
- if (accept(fd, (struct sockaddr *)&addr, &len) >= 0)
- error(1, errno, "Unexpected success in second accept");
+ if (CHECK_FAIL(accept(fd, (struct sockaddr *)&addr, &len) >= 0)) {
+ perror("Unexpected success in second accept");
+ return NULL;
+ }
close(client_fd);
return NULL;
}
-int main(int args, char **argv)
+void test_tcp_rtt(void)
{
int server_fd, cgroup_fd;
- int err = EXIT_SUCCESS;
pthread_t tid;
- if (setup_cgroup_environment())
- goto cleanup_obj;
-
- cgroup_fd = create_and_get_cgroup(CG_PATH);
- if (cgroup_fd < 0)
- goto cleanup_cgroup_env;
-
- if (join_cgroup(CG_PATH))
- goto cleanup_cgroup;
+ cgroup_fd = test__join_cgroup("/tcp_rtt");
+ if (CHECK_FAIL(cgroup_fd < 0))
+ return;
server_fd = start_server();
- if (server_fd < 0) {
- err = EXIT_FAILURE;
- goto cleanup_cgroup;
- }
+ if (CHECK_FAIL(server_fd < 0))
+ goto close_cgroup_fd;
pthread_create(&tid, NULL, server_thread, (void *)&server_fd);
-
- if (run_test(cgroup_fd, server_fd))
- err = EXIT_FAILURE;
-
+ CHECK_FAIL(run_test(cgroup_fd, server_fd));
close(server_fd);
-
- printf("test_sockopt_sk: %s\n",
- err == EXIT_SUCCESS ? "PASSED" : "FAILED");
-
-cleanup_cgroup:
+close_cgroup_fd:
close(cgroup_fd);
-cleanup_cgroup_env:
- cleanup_cgroup_environment();
-cleanup_obj:
- return err;
}
--
2.23.0.187.g17f5b7556c-goog
^ permalink raw reply related
* Re: [PATCH iproute2-next] bpf: fix snprintf truncation warning
From: Andrea Claudi @ 2019-09-04 16:28 UTC (permalink / raw)
To: linux-netdev; +Cc: Stephen Hemminger, David Ahern
In-Reply-To: <12a9cb8d91e41a08466141d4bb8ee659487d01df.1567611976.git.aclaudi@redhat.com>
On Wed, Sep 4, 2019 at 5:50 PM Andrea Claudi <aclaudi@redhat.com> wrote:
>
> gcc v9.2.1 produces the following warning compiling iproute2:
>
> bpf.c: In function ‘bpf_get_work_dir’:
> bpf.c:784:49: warning: ‘snprintf’ output may be truncated before the last format character [-Wformat-truncation=]
> 784 | snprintf(bpf_wrk_dir, sizeof(bpf_wrk_dir), "%s/", mnt);
> | ^
> bpf.c:784:2: note: ‘snprintf’ output between 2 and 4097 bytes into a destination of size 4096
> 784 | snprintf(bpf_wrk_dir, sizeof(bpf_wrk_dir), "%s/", mnt);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Fix it extending bpf_wrk_dir size by 1 byte for the extra "/" char.
>
> Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
> ---
> lib/bpf.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/lib/bpf.c b/lib/bpf.c
> index 7d2a322ffbaec..95de7894a93ce 100644
> --- a/lib/bpf.c
> +++ b/lib/bpf.c
> @@ -742,7 +742,7 @@ static int bpf_gen_hierarchy(const char *base)
> static const char *bpf_get_work_dir(enum bpf_prog_type type)
> {
> static char bpf_tmp[PATH_MAX] = BPF_DIR_MNT;
> - static char bpf_wrk_dir[PATH_MAX];
> + static char bpf_wrk_dir[PATH_MAX + 1];
> static const char *mnt;
> static bool bpf_mnt_cached;
> const char *mnt_env = getenv(BPF_ENV_MNT);
> --
> 2.21.0
>
Sorry, I forgot to add:
Fixes: e42256699cac ("bpf: make tc's bpf loader generic and move into lib")
^ permalink raw reply
* Re: rtnl_lock() question
From: Jonathan Lemon @ 2019-09-04 16:38 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Netdev, Saeed Mahameed
In-Reply-To: <3164f8de-de20-44f7-03fb-8bc39ca8449e@gmail.com>
On 4 Sep 2019, at 0:39, Eric Dumazet wrote:
> On 9/3/19 11:55 PM, Jonathan Lemon wrote:
>> How appropriate is it to hold the rtnl_lock() across a sleepable
>> memory allocation? On one hand it's just a mutex, but it would
>> seem like it could block quite a few things.
>>
>
> Sure, all GFP_KERNEL allocations can sleep for quite a while.
>
> On the other hand, we may want to delay stuff if memory is under
> pressure,
> or complex operations like NEWLINK would fail.
>
> RTNL is mostly taken for control path operations, we prefer them to be
> mostly reliable, otherwise admins job would be a nightmare.
>
> In some cases, it is relatively easy to pre-allocate memory before
> rtnl is taken,
> but that will only take care of some selected paths.
The particular code path that I'm looking at is mlx5e_tx_timeout_work().
This is called on TX timeout, and mlx5 wants to move an entire channel
and all the supporting structures elsewhere. Under the rtnl_lock(), it
calls kvzmalloc() in order to grab a large chunk of contig memory, which
ends up stalling the system.
I suspect these large allocation should really be done outside the lock.
--
Jonathan
^ permalink raw reply
* Re: [PATCH bpf-next v3 3/4] xsk: use state member for socket synchronization
From: Jonathan Lemon @ 2019-09-04 16:40 UTC (permalink / raw)
To: Björn Töpel
Cc: ast, daniel, netdev, Björn Töpel, magnus.karlsson,
magnus.karlsson, bpf, syzbot+c82697e3043781e08802, hdanton,
i.maximets
In-Reply-To: <20190904114913.17217-4-bjorn.topel@gmail.com>
On 4 Sep 2019, at 4:49, Björn Töpel wrote:
> From: Björn Töpel <bjorn.topel@intel.com>
>
> Prior the state variable was introduced by Ilya, the dev member was
> used to determine whether the socket was bound or not. However, when
> dev was read, proper SMP barriers and READ_ONCE were missing. In order
> to address the missing barriers and READ_ONCE, we start using the
> state variable as a point of synchronization. The state member
> read/write is paired with proper SMP barriers, and from this follows
> that the members described above does not need READ_ONCE if used in
> conjunction with state check.
>
> In all syscalls and the xsk_rcv path we check if state is
> XSK_BOUND. If that is the case we do a SMP read barrier, and this
> implies that the dev, umem and all rings are correctly setup. Note
> that no READ_ONCE are needed for these variable if used when state is
> XSK_BOUND (plus the read barrier).
>
> To summarize: The members struct xdp_sock members dev, queue_id, umem,
> fq, cq, tx, rx, and state were read lock-less, with incorrect barriers
> and missing {READ, WRITE}_ONCE. Now, umem, fq, cq, tx, rx, and state
> are read lock-less. When these members are updated, WRITE_ONCE is
> used. When read, READ_ONCE are only used when read outside the control
> mutex (e.g. mmap) or, not synchronized with the state member
> (XSK_BOUND plus smp_rmb())
>
> Note that dev and queue_id do not need a WRITE_ONCE or READ_ONCE, due
> to the introduce state synchronization (XSK_BOUND plus smp_rmb()).
>
> Introducing the state check also fixes a race, found by syzcaller, in
> xsk_poll() where umem could be accessed when stale.
>
> Suggested-by: Hillf Danton <hdanton@sina.com>
> Reported-by: syzbot+c82697e3043781e08802@syzkaller.appspotmail.com
> Fixes: 77cd0d7b3f25 ("xsk: add support for need_wakeup flag in AF_XDP
> rings")
> Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
Acked-by: Jonathan Lemon <jonathan.lemon@gmail.com>
^ permalink raw reply
* Re: [PATCH v2 1/2] include: mdio: Add driver data helpers
From: Andrew Lunn @ 2019-09-04 16:46 UTC (permalink / raw)
To: Harini Katakam
Cc: f.fainelli, hkallweit1, davem, michal.simek, netdev,
linux-arm-kernel, linux-kernel, harinikatakamlinux,
radhey.shyam.pandey
In-Reply-To: <1567605621-6818-2-git-send-email-harini.katakam@xilinx.com>
On Wed, Sep 04, 2019 at 07:30:20PM +0530, Harini Katakam wrote:
> Add set/get drv_data helpers for mdio device.
>
> Signed-off-by: Harini Katakam <harini.katakam@xilinx.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH v2 2/2] net: phy: gmii2rgmii: Dont use priv field in phy device
From: Andrew Lunn @ 2019-09-04 16:47 UTC (permalink / raw)
To: Harini Katakam
Cc: f.fainelli, hkallweit1, davem, michal.simek, netdev,
linux-arm-kernel, linux-kernel, harinikatakamlinux,
radhey.shyam.pandey
In-Reply-To: <1567605621-6818-3-git-send-email-harini.katakam@xilinx.com>
On Wed, Sep 04, 2019 at 07:30:21PM +0530, Harini Katakam wrote:
> Use set/get drv data in phydev's mdio device instead. Phy device priv
> field maybe used by the external phy driver and should not be
> overwritten.
>
> Signed-off-by: Harini Katakam <harini.katakam@xilinx.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH v2 1/2] include: mdio: Add driver data helpers
From: Florian Fainelli @ 2019-09-04 17:07 UTC (permalink / raw)
To: Harini Katakam, andrew, hkallweit1, davem
Cc: michal.simek, netdev, linux-arm-kernel, linux-kernel,
harinikatakamlinux, radhey.shyam.pandey
In-Reply-To: <1567605621-6818-2-git-send-email-harini.katakam@xilinx.com>
On 9/4/19 7:00 AM, Harini Katakam wrote:
> Add set/get drv_data helpers for mdio device.
>
> Signed-off-by: Harini Katakam <harini.katakam@xilinx.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATCH v2 2/2] net: phy: gmii2rgmii: Dont use priv field in phy device
From: Florian Fainelli @ 2019-09-04 17:11 UTC (permalink / raw)
To: Harini Katakam, andrew, hkallweit1, davem
Cc: michal.simek, netdev, linux-arm-kernel, linux-kernel,
harinikatakamlinux, radhey.shyam.pandey
In-Reply-To: <1567605621-6818-3-git-send-email-harini.katakam@xilinx.com>
On 9/4/19 7:00 AM, Harini Katakam wrote:
> Use set/get drv data in phydev's mdio device instead. Phy device priv
> field maybe used by the external phy driver and should not be
> overwritten.
>
> Signed-off-by: Harini Katakam <harini.katakam@xilinx.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* [PATCH iproute2] devlink: fix segfault on health command
From: Andrea Claudi @ 2019-09-04 17:26 UTC (permalink / raw)
To: netdev; +Cc: stephen, dsahern
devlink segfaults when using grace_period without reporter
$ devlink health set pci/0000:00:09.0 grace_period 3500
Segmentation fault
devlink is instead supposed to gracefully fail printing a warning
message
$ devlink health set pci/0000:00:09.0 grace_period 3500
Reporter's name is expected.
This happens because DL_OPT_HEALTH_REPORTER_NAME and
DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD are both defined as BIT(27).
When dl_opts_put() parse options and grace_period is set, it erroneously
tries to set reporter name to null.
This is fixed simply shifting by 1 bit enumeration starting with
DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD.
Fixes: b18d89195b16 ("devlink: Add devlink health set command")
Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
---
devlink/devlink.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/devlink/devlink.c b/devlink/devlink.c
index 91c85dc1de730..0293373928f50 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -231,8 +231,8 @@ static void ifname_map_free(struct ifname_map *ifname_map)
#define DL_OPT_FLASH_FILE_NAME BIT(25)
#define DL_OPT_FLASH_COMPONENT BIT(26)
#define DL_OPT_HEALTH_REPORTER_NAME BIT(27)
-#define DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD BIT(27)
-#define DL_OPT_HEALTH_REPORTER_AUTO_RECOVER BIT(28)
+#define DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD BIT(28)
+#define DL_OPT_HEALTH_REPORTER_AUTO_RECOVER BIT(29)
struct dl_opts {
uint32_t present; /* flags of present items */
--
2.21.0
^ permalink raw reply related
* RE: [PATCH V2 4/4] crypto: Add Xilinx AES driver
From: Kalyani Akula @ 2019-09-04 17:40 UTC (permalink / raw)
To: Corentin Labbe
Cc: herbert@gondor.apana.org.au, kstewart@linuxfoundation.org,
gregkh@linuxfoundation.org, tglx@linutronix.de,
pombredanne@nexb.com, linux-crypto@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Sarat Chand Savitala
In-Reply-To: <20190902065854.GA28750@Red>
Hi Corentin,
Thanks for the review comments.
Please find my response/queries inline.
> -----Original Message-----
> From: Corentin Labbe <clabbe.montjoie@gmail.com>
> Sent: Monday, September 2, 2019 12:29 PM
> To: Kalyani Akula <kalyania@xilinx.com>
> Cc: herbert@gondor.apana.org.au; kstewart@linuxfoundation.org;
> gregkh@linuxfoundation.org; tglx@linutronix.de; pombredanne@nexb.com;
> linux-crypto@vger.kernel.org; linux-kernel@vger.kernel.org;
> netdev@vger.kernel.org; Kalyani Akula <kalyania@xilinx.com>
> Subject: Re: [PATCH V2 4/4] crypto: Add Xilinx AES driver
>
> On Sun, Sep 01, 2019 at 07:24:58PM +0530, Kalyani Akula wrote:
> > This patch adds AES driver support for the Xilinx ZynqMP SoC.
> >
> > Signed-off-by: Kalyani Akula <kalyani.akula@xilinx.com>
> > ---
>
> Hello
>
> I have some comment below
>
> > drivers/crypto/Kconfig | 11 ++
> > drivers/crypto/Makefile | 1 +
> > drivers/crypto/zynqmp-aes-gcm.c | 297
> > ++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 309 insertions(+)
> > create mode 100644 drivers/crypto/zynqmp-aes-gcm.c
> >
> > diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index
> > 603413f..a0d058a 100644
> > --- a/drivers/crypto/Kconfig
> > +++ b/drivers/crypto/Kconfig
> > @@ -677,6 +677,17 @@ config CRYPTO_DEV_ROCKCHIP
> > This driver interfaces with the hardware crypto accelerator.
> > Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode.
> >
> > +config CRYPTO_DEV_ZYNQMP_AES
> > + tristate "Support for Xilinx ZynqMP AES hw accelerator"
> > + depends on ARCH_ZYNQMP || COMPILE_TEST
> > + select CRYPTO_AES
> > + select CRYPTO_SKCIPHER
> > + help
> > + Xilinx ZynqMP has AES-GCM engine used for symmetric key
> > + encryption and decryption. This driver interfaces with AES hw
> > + accelerator. Select this if you want to use the ZynqMP module
> > + for AES algorithms.
> > +
> > config CRYPTO_DEV_MEDIATEK
> > tristate "MediaTek's EIP97 Cryptographic Engine driver"
> > depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST diff --git
> > a/drivers/crypto/Makefile b/drivers/crypto/Makefile index
> > afc4753..c99663a 100644
> > --- a/drivers/crypto/Makefile
> > +++ b/drivers/crypto/Makefile
> > @@ -48,3 +48,4 @@ obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
> > obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
> > obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/ obj-y += hisilicon/
> > +obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += zynqmp-aes-gcm.o
> > diff --git a/drivers/crypto/zynqmp-aes-gcm.c
> > b/drivers/crypto/zynqmp-aes-gcm.c new file mode 100644 index
> > 0000000..d65f038
> > --- /dev/null
> > +++ b/drivers/crypto/zynqmp-aes-gcm.c
> > @@ -0,0 +1,297 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Xilinx ZynqMP AES Driver.
> > + * Copyright (c) 2019 Xilinx Inc.
> > + */
> > +
> > +#include <crypto/aes.h>
> > +#include <crypto/scatterwalk.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/scatterlist.h>
> > +#include <linux/firmware/xlnx-zynqmp.h>
> > +
> > +#define ZYNQMP_AES_IV_SIZE 12
> > +#define ZYNQMP_AES_GCM_SIZE 16
> > +#define ZYNQMP_AES_KEY_SIZE 32
> > +
> > +#define ZYNQMP_AES_DECRYPT 0
> > +#define ZYNQMP_AES_ENCRYPT 1
> > +
> > +#define ZYNQMP_AES_KUP_KEY 0
> > +#define ZYNQMP_AES_DEVICE_KEY 1
> > +#define ZYNQMP_AES_PUF_KEY 2
> > +
> > +#define ZYNQMP_AES_GCM_TAG_MISMATCH_ERR 0x01
> > +#define ZYNQMP_AES_SIZE_ERR 0x06
> > +#define ZYNQMP_AES_WRONG_KEY_SRC_ERR 0x13
> > +#define ZYNQMP_AES_PUF_NOT_PROGRAMMED 0xE300
> > +
> > +#define ZYNQMP_AES_BLOCKSIZE 0x04
> > +
> > +static const struct zynqmp_eemi_ops *eemi_ops; struct zynqmp_aes_dev
> > +*aes_dd;
>
> I still think that using a global variable for storing device driver data is bad.
I think storing the list of dd's would solve up the issue with global variable, but there is only one AES instance here.
Please suggest
>
> > +
> > +struct zynqmp_aes_dev {
> > + struct device *dev;
> > +};
> > +
> > +struct zynqmp_aes_op {
> > + struct zynqmp_aes_dev *dd;
> > + void *src;
> > + void *dst;
> > + int len;
> > + u8 key[ZYNQMP_AES_KEY_SIZE];
> > + u8 *iv;
> > + u32 keylen;
> > + u32 keytype;
> > +};
> > +
> > +struct zynqmp_aes_data {
> > + u64 src;
> > + u64 iv;
> > + u64 key;
> > + u64 dst;
> > + u64 size;
> > + u64 optype;
> > + u64 keysrc;
> > +};
> > +
> > +static int zynqmp_setkey_blk(struct crypto_tfm *tfm, const u8 *key,
> > + unsigned int len)
> > +{
> > + struct zynqmp_aes_op *op = crypto_tfm_ctx(tfm);
> > +
> > + if (((len != 1) && (len != ZYNQMP_AES_KEY_SIZE)) || (!key))
>
> typo, two space
Will fix in the next version
>
> > + return -EINVAL;
> > +
> > + if (len == 1) {
> > + op->keytype = *key;
> > +
> > + if ((op->keytype < ZYNQMP_AES_KUP_KEY) ||
> > + (op->keytype > ZYNQMP_AES_PUF_KEY))
> > + return -EINVAL;
> > +
> > + } else if (len == ZYNQMP_AES_KEY_SIZE) {
> > + op->keytype = ZYNQMP_AES_KUP_KEY;
> > + op->keylen = len;
> > + memcpy(op->key, key, len);
> > + }
> > +
> > + return 0;
> > +}
>
> It seems your driver does not support AES keysize of 128/196, you need to
> fallback in that case.
[Kalyani] In case of 128/196 keysize, returning the error would suffice ?
Or still algorithm need to work ?
If error is enough, it is taken care by this condition
if (((len != 1) && (len != ZYNQMP_AES_KEY_SIZE)) || (!key))
> You need to comment the keylen=1 usecase and use a define for this value.
>
Will fix in next version
> > +
> > +static int zynqmp_aes_xcrypt(struct blkcipher_desc *desc,
> > + struct scatterlist *dst,
> > + struct scatterlist *src,
> > + unsigned int nbytes,
> > + unsigned int flags)
> > +{
> > + struct zynqmp_aes_op *op = crypto_blkcipher_ctx(desc->tfm);
> > + struct zynqmp_aes_dev *dd = aes_dd;
> > + int err, ret, copy_bytes, src_data = 0, dst_data = 0;
> > + dma_addr_t dma_addr, dma_addr_buf;
> > + struct zynqmp_aes_data *abuf;
> > + struct blkcipher_walk walk;
> > + unsigned int data_size;
> > + size_t dma_size;
> > + char *kbuf;
> > +
> > + if (!eemi_ops->aes)
> > + return -ENOTSUPP;
> > +
> > + if (op->keytype == ZYNQMP_AES_KUP_KEY)
> > + dma_size = nbytes + ZYNQMP_AES_KEY_SIZE
> > + + ZYNQMP_AES_IV_SIZE;
> > + else
> > + dma_size = nbytes + ZYNQMP_AES_IV_SIZE;
> > +
> > + kbuf = dma_alloc_coherent(dd->dev, dma_size, &dma_addr,
> GFP_KERNEL);
> > + if (!kbuf)
> > + return -ENOMEM;
> > +
> > + abuf = dma_alloc_coherent(dd->dev, sizeof(struct zynqmp_aes_data),
> > + &dma_addr_buf, GFP_KERNEL);
> > + if (!abuf) {
> > + dma_free_coherent(dd->dev, dma_size, kbuf, dma_addr);
> > + return -ENOMEM;
> > + }
> > +
> > + data_size = nbytes;
> > + blkcipher_walk_init(&walk, dst, src, data_size);
> > + err = blkcipher_walk_virt(desc, &walk);
> > + op->iv = walk.iv;
> > +
> > + while ((nbytes = walk.nbytes)) {
> > + op->src = walk.src.virt.addr;
> > + memcpy(kbuf + src_data, op->src, nbytes);
> > + src_data = src_data + nbytes;
> > + nbytes &= (ZYNQMP_AES_BLOCKSIZE - 1);
> > + err = blkcipher_walk_done(desc, &walk, nbytes);
> > + }
> > + memcpy(kbuf + data_size, op->iv, ZYNQMP_AES_IV_SIZE);
> > + abuf->src = dma_addr;
> > + abuf->dst = dma_addr;
> > + abuf->iv = abuf->src + data_size;
> > + abuf->size = data_size - ZYNQMP_AES_GCM_SIZE;
> > + abuf->optype = flags;
> > + abuf->keysrc = op->keytype;
> > +
> > + if (op->keytype == ZYNQMP_AES_KUP_KEY) {
> > + memcpy(kbuf + data_size + ZYNQMP_AES_IV_SIZE,
> > + op->key, ZYNQMP_AES_KEY_SIZE);
> > +
> > + abuf->key = abuf->src + data_size + ZYNQMP_AES_IV_SIZE;
> > + } else {
> > + abuf->key = 0;
> > + }
> > + eemi_ops->aes(dma_addr_buf, &ret);
> > +
> > + if (ret != 0) {
> > + switch (ret) {
> > + case ZYNQMP_AES_GCM_TAG_MISMATCH_ERR:
> > + dev_err(dd->dev, "ERROR: Gcm Tag mismatch\n\r");
> > + break;
> > + case ZYNQMP_AES_SIZE_ERR:
> > + dev_err(dd->dev, "ERROR : Non word aligned
> data\n\r");
> > + break;
> > + case ZYNQMP_AES_WRONG_KEY_SRC_ERR:
> > + dev_err(dd->dev, "ERROR: Wrong KeySrc, enable secure
> mode\n\r");
> > + break;
> > + case ZYNQMP_AES_PUF_NOT_PROGRAMMED:
> > + dev_err(dd->dev, "ERROR: PUF is not registered\r\n");
> > + break;
> > + default:
> > + dev_err(dd->dev, "ERROR: Invalid");
> > + break;
> > + }
> > + goto END;
> > + }
> > + if (flags)
> > + copy_bytes = data_size;
> > + else
> > + copy_bytes = data_size - ZYNQMP_AES_GCM_SIZE;
> > +
> > + blkcipher_walk_init(&walk, dst, src, copy_bytes);
> > + err = blkcipher_walk_virt(desc, &walk);
> > +
> > + while ((nbytes = walk.nbytes)) {
> > + memcpy(walk.dst.virt.addr, kbuf + dst_data, nbytes);
> > + dst_data = dst_data + nbytes;
> > + nbytes &= (ZYNQMP_AES_BLOCKSIZE - 1);
> > + err = blkcipher_walk_done(desc, &walk, nbytes);
> > + }
> > +END:
> > + memset(kbuf, 0, dma_size);
> > + memset(abuf, 0, sizeof(struct zynqmp_aes_data));
> > + dma_free_coherent(dd->dev, dma_size, kbuf, dma_addr);
> > + dma_free_coherent(dd->dev, sizeof(struct zynqmp_aes_data),
> > + abuf, dma_addr_buf);
> > + return err;
> > +}
> > +
> > +static int zynqmp_aes_decrypt(struct blkcipher_desc *desc,
> > + struct scatterlist *dst,
> > + struct scatterlist *src,
> > + unsigned int nbytes)
> > +{
> > + return zynqmp_aes_xcrypt(desc, dst, src, nbytes,
> > +ZYNQMP_AES_DECRYPT); }
> > +
> > +static int zynqmp_aes_encrypt(struct blkcipher_desc *desc,
> > + struct scatterlist *dst,
> > + struct scatterlist *src,
> > + unsigned int nbytes)
> > +{
> > + return zynqmp_aes_xcrypt(desc, dst, src, nbytes,
> > +ZYNQMP_AES_ENCRYPT); }
> > +
> > +static struct crypto_alg zynqmp_alg = {
> > + .cra_name = "xilinx-zynqmp-aes",
> > + .cra_driver_name = "zynqmp-aes-gcm",
> > + .cra_priority = 400,
> > + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
> > + CRYPTO_ALG_KERN_DRIVER_ONLY,
> > + .cra_blocksize = ZYNQMP_AES_BLOCKSIZE,
> > + .cra_ctxsize = sizeof(struct zynqmp_aes_op),
> > + .cra_alignmask = 15,
> > + .cra_type = &crypto_blkcipher_type,
> > + .cra_module = THIS_MODULE,
> > + .cra_u = {
> > + .blkcipher = {
> > + .min_keysize = 0,
>
> Are you sure to accept this a keysize of 0 ?
>
Will correct in next version
Regards
kalyani
> Regards
^ permalink raw reply
* [PATCH v1] pppoatm: use %*ph to print small buffer
From: Andy Shevchenko @ 2019-09-04 17:44 UTC (permalink / raw)
To: Mitchell Blank Jr, David S. Miller, netdev; +Cc: Andy Shevchenko
Use %*ph format to print small buffer as hex string.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
net/atm/pppoatm.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index bd3da9af5ef6..45d8e1d5d033 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -216,9 +216,7 @@ static void pppoatm_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
pvcc->chan.mtu += LLC_LEN;
break;
}
- pr_debug("Couldn't autodetect yet (skb: %02X %02X %02X %02X %02X %02X)\n",
- skb->data[0], skb->data[1], skb->data[2],
- skb->data[3], skb->data[4], skb->data[5]);
+ pr_debug("Couldn't autodetect yet (skb: %6ph)\n", skb->data);
goto error;
case e_vc:
break;
--
2.23.0.rc1
^ permalink raw reply related
* Re: [PATCH][next] Bluetooth: mgmt: Use struct_size() helper
From: Marcel Holtmann @ 2019-09-04 18:08 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: Johan Hedberg, David S. Miller, linux-bluetooth, netdev,
linux-kernel
In-Reply-To: <20190830011211.GA26531@embeddedor>
Hi Gustavo,
> One of the more common cases of allocation size calculations is finding
> the size of a structure that has a zero-sized array at the end, along
> with memory for some number of elements for that array. For example:
>
> struct mgmt_rp_get_connections {
> ...
> struct mgmt_addr_info addr[0];
> } __packed;
>
> Make use of the struct_size() helper instead of an open-coded version
> in order to avoid any potential type mistakes.
>
> So, replace the following form:
>
> sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
>
> with:
>
> struct_size(rp, addr, i)
>
> Also, notice that, in this case, variable rp_len is not necessary,
> hence it is removed.
>
> This code was detected with the help of Coccinelle.
>
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
> ---
> net/bluetooth/mgmt.c | 8 ++------
> 1 file changed, 2 insertions(+), 6 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* [PATCH net 00/11] net: fix nested device bugs
From: Taehee Yoo @ 2019-09-04 18:38 UTC (permalink / raw)
To: davem, netdev, j.vosburgh, vfalico, andy, jiri, sd, roopa, saeedm,
manishc, rahulv, kys, haiyangz, sthemmin, sashal, hare, varun,
ubraun, kgraul
Cc: ap420073
This patchset fixes several bugs that are related to nesting
device infrastructure.
Current nesting infrastructure code doesn't limit the depth level of
devices. nested devices could be handled recursively. at that moment,
it needs huge memory and stack overflow could occur.
Below devices type have same bug.
VLAN, BONDING, TEAM, MACSEC, MACVLAN and VXLAN.
Test commands:
ip link add dummy0 type dummy
ip link add vlan1 link dummy0 type vlan id 1
for i in {2..100}
do
let A=$i-1
ip link add name vlan$i link vlan$A type vlan id $i
done
ip link del dummy0
1st patch actually fixes the root cause.
It adds new common variables {upper/lower}_level that represent
depth level. upper_level variable is depth of upper devices.
lower_level variable is depth of lower devices.
[U][L] [U][L]
vlan1 1 5 vlan4 1 4
vlan2 2 4 vlan5 2 3
vlan3 3 3 |
| |
+------------+
|
vlan6 4 2
dummy0 5 1
After this patch, the nesting infrastructure code uses this variable to
check the depth level.
2, 4, 5, 6, 7 patches fix lockdep related problem.
Before this patch, devices use static lockdep map.
So, if devices that are same type is nested, lockdep will warn about
recursive situation.
These patches make these devices use dynamic lockdep key instead of
static lock or subclass.
3rd patch splits IFF_BONDING flag into IFF_BONDING and IFF_BONDING_SLAVE.
Before this patch, there is only IFF_BONDING flags, which means
a bonding master or a bonding slave device.
But this single flag could be problem when bonding devices are set to
nested.
8th patch fixes a refcnt leak in the macsec module.
9th patch adds ignore flag to an adjacent structure.
In order to exchange an adjacent node safely, ignore flag is needed.
10th patch makes vxlan add an adjacent link to limit depth level.
11th patch removes unnecessary variables and callback.
Taehee Yoo (11):
net: core: limit nested device depth
vlan: use dynamic lockdep key instead of subclass
bonding: split IFF_BONDING into IFF_BONDING and IFF_BONDING_SLAVE
bonding: use dynamic lockdep key instead of subclass
team: use dynamic lockdep key instead of static key
macsec: use dynamic lockdep key instead of subclass
macvlan: use dynamic lockdep key instead of subclass
macsec: fix refcnt leak in module exit routine
net: core: add ignore flag to netdev_adjacent structure
vxlan: add adjacent link to limit depth level
net: remove unnecessary variables and callback
drivers/net/bonding/bond_alb.c | 2 +-
drivers/net/bonding/bond_main.c | 87 ++++--
.../net/ethernet/mellanox/mlx5/core/en_tc.c | 2 +-
.../ethernet/qlogic/netxen/netxen_nic_main.c | 2 +-
drivers/net/hyperv/netvsc_drv.c | 3 +-
drivers/net/macsec.c | 50 ++--
drivers/net/macvlan.c | 36 ++-
drivers/net/team/team.c | 61 ++++-
drivers/net/vxlan.c | 71 ++++-
drivers/scsi/fcoe/fcoe.c | 2 +-
drivers/target/iscsi/cxgbit/cxgbit_cm.c | 2 +-
include/linux/if_macvlan.h | 3 +-
include/linux/if_team.h | 5 +
include/linux/if_vlan.h | 13 +-
include/linux/netdevice.h | 29 +-
include/net/bonding.h | 4 +-
include/net/vxlan.h | 1 +
net/8021q/vlan.c | 1 -
net/8021q/vlan_dev.c | 32 +--
net/core/dev.c | 252 ++++++++++++++++--
net/core/dev_addr_lists.c | 12 +-
net/smc/smc_core.c | 2 +-
net/smc/smc_pnet.c | 2 +-
23 files changed, 519 insertions(+), 155 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH net 01/11] net: core: limit nested device depth
From: Taehee Yoo @ 2019-09-04 18:38 UTC (permalink / raw)
To: davem, netdev, j.vosburgh, vfalico, andy, jiri, sd, roopa, saeedm,
manishc, rahulv, kys, haiyangz, sthemmin, sashal, hare, varun,
ubraun, kgraul
Cc: ap420073
Current code doesn't limit the number of nested devices.
Nested devices would be handled recursively and this needs huge stack
memory. So, unlimited nested devices could make stack overflow.
This patch adds upper_level and lower_leve, they are common variables
and represent maximum lower/upper depth.
When upper/lower device is attached or dettached,
{lower/upper}_level are updated. and if maximum depth is bigger than 8,
attach routine fails and returns -EMLINK.
Test commands:
ip link add dummy0 type dummy
ip link add link dummy0 name vlan1 type vlan id 1
ip link set vlan1 up
for i in {2..100}
do
let A=$i-1
ip link add name vlan$i link vlan$A type vlan id $i
done
Splat looks like:
[ 140.483124] BUG: looking up invalid subclass: 8
[ 140.483505] turning off the locking correctness validator.
[ 140.483505] CPU: 0 PID: 1324 Comm: ip Not tainted 5.3.0-rc7+ #322
[ 140.483505] Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 07/08/2015
[ 140.483505] Call Trace:
[ 140.483505] dump_stack+0x7c/0xbb
[ 140.483505] register_lock_class+0x64d/0x14d0
[ 140.483505] ? is_dynamic_key+0x230/0x230
[ 140.483505] ? module_assert_mutex_or_preempt+0x41/0x70
[ 140.483505] ? __module_address+0x3f/0x3c0
[ 140.483505] lockdep_init_map+0x24e/0x630
[ 140.483505] vlan_dev_init+0x828/0xce0 [8021q]
[ 140.483505] register_netdevice+0x24f/0xd70
[ 140.483505] ? netdev_change_features+0xa0/0xa0
[ 140.483505] ? dev_get_nest_level+0xe1/0x170
[ 140.483505] register_vlan_dev+0x29b/0x710 [8021q]
[ 140.483505] __rtnl_newlink+0xb75/0x1180
[ ... ]
[ 168.446539] WARNING: can't dereference registers at 00000000bef3d701 for ip apic_timer_interrupt+0xf/0x20
[ 168.466843] ==================================================================
[ 168.469452] BUG: KASAN: slab-out-of-bounds in __unwind_start+0x71/0x850
[ 168.480707] Write of size 88 at addr ffff8880b8856d38 by task ip/1758
[ 168.480707]
[ 168.480707] CPU: 1 PID: 1758 Comm: ip Not tainted 5.3.0-rc7+ #322
[ ... ]
[ 168.794493] Rebooting in 5 seconds..
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
---
include/linux/netdevice.h | 4 ++
net/core/dev.c | 106 ++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 88292953aa6f..5bb5756129af 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1624,6 +1624,8 @@ enum netdev_priv_flags {
* @type: Interface hardware type
* @hard_header_len: Maximum hardware header length.
* @min_header_len: Minimum hardware header length
+ * @upper_level: Maximum depth level of upper devices.
+ * @lower_level: Maximum depth level of lower devices.
*
* @needed_headroom: Extra headroom the hardware may need, but not in all
* cases can this be guaranteed
@@ -1854,6 +1856,8 @@ struct net_device {
unsigned short type;
unsigned short hard_header_len;
unsigned char min_header_len;
+ unsigned char upper_level;
+ unsigned char lower_level;
unsigned short needed_headroom;
unsigned short needed_tailroom;
diff --git a/net/core/dev.c b/net/core/dev.c
index 0891f499c1bb..6a4b4ce62204 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -146,6 +146,7 @@
#include "net-sysfs.h"
#define MAX_GRO_SKBS 8
+#define MAX_NEST_DEV 8
/* This should be increased if a protocol with a bigger head is added. */
#define GRO_MAX_HEAD (MAX_HEADER + 128)
@@ -6602,6 +6603,21 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
}
EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu);
+static struct net_device *netdev_next_upper_dev(struct net_device *dev,
+ struct list_head **iter)
+{
+ struct netdev_adjacent *upper;
+
+ upper = list_entry((*iter)->next, struct netdev_adjacent, list);
+
+ if (&upper->list == &dev->adj_list.upper)
+ return NULL;
+
+ *iter = &upper->list;
+
+ return upper->dev;
+}
+
static struct net_device *netdev_next_upper_dev_rcu(struct net_device *dev,
struct list_head **iter)
{
@@ -6619,6 +6635,33 @@ static struct net_device *netdev_next_upper_dev_rcu(struct net_device *dev,
return upper->dev;
}
+int netdev_walk_all_upper_dev(struct net_device *dev,
+ int (*fn)(struct net_device *dev,
+ void *data),
+ void *data)
+{
+ struct net_device *udev;
+ struct list_head *iter;
+ int ret;
+
+ for (iter = &dev->adj_list.upper,
+ udev = netdev_next_upper_dev(dev, &iter);
+ udev;
+ udev = netdev_next_upper_dev(dev, &iter)) {
+ /* first is the upper device itself */
+ ret = fn(udev, data);
+ if (ret)
+ return ret;
+
+ /* then look at all of its upper devices */
+ ret = netdev_walk_all_upper_dev(udev, fn, data);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
int netdev_walk_all_upper_dev_rcu(struct net_device *dev,
int (*fn)(struct net_device *dev,
void *data),
@@ -6785,6 +6828,52 @@ static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev,
return lower->dev;
}
+static u8 __netdev_upper_depth(struct net_device *dev)
+{
+ struct net_device *udev;
+ struct list_head *iter;
+ u8 max_depth = 0;
+
+ for (iter = &dev->adj_list.upper,
+ udev = netdev_next_upper_dev(dev, &iter);
+ udev;
+ udev = netdev_next_upper_dev(dev, &iter)) {
+ if (max_depth < udev->upper_level)
+ max_depth = udev->upper_level;
+ }
+
+ return max_depth;
+}
+
+static u8 __netdev_lower_depth(struct net_device *dev)
+{
+ struct net_device *ldev;
+ struct list_head *iter;
+ u8 max_depth = 0;
+
+ for (iter = &dev->adj_list.lower,
+ ldev = netdev_next_lower_dev(dev, &iter);
+ ldev;
+ ldev = netdev_next_lower_dev(dev, &iter)) {
+ if (max_depth < ldev->lower_level)
+ max_depth = ldev->lower_level;
+ }
+
+ return max_depth;
+}
+
+static int __netdev_update_upper_level(struct net_device *dev, void *data)
+{
+ dev->upper_level = __netdev_upper_depth(dev) + 1;
+ return 0;
+}
+
+static int __netdev_update_lower_level(struct net_device *dev, void *data)
+{
+ dev->lower_level = __netdev_lower_depth(dev) + 1;
+ return 0;
+}
+
int netdev_walk_all_lower_dev_rcu(struct net_device *dev,
int (*fn)(struct net_device *dev,
void *data),
@@ -7063,6 +7152,9 @@ static int __netdev_upper_dev_link(struct net_device *dev,
if (netdev_has_upper_dev(upper_dev, dev))
return -EBUSY;
+ if ((dev->lower_level + upper_dev->upper_level) > MAX_NEST_DEV)
+ return -EMLINK;
+
if (!master) {
if (netdev_has_upper_dev(dev, upper_dev))
return -EEXIST;
@@ -7089,6 +7181,12 @@ static int __netdev_upper_dev_link(struct net_device *dev,
if (ret)
goto rollback;
+ __netdev_update_upper_level(dev, NULL);
+ netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL);
+
+ __netdev_update_lower_level(upper_dev, NULL);
+ netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, NULL);
+
return 0;
rollback:
@@ -7171,6 +7269,12 @@ void netdev_upper_dev_unlink(struct net_device *dev,
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
&changeupper_info.info);
+
+ __netdev_update_upper_level(dev, NULL);
+ netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL);
+
+ __netdev_update_lower_level(upper_dev, NULL);
+ netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, NULL);
}
EXPORT_SYMBOL(netdev_upper_dev_unlink);
@@ -9157,6 +9261,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
dev->gso_max_size = GSO_MAX_SIZE;
dev->gso_max_segs = GSO_MAX_SEGS;
+ dev->upper_level = 1;
+ dev->lower_level = 1;
INIT_LIST_HEAD(&dev->napi_list);
INIT_LIST_HEAD(&dev->unreg_list);
--
2.17.1
^ 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