LCOV - code coverage report
Current view: top level - bpfilter/cgen/matcher - tcp.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 50 0
Test Date: 2025-03-25 15:17:39 Functions: 0.0 % 3 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/tcp.h"
       7              : 
       8              : #include <linux/bpf.h>
       9              : #include <linux/bpf_common.h>
      10              : #include <linux/in.h> // NOLINT
      11              : #include <linux/tcp.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/logger.h"
      20              : #include "core/matcher.h"
      21              : 
      22              : #include "external/filter.h"
      23              : 
      24            0 : static int _bf_matcher_generate_tcp_port(struct bf_program *program,
      25              :                                          const struct bf_matcher *matcher)
      26              : {
      27              :     uint16_t *port = (uint16_t *)&matcher->payload;
      28            0 :     size_t offset = matcher->type == BF_MATCHER_TCP_SPORT ?
      29            0 :                         offsetof(struct tcphdr, source) :
      30              :                         offsetof(struct tcphdr, dest);
      31              : 
      32            0 :     EMIT(program, BPF_LDX_MEM(BPF_H, BPF_REG_1, BPF_REG_6, offset));
      33              : 
      34            0 :     switch (matcher->op) {
      35            0 :     case BF_MATCHER_EQ:
      36            0 :         EMIT_FIXUP_JMP_NEXT_RULE(
      37              :             program, BPF_JMP_IMM(BPF_JNE, BPF_REG_1, htobe16(*port), 0));
      38            0 :         break;
      39            0 :     case BF_MATCHER_NE:
      40            0 :         EMIT_FIXUP_JMP_NEXT_RULE(
      41              :             program, BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, htobe16(*port), 0));
      42            0 :         break;
      43            0 :     case BF_MATCHER_RANGE:
      44              :         /* Convert the big-endian value stored in the packet into a
      45              :          * little-endian value for x86 and arm before comparing it to the
      46              :          * reference value. This is a JLT/JGT comparison, we need to have the
      47              :          * MSB where the machine expects then. */
      48            0 :         EMIT(program, BPF_BSWAP(BPF_REG_1, 16));
      49            0 :         EMIT_FIXUP_JMP_NEXT_RULE(
      50              :             program, BPF_JMP_IMM(BPF_JLT, BPF_REG_1, port[0], 0));
      51            0 :         EMIT_FIXUP_JMP_NEXT_RULE(
      52              :             program, BPF_JMP_IMM(BPF_JGT, BPF_REG_1, port[1], 0));
      53            0 :         break;
      54            0 :     default:
      55            0 :         return bf_err_r(-EINVAL, "unknown matcher operator '%s' (%d)",
      56              :                         bf_matcher_op_to_str(matcher->op), matcher->op);
      57              :     }
      58              : 
      59              :     return 0;
      60              : }
      61              : 
      62            0 : static int _bf_matcher_generate_tcp_flags(struct bf_program *program,
      63              :                                           const struct bf_matcher *matcher)
      64              : {
      65            0 :     uint8_t flags = *(uint8_t *)matcher->payload;
      66              : 
      67            0 :     EMIT(program, BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_6, 13));
      68              : 
      69            0 :     switch (matcher->op) {
      70            0 :     case BF_MATCHER_EQ:
      71            0 :         EMIT_FIXUP_JMP_NEXT_RULE(program,
      72              :                                  BPF_JMP_IMM(BPF_JNE, BPF_REG_1, flags, 0));
      73            0 :         break;
      74            0 :     case BF_MATCHER_NE:
      75            0 :         EMIT_FIXUP_JMP_NEXT_RULE(program,
      76              :                                  BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, flags, 0));
      77            0 :         break;
      78            0 :     case BF_MATCHER_ANY:
      79            0 :         EMIT(program, BPF_ALU32_IMM(BPF_AND, BPF_REG_1, flags));
      80            0 :         EMIT_FIXUP_JMP_NEXT_RULE(program,
      81              :                                  BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0));
      82            0 :         break;
      83            0 :     case BF_MATCHER_ALL:
      84            0 :         EMIT(program, BPF_ALU32_IMM(BPF_AND, BPF_REG_1, flags));
      85            0 :         EMIT_FIXUP_JMP_NEXT_RULE(program,
      86              :                                  BPF_JMP_IMM(BPF_JNE, BPF_REG_1, flags, 0));
      87            0 :         break;
      88            0 :     default:
      89            0 :         return bf_err_r(-EINVAL, "unsupported matcher for tcp.flags: %s",
      90              :                         bf_matcher_op_to_str(matcher->op));
      91              :     }
      92              : 
      93              :     return 0;
      94              : }
      95              : 
      96            0 : int bf_matcher_generate_tcp(struct bf_program *program,
      97              :                             const struct bf_matcher *matcher)
      98              : {
      99              :     int r;
     100              : 
     101            0 :     EMIT_FIXUP_JMP_NEXT_RULE(program,
     102              :                              BPF_JMP_IMM(BPF_JNE, BPF_REG_8, IPPROTO_TCP, 0));
     103            0 :     EMIT(program,
     104              :          BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, BF_PROG_CTX_OFF(l4_hdr)));
     105              : 
     106            0 :     switch (matcher->type) {
     107            0 :     case BF_MATCHER_TCP_SPORT:
     108              :     case BF_MATCHER_TCP_DPORT:
     109            0 :         r = _bf_matcher_generate_tcp_port(program, matcher);
     110            0 :         break;
     111            0 :     case BF_MATCHER_TCP_FLAGS:
     112            0 :         r = _bf_matcher_generate_tcp_flags(program, matcher);
     113            0 :         break;
     114            0 :     default:
     115            0 :         return bf_err_r(-EINVAL, "unknown matcher type %d", matcher->type);
     116              :     };
     117              : 
     118              :     return r;
     119              : }
        

Generated by: LCOV version 2.0-1