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

Generated by: LCOV version 2.0-1