LCOV - code coverage report
Current view: top level - bpfilter/cgen/matcher - ip4.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 50 0
Test Date: 2025-08-19 17:27:08 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/logger.h"
      21              : #include "core/matcher.h"
      22              : #include "core/runtime.h"
      23              : 
      24              : #include "external/filter.h"
      25              : 
      26            0 : static int _bf_matcher_generate_ip4_addr(struct bf_program *program,
      27              :                                          const struct bf_matcher *matcher)
      28              : {
      29            0 :     bf_assert(program && matcher);
      30              : 
      31              :     uint32_t *addr = (uint32_t *)&matcher->payload;
      32            0 :     size_t offset = matcher->type == BF_MATCHER_IP4_SADDR ?
      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));
      38              : 
      39            0 :     EMIT_FIXUP_JMP_NEXT_RULE(
      40              :         program, BPF_JMP_REG(matcher->op == BF_MATCHER_EQ ? BPF_JNE : BPF_JEQ,
      41              :                              BPF_REG_1, BPF_REG_2, 0));
      42              : 
      43            0 :     return 0;
      44              : }
      45              : 
      46            0 : static int _bf_matcher_generate_ip4_proto(struct bf_program *program,
      47              :                                           const struct bf_matcher *matcher)
      48              : {
      49            0 :     bf_assert(program && matcher);
      50              : 
      51            0 :     uint8_t proto = *(uint8_t *)&matcher->payload;
      52              : 
      53            0 :     EMIT(program, BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_6,
      54              :                               offsetof(struct iphdr, protocol)));
      55            0 :     EMIT_FIXUP_JMP_NEXT_RULE(
      56              :         program, BPF_JMP_IMM(matcher->op == BF_MATCHER_EQ ? BPF_JNE : BPF_JEQ,
      57              :                              BPF_REG_1, proto, 0));
      58              : 
      59            0 :     return 0;
      60              : }
      61              : 
      62            0 : static void _bf_ip4_prefix_to_mask(uint32_t prefixlen, uint8_t *mask)
      63              : {
      64            0 :     bf_assert(mask);
      65              : 
      66            0 :     memset(mask, 0x00, 4);
      67              : 
      68            0 :     memset(mask, 0xff, prefixlen / 8);
      69            0 :     if (prefixlen % 8)
      70            0 :         mask[prefixlen / 8] = 0xff << (8 - prefixlen % 8) & 0xff;
      71            0 : }
      72              : 
      73            0 : static int _bf_matcher_generate_ip4_net(struct bf_program *program,
      74              :                                         const struct bf_matcher *matcher)
      75              : {
      76            0 :     bf_assert(program && matcher);
      77              : 
      78              :     uint32_t mask;
      79              :     struct bf_ip4_lpm_key *addr = (struct bf_ip4_lpm_key *)&matcher->payload;
      80            0 :     size_t offset = matcher->type == BF_MATCHER_IP4_SNET ?
      81            0 :                         offsetof(struct iphdr, saddr) :
      82              :                         offsetof(struct iphdr, daddr);
      83              : 
      84            0 :     _bf_ip4_prefix_to_mask(addr->prefixlen, (void *)&mask);
      85              : 
      86            0 :     EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, offset));
      87            0 :     EMIT(program, BPF_MOV32_IMM(BPF_REG_2, addr->data));
      88              : 
      89            0 :     if (mask != ~0U) {
      90            0 :         EMIT(program, BPF_MOV32_IMM(BPF_REG_3, mask));
      91            0 :         EMIT(program, BPF_ALU32_REG(BPF_AND, BPF_REG_1, BPF_REG_3));
      92            0 :         EMIT(program, BPF_ALU32_REG(BPF_AND, BPF_REG_2, BPF_REG_3));
      93              :     }
      94              : 
      95            0 :     EMIT_FIXUP_JMP_NEXT_RULE(
      96              :         program, BPF_JMP_REG(matcher->op == BF_MATCHER_EQ ? BPF_JNE : BPF_JEQ,
      97              :                              BPF_REG_1, BPF_REG_2, 0));
      98              : 
      99            0 :     return 0;
     100              : }
     101              : 
     102            0 : int bf_matcher_generate_ip4(struct bf_program *program,
     103              :                             const struct bf_matcher *matcher)
     104              : {
     105            0 :     bf_assert(program && matcher);
     106              : 
     107              :     int r;
     108              : 
     109            0 :     EMIT_FIXUP_JMP_NEXT_RULE(
     110              :         program, BPF_JMP_IMM(BPF_JNE, BPF_REG_7, htobe16(ETH_P_IP), 0));
     111              : 
     112            0 :     EMIT(program,
     113              :          BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, BF_PROG_CTX_OFF(l3_hdr)));
     114              : 
     115            0 :     switch (matcher->type) {
     116            0 :     case BF_MATCHER_IP4_SADDR:
     117              :     case BF_MATCHER_IP4_DADDR:
     118            0 :         r = _bf_matcher_generate_ip4_addr(program, matcher);
     119            0 :         break;
     120            0 :     case BF_MATCHER_IP4_PROTO:
     121            0 :         r = _bf_matcher_generate_ip4_proto(program, matcher);
     122            0 :         break;
     123            0 :     case BF_MATCHER_IP4_SNET:
     124              :     case BF_MATCHER_IP4_DNET:
     125            0 :         r = _bf_matcher_generate_ip4_net(program, matcher);
     126            0 :         break;
     127            0 :     default:
     128            0 :         return bf_err_r(-EINVAL, "unknown matcher type %d", matcher->type);
     129              :     };
     130              : 
     131              :     if (r)
     132              :         return r;
     133              : 
     134              :     return 0;
     135              : }
        

Generated by: LCOV version 2.0-1