LCOV - code coverage report
Current view: top level - libbpfilter - ipt.c (source / functions) Coverage Total Hit
Test: coverage.lcov Lines: 59.4 % 69 41
Test Date: 2025-11-24 12:34:34 Functions: 100.0 % 4 4
Branches: 21.4 % 56 12

             Branch data     Line data    Source code
       1                 :             : /* SPDX-License-Identifier: GPL-2.0-only */
       2                 :             : /*
       3                 :             :  * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
       4                 :             :  */
       5                 :             : 
       6                 :             : #include <linux/netfilter/x_tables.h>
       7                 :             : #include <linux/netfilter_ipv4/ip_tables.h>
       8                 :             : 
       9                 :             : #include <errno.h>
      10                 :             : #include <stddef.h>
      11                 :             : #include <stdio.h>
      12                 :             : #include <string.h>
      13                 :             : 
      14                 :             : #include "bpfilter/front.h"
      15                 :             : #include "bpfilter/helper.h"
      16                 :             : #include "bpfilter/io.h"
      17                 :             : #include "bpfilter/logger.h"
      18                 :             : #include "bpfilter/request.h"
      19                 :             : #include "bpfilter/response.h"
      20                 :             : 
      21                 :             : /**
      22                 :             :  * Get size of an ipt_get_entries structure.
      23                 :             :  *
      24                 :             :  * @param ipt_get_entries_ptr Pointer to a valid ipt_get_entries structure.
      25                 :             :  * @return Size of the structure, including variable length entries field.
      26                 :             :  */
      27                 :             : #define bf_ipt_get_entries_size(ipt_get_entries_ptr)                           \
      28                 :             :     (sizeof(struct ipt_get_entries) + (ipt_get_entries_ptr)->size)
      29                 :             : 
      30                 :             : /**
      31                 :             :  * Get size of an xt_counters_info structure.
      32                 :             :  *
      33                 :             :  * @param xt_counters_info_ptr Pointer to a valid xt_counters_info structure.
      34                 :             :  * @return Size of the structure, including variable length counters field.
      35                 :             :  */
      36                 :             : #define bf_xt_counters_info_size(xt_counters_info_ptr)                         \
      37                 :             :     (sizeof(struct xt_counters_info) +                                         \
      38                 :             :      ((xt_counters_info_ptr)->num_counters * sizeof(struct xt_counters)))
      39                 :             : /**
      40                 :             :  * Get size of an ipt_replace structure.
      41                 :             :  *
      42                 :             :  * @param ipt_replace_ptr Pointer to a valid ipt_replace structure.
      43                 :             :  * @return Size of the structure, including variable length entries field.
      44                 :             :  */
      45                 :             : #define bf_ipt_replace_size(ipt_replace_ptr)                                   \
      46                 :             :     (sizeof(struct ipt_replace) + (ipt_replace_ptr)->size)
      47                 :             : 
      48                 :           1 : int bf_ipt_replace(struct ipt_replace *ipt_replace)
      49                 :             : {
      50                 :           1 :     _cleanup_close_ int fd = -1;
      51                 :           1 :     _free_bf_request_ struct bf_request *request = NULL;
      52                 :           1 :     _free_bf_response_ struct bf_response *response = NULL;
      53                 :             :     int r;
      54                 :             : 
      55                 :             :     bf_assert(ipt_replace);
      56                 :             : 
      57                 :           1 :     r = bf_request_new(&request, BF_FRONT_IPT, BF_REQ_RULESET_SET, ipt_replace,
      58                 :           1 :                        bf_ipt_replace_size(ipt_replace));
      59         [ +  - ]:           1 :     if (r < 0)
      60                 :             :         return r;
      61                 :             : 
      62                 :           1 :     fd = bf_connect_to_daemon();
      63         [ +  - ]:           1 :     if (fd < 0)
      64         [ +  - ]:           1 :         return bf_err_r(fd, "failed to connect to the daemon");
      65                 :             : 
      66                 :           0 :     r = bf_send(fd, request, &response, NULL);
      67         [ #  # ]:           0 :     if (r < 0)
      68                 :             :         return r;
      69                 :             : 
      70         [ #  # ]:           0 :     if (bf_response_status(response) == 0) {
      71         [ #  # ]:           0 :         if (bf_response_data_len(response) != bf_request_data_len(request)) {
      72         [ #  # ]:           0 :             return bf_err_r(
      73                 :             :                 EINVAL, "bpfilter: response size is %lu, expected %lu",
      74                 :             :                 bf_response_data_len(response), bf_request_data_len(request));
      75                 :             :         }
      76                 :             : 
      77                 :           0 :         memcpy(ipt_replace, bf_response_data(response),
      78                 :             :                bf_response_data_len(response));
      79                 :             :     }
      80                 :             : 
      81                 :           0 :     return bf_response_status(response);
      82                 :             : }
      83                 :             : 
      84                 :           1 : int bf_ipt_add_counters(struct xt_counters_info *counters)
      85                 :             : {
      86                 :           1 :     _cleanup_close_ int fd = -1;
      87                 :           1 :     _free_bf_request_ struct bf_request *request = NULL;
      88                 :           1 :     _free_bf_response_ struct bf_response *response = NULL;
      89                 :             :     int r;
      90                 :             : 
      91                 :             :     bf_assert(counters);
      92                 :             : 
      93                 :           1 :     r = bf_request_new(&request, BF_FRONT_IPT, BF_REQ_COUNTERS_SET, counters,
      94                 :           1 :                        bf_xt_counters_info_size(counters));
      95         [ +  - ]:           1 :     if (r < 0)
      96                 :             :         return r;
      97                 :             : 
      98                 :           1 :     fd = bf_connect_to_daemon();
      99         [ +  - ]:           1 :     if (fd < 0)
     100         [ +  - ]:           1 :         return bf_err_r(fd, "failed to connect to the daemon");
     101                 :             : 
     102                 :           0 :     r = bf_send(fd, request, &response, NULL);
     103         [ #  # ]:           0 :     if (r < 0)
     104                 :             :         return r;
     105                 :             : 
     106         [ #  # ]:           0 :     if (bf_response_status(response) == 0) {
     107         [ #  # ]:           0 :         if (bf_response_data_len(response) != bf_request_data_len(request)) {
     108         [ #  # ]:           0 :             return bf_err_r(
     109                 :             :                 EINVAL, "bpfilter: response size is %lu, expected %lu",
     110                 :             :                 bf_response_data_len(response), bf_request_data_len(request));
     111                 :             :         }
     112                 :             : 
     113                 :           0 :         memcpy(counters, bf_response_data(response),
     114                 :             :                bf_response_data_len(response));
     115                 :             :     }
     116                 :             : 
     117                 :           0 :     return bf_response_status(response);
     118                 :             : }
     119                 :             : 
     120                 :           1 : int bf_ipt_get_info(struct ipt_getinfo *info)
     121                 :             : {
     122                 :           1 :     _cleanup_close_ int fd = -1;
     123                 :           1 :     _free_bf_request_ struct bf_request *request = NULL;
     124                 :           1 :     _free_bf_response_ struct bf_response *response = NULL;
     125                 :             :     int r;
     126                 :             : 
     127                 :             :     bf_assert(info);
     128                 :             : 
     129                 :           1 :     r = bf_request_new(&request, BF_FRONT_IPT, BF_REQ_CUSTOM, info,
     130                 :             :                        sizeof(*info));
     131         [ +  - ]:           1 :     if (r < 0)
     132                 :             :         return r;
     133                 :             : 
     134                 :           1 :     bf_request_set_ipt_cmd(request, IPT_SO_GET_INFO);
     135                 :             : 
     136                 :           1 :     fd = bf_connect_to_daemon();
     137         [ +  - ]:           1 :     if (fd < 0)
     138         [ +  - ]:           1 :         return bf_err_r(fd, "failed to connect to the daemon");
     139                 :             : 
     140                 :           0 :     r = bf_send(fd, request, &response, NULL);
     141         [ #  # ]:           0 :     if (r < 0)
     142                 :             :         return r;
     143                 :             : 
     144         [ #  # ]:           0 :     if (bf_response_status(response) == 0) {
     145         [ #  # ]:           0 :         if (bf_response_data_len(response) != bf_request_data_len(request)) {
     146         [ #  # ]:           0 :             return bf_err_r(
     147                 :             :                 EINVAL, "bpfilter: response size is %lu, expected %lu",
     148                 :             :                 bf_response_data_len(response), bf_request_data_len(request));
     149                 :             :         }
     150                 :             : 
     151                 :           0 :         memcpy(info, bf_response_data(response),
     152                 :             :                bf_response_data_len(response));
     153                 :             :     }
     154                 :             : 
     155                 :           0 :     return bf_response_status(response);
     156                 :             : }
     157                 :             : 
     158                 :           1 : int bf_ipt_get_entries(struct ipt_get_entries *entries)
     159                 :             : {
     160                 :           1 :     _cleanup_close_ int fd = -1;
     161                 :           1 :     _free_bf_request_ struct bf_request *request = NULL;
     162                 :           1 :     _free_bf_response_ struct bf_response *response = NULL;
     163                 :             :     int r;
     164                 :             : 
     165                 :             :     bf_assert(entries);
     166                 :             : 
     167                 :           1 :     r = bf_request_new(&request, BF_FRONT_IPT, BF_REQ_CUSTOM, entries,
     168                 :           1 :                        bf_ipt_get_entries_size(entries));
     169         [ +  - ]:           1 :     if (r < 0)
     170                 :             :         return r;
     171                 :             : 
     172                 :           1 :     bf_request_set_ipt_cmd(request, IPT_SO_GET_ENTRIES);
     173                 :             : 
     174                 :           1 :     fd = bf_connect_to_daemon();
     175         [ +  - ]:           1 :     if (fd < 0)
     176         [ +  - ]:           1 :         return bf_err_r(fd, "failed to connect to the daemon");
     177                 :             : 
     178                 :           0 :     r = bf_send(fd, request, &response, NULL);
     179         [ #  # ]:           0 :     if (r < 0)
     180                 :             :         return r;
     181                 :             : 
     182         [ #  # ]:           0 :     if (bf_response_status(response) == 0) {
     183         [ #  # ]:           0 :         if (bf_response_data_len(response) != bf_request_data_len(request)) {
     184         [ #  # ]:           0 :             return bf_err_r(
     185                 :             :                 EINVAL, "bpfilter: response size is %lu, expected %lu",
     186                 :             :                 bf_response_data_len(response), bf_request_data_len(request));
     187                 :             :         }
     188                 :             : 
     189                 :           0 :         memcpy(entries, bf_response_data(response),
     190                 :             :                bf_response_data_len(response));
     191                 :             :     }
     192                 :             : 
     193                 :           0 :     return bf_response_status(response);
     194                 :             : }
        

Generated by: LCOV version 2.0-1