mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-06 22:08:54 +00:00
5582fbd613
With global NLS support enabled (CONFIG_BUILD_NLS), the linked libelf.so
and libbfd.so libraries will depend on libintl.so. Import the nls.mk helper
to set library prefixes and flags accordingly, and also conditionally add
"-lintl" as link-time library.
Fix a build error on ppc due to a EDEADLOCK redefinition in errno.h.
Use upstream stable kernel 5.8.9, and fix overriding of feature detection
to only allow/hide detected features. Also refresh existing patches.
Fixes: 2f0d672088
("bpftools: add utility and library packages supporting
eBPF usage")
Signed-off-by: Tony Ambardar <itugrok@yahoo.com>
232 lines
6.2 KiB
Diff
232 lines
6.2 KiB
Diff
From 6edda7633e4fdf33b91c2e86c05cab805a0dabb3 Mon Sep 17 00:00:00 2001
|
|
From: Tony Ambardar <tony.ambardar@gmail.com>
|
|
Date: Mon, 20 Jul 2020 19:48:16 -0700
|
|
Subject: [PATCH] bpftool: Use only nftw for file tree parsing
|
|
|
|
The bpftool sources include code to walk file trees, but use multiple
|
|
frameworks to do so: nftw and fts. While nftw conforms to POSIX/SUSv3 and
|
|
is widely available, fts is not conformant and less common, especially on
|
|
non-glibc systems. The inconsistent framework usage hampers maintenance
|
|
and portability of bpftool, in particular for embedded systems.
|
|
|
|
Standardize code usage by rewriting one fts-based function to use nftw and
|
|
clean up some related function warnings by extending use of "const char *"
|
|
arguments. This change helps in building bpftool against musl for OpenWrt.
|
|
|
|
Also fix an unsafe call to dirname() by duplicating the string to pass,
|
|
since some implementations may directly alter it. The same approach is
|
|
used in libbpf.c.
|
|
|
|
Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
|
|
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Reviewed-by: Quentin Monnet <quentin@isovalent.com>
|
|
Link: https://lore.kernel.org/bpf/20200721024817.13701-1-Tony.Ambardar@gmail.com
|
|
---
|
|
tools/bpf/bpftool/common.c | 137 ++++++++++++++++++++++---------------
|
|
tools/bpf/bpftool/main.h | 4 +-
|
|
2 files changed, 82 insertions(+), 59 deletions(-)
|
|
|
|
--- a/tools/bpf/bpftool/common.c
|
|
+++ b/tools/bpf/bpftool/common.c
|
|
@@ -1,10 +1,11 @@
|
|
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
|
/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
|
|
|
|
+#define _GNU_SOURCE
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
-#include <fts.h>
|
|
+#include <ftw.h>
|
|
#include <libgen.h>
|
|
#include <mntent.h>
|
|
#include <stdbool.h>
|
|
@@ -123,24 +124,35 @@ int mount_tracefs(const char *target)
|
|
return err;
|
|
}
|
|
|
|
-int open_obj_pinned(char *path, bool quiet)
|
|
+int open_obj_pinned(const char *path, bool quiet)
|
|
{
|
|
- int fd;
|
|
+ char *pname;
|
|
+ int fd = -1;
|
|
|
|
- fd = bpf_obj_get(path);
|
|
+ pname = strdup(path);
|
|
+ if (!pname) {
|
|
+ if (!quiet)
|
|
+ p_err("mem alloc failed");
|
|
+ goto out_ret;
|
|
+ }
|
|
+
|
|
+ fd = bpf_obj_get(pname);
|
|
if (fd < 0) {
|
|
if (!quiet)
|
|
- p_err("bpf obj get (%s): %s", path,
|
|
- errno == EACCES && !is_bpffs(dirname(path)) ?
|
|
+ p_err("bpf obj get (%s): %s", pname,
|
|
+ errno == EACCES && !is_bpffs(dirname(pname)) ?
|
|
"directory not in bpf file system (bpffs)" :
|
|
strerror(errno));
|
|
- return -1;
|
|
+ goto out_free;
|
|
}
|
|
|
|
+out_free:
|
|
+ free(pname);
|
|
+out_ret:
|
|
return fd;
|
|
}
|
|
|
|
-int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type)
|
|
+int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type)
|
|
{
|
|
enum bpf_obj_type type;
|
|
int fd;
|
|
@@ -330,71 +342,82 @@ void print_hex_data_json(uint8_t *data,
|
|
jsonw_end_array(json_wtr);
|
|
}
|
|
|
|
+/* extra params for nftw cb */
|
|
+static struct pinned_obj_table *build_fn_table;
|
|
+static enum bpf_obj_type build_fn_type;
|
|
+
|
|
+static int do_build_table_cb(const char *fpath, const struct stat *sb,
|
|
+ int typeflag, struct FTW *ftwbuf)
|
|
+{
|
|
+ struct bpf_prog_info pinned_info;
|
|
+ __u32 len = sizeof(pinned_info);
|
|
+ struct pinned_obj *obj_node;
|
|
+ enum bpf_obj_type objtype;
|
|
+ int fd, err = 0;
|
|
+
|
|
+ if (typeflag != FTW_F)
|
|
+ goto out_ret;
|
|
+
|
|
+ fd = open_obj_pinned(fpath, true);
|
|
+ if (fd < 0)
|
|
+ goto out_ret;
|
|
+
|
|
+ objtype = get_fd_type(fd);
|
|
+ if (objtype != build_fn_type)
|
|
+ goto out_close;
|
|
+
|
|
+ memset(&pinned_info, 0, sizeof(pinned_info));
|
|
+ if (bpf_obj_get_info_by_fd(fd, &pinned_info, &len))
|
|
+ goto out_close;
|
|
+
|
|
+ obj_node = calloc(1, sizeof(*obj_node));
|
|
+ if (!obj_node) {
|
|
+ err = -1;
|
|
+ goto out_close;
|
|
+ }
|
|
+
|
|
+ obj_node->id = pinned_info.id;
|
|
+ obj_node->path = strdup(fpath);
|
|
+ if (!obj_node->path) {
|
|
+ err = -1;
|
|
+ free(obj_node);
|
|
+ goto out_close;
|
|
+ }
|
|
+
|
|
+ hash_add(build_fn_table->table, &obj_node->hash, obj_node->id);
|
|
+out_close:
|
|
+ close(fd);
|
|
+out_ret:
|
|
+ return err;
|
|
+}
|
|
+
|
|
int build_pinned_obj_table(struct pinned_obj_table *tab,
|
|
enum bpf_obj_type type)
|
|
{
|
|
- struct bpf_prog_info pinned_info = {};
|
|
- struct pinned_obj *obj_node = NULL;
|
|
- __u32 len = sizeof(pinned_info);
|
|
struct mntent *mntent = NULL;
|
|
- enum bpf_obj_type objtype;
|
|
FILE *mntfile = NULL;
|
|
- FTSENT *ftse = NULL;
|
|
- FTS *fts = NULL;
|
|
- int fd, err;
|
|
+ int flags = FTW_PHYS;
|
|
+ int nopenfd = 16;
|
|
+ int err = 0;
|
|
|
|
mntfile = setmntent("/proc/mounts", "r");
|
|
if (!mntfile)
|
|
return -1;
|
|
|
|
+ build_fn_table = tab;
|
|
+ build_fn_type = type;
|
|
+
|
|
while ((mntent = getmntent(mntfile))) {
|
|
- char *path[] = { mntent->mnt_dir, NULL };
|
|
+ char *path = mntent->mnt_dir;
|
|
|
|
if (strncmp(mntent->mnt_type, "bpf", 3) != 0)
|
|
continue;
|
|
-
|
|
- fts = fts_open(path, 0, NULL);
|
|
- if (!fts)
|
|
- continue;
|
|
-
|
|
- while ((ftse = fts_read(fts))) {
|
|
- if (!(ftse->fts_info & FTS_F))
|
|
- continue;
|
|
- fd = open_obj_pinned(ftse->fts_path, true);
|
|
- if (fd < 0)
|
|
- continue;
|
|
-
|
|
- objtype = get_fd_type(fd);
|
|
- if (objtype != type) {
|
|
- close(fd);
|
|
- continue;
|
|
- }
|
|
- memset(&pinned_info, 0, sizeof(pinned_info));
|
|
- err = bpf_obj_get_info_by_fd(fd, &pinned_info, &len);
|
|
- if (err) {
|
|
- close(fd);
|
|
- continue;
|
|
- }
|
|
-
|
|
- obj_node = malloc(sizeof(*obj_node));
|
|
- if (!obj_node) {
|
|
- close(fd);
|
|
- fts_close(fts);
|
|
- fclose(mntfile);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- memset(obj_node, 0, sizeof(*obj_node));
|
|
- obj_node->id = pinned_info.id;
|
|
- obj_node->path = strdup(ftse->fts_path);
|
|
- hash_add(tab->table, &obj_node->hash, obj_node->id);
|
|
-
|
|
- close(fd);
|
|
- }
|
|
- fts_close(fts);
|
|
+ err = nftw(path, do_build_table_cb, nopenfd, flags);
|
|
+ if (err)
|
|
+ break;
|
|
}
|
|
fclose(mntfile);
|
|
- return 0;
|
|
+ return err;
|
|
}
|
|
|
|
void delete_pinned_obj_table(struct pinned_obj_table *tab)
|
|
--- a/tools/bpf/bpftool/main.h
|
|
+++ b/tools/bpf/bpftool/main.h
|
|
@@ -196,8 +196,8 @@ int cmd_select(const struct cmd *cmds, i
|
|
int get_fd_type(int fd);
|
|
const char *get_fd_type_name(enum bpf_obj_type type);
|
|
char *get_fdinfo(int fd, const char *key);
|
|
-int open_obj_pinned(char *path, bool quiet);
|
|
-int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type);
|
|
+int open_obj_pinned(const char *path, bool quiet);
|
|
+int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type);
|
|
int mount_bpffs_for_pin(const char *name);
|
|
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(int *, char ***));
|
|
int do_pin_fd(int fd, const char *name);
|