mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 14:04:26 -04:00 
			
		
		
		
	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);
 |