cregit-Linux how code gets into the kernel

Release 4.18 tools/bpf/bpftool/main.c

/*
 * Copyright (C) 2017 Netronome Systems, Inc.
 *
 * This software is dual licensed under the GNU General License Version 2,
 * June 1991 as shown in the file COPYING in the top-level directory of this
 * source tree or the BSD 2-Clause License provided below.  You have the
 * option to license this software under the complete terms of either license.
 *
 * The BSD 2-Clause License:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      1. Redistributions of source code must retain the above
 *         copyright notice, this list of conditions and the following
 *         disclaimer.
 *
 *      2. Redistributions in binary form must reproduce the above
 *         copyright notice, this list of conditions and the following
 *         disclaimer in the documentation and/or other materials
 *         provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/* Author: Jakub Kicinski <kubakici@wp.pl> */

#include <bfd.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <linux/bpf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <bpf.h>

#include "main.h"


#define BATCH_LINE_LEN_MAX 65536

#define BATCH_ARG_NB_MAX 4096


const char *bin_name;

static int last_argc;

static char **last_argv;

static int (*last_do_help)(int argc, char **argv);

json_writer_t *json_wtr;

bool pretty_output;

bool json_output;

bool show_pinned;

struct pinned_obj_table prog_table;

struct pinned_obj_table map_table;


static void __noreturn clean_and_exit(int i) { if (json_output) jsonw_destroy(&json_wtr); exit(i); }

Contributors

PersonTokensPropCommitsCommitProp
Quentin Monnet25100.00%1100.00%
Total25100.00%1100.00%


void usage(void) { last_do_help(last_argc - 1, last_argv + 1); clean_and_exit(-1); }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński2395.83%150.00%
Quentin Monnet14.17%150.00%
Total24100.00%2100.00%


