Skip to content

Commit

Permalink
tools: bpftool: improve architecture detection by using ifindex
Browse files Browse the repository at this point in the history
The current architecture detection method in bpftool is designed for host
case.

For offload case, we can't use the architecture of "bpftool" itself.
Instead, we could call the existing "ifindex_to_name_ns" to get DEVNAME,
then read pci id from /sys/class/dev/DEVNAME/device/vendor, finally we map
vendor id to bfd arch name which will finally be used to select bfd backend
for the disassembler.

Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Jiong Wang <jiong.wang@netronome.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
  • Loading branch information
Jiong Wang authored and Daniel Borkmann committed Jan 18, 2018
1 parent eb1d7db commit e659359
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 3 deletions.
72 changes: 72 additions & 0 deletions tools/bpf/bpftool/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
/* Author: Jakub Kicinski <kubakici@wp.pl> */

#include <errno.h>
#include <fcntl.h>
#include <fts.h>
#include <libgen.h>
#include <mntent.h>
Expand Down Expand Up @@ -433,6 +434,77 @@ ifindex_to_name_ns(__u32 ifindex, __u32 ns_dev, __u32 ns_ino, char *buf)
return if_indextoname(ifindex, buf);
}

static int read_sysfs_hex_int(char *path)
{
char vendor_id_buf[8];
int len;
int fd;

fd = open(path, O_RDONLY);
if (fd < 0) {
p_err("Can't open %s: %s", path, strerror(errno));
return -1;
}

len = read(fd, vendor_id_buf, sizeof(vendor_id_buf));
close(fd);
if (len < 0) {
p_err("Can't read %s: %s", path, strerror(errno));
return -1;
}
if (len >= (int)sizeof(vendor_id_buf)) {
p_err("Value in %s too long", path);
return -1;
}

vendor_id_buf[len] = 0;

return strtol(vendor_id_buf, NULL, 0);
}

static int read_sysfs_netdev_hex_int(char *devname, const char *entry_name)
{
char full_path[64];

snprintf(full_path, sizeof(full_path), "/sys/class/net/%s/device/%s",
devname, entry_name);

return read_sysfs_hex_int(full_path);
}

const char *ifindex_to_bfd_name_ns(__u32 ifindex, __u64 ns_dev, __u64 ns_ino)
{
char devname[IF_NAMESIZE];
int vendor_id;
int device_id;

if (!ifindex_to_name_ns(ifindex, ns_dev, ns_ino, devname)) {
p_err("Can't get net device name for ifindex %d: %s", ifindex,
strerror(errno));
return NULL;
}

vendor_id = read_sysfs_netdev_hex_int(devname, "vendor");
if (vendor_id < 0) {
p_err("Can't get device vendor id for %s", devname);
return NULL;
}

switch (vendor_id) {
case 0x19ee:
device_id = read_sysfs_netdev_hex_int(devname, "device");
if (device_id != 0x4000 &&
device_id != 0x6000 &&
device_id != 0x6003)
p_info("Unknown NFP device ID, assuming it is NFP-6xxx arch");
return "NFP-6xxx";
default:
p_err("Can't get bfd arch name for device vendor id 0x%04x",
vendor_id);
return NULL;
}
}

void print_dev_plain(__u32 ifindex, __u64 ns_dev, __u64 ns_inode)
{
char name[IF_NAMESIZE];
Expand Down
16 changes: 15 additions & 1 deletion tools/bpf/bpftool/jit_disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ static int fprintf_json(void *out, const char *fmt, ...)
return 0;
}

void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes)
void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
const char *arch)
{
disassembler_ftype disassemble;
struct disassemble_info info;
Expand All @@ -100,6 +101,19 @@ void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes)
else
init_disassemble_info(&info, stdout,
(fprintf_ftype) fprintf);

/* Update architecture info for offload. */
if (arch) {
const bfd_arch_info_type *inf = bfd_scan_arch(arch);

if (inf) {
bfdf->arch_info = inf;
} else {
p_err("No libfd support for %s", arch);
return;
}
}

info.arch = bfd_get_arch(bfdf);
info.mach = bfd_get_mach(bfdf);
info.buffer = image;
Expand Down
5 changes: 4 additions & 1 deletion tools/bpf/bpftool/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ int do_cgroup(int argc, char **arg);

int prog_parse_fd(int *argc, char ***argv);

void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes);
void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
const char *arch);
void print_hex_data_json(uint8_t *data, size_t len);

const char *ifindex_to_bfd_name_ns(__u32 ifindex, __u64 ns_dev, __u64 ns_ino);

#endif
12 changes: 11 additions & 1 deletion tools/bpf/bpftool/prog.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,17 @@ static int do_dump(int argc, char **argv)
}
} else {
if (member_len == &info.jited_prog_len) {
disasm_print_insn(buf, *member_len, opcodes);
const char *name = NULL;

if (info.ifindex) {
name = ifindex_to_bfd_name_ns(info.ifindex,
info.netns_dev,
info.netns_ino);
if (!name)
goto err_free;
}

disasm_print_insn(buf, *member_len, opcodes, name);
} else {
kernel_syms_load(&dd);
if (json_output)
Expand Down

0 comments on commit e659359

Please sign in to comment.