LCOV - code coverage report
Current view: top level - bpfilter/cgen - tc.c (source / functions) Coverage Total Hit
Test: coverage.lcov Lines: 100.0 % 29 29
Test Date: 2025-11-24 12:34:34 Functions: 100.0 % 6 6
Branches: 50.0 % 28 14

             Branch data     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 "cgen/tc.h"
       7                 :             : 
       8                 :             : #include <linux/bpf.h>
       9                 :             : #include <linux/bpf_common.h>
      10                 :             : #include <linux/pkt_cls.h>
      11                 :             : 
      12                 :             : #include <stddef.h>
      13                 :             : #include <stdint.h>
      14                 :             : 
      15                 :             : #include <bpfilter/btf.h>
      16                 :             : #include <bpfilter/flavor.h>
      17                 :             : #include <bpfilter/helper.h>
      18                 :             : #include <bpfilter/verdict.h>
      19                 :             : 
      20                 :             : #include "cgen/cgen.h"
      21                 :             : #include "cgen/program.h"
      22                 :             : #include "cgen/stub.h"
      23                 :             : #include "filter.h"
      24                 :             : 
      25                 :          11 : static int _bf_tc_gen_inline_prologue(struct bf_program *program)
      26                 :             : {
      27                 :             :     int r;
      28                 :             : 
      29                 :             :     bf_assert(program);
      30                 :             : 
      31                 :             :     // Copy the packet size into the runtime context
      32         [ -  + ]:          11 :     EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
      33                 :             :                               offsetof(struct __sk_buff, len)));
      34         [ -  + ]:          11 :     EMIT(program,
      35                 :             :          BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_3, BF_PROG_CTX_OFF(pkt_size)));
      36                 :             : 
      37                 :             :     /** The @c __sk_buff structure contains two fields related to the interface
      38                 :             :      * index: @c ingress_ifindex and @c ifindex . @c ingress_ifindex is the
      39                 :             :      * interface index the packet has been received on. However, we use
      40                 :             :      * @c ifindex which is the interface index the packet is processed by: if
      41                 :             :      * a packet is redirected locally from interface #1 to interface #2, then
      42                 :             :      * @c ingress_ifindex will contain @c 1 but @c ifindex will contains @c 2 .
      43                 :             :      * For egress, only @c ifindex is used.
      44                 :             :      */
      45         [ +  - ]:          11 :     if ((r = bf_btf_get_field_off("__sk_buff", "ifindex")) < 0)
      46                 :             :         return r;
      47         [ -  + ]:          11 :     EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, r));
      48         [ -  + ]:          11 :     EMIT(program,
      49                 :             :          BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, BF_PROG_CTX_OFF(ifindex)));
      50                 :             : 
      51                 :          11 :     r = bf_stub_make_ctx_skb_dynptr(program, BPF_REG_1);
      52         [ +  - ]:          11 :     if (r)
      53                 :             :         return r;
      54                 :             : 
      55                 :          11 :     r = bf_stub_parse_l2_ethhdr(program);
      56         [ +  - ]:          11 :     if (r)
      57                 :             :         return r;
      58                 :             : 
      59                 :          11 :     r = bf_stub_parse_l3_hdr(program);
      60         [ +  - ]:          11 :     if (r)
      61                 :             :         return r;
      62                 :             : 
      63                 :          11 :     r = bf_stub_parse_l4_hdr(program);
      64                 :             :     if (r)
      65                 :             :         return r;
      66                 :             : 
      67                 :             :     return 0;
      68                 :             : }
      69                 :             : 
      70                 :          11 : static int _bf_tc_gen_inline_epilogue(struct bf_program *program)
      71                 :             : {
      72                 :             :     UNUSED(program);
      73                 :             : 
      74                 :          11 :     return 0;
      75                 :             : }
      76                 :             : 
      77                 :           6 : static int _bf_tc_gen_inline_set_mark(struct bf_program *program, uint32_t mark)
      78                 :             : {
      79         [ -  + ]:           6 :     EMIT(program,
      80                 :             :          BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg)));
      81         [ -  + ]:           6 :     EMIT(program, BPF_MOV64_IMM(BPF_REG_2, mark));
      82         [ -  + ]:           6 :     EMIT(program, BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_2,
      83                 :             :                               offsetof(struct __sk_buff, mark)));
      84                 :             : 
      85                 :           6 :     return 0;
      86                 :             : }
      87                 :             : 
      88                 :           4 : static int _bf_tc_gen_inline_get_mark(struct bf_program *program, int reg)
      89                 :             : {
      90         [ -  + ]:           4 :     EMIT(program,
      91                 :             :          BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg)));
      92         [ -  + ]:           4 :     EMIT(program,
      93                 :             :          BPF_LDX_MEM(BPF_W, reg, BPF_REG_1, offsetof(struct __sk_buff, mark)));
      94                 :             : 
      95                 :           4 :     return 0;
      96                 :             : }
      97                 :             : 
      98                 :          28 : static int _bf_tc_gen_inline_get_skb(struct bf_program *program, int reg)
      99                 :             : {
     100         [ -  + ]:          28 :     EMIT(program, BPF_LDX_MEM(BPF_DW, reg, BPF_REG_10, BF_PROG_CTX_OFF(arg)));
     101                 :             : 
     102                 :          28 :     return 0;
     103                 :             : }
     104                 :             : 
     105                 :             : /**
     106                 :             :  * Convert a standard verdict into a return value.
     107                 :             :  *
     108                 :             :  * @param verdict Verdict to convert. Must be valid.
     109                 :             :  * @return TC return code corresponding to the verdict, as an integer.
     110                 :             :  */
     111                 :         110 : static int _bf_tc_get_verdict(enum bf_verdict verdict)
     112                 :             : {
     113                 :             :     bf_assert(0 <= verdict && verdict < _BF_TERMINAL_VERDICT_MAX);
     114                 :             : 
     115                 :             :     static const int verdicts[] = {
     116                 :             :         [BF_VERDICT_ACCEPT] = TC_ACT_OK,
     117                 :             :         [BF_VERDICT_DROP] = TC_ACT_SHOT,
     118                 :             :     };
     119                 :             : 
     120                 :             :     static_assert(ARRAY_SIZE(verdicts) == _BF_TERMINAL_VERDICT_MAX);
     121                 :             : 
     122                 :         110 :     return verdicts[verdict];
     123                 :             : }
     124                 :             : 
     125                 :             : const struct bf_flavor_ops bf_flavor_ops_tc = {
     126                 :             :     .gen_inline_prologue = _bf_tc_gen_inline_prologue,
     127                 :             :     .gen_inline_epilogue = _bf_tc_gen_inline_epilogue,
     128                 :             :     .gen_inline_set_mark = _bf_tc_gen_inline_set_mark,
     129                 :             :     .gen_inline_get_mark = _bf_tc_gen_inline_get_mark,
     130                 :             :     .gen_inline_get_skb = _bf_tc_gen_inline_get_skb,
     131                 :             :     .get_verdict = _bf_tc_get_verdict,
     132                 :             : };
        

Generated by: LCOV version 2.0-1