static int do_help(int argc, char **argv) { if (json_output) { jsonw_null(json_wtr); return 0; } fprintf(stderr, "Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n" " %s batch file FILE\n" " %s version\n" "\n" " OBJECT := { prog | map | cgroup | perf }\n" " " HELP_SPEC_OPTIONS "\n" "", bin_name, bin_name, bin_name); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Quentin Monnet2853.85%360.00%
Jakub Kiciński2344.23%120.00%
Yonghong Song11.92%120.00%
Total52100.00%5100.00%


static int do_version(int argc, char **argv) { if (json_output) { jsonw_start_object(json_wtr); jsonw_name(json_wtr, "version"); jsonw_printf(json_wtr, "\"%s\"", BPFTOOL_VERSION); jsonw_end_object(json_wtr); } else { printf("%s v%s\n", bin_name, BPFTOOL_VERSION); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Quentin Monnet5183.61%250.00%
Jakub Kiciński69.84%125.00%
Roman Gushchin46.56%125.00%
Total61100.00%4100.00%


int cmd_select(const struct cmd *cmds, int argc, char **argv, int (*help)(int argc, char **argv)) { unsigned int i; last_argc = argc; last_argv = argv; last_do_help = help; if (argc < 1 && cmds[0].func) return cmds[0].func(argc, argv); for (i = 0; cmds[i].func; i++) if (is_prefix(*argv, cmds[i].cmd)) return cmds[i].func(argc - 1, argv + 1); help(argc - 1, argv + 1); return -1; }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński139100.00%1100.00%
Total139100.00%1100.00%


bool is_prefix(const char *pfx, const char *str) { if (!pfx) return false; if (strlen(str) < strlen(pfx)) return false; return !memcmp(str, pfx, strlen(pfx)); }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński52100.00%1100.00%
Total52100.00%1100.00%


void fprint_hex(FILE *f, void *arg, unsigned int n, const char *sep) { unsigned char *data = arg; unsigned int i; for (i = 0; i < n; i++) { const char *pfx = ""; if (!i) /* nothing */; else if (!(i % 16)) fprintf(f, "\n"); else if (!(i % 8)) fprintf(f, " "); else pfx = sep; fprintf(f, "%s%02hhx", i ? pfx : "", data[i]); } }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński10588.24%150.00%
Quentin Monnet1411.76%150.00%
Total119100.00%2100.00%

/* Split command line into argument vector. */
static int make_args(char *line, char *n_argv[], int maxargs, int cmd_nb) { static const char ws[] = " \t\r\n"; char *cp = line; int n_argc = 0; while (*cp) { /* Skip leading whitespace. */ cp += strspn(cp, ws); if (*cp == '\0') break; if (n_argc >= (maxargs - 1)) { p_err("too many arguments to command %d", cmd_nb); return -1; } /* Word begins with quote. */ if (*cp == '\'' || *cp == '"') { char quote = *cp++; n_argv[n_argc++] = cp; /* Find ending quote. */ cp = strchr(cp, quote); if (!cp) { p_err("unterminated quoted string in command %d", cmd_nb); return -1; } } else { n_argv[n_argc++] = cp; /* Find end of word. */ cp += strcspn(cp, ws); if (*cp == '\0') break; } /* Separate words. */ *cp++ = 0; } n_argv[n_argc] = NULL; return n_argc; }

Contributors

PersonTokensPropCommitsCommitProp
Quentin Monnet192100.00%1100.00%
Total192100.00%1100.00%

static int do_batch(int argc, char **argv); static const struct cmd cmds[] = { { "help", do_help }, { "batch", do_batch }, { "prog", do_prog }, { "map", do_map }, { "cgroup", do_cgroup }, { "perf", do_perf }, { "version", do_version }, { 0 } };
static int do_batch(int argc, char **argv) { char buf[BATCH_LINE_LEN_MAX], contline[BATCH_LINE_LEN_MAX]; char *n_argv[BATCH_ARG_NB_MAX]; unsigned int lines = 0; int n_argc; FILE *fp; char *cp; int err; int i; if (argc < 2) { p_err("too few parameters for batch"); return -1; } else if (!is_prefix(*argv, "file")) { p_err("expected 'file', got: %s", *argv); return -1; } else if (argc > 2) { p_err("too many parameters for batch"); return -1; } NEXT_ARG(); if (!strcmp(*argv, "-")) fp = stdin; else fp = fopen(*argv, "r"); if (!fp) { p_err("Can't open file (%s): %s", *argv, strerror(errno)); return -1; } if (json_output) jsonw_start_array(json_wtr); while (fgets(buf, sizeof(buf), fp)) { cp = strchr(buf, '#'); if (cp) *cp = '\0'; if (strlen(buf) == sizeof(buf) - 1) { errno = E2BIG; break; } /* Append continuation lines if any (coming after a line ending * with '\' in the batch file). */ while ((cp = strstr(buf, "\\\n")) != NULL) { if (!fgets(contline, sizeof(contline), fp) || strlen(contline) == 0) { p_err("missing continuation line on command %d", lines); err = -1; goto err_close; } cp = strchr(contline, '#'); if (cp) *cp = '\0'; if (strlen(buf) + strlen(contline) + 1 > sizeof(buf)) { p_err("command %d is too long", lines); err = -1; goto err_close; } buf[strlen(buf) - 2] = '\0'; strcat(buf, contline); } n_argc = make_args(buf, n_argv, BATCH_ARG_NB_MAX, lines); if (!n_argc) continue; if (n_argc < 0) goto err_close; if (json_output) { jsonw_start_object(json_wtr); jsonw_name(json_wtr, "command"); jsonw_start_array(json_wtr); for (i = 0; i < n_argc; i++) jsonw_string(json_wtr, n_argv[i]); jsonw_end_array(json_wtr); jsonw_name(json_wtr, "output"); } err = cmd_select(cmds, n_argc, n_argv, do_help); if (json_output) jsonw_end_object(json_wtr); if (err) goto err_close; lines++; } if (errno && errno != ENOENT) { p_err("reading batch file failed: %s", strerror(errno)); err = -1; } else { p_info("processed %d commands", lines); err = 0; } err_close: if (fp != stdin) fclose(fp); if (json_output) jsonw_end_array(json_wtr); return err; }

Contributors

PersonTokensPropCommitsCommitProp
Quentin Monnet30756.33%787.50%
Jakub Kiciński23843.67%112.50%
Total545100.00%8100.00%


int main(int argc, char **argv) { static const struct option options[] = { { "json", no_argument, NULL, 'j' }, { "help", no_argument, NULL, 'h' }, { "pretty", no_argument, NULL, 'p' }, { "version", no_argument, NULL, 'V' }, { "bpffs", no_argument, NULL, 'f' }, { 0 } }; int opt, ret; last_do_help = do_help; pretty_output = false; json_output = false; show_pinned = false; bin_name = argv[0]; hash_init(prog_table.table); hash_init(map_table.table); opterr = 0; while ((opt = getopt_long(argc, argv, "Vhpjf", options, NULL)) >= 0) { switch (opt) { case 'V': return do_version(argc, argv); case 'h': return do_help(argc, argv); case 'p': pretty_output = true; /* fall through */ case 'j': if (!json_output) { json_wtr = jsonw_new(stdout); if (!json_wtr) { p_err("failed to create JSON writer"); return -1; } json_output = true; } jsonw_pretty(json_wtr, pretty_output); break; case 'f': show_pinned = true; break; default: p_err("unrecognized option '%s'", argv[optind - 1]); if (json_output) clean_and_exit(-1); else usage(); } } argc -= optind; argv += optind; if (argc < 0) usage(); bfd_init(); ret = cmd_select(cmds, argc, argv, do_help); if (json_output) jsonw_destroy(&json_wtr); if (show_pinned) { delete_pinned_obj_table(&prog_table); delete_pinned_obj_table(&map_table); } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Quentin Monnet24475.08%562.50%
Prashant Bhole4714.46%225.00%
Jakub Kiciński3410.46%112.50%
Total325100.00%8100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Quentin Monnet89052.51%1672.73%
Jakub Kiciński73043.07%14.55%
Prashant Bhole583.42%29.09%
Roman Gushchin100.59%29.09%
Yonghong Song70.41%14.55%
Total1695100.00%22100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.