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

Generated by: LCOV version 2.0-1