LCOV - code coverage report
Current view: top level - core - opts.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 20.3 % 59 12
Test Date: 2025-02-26 17:59:59 Functions: 37.5 % 8 3

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-2.0-only */
       2              : /*
       3              :  * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #include "core/opts.h"
       7              : 
       8              : #include <argp.h>
       9              : #include <errno.h>
      10              : #include <limits.h>
      11              : #include <stdbool.h>
      12              : #include <stddef.h>
      13              : #include <stdint.h>
      14              : #include <stdlib.h>
      15              : 
      16              : #include "core/front.h"
      17              : #include "core/helper.h"
      18              : #include "core/logger.h"
      19              : #include "version.h"
      20              : 
      21              : enum
      22              : {
      23              :     BF_OPT_NO_IPTABLES_KEY,
      24              :     BF_OPT_NO_NFTABLES_KEY,
      25              :     BF_OPT_NO_CLI_KEY,
      26              :     BF_OPT_VERSION,
      27              : };
      28              : 
      29              : static const char *_bf_verbose_strs[] = {
      30              :     [BF_VERBOSE_DEBUG] = "debug",
      31              :     [BF_VERBOSE_BPF] = "bpf",
      32              :     [BF_VERBOSE_BYTECODE] = "bytecode",
      33              : };
      34              : 
      35              : static_assert(ARRAY_SIZE(_bf_verbose_strs) == _BF_VERBOSE_MAX,
      36              :               "missing entries in _bf_verbose_strs array");
      37              : 
      38            0 : int bf_verbose_to_str(const char *str, enum bf_verbose *opt)
      39              : {
      40            0 :     bf_assert(str && opt);
      41              : 
      42            0 :     for (size_t i = 0; i < _BF_VERBOSE_MAX; ++i) {
      43            0 :         if (bf_streq(_bf_verbose_strs[i], str)) {
      44            0 :             *opt = i;
      45            0 :             return 0;
      46              :         }
      47              :     }
      48              : 
      49              :     return -EINVAL;
      50              : }
      51              : 
      52              : /**
      53              :  * bpfilter runtime configuration
      54              :  */
      55              : static struct bf_options
      56              : {
      57              :     /** If true, bpfilter won't load or save its state to the filesystem, and
      58              :      * all the loaded BPF programs will be unloaded before shuting down. Hence,
      59              :      * as long as bpfilter is running, filtering rules will be applied. When
      60              :      * bpfilter is stopped, everything is cleaned up. */
      61              :     bool transient;
      62              : 
      63              :     /** Size of the log buffer when loading a BPF program, as a power of 2. */
      64              :     unsigned int bpf_log_buf_len_pow;
      65              : 
      66              :     /** Bit flags for enabled fronts. */
      67              :     uint16_t fronts;
      68              : 
      69              :     /** Verbose flags. Supported flags are:
      70              :      * - @c debug Print all the debug logs.
      71              :      * - @c bpf Add debug log messages in the generated BPF programs. */
      72              :     uint16_t verbose;
      73              : } _bf_opts = {
      74              :     .transient = false,
      75              :     .bpf_log_buf_len_pow = 16,
      76              :     .fronts = 0xffff,
      77              :     .verbose = 0,
      78              : };
      79              : 
      80              : static struct argp_option options[] = {
      81              :     {"transient", 't', 0, 0,
      82              :      "Do not load or save runtime context and remove all BPF programs on shutdown",
      83              :      0},
      84              :     {"buffer-len", 'b', "BUF_LEN_POW", 0,
      85              :      "Size of the BPF log buffer as a power of 2 (only used when --verbose is used). Default: 16.",
      86              :      0},
      87              :     {"no-iptables", BF_OPT_NO_IPTABLES_KEY, 0, 0, "Disable iptables support",
      88              :      0},
      89              :     {"no-nftables", BF_OPT_NO_NFTABLES_KEY, 0, 0, "Disable nftables support",
      90              :      0},
      91              :     {"no-cli", BF_OPT_NO_CLI_KEY, 0, 0, "Disable CLI support", 0},
      92              :     {"verbose", 'v', "VERBOSE_FLAG", 0,
      93              :      "Verbose flags to enable. Can be used more than once.", 0},
      94              :     {"version", BF_OPT_VERSION, 0, 0, "Print the version and return.", 0},
      95              :     {0},
      96              : };
      97              : 
      98              : /**
      99              :  * argp callback to process command line arguments.
     100              :  *
     101              :  * @return 0 on succcess, non-zero on failure.
     102              :  */
     103            6 : static error_t _bf_opts_parser(int key, char *arg, struct argp_state *state)
     104              : {
     105              :     UNUSED(arg);
     106              : 
     107            6 :     struct bf_options *args = state->input;
     108              :     enum bf_verbose opt;
     109              :     long pow;
     110              :     char *end;
     111              :     int r;
     112              : 
     113            6 :     switch (key) {
     114            0 :     case 't':
     115            0 :         args->transient = true;
     116            0 :         break;
     117            0 :     case 'b':
     118            0 :         errno = 0;
     119            0 :         pow = strtol(arg, &end, 0);
     120            0 :         if (errno == ERANGE) {
     121            0 :             return bf_err_r(EINVAL, "failed to convert '%s' into an integer",
     122              :                             arg);
     123              :         }
     124            0 :         if (pow > UINT_MAX) {
     125            0 :             return bf_err_r(EINVAL, "--buffer-len can't be bigger than %d",
     126              :                             UINT_MAX);
     127              :         }
     128            0 :         if (pow < 0)
     129            0 :             return bf_err_r(EINVAL, "--buffer-len can't be negative");
     130            0 :         args->bpf_log_buf_len_pow = (unsigned int)pow;
     131            0 :         break;
     132            0 :     case BF_OPT_NO_IPTABLES_KEY:
     133            0 :         bf_info("disabling iptables support");
     134            0 :         args->fronts &= ~(1 << BF_FRONT_IPT);
     135            0 :         break;
     136            1 :     case BF_OPT_NO_NFTABLES_KEY:
     137            1 :         bf_info("disabling nftables support");
     138            1 :         args->fronts &= ~(1 << BF_FRONT_NFT);
     139            1 :         break;
     140            0 :     case BF_OPT_NO_CLI_KEY:
     141            0 :         bf_info("disabling CLI support");
     142            0 :         args->fronts &= ~(1 << BF_FRONT_CLI);
     143            0 :         break;
     144            0 :     case 'v':
     145            0 :         r = bf_verbose_to_str(arg, &opt);
     146            0 :         if (r < 0)
     147            0 :             return bf_err_r(
     148              :                 EINVAL,
     149              :                 "unknown --verbose option '%s', valid --verbose options: [debug, bpf, bytecode]",
     150              :                 arg);
     151            0 :         bf_info("enabling verbose for '%s'", arg);
     152            0 :         args->verbose |= (1 << opt);
     153            0 :         break;
     154            0 :     case BF_OPT_VERSION:
     155            0 :         bf_info("bpfilter version %s", BF_VERSION);
     156            0 :         exit(0);
     157              :     default:
     158              :         return ARGP_ERR_UNKNOWN;
     159              :     }
     160              : 
     161              :     return 0;
     162              : }
     163              : 
     164            1 : int bf_opts_init(int argc, char *argv[])
     165              : {
     166            1 :     struct argp argp = {options, _bf_opts_parser, NULL, NULL, 0, NULL, NULL};
     167              : 
     168            1 :     return argp_parse(&argp, argc, argv, 0, 0, &_bf_opts);
     169              : }
     170              : 
     171            0 : bool bf_opts_transient(void)
     172              : {
     173            0 :     return _bf_opts.transient;
     174              : }
     175              : 
     176            0 : unsigned int bf_opts_bpf_log_buf_len_pow(void)
     177              : {
     178            0 :     return _bf_opts.bpf_log_buf_len_pow;
     179              : }
     180              : 
     181            0 : bool bf_opts_is_front_enabled(enum bf_front front)
     182              : {
     183            0 :     return _bf_opts.fronts & (1 << front);
     184              : }
     185              : 
     186            8 : bool bf_opts_is_verbose(enum bf_verbose opt)
     187              : {
     188            8 :     return _bf_opts.verbose & (1 << opt);
     189              : }
     190              : 
     191            0 : void bf_opts_set_verbose(enum bf_verbose opt)
     192              : {
     193            0 :     _bf_opts.verbose |= (1 << opt);
     194            0 : }
        

Generated by: LCOV version 2.0-1