* [PATCH] tc, bpf: add option to dump bpf verifier as C program fragment
@ 2018-06-17 8:48 Ophir Munk
2018-06-18 20:18 ` Jakub Kicinski
0 siblings, 1 reply; 5+ messages in thread
From: Ophir Munk @ 2018-06-17 8:48 UTC (permalink / raw)
To: netdev, Stephen Hemminger, David Ahern
Cc: Thomas Monjalon, Olga Shern, Ophir Munk
Similar to cbpf used within tcpdump utility with a "-d" option to dump
the compiled packet-matching code in a human readable form - tc has the
"verbose" option to dump ebpf verifier output.
Another useful option of cbpf using tcpdump "-dd" option is to dump
packet-matching code a C program fragment. Similar to this - this commit
adds a new tc ebpf option named "code" to dump ebpf verifier as C program
fragment.
Existing "verbose" option sample output:
Verifier analysis:
0: (61) r2 = *(u32 *)(r1 +52)
1: (18) r3 = 0xdeadbeef
3: (63) *(u32 *)(r10 -4) = r3
.
.
11: (63) *(u32 *)(r1 +52) = r2
12: (18) r0 = 0xffffffff
14: (95) exit
New "code" option sample output:
/* struct bpf_insn cls_q_code[] = { */
{0x61, 2, 1, 52, 0x00000000},
{0x18, 3, 0, 0, 0xdeadbeef},
{0x00, 0, 0, 0, 0x00000000},
.
.
{0x63, 1, 2, 52, 0x00000000},
{0x18, 0, 0, 0, 0xffffffff},
{0x00, 0, 0, 0, 0x00000000},
{0x95, 0, 0, 0, 0x00000000},
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
include/bpf_util.h | 1 +
lib/bpf.c | 35 +++++++++++++++++++++++++++++------
tc/m_bpf.c | 3 ++-
3 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/include/bpf_util.h b/include/bpf_util.h
index 219beb4..cf611c5 100644
--- a/include/bpf_util.h
+++ b/include/bpf_util.h
@@ -72,6 +72,7 @@ struct bpf_cfg_in {
enum bpf_mode mode;
__u32 ifindex;
bool verbose;
+ bool code;
int argc;
char **argv;
struct sock_filter opcodes[BPF_MAXINSNS];
diff --git a/lib/bpf.c b/lib/bpf.c
index c38d92d..b13ec3f 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -113,10 +113,10 @@ const char *bpf_prog_to_default_section(enum bpf_prog_type type)
#ifdef HAVE_ELF
static int bpf_obj_open(const char *path, enum bpf_prog_type type,
- const char *sec, __u32 ifindex, bool verbose);
+ const char *sec, __u32 ifindex, bool verbose, bool code);
#else
static int bpf_obj_open(const char *path, enum bpf_prog_type type,
- const char *sec, __u32 ifindex, bool verbose)
+ const char *sec, __u32 ifindex, bool verbose, bool code)
{
fprintf(stderr, "No ELF library support compiled in.\n");
errno = ENOSYS;
@@ -809,6 +809,7 @@ static int bpf_do_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl)
{
const char *file, *section, *uds_name;
bool verbose = false;
+ bool code = false;
int i, ret, argc;
char **argv;
@@ -890,6 +891,11 @@ static int bpf_do_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl)
NEXT_ARG_FWD();
}
+ if (argc > 0 && matches(*argv, "code") == 0) {
+ code = true;
+ NEXT_ARG_FWD();
+ }
+
PREV_ARG();
}
@@ -911,6 +917,7 @@ static int bpf_do_parse(struct bpf_cfg_in *cfg, const bool *opt_tbl)
cfg->uds = uds_name;
cfg->argc = argc;
cfg->argv = argv;
+ cfg->code = code;
cfg->verbose = verbose;
return ret;
@@ -921,7 +928,7 @@ static int bpf_do_load(struct bpf_cfg_in *cfg)
if (cfg->mode == EBPF_OBJECT) {
cfg->prog_fd = bpf_obj_open(cfg->object, cfg->type,
cfg->section, cfg->ifindex,
- cfg->verbose);
+ cfg->verbose, cfg->code);
return cfg->prog_fd;
}
return 0;
@@ -1133,6 +1140,7 @@ struct bpf_elf_ctx {
enum bpf_prog_type type;
__u32 ifindex;
bool verbose;
+ bool code;
struct bpf_elf_st stat;
struct bpf_hash_entry *ht[256];
char *log;
@@ -1179,6 +1187,17 @@ bpf_dump_error(struct bpf_elf_ctx *ctx, const char *format, ...)
}
}
+static void bpf_dump_code(const char *section, const struct bpf_insn *insns, unsigned int cnt)
+{
+ int i;
+ fprintf(stderr, "/* struct bpf_insn %s_code[] = { */\n", section);
+ for (i=0; i < cnt; i++) {
+ fprintf(stderr, "\t{0x%.2x, %4u, %4u, %8d, 0x%.8x},\n",
+ insns[i].code, insns[i].dst_reg, insns[i].src_reg, insns[i].off, insns[i].imm);
+ }
+ fprintf(stderr, "\n");
+}
+
static int bpf_log_realloc(struct bpf_elf_ctx *ctx)
{
const size_t log_max = UINT_MAX >> 8;
@@ -1526,6 +1545,9 @@ retry:
bpf_prog_report(fd, section, prog, ctx);
}
+ if (ctx->code)
+ bpf_dump_code(section, prog->insns, prog->size / sizeof(struct bpf_insn));
+
return fd;
}
@@ -2439,7 +2461,7 @@ static void bpf_get_cfg(struct bpf_elf_ctx *ctx)
static int bpf_elf_ctx_init(struct bpf_elf_ctx *ctx, const char *pathname,
enum bpf_prog_type type, __u32 ifindex,
- bool verbose)
+ bool verbose, bool code)
{
int ret = -EINVAL;
@@ -2450,6 +2472,7 @@ static int bpf_elf_ctx_init(struct bpf_elf_ctx *ctx, const char *pathname,
memset(ctx, 0, sizeof(*ctx));
bpf_get_cfg(ctx);
ctx->verbose = verbose;
+ ctx->code = code;
ctx->type = type;
ctx->ifindex = ifindex;
@@ -2543,12 +2566,12 @@ static void bpf_elf_ctx_destroy(struct bpf_elf_ctx *ctx, bool failure)
static struct bpf_elf_ctx __ctx;
static int bpf_obj_open(const char *pathname, enum bpf_prog_type type,
- const char *section, __u32 ifindex, bool verbose)
+ const char *section, __u32 ifindex, bool verbose, bool code)
{
struct bpf_elf_ctx *ctx = &__ctx;
int fd = 0, ret;
- ret = bpf_elf_ctx_init(ctx, pathname, type, ifindex, verbose);
+ ret = bpf_elf_ctx_init(ctx, pathname, type, ifindex, verbose, code);
if (ret < 0) {
fprintf(stderr, "Cannot initialize ELF context!\n");
return ret;
diff --git a/tc/m_bpf.c b/tc/m_bpf.c
index 1c1f71c..9947113 100644
--- a/tc/m_bpf.c
+++ b/tc/m_bpf.c
@@ -33,7 +33,8 @@ static void explain(void)
fprintf(stderr, "\n");
fprintf(stderr, "eBPF use case:\n");
fprintf(stderr, " object-file FILE [ section ACT_NAME ] [ export UDS_FILE ]");
- fprintf(stderr, " [ verbose ]\n");
+ fprintf(stderr, " [ verbose ]");
+ fprintf(stderr, " [ code ]\n");
fprintf(stderr, " object-pinned FILE\n");
fprintf(stderr, "\n");
fprintf(stderr, "Where BPF_BYTECODE := \'s,c t f k,c t f k,c t f k,...\'\n");
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] tc, bpf: add option to dump bpf verifier as C program fragment
2018-06-17 8:48 [PATCH] tc, bpf: add option to dump bpf verifier as C program fragment Ophir Munk
@ 2018-06-18 20:18 ` Jakub Kicinski
2018-06-18 21:44 ` David Ahern
0 siblings, 1 reply; 5+ messages in thread
From: Jakub Kicinski @ 2018-06-18 20:18 UTC (permalink / raw)
To: Ophir Munk
Cc: netdev, Stephen Hemminger, David Ahern, Thomas Monjalon, Olga Shern
On Sun, 17 Jun 2018 08:48:41 +0000, Ophir Munk wrote:
> Similar to cbpf used within tcpdump utility with a "-d" option to dump
> the compiled packet-matching code in a human readable form - tc has the
> "verbose" option to dump ebpf verifier output.
> Another useful option of cbpf using tcpdump "-dd" option is to dump
> packet-matching code a C program fragment. Similar to this - this commit
> adds a new tc ebpf option named "code" to dump ebpf verifier as C program
> fragment.
>
> Existing "verbose" option sample output:
>
> Verifier analysis:
> 0: (61) r2 = *(u32 *)(r1 +52)
> 1: (18) r3 = 0xdeadbeef
> 3: (63) *(u32 *)(r10 -4) = r3
> .
> .
> 11: (63) *(u32 *)(r1 +52) = r2
> 12: (18) r0 = 0xffffffff
> 14: (95) exit
>
> New "code" option sample output:
>
> /* struct bpf_insn cls_q_code[] = { */
> {0x61, 2, 1, 52, 0x00000000},
> {0x18, 3, 0, 0, 0xdeadbeef},
> {0x00, 0, 0, 0, 0x00000000},
> .
> .
> {0x63, 1, 2, 52, 0x00000000},
> {0x18, 0, 0, 0, 0xffffffff},
> {0x00, 0, 0, 0, 0x00000000},
> {0x95, 0, 0, 0, 0x00000000},
>
> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Hmm... printing C arrays looks like hacky integration with some C
code... Would you not be better served by simply using libbpf in
whatever is consuming this output?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tc, bpf: add option to dump bpf verifier as C program fragment
2018-06-18 20:18 ` Jakub Kicinski
@ 2018-06-18 21:44 ` David Ahern
2018-06-19 22:13 ` Daniel Borkmann
0 siblings, 1 reply; 5+ messages in thread
From: David Ahern @ 2018-06-18 21:44 UTC (permalink / raw)
To: Jakub Kicinski, Ophir Munk
Cc: netdev, Stephen Hemminger, Thomas Monjalon, Olga Shern
[-- Attachment #1: Type: text/plain, Size: 1670 bytes --]
On 6/18/18 2:18 PM, Jakub Kicinski wrote:
> On Sun, 17 Jun 2018 08:48:41 +0000, Ophir Munk wrote:
>> Similar to cbpf used within tcpdump utility with a "-d" option to dump
>> the compiled packet-matching code in a human readable form - tc has the
>> "verbose" option to dump ebpf verifier output.
>> Another useful option of cbpf using tcpdump "-dd" option is to dump
>> packet-matching code a C program fragment. Similar to this - this commit
>> adds a new tc ebpf option named "code" to dump ebpf verifier as C program
>> fragment.
>>
>> Existing "verbose" option sample output:
>>
>> Verifier analysis:
>> 0: (61) r2 = *(u32 *)(r1 +52)
>> 1: (18) r3 = 0xdeadbeef
>> 3: (63) *(u32 *)(r10 -4) = r3
>> .
>> .
>> 11: (63) *(u32 *)(r1 +52) = r2
>> 12: (18) r0 = 0xffffffff
>> 14: (95) exit
>>
>> New "code" option sample output:
>>
>> /* struct bpf_insn cls_q_code[] = { */
>> {0x61, 2, 1, 52, 0x00000000},
>> {0x18, 3, 0, 0, 0xdeadbeef},
>> {0x00, 0, 0, 0, 0x00000000},
>> .
>> .
>> {0x63, 1, 2, 52, 0x00000000},
>> {0x18, 0, 0, 0, 0xffffffff},
>> {0x00, 0, 0, 0, 0x00000000},
>> {0x95, 0, 0, 0, 0x00000000},
>>
>> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
>
> Hmm... printing C arrays looks like hacky integration with some C
> code... Would you not be better served by simply using libbpf in
> whatever is consuming this output?
>
I was thinking the same. bpftool would provide options too -- print the
above, print in macro encodings and verifier. I gave an example of this
side by side dump at netconf 2.1. Does not look like the slides made it
online; see attached.
[-- Attachment #2: netconf-2.1-bpf.pdf --]
[-- Type: application/pdf, Size: 38266 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tc, bpf: add option to dump bpf verifier as C program fragment
2018-06-18 21:44 ` David Ahern
@ 2018-06-19 22:13 ` Daniel Borkmann
2018-06-20 16:40 ` Stephen Hemminger
0 siblings, 1 reply; 5+ messages in thread
From: Daniel Borkmann @ 2018-06-19 22:13 UTC (permalink / raw)
To: David Ahern, Jakub Kicinski, Ophir Munk
Cc: netdev, Stephen Hemminger, Thomas Monjalon, Olga Shern, ast
On 06/18/2018 11:44 PM, David Ahern wrote:
> On 6/18/18 2:18 PM, Jakub Kicinski wrote:
>> On Sun, 17 Jun 2018 08:48:41 +0000, Ophir Munk wrote:
>>> Similar to cbpf used within tcpdump utility with a "-d" option to dump
>>> the compiled packet-matching code in a human readable form - tc has the
>>> "verbose" option to dump ebpf verifier output.
>>> Another useful option of cbpf using tcpdump "-dd" option is to dump
>>> packet-matching code a C program fragment. Similar to this - this commit
>>> adds a new tc ebpf option named "code" to dump ebpf verifier as C program
>>> fragment.
>>>
>>> Existing "verbose" option sample output:
>>>
>>> Verifier analysis:
>>> 0: (61) r2 = *(u32 *)(r1 +52)
>>> 1: (18) r3 = 0xdeadbeef
>>> 3: (63) *(u32 *)(r10 -4) = r3
>>> .
>>> .
>>> 11: (63) *(u32 *)(r1 +52) = r2
>>> 12: (18) r0 = 0xffffffff
>>> 14: (95) exit
>>>
>>> New "code" option sample output:
>>>
>>> /* struct bpf_insn cls_q_code[] = { */
>>> {0x61, 2, 1, 52, 0x00000000},
>>> {0x18, 3, 0, 0, 0xdeadbeef},
>>> {0x00, 0, 0, 0, 0x00000000},
>>> .
>>> .
>>> {0x63, 1, 2, 52, 0x00000000},
>>> {0x18, 0, 0, 0, 0xffffffff},
>>> {0x00, 0, 0, 0, 0x00000000},
>>> {0x95, 0, 0, 0, 0x00000000},
>>>
>>> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
>>
>> Hmm... printing C arrays looks like hacky integration with some C
>> code... Would you not be better served by simply using libbpf in
>> whatever is consuming this output?
>
> I was thinking the same. bpftool would provide options too -- print the
> above, print in macro encodings and verifier. I gave an example of this
> side by side dump at netconf 2.1. Does not look like the slides made it
> online; see attached.
+1, I would also doubt that this adds a lot in terms of debuggability
when you're trying to load an object file with thousands of insns. Better
way would be to use llvm-objdump on the obj file to get to the annotated
disassembly, see also example in [0]. A .o to .c converter is wip for
libbpf/bpftool as presented in [1], which should provide the flexibility
to embedd an obj file.
Cheers,
Daniel
[0] http://cilium.readthedocs.io/en/latest/bpf/#llvm
[1] http://vger.kernel.org/netconf2018_files/AlexeiStarovoitov_netconf2018.pdf page 22
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] tc, bpf: add option to dump bpf verifier as C program fragment
2018-06-19 22:13 ` Daniel Borkmann
@ 2018-06-20 16:40 ` Stephen Hemminger
0 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2018-06-20 16:40 UTC (permalink / raw)
To: Daniel Borkmann
Cc: David Ahern, Jakub Kicinski, Ophir Munk, netdev, Thomas Monjalon,
Olga Shern, ast
On Wed, 20 Jun 2018 00:13:52 +0200
Daniel Borkmann <daniel@iogearbox.net> wrote:
> On 06/18/2018 11:44 PM, David Ahern wrote:
> > On 6/18/18 2:18 PM, Jakub Kicinski wrote:
> >> On Sun, 17 Jun 2018 08:48:41 +0000, Ophir Munk wrote:
> >>> Similar to cbpf used within tcpdump utility with a "-d" option to dump
> >>> the compiled packet-matching code in a human readable form - tc has the
> >>> "verbose" option to dump ebpf verifier output.
> >>> Another useful option of cbpf using tcpdump "-dd" option is to dump
> >>> packet-matching code a C program fragment. Similar to this - this commit
> >>> adds a new tc ebpf option named "code" to dump ebpf verifier as C program
> >>> fragment.
> >>>
> >>> Existing "verbose" option sample output:
> >>>
> >>> Verifier analysis:
> >>> 0: (61) r2 = *(u32 *)(r1 +52)
> >>> 1: (18) r3 = 0xdeadbeef
> >>> 3: (63) *(u32 *)(r10 -4) = r3
> >>> .
> >>> .
> >>> 11: (63) *(u32 *)(r1 +52) = r2
> >>> 12: (18) r0 = 0xffffffff
> >>> 14: (95) exit
> >>>
> >>> New "code" option sample output:
> >>>
> >>> /* struct bpf_insn cls_q_code[] = { */
> >>> {0x61, 2, 1, 52, 0x00000000},
> >>> {0x18, 3, 0, 0, 0xdeadbeef},
> >>> {0x00, 0, 0, 0, 0x00000000},
> >>> .
> >>> .
> >>> {0x63, 1, 2, 52, 0x00000000},
> >>> {0x18, 0, 0, 0, 0xffffffff},
> >>> {0x00, 0, 0, 0, 0x00000000},
> >>> {0x95, 0, 0, 0, 0x00000000},
> >>>
> >>> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
> >>
> >> Hmm... printing C arrays looks like hacky integration with some C
> >> code... Would you not be better served by simply using libbpf in
> >> whatever is consuming this output?
> >
> > I was thinking the same. bpftool would provide options too -- print the
> > above, print in macro encodings and verifier. I gave an example of this
> > side by side dump at netconf 2.1. Does not look like the slides made it
> > online; see attached.
>
> +1, I would also doubt that this adds a lot in terms of debuggability
> when you're trying to load an object file with thousands of insns. Better
> way would be to use llvm-objdump on the obj file to get to the annotated
> disassembly, see also example in [0]. A .o to .c converter is wip for
> libbpf/bpftool as presented in [1], which should provide the flexibility
> to embedd an obj file.
>
> Cheers,
> Daniel
>
> [0] http://cilium.readthedocs.io/en/latest/bpf/#llvm
> [1] http://vger.kernel.org/netconf2018_files/AlexeiStarovoitov_netconf2018.pdf page 22
I am going to not accept this for now. Please respin for iproute2 next if
you think bpftool won't be able to handle this.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-06-20 16:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-17 8:48 [PATCH] tc, bpf: add option to dump bpf verifier as C program fragment Ophir Munk
2018-06-18 20:18 ` Jakub Kicinski
2018-06-18 21:44 ` David Ahern
2018-06-19 22:13 ` Daniel Borkmann
2018-06-20 16:40 ` Stephen Hemminger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.