LCOV - code coverage report
Current view: top level - core - bpf.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 70 0
Test Date: 2025-03-25 15:17:39 Functions: 0.0 % 7 0

            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/bpf.h"
       7              : 
       8              : #include <linux/bpf.h>
       9              : 
      10              : #include <errno.h>
      11              : #include <stdint.h>
      12              : #include <stdio.h>
      13              : #include <stdlib.h>
      14              : #include <unistd.h>
      15              : 
      16              : #include "core/helper.h"
      17              : #include "core/logger.h"
      18              : #include "core/opts.h"
      19              : 
      20              : #if defined(__i386__)
      21              : #define _BF_NR_bpf 357
      22              : #elif defined(__x86_64__)
      23              : #define _BF_NR_bpf 321
      24              : #elif defined(__aarch64__)
      25              : #define _BF_NR_bpf 280
      26              : #else
      27              : #error _BF_NR_bpf not defined. bpfilter does not support your arch.
      28              : #endif
      29              : 
      30            0 : int bf_bpf(enum bpf_cmd cmd, union bpf_attr *attr)
      31              : {
      32            0 :     int r = (int)syscall(_BF_NR_bpf, cmd, attr, sizeof(*attr));
      33            0 :     if (r < 0)
      34            0 :         return -errno;
      35              : 
      36              :     return r;
      37              : }
      38              : 
      39            0 : int bf_bpf_prog_load(const char *name, unsigned int prog_type, void *img,
      40              :                      size_t img_len, enum bpf_attach_type attach_type, int *fd)
      41              : {
      42              :     _cleanup_free_ char *log_buf = NULL;
      43            0 :     union bpf_attr attr = {
      44              :         .prog_type = prog_type,
      45            0 :         .insns = bf_ptr_to_u64(img),
      46            0 :         .insn_cnt = (unsigned int)img_len,
      47            0 :         .license = bf_ptr_to_u64("GPL"),
      48              :         .expected_attach_type = attach_type,
      49              :     };
      50              :     int r;
      51              : 
      52            0 :     bf_assert(name && img && fd);
      53              : 
      54            0 :     if (bf_opts_is_verbose(BF_VERBOSE_BPF)) {
      55            0 :         log_buf = malloc(1 << bf_opts_bpf_log_buf_len_pow());
      56            0 :         if (!log_buf)
      57              :             return -ENOMEM;
      58              : 
      59            0 :         attr.log_buf = bf_ptr_to_u64(log_buf);
      60            0 :         attr.log_size = (uint32_t)(1 << bf_opts_bpf_log_buf_len_pow());
      61            0 :         attr.log_level = 1;
      62              :     }
      63              : 
      64            0 :     (void)snprintf(attr.prog_name, BPF_OBJ_NAME_LEN, "%s", name);
      65              : 
      66            0 :     r = bf_bpf(BPF_PROG_LOAD, &attr);
      67            0 :     if (r < 0) {
      68            0 :         return bf_err_r(r, "failed to load BPF program (%lu bytes):\n%s\n",
      69              :                         img_len, log_buf ?: "(no log buffer available)");
      70              :     }
      71              : 
      72            0 :     *fd = r;
      73              : 
      74            0 :     return 0;
      75              : }
      76              : 
      77            0 : int bf_bpf_map_lookup_elem(int fd, const void *key, void *value)
      78              : {
      79            0 :     union bpf_attr attr = {
      80              :         .map_fd = fd,
      81            0 :         .key = (uint64_t)key,
      82            0 :         .value = (uint64_t)value,
      83              :     };
      84              : 
      85            0 :     bf_assert(key);
      86            0 :     bf_assert(value);
      87              : 
      88            0 :     return bf_bpf(BPF_MAP_LOOKUP_ELEM, &attr);
      89              : }
      90              : 
      91            0 : int bf_bpf_map_update_elem(int fd, const void *key, void *value)
      92              : {
      93            0 :     union bpf_attr attr = {
      94              :         .map_fd = fd,
      95            0 :         .key = bf_ptr_to_u64(key),
      96            0 :         .value = bf_ptr_to_u64(value),
      97              :         .flags = BPF_ANY,
      98              :     };
      99              : 
     100            0 :     return bf_bpf(BPF_MAP_UPDATE_ELEM, &attr);
     101              : }
     102              : 
     103            0 : int bf_bpf_obj_pin(const char *path, int fd, int dir_fd)
     104              : {
     105            0 :     union bpf_attr attr = {
     106            0 :         .pathname = bf_ptr_to_u64(path),
     107              :         .bpf_fd = fd,
     108            0 :         .file_flags = dir_fd ? BPF_F_PATH_FD : 0,
     109              :         .path_fd = dir_fd,
     110              :     };
     111              : 
     112            0 :     bf_assert(path);
     113            0 :     bf_assert(dir_fd >= 0);
     114            0 :     bf_assert(path[0] == '/' ? !dir_fd : 1);
     115              : 
     116            0 :     int r = bf_bpf(BPF_OBJ_PIN, &attr);
     117            0 :     return r;
     118              : }
     119              : 
     120            0 : int bf_bpf_obj_get(const char *path, int dir_fd, int *fd)
     121              : {
     122            0 :     union bpf_attr attr = {
     123            0 :         .pathname = bf_ptr_to_u64(path),
     124            0 :         .file_flags = dir_fd ? BPF_F_PATH_FD : 0,
     125              :         .path_fd = dir_fd,
     126              :     };
     127              :     int r;
     128              : 
     129            0 :     bf_assert(path && fd);
     130            0 :     bf_assert(dir_fd >= 0);
     131            0 :     bf_assert(path[0] == '/' ? !dir_fd : 1);
     132              : 
     133            0 :     r = bf_bpf(BPF_OBJ_GET, &attr);
     134            0 :     if (r < 0)
     135              :         return r;
     136              : 
     137            0 :     *fd = r;
     138              : 
     139            0 :     return 0;
     140              : }
     141              : 
     142            0 : int bf_prog_run(int prog_fd, const void *pkt, size_t pkt_len, const void *ctx,
     143              :                 size_t ctx_len)
     144              : {
     145            0 :     union bpf_attr attr = {};
     146              :     int r;
     147              : 
     148            0 :     bf_assert(pkt);
     149            0 :     bf_assert(pkt_len > 0);
     150            0 :     bf_assert(!(!!ctx ^ !!ctx_len));
     151              : 
     152            0 :     attr.test.prog_fd = prog_fd;
     153            0 :     attr.test.data_size_in = pkt_len;
     154            0 :     attr.test.data_in = ((unsigned long long)(pkt));
     155            0 :     attr.test.repeat = 1;
     156              : 
     157            0 :     if (ctx_len) {
     158            0 :         attr.test.ctx_size_in = ctx_len;
     159            0 :         attr.test.ctx_in = ((unsigned long long)(ctx));
     160              :     }
     161              : 
     162            0 :     r = bf_bpf(BPF_PROG_TEST_RUN, &attr);
     163            0 :     if (r)
     164            0 :         return bf_err_r(r, "failed to run the test program");
     165              : 
     166            0 :     return (int)attr.test.retval;
     167              : }
        

Generated by: LCOV version 2.0-1