LCOV - code coverage report
Current view: top level - bpfilter/cgen/matcher - ip4.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 51 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) 2022 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #include "bpfilter/cgen/matcher/ip4.h"
       7              : 
       8              : #include <linux/bpf.h>
       9              : #include <linux/bpf_common.h>
      10              : #include <linux/if_ether.h>
      11              : #include <linux/ip.h>
      12              : 
      13              : #include <endian.h>
      14              : #include <errno.h>
      15              : #include <stddef.h>
      16              : #include <stdint.h>
      17              : 
      18              : #include "bpfilter/cgen/program.h"
      19              : #include "core/helper.h"
      20              : #include "core/list.h"
      21              : #include "core/logger.h"
      22              : #include "core/matcher.h"
      23              : #include "core/set.h"
      24              : 
      25              : #include "external/filter.h"
      26              : 
      27              : static int
      28            0 : _bf_matcher_generate_ip4_addr_unique(struct bf_program *program,
      29              :                                      const struct bf_matcher *matcher)
      30              : {
      31              :     struct bf_matcher_ip4_addr *addr = (void *)&matcher->payload;
      32            0 :     size_t offset = matcher->type == BF_MATCHER_IP4_SRC_ADDR ?
      33            0 :                         offsetof(struct iphdr, saddr) :
      34              :                         offsetof(struct iphdr, daddr);
      35              : 
      36            0 :     EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, offset));
      37            0 :     EMIT(program, BPF_MOV32_IMM(BPF_REG_2, addr->addr));
      38              : 
      39            0 :     if (addr->mask != ~0U) {
      40            0 :         EMIT(program, BPF_MOV32_IMM(BPF_REG_3, addr->mask));
      41            0 :         EMIT(program, BPF_ALU32_REG(BPF_AND, BPF_REG_2, BPF_REG_3));
      42              :     }
      43              : 
      44            0 :     EMIT_FIXUP_JMP_NEXT_RULE(
      45              :         program, BPF_JMP_REG(matcher->op == BF_MATCHER_EQ ? BPF_JNE : BPF_JEQ,
      46              :                              BPF_REG_1, BPF_REG_2, 0));
      47              : 
      48            0 :     return 0;
      49              : }
      50              : 
      51            0 : static int _bf_matcher_generate_ip4_addr_set(struct bf_program *program,
      52              :                                              const struct bf_matcher *matcher)
      53              : {
      54              :     uint32_t set_id;
      55              :     struct bf_set *set;
      56              :     int16_t offset;
      57              : 
      58            0 :     bf_assert(program);
      59            0 :     bf_assert(matcher);
      60              : 
      61            0 :     set_id = *(uint32_t *)matcher->payload;
      62            0 :     set = bf_list_get_at(&program->runtime.chain->sets, set_id);
      63              : 
      64            0 :     switch (set->type) {
      65            0 :     case BF_SET_IP4:
      66            0 :         offset = matcher->type == BF_MATCHER_IP4_SRC_ADDR ?
      67              :                      offsetof(struct iphdr, saddr) :
      68              :                      offsetof(struct iphdr, daddr);
      69            0 :         EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_6, offset));
      70            0 :         EMIT(program,
      71              :              BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, BF_PROG_SCR_OFF(0)));
      72              :         break;
      73            0 :     default:
      74            0 :         return bf_err_r(-EINVAL, "unsupported set type: %s",
      75              :                         bf_set_type_to_str(set->type));
      76              :     }
      77              : 
      78            0 :     EMIT_LOAD_SET_FD_FIXUP(program, BPF_REG_1, set_id);
      79            0 :     EMIT(program, BPF_MOV64_REG(BPF_REG_2, BPF_REG_10));
      80            0 :     EMIT(program, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, BF_PROG_SCR_OFF(0)));
      81              : 
      82            0 :     EMIT(program, BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem));
      83              : 
      84              :     // Jump to the next rule if map_lookup_elem returned 0
      85            0 :     EMIT_FIXUP_JMP_NEXT_RULE(program, BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 0));
      86              : 
      87            0 :     return 0;
      88              : }
      89              : 
      90            0 : static int _bf_matcher_generate_ip4_addr(struct bf_program *program,
      91              :                                          const struct bf_matcher *matcher)
      92              : {
      93            0 :     switch (matcher->op) {
      94            0 :     case BF_MATCHER_EQ:
      95              :     case BF_MATCHER_NE:
      96            0 :         return _bf_matcher_generate_ip4_addr_unique(program, matcher);
      97            0 :     case BF_MATCHER_IN:
      98            0 :         return _bf_matcher_generate_ip4_addr_set(program, matcher);
      99              :     default:
     100              :         return -EINVAL;
     101              :     }
     102              : 
     103              :     return 0;
     104              : }
     105              : 
     106            0 : static int _bf_matcher_generate_ip4_proto(struct bf_program *program,
     107              :                                           const struct bf_matcher *matcher)
     108              : {
     109            0 :     uint8_t proto = *(uint8_t *)&matcher->payload;
     110              : 
     111            0 :     EMIT(program, BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_6,
     112              :                               offsetof(struct iphdr, protocol)));
     113            0 :     EMIT_FIXUP_JMP_NEXT_RULE(
     114              :         program, BPF_JMP_IMM(matcher->op == BF_MATCHER_EQ ? BPF_JNE : BPF_JEQ,
     115              :                              BPF_REG_1, proto, 0));
     116              : 
     117            0 :     return 0;
     118              : }
     119              : 
     120            0 : int bf_matcher_generate_ip4(struct bf_program *program,
     121              :                             const struct bf_matcher *matcher)
     122              : {
     123              :     int r;
     124              : 
     125            0 :     EMIT_FIXUP_JMP_NEXT_RULE(
     126              :         program, BPF_JMP_IMM(BPF_JNE, BPF_REG_7, htobe16(ETH_P_IP), 0));
     127              : 
     128            0 :     EMIT(program,
     129              :          BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, BF_PROG_CTX_OFF(l3_hdr)));
     130              : 
     131            0 :     switch (matcher->type) {
     132            0 :     case BF_MATCHER_IP4_SRC_ADDR:
     133              :     case BF_MATCHER_IP4_DST_ADDR:
     134            0 :         r = _bf_matcher_generate_ip4_addr(program, matcher);
     135            0 :         break;
     136            0 :     case BF_MATCHER_IP4_PROTO:
     137            0 :         r = _bf_matcher_generate_ip4_proto(program, matcher);
     138            0 :         break;
     139            0 :     default:
     140            0 :         return bf_err_r(-EINVAL, "unknown matcher type %d", matcher->type);
     141              :     };
     142              : 
     143              :     if (r)
     144              :         return r;
     145              : 
     146              :     return 0;
     147              : }
        

Generated by: LCOV version 2.0-1