LCOV - code coverage report
Current view: top level - bpfilter/cgen/matcher - set.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 63 0
Test Date: 2025-08-19 17:27:08 Functions: 0.0 % 2 0

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-2.0-only */
       2              : /*
       3              :  * Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #include "bpfilter/cgen/matcher/set.h"
       7              : 
       8              : #include "bpfilter/cgen/program.h"
       9              : #include "bpfilter/cgen/stub.h"
      10              : #include "core/chain.h"
      11              : #include "core/matcher.h"
      12              : #include "core/set.h"
      13              : 
      14            0 : static int _bf_matcher_generate_set_trie(struct bf_program *program,
      15              :                                          const struct bf_matcher *matcher)
      16              : {
      17            0 :     bf_assert(program && matcher);
      18              : 
      19              :     const struct bf_set *set =
      20            0 :         bf_chain_get_set_for_matcher(program->runtime.chain, matcher);
      21            0 :     enum bf_matcher_type type = set->key[0];
      22            0 :     const struct bf_matcher_meta *meta = bf_matcher_get_meta(type);
      23              :     int r;
      24              : 
      25              :     if (!set) {
      26              :         return bf_err_r(-ENOENT, "set #%u not found in %s",
      27              :                         *(uint32_t *)matcher->payload,
      28              :                         program->runtime.chain->name);
      29              :     }
      30              : 
      31            0 :     r = bf_stub_rule_check_protocol(program, meta);
      32            0 :     if (r)
      33            0 :         return bf_err_r(r, "failed to check for protocol");
      34              : 
      35            0 :     r = bf_stub_load_header(program, meta, BPF_REG_6);
      36            0 :     if (r)
      37            0 :         return bf_err_r(r, "failed to load protocol header into BPF_REG_6");
      38              : 
      39            0 :     if (BF_FLAG(type) & (BF_FLAGS(BF_MATCHER_IP4_SNET, BF_MATCHER_IP4_DNET))) {
      40            0 :         EMIT(program, BPF_MOV64_IMM(BPF_REG_1, 32));
      41            0 :         EMIT(program,
      42              :              BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_1, BF_PROG_SCR_OFF(4)));
      43            0 :         EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6,
      44              :                                   meta->hdr_payload_offset));
      45            0 :         EMIT(program,
      46              :              BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_1, BF_PROG_SCR_OFF(8)));
      47            0 :     } else if (BF_FLAG(type) &
      48              :                (BF_FLAGS(BF_MATCHER_IP6_SNET, BF_MATCHER_IP6_DNET))) {
      49            0 :         EMIT(program, BPF_MOV64_IMM(BPF_REG_1, 128));
      50            0 :         EMIT(program,
      51              :              BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_1, BF_PROG_SCR_OFF(4)));
      52              : 
      53            0 :         EMIT(program, BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6,
      54              :                                   meta->hdr_payload_offset));
      55            0 :         EMIT(program,
      56              :              BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, BF_PROG_SCR_OFF(8)));
      57              : 
      58            0 :         EMIT(program, BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6,
      59              :                                   meta->hdr_payload_offset + 8));
      60            0 :         EMIT(program,
      61              :              BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, BF_PROG_SCR_OFF(16)));
      62              :     } else {
      63            0 :         return bf_err_r(-EINVAL,
      64              :                         "set key '%s' (%d) should not use a LPM trie map",
      65              :                         bf_matcher_type_to_str(type), type);
      66              :     }
      67              : 
      68            0 :     EMIT_LOAD_SET_FD_FIXUP(program, BPF_REG_1, *(uint32_t *)matcher->payload);
      69            0 :     EMIT(program, BPF_MOV64_REG(BPF_REG_2, BPF_REG_10));
      70            0 :     EMIT(program, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, BF_PROG_SCR_OFF(4)));
      71            0 :     EMIT(program, BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem));
      72              : 
      73              :     // Jump to the next rule if map_lookup_elem returned 0
      74            0 :     EMIT_FIXUP_JMP_NEXT_RULE(program, BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 0));
      75            0 :     return 0;
      76              : }
      77              : 
      78            0 : int bf_matcher_generate_set(struct bf_program *program,
      79              :                             const struct bf_matcher *matcher)
      80              : {
      81            0 :     bf_assert(program && matcher);
      82              : 
      83              :     const struct bf_set *set =
      84            0 :         bf_chain_get_set_for_matcher(program->runtime.chain, matcher);
      85              :     size_t offset = 0;
      86              :     int r;
      87              : 
      88            0 :     if (!set) {
      89            0 :         return bf_err_r(-ENOENT, "set #%u not found in %s",
      90              :                         *(uint32_t *)matcher->payload,
      91              :                         program->runtime.chain->name);
      92              :     }
      93              : 
      94            0 :     if (set->use_trie)
      95            0 :         return _bf_matcher_generate_set_trie(program, matcher);
      96              : 
      97              :     // Ensure the packet uses the required protocols
      98            0 :     for (size_t i = 0; i < set->n_comps; ++i) {
      99            0 :         enum bf_matcher_type type = set->key[i];
     100            0 :         const struct bf_matcher_meta *meta = bf_matcher_get_meta(type);
     101              : 
     102            0 :         if (!meta) {
     103            0 :             return bf_err_r(-ENOENT, "meta for '%s' not found",
     104              :                             bf_matcher_type_to_str(type));
     105              :         }
     106              : 
     107            0 :         r = bf_stub_rule_check_protocol(program, meta);
     108            0 :         if (r)
     109            0 :             return bf_err_r(r, "failed to check for protocol");
     110              :     }
     111              : 
     112              :     // Generate the bytecode to build the set key
     113            0 :     for (size_t i = 0; i < set->n_comps; ++i) {
     114            0 :         enum bf_matcher_type type = set->key[i];
     115            0 :         const struct bf_matcher_meta *meta = bf_matcher_get_meta(type);
     116              : 
     117            0 :         if (!meta) {
     118            0 :             return bf_err_r(-ENOENT, "meta for '%s' not found",
     119              :                             bf_matcher_type_to_str(type));
     120              :         }
     121              : 
     122            0 :         r = bf_stub_load_header(program, meta, BPF_REG_6);
     123            0 :         if (r)
     124            0 :             return bf_err_r(r, "failed to load protocol header into BPF_REG_6");
     125              : 
     126            0 :         r = bf_stub_stx_payload(program, meta, offset);
     127            0 :         if (r) {
     128            0 :             return bf_err_r(r,
     129              :                             "failed to generate bytecode to load packet data");
     130              :         }
     131              : 
     132            0 :         offset += meta->hdr_payload_size;
     133              :     }
     134              : 
     135            0 :     EMIT_LOAD_SET_FD_FIXUP(program, BPF_REG_1, *(uint32_t *)matcher->payload);
     136            0 :     EMIT(program, BPF_MOV64_REG(BPF_REG_2, BPF_REG_10));
     137            0 :     EMIT(program, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, BF_PROG_SCR_OFF(0)));
     138            0 :     EMIT(program, BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem));
     139              : 
     140              :     // Jump to the next rule if map_lookup_elem returned 0
     141            0 :     EMIT_FIXUP_JMP_NEXT_RULE(program, BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 0));
     142              : 
     143            0 :     return 0;
     144              : }
        

Generated by: LCOV version 2.0-1