LCOV - code coverage report
Current view: top level - bpfilter/cgen - xdp.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 38 0
Test Date: 2025-02-26 17:59:59 Functions: 0.0 % 5 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 <linux/bpf.h>
       7              : #include <linux/bpf_common.h>
       8              : 
       9              : #include <stddef.h>
      10              : 
      11              : #include "bpfilter/cgen/prog/link.h"
      12              : #include "bpfilter/cgen/program.h"
      13              : #include "bpfilter/cgen/stub.h"
      14              : #include "core/bpf.h"
      15              : #include "core/flavor.h"
      16              : #include "core/helper.h"
      17              : #include "core/hook.h"
      18              : #include "core/list.h"
      19              : #include "core/logger.h"
      20              : #include "core/verdict.h"
      21              : 
      22              : #include "external/filter.h"
      23              : 
      24              : static int _bf_xdp_gen_inline_prologue(struct bf_program *program);
      25              : static int _bf_xdp_gen_inline_epilogue(struct bf_program *program);
      26              : static int _bf_xdp_get_verdict(enum bf_verdict verdict);
      27              : static int _bf_xdp_attach_prog(
      28              :     struct bf_program *new_prog, struct bf_program *old_prog,
      29              :     int (*get_new_link_cb)(struct bf_program *prog, struct bf_link *old_link,
      30              :                            struct bf_link **new_link));
      31              : static int _bf_xdp_detach_prog(struct bf_program *program);
      32              : 
      33              : const struct bf_flavor_ops bf_flavor_ops_xdp = {
      34              :     .gen_inline_prologue = _bf_xdp_gen_inline_prologue,
      35              :     .gen_inline_epilogue = _bf_xdp_gen_inline_epilogue,
      36              :     .get_verdict = _bf_xdp_get_verdict,
      37              :     .attach_prog = _bf_xdp_attach_prog,
      38              :     .detach_prog = _bf_xdp_detach_prog,
      39              : };
      40              : 
      41              : /**
      42              :  * Generate XDP program prologue.
      43              :  *
      44              :  * @warning @ref bf_stub_parse_l2_ethhdr will check for L3 protocol. If L3 is
      45              :  * not IPv4, the program will be terminated.
      46              :  *
      47              :  * @param program Program to generate the prologue for. Must not be NULL.
      48              :  * @return 0 on success, or negative errno value on error.
      49              :  */
      50            0 : static int _bf_xdp_gen_inline_prologue(struct bf_program *program)
      51              : {
      52              :     int r;
      53              : 
      54            0 :     bf_assert(program);
      55              : 
      56              :     // Calculate the packet size and store it into the runtime context
      57            0 :     EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
      58              :                               offsetof(struct xdp_md, data)));
      59            0 :     EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
      60              :                               offsetof(struct xdp_md, data_end)));
      61            0 :     EMIT(program, BPF_ALU64_REG(BPF_SUB, BPF_REG_3, BPF_REG_2));
      62            0 :     EMIT(program,
      63              :          BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, BF_PROG_CTX_OFF(pkt_size)));
      64              : 
      65              :     // Store the ingress ifindex into the runtime context
      66            0 :     EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
      67              :                               offsetof(struct xdp_md, ingress_ifindex)));
      68            0 :     EMIT(program,
      69              :          BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, BF_PROG_CTX_OFF(ifindex)));
      70              : 
      71            0 :     r = bf_stub_make_ctx_xdp_dynptr(program, BPF_REG_1);
      72            0 :     if (r)
      73              :         return r;
      74              : 
      75            0 :     r = bf_stub_parse_l2_ethhdr(program);
      76            0 :     if (r)
      77              :         return r;
      78              : 
      79            0 :     r = bf_stub_parse_l3_hdr(program);
      80            0 :     if (r)
      81              :         return r;
      82              : 
      83            0 :     r = bf_stub_parse_l4_hdr(program);
      84              :     if (r)
      85              :         return r;
      86              : 
      87              :     return 0;
      88              : }
      89              : 
      90            0 : static int _bf_xdp_gen_inline_epilogue(struct bf_program *program)
      91              : {
      92              :     UNUSED(program);
      93              : 
      94            0 :     return 0;
      95              : }
      96              : 
      97            0 : static int _bf_xdp_get_verdict(enum bf_verdict verdict)
      98              : {
      99            0 :     bf_assert(0 <= verdict && verdict < _BF_TERMINAL_VERDICT_MAX);
     100              : 
     101              :     static const int verdicts[] = {
     102              :         [BF_VERDICT_ACCEPT] = XDP_PASS,
     103              :         [BF_VERDICT_DROP] = XDP_DROP,
     104              :     };
     105              : 
     106              :     static_assert(ARRAY_SIZE(verdicts) == _BF_TERMINAL_VERDICT_MAX);
     107              : 
     108            0 :     return verdicts[verdict];
     109              : }
     110              : 
     111            0 : static int _bf_xdp_attach_prog(
     112              :     struct bf_program *new_prog, struct bf_program *old_prog,
     113              :     int (*get_new_link_cb)(struct bf_program *prog, struct bf_link *old_link,
     114              :                            struct bf_link **new_link))
     115              : {
     116              :     struct bf_link *new_link;
     117              :     struct bf_link *old_link;
     118              :     int new_fd;
     119              :     unsigned int ifindex;
     120              :     int r;
     121              : 
     122            0 :     bf_assert(new_prog && get_new_link_cb);
     123              : 
     124            0 :     old_link = old_prog ? bf_list_get_at(&old_prog->links, 0) : NULL;
     125            0 :     new_fd = new_prog->runtime.prog_fd;
     126            0 :     ifindex = new_prog->runtime.chain->hook_opts.ifindex;
     127              : 
     128            0 :     r = get_new_link_cb(new_prog, old_link, &new_link);
     129            0 :     if (r)
     130            0 :         return bf_err_r(r, "failed to create new XDP link");
     131              : 
     132            0 :     if (old_link) {
     133            0 :         r = bf_link_update(new_link, new_fd);
     134            0 :         if (r) {
     135            0 :             return bf_err_r(
     136              :                 r, "failed to update existing link for XDP bf_program");
     137              :         }
     138              :     } else {
     139            0 :         r = bf_link_attach_xdp(new_link, new_fd, ifindex, BF_XDP_MODE_SKB);
     140            0 :         if (r)
     141            0 :             return bf_err_r(r, "failed to attach XDP program");
     142              :     }
     143              : 
     144              :     return 0;
     145              : }
     146              : 
     147            0 : static int _bf_xdp_detach_prog(struct bf_program *program)
     148              : {
     149            0 :     bf_assert(program);
     150              : 
     151            0 :     return bf_link_detach(bf_list_get_at(&program->links, 0));
     152              : }
        

Generated by: LCOV version 2.0-1