LCOV - code coverage report
Current view: top level - libbpfilter - cli.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 259 0
Test Date: 2025-09-16 14:46:44 Functions: 0.0 % 11 0

            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 <errno.h>
       7              : #include <string.h>
       8              : 
       9              : #include "bpfilter/chain.h"
      10              : #include "bpfilter/counter.h"
      11              : #include "bpfilter/front.h"
      12              : #include "bpfilter/generic.h"
      13              : #include "bpfilter/helper.h"
      14              : #include "bpfilter/hook.h"
      15              : #include "bpfilter/io.h"
      16              : #include "bpfilter/list.h"
      17              : #include "bpfilter/logger.h"
      18              : #include "bpfilter/pack.h"
      19              : #include "bpfilter/request.h"
      20              : #include "bpfilter/response.h"
      21              : 
      22            0 : int bf_ruleset_get(bf_list *chains, bf_list *hookopts, bf_list *counters)
      23              : {
      24            0 :     _free_bf_request_ struct bf_request *request = NULL;
      25            0 :     _free_bf_response_ struct bf_response *response = NULL;
      26            0 :     _clean_bf_list_ bf_list _chains = bf_list_default_from(*chains);
      27            0 :     _clean_bf_list_ bf_list _hookopts = bf_list_default_from(*hookopts);
      28            0 :     _clean_bf_list_ bf_list _counters = bf_list_default_from(*counters);
      29            0 :     _free_bf_rpack_ bf_rpack_t *pack;
      30              :     bf_rpack_node_t root, node, child;
      31              :     int r;
      32              : 
      33            0 :     r = bf_request_new(&request, BF_FRONT_CLI, BF_REQ_RULESET_GET, NULL, 0);
      34            0 :     if (r < 0)
      35            0 :         return bf_err_r(r, "failed to init request");
      36              : 
      37            0 :     r = bf_send(request, &response);
      38            0 :     if (r < 0)
      39            0 :         return bf_err_r(r, "failed to send a ruleset get request");
      40              : 
      41            0 :     if (bf_response_status(response) != 0)
      42            0 :         return bf_response_status(response);
      43              : 
      44            0 :     r = bf_rpack_new(&pack, bf_response_data(response),
      45              :                      bf_response_data_len(response));
      46            0 :     if (r)
      47              :         return r;
      48              : 
      49            0 :     r = bf_rpack_kv_obj(bf_rpack_root(pack), "ruleset", &root);
      50            0 :     if (r)
      51              :         return r;
      52              : 
      53            0 :     r = bf_rpack_kv_array(root, "chains", &node);
      54            0 :     if (r)
      55              :         return r;
      56            0 :     bf_rpack_array_foreach (node, child) {
      57            0 :         _free_bf_chain_ struct bf_chain *chain = NULL;
      58              : 
      59            0 :         r = bf_list_emplace(&_chains, bf_chain_new_from_pack, chain, child);
      60              :         if (r)
      61              :             return r;
      62              :     }
      63              : 
      64            0 :     r = bf_rpack_kv_array(root, "hookopts", &node);
      65            0 :     if (r)
      66              :         return r;
      67            0 :     bf_rpack_array_foreach (node, child) {
      68            0 :         _free_bf_hookopts_ struct bf_hookopts *hookopts = NULL;
      69              : 
      70            0 :         if (!bf_rpack_is_nil(child)) {
      71            0 :             r = bf_list_emplace(&_hookopts, bf_hookopts_new_from_pack, hookopts,
      72              :                                 child);
      73              :         } else {
      74            0 :             r = bf_list_add_tail(&_hookopts, NULL);
      75              :         }
      76              : 
      77            0 :         if (r)
      78              :             return r;
      79              :     }
      80              : 
      81            0 :     r = bf_rpack_kv_array(root, "counters", &node);
      82            0 :     if (r)
      83              :         return r;
      84            0 :     bf_rpack_array_foreach (node, child) {
      85            0 :         _free_bf_list_ bf_list *nested = NULL;
      86              :         bf_rpack_node_t subchild;
      87              : 
      88            0 :         if (!bf_rpack_is_array(child))
      89              :             return -EDOM;
      90              : 
      91            0 :         r = bf_list_new(&nested, &bf_list_ops_default(bf_counter_free, NULL));
      92            0 :         if (r)
      93              :             return r;
      94              : 
      95            0 :         bf_rpack_array_foreach (child, subchild) {
      96            0 :             _free_bf_counter_ struct bf_counter *counter = NULL;
      97              : 
      98            0 :             r = bf_list_emplace(nested, bf_counter_new_from_pack, counter,
      99              :                                 subchild);
     100              :             if (r)
     101              :                 return r;
     102              :         }
     103              : 
     104            0 :         r = bf_list_add_tail(&_counters, nested);
     105            0 :         if (r)
     106              :             return r;
     107              : 
     108            0 :         TAKE_PTR(nested);
     109              :     }
     110              : 
     111            0 :     *chains = bf_list_move(_chains);
     112            0 :     *hookopts = bf_list_move(_hookopts);
     113            0 :     *counters = bf_list_move(_counters);
     114              : 
     115            0 :     return 0;
     116              : }
     117              : 
     118            0 : int bf_ruleset_set(bf_list *chains, bf_list *hookopts)
     119              : {
     120            0 :     _free_bf_wpack_ bf_wpack_t *pack = NULL;
     121            0 :     _free_bf_request_ struct bf_request *request = NULL;
     122            0 :     _free_bf_response_ struct bf_response *response = NULL;
     123            0 :     struct bf_list_node *chain_node = bf_list_get_head(chains);
     124            0 :     struct bf_list_node *hookopts_node = bf_list_get_head(hookopts);
     125              :     int r;
     126              : 
     127            0 :     if (bf_list_size(chains) != bf_list_size(hookopts))
     128              :         return -EINVAL;
     129              : 
     130            0 :     r = bf_wpack_new(&pack);
     131            0 :     if (r)
     132              :         return r;
     133              : 
     134            0 :     bf_wpack_open_array(pack, "ruleset");
     135            0 :     while (chain_node && hookopts_node) {
     136            0 :         struct bf_chain *chain = bf_list_node_get_data(chain_node);
     137            0 :         struct bf_hookopts *hookopts = bf_list_node_get_data(hookopts_node);
     138              : 
     139            0 :         bf_wpack_open_object(pack, NULL);
     140              : 
     141            0 :         bf_wpack_open_object(pack, "chain");
     142            0 :         bf_chain_pack(chain, pack);
     143            0 :         bf_wpack_close_object(pack);
     144              : 
     145            0 :         if (hookopts) {
     146            0 :             bf_wpack_open_object(pack, "hookopts");
     147            0 :             bf_hookopts_pack(hookopts, pack);
     148            0 :             bf_wpack_close_object(pack);
     149              :         } else {
     150            0 :             bf_wpack_kv_nil(pack, "hookopts");
     151              :         }
     152              : 
     153            0 :         bf_wpack_close_object(pack);
     154              : 
     155            0 :         chain_node = bf_list_node_next(chain_node);
     156            0 :         hookopts_node = bf_list_node_next(hookopts_node);
     157              :     }
     158            0 :     bf_wpack_close_array(pack);
     159              : 
     160            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_RULESET_SET,
     161              :                                  pack);
     162            0 :     if (r)
     163            0 :         return bf_err_r(r, "failed to create request for chain");
     164              : 
     165            0 :     r = bf_send(request, &response);
     166            0 :     if (r)
     167            0 :         return bf_err_r(r, "failed to send chain to the daemon");
     168              : 
     169            0 :     return bf_response_status(response);
     170              : }
     171              : 
     172            0 : int bf_ruleset_flush(void)
     173              : {
     174            0 :     _free_bf_request_ struct bf_request *request = NULL;
     175            0 :     _free_bf_response_ struct bf_response *response = NULL;
     176              :     int r;
     177              : 
     178            0 :     r = bf_request_new(&request, BF_FRONT_CLI, BF_REQ_RULESET_FLUSH, NULL, 0);
     179            0 :     if (r)
     180            0 :         return bf_err_r(r, "failed to create a ruleset flush request");
     181              : 
     182            0 :     r = bf_send(request, &response);
     183            0 :     if (r)
     184            0 :         return bf_err_r(r, "failed to send a ruleset flush request");
     185              : 
     186            0 :     return bf_response_status(response);
     187              : }
     188              : 
     189            0 : int bf_chain_set(struct bf_chain *chain, struct bf_hookopts *hookopts)
     190              : {
     191            0 :     _free_bf_wpack_ bf_wpack_t *pack = NULL;
     192            0 :     _free_bf_request_ struct bf_request *request = NULL;
     193            0 :     _free_bf_response_ struct bf_response *response = NULL;
     194              :     int r;
     195              : 
     196            0 :     r = bf_wpack_new(&pack);
     197            0 :     if (r)
     198              :         return r;
     199              : 
     200            0 :     bf_wpack_open_object(pack, "chain");
     201            0 :     r = bf_chain_pack(chain, pack);
     202            0 :     if (r)
     203              :         return r;
     204            0 :     bf_wpack_close_object(pack);
     205              : 
     206            0 :     if (hookopts) {
     207            0 :         bf_wpack_open_object(pack, "hookopts");
     208            0 :         r = bf_hookopts_pack(hookopts, pack);
     209            0 :         if (r)
     210              :             return r;
     211            0 :         bf_wpack_close_object(pack);
     212              :     } else {
     213            0 :         bf_wpack_kv_nil(pack, "hookopts");
     214              :     }
     215              : 
     216            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_SET,
     217              :                                  pack);
     218            0 :     if (r)
     219            0 :         return bf_err_r(r, "bf_chain_set: failed to create request");
     220              : 
     221            0 :     r = bf_send(request, &response);
     222            0 :     if (r)
     223            0 :         return bf_err_r(r, "bf_chain_set: failed to send request");
     224              : 
     225            0 :     return bf_response_status(response);
     226              : }
     227              : 
     228            0 : int bf_chain_get(const char *name, struct bf_chain **chain,
     229              :                  struct bf_hookopts **hookopts, bf_list *counters)
     230              : {
     231            0 :     _free_bf_request_ struct bf_request *request = NULL;
     232            0 :     _free_bf_response_ struct bf_response *response = NULL;
     233            0 :     _free_bf_chain_ struct bf_chain *_chain = NULL;
     234            0 :     _free_bf_hookopts_ struct bf_hookopts *_hookopts = NULL;
     235            0 :     _clean_bf_list_ bf_list _counters = bf_list_default_from(*counters);
     236            0 :     _free_bf_wpack_ bf_wpack_t *wpack = NULL;
     237            0 :     _free_bf_rpack_ bf_rpack_t *rpack = NULL;
     238              :     bf_rpack_node_t child, array_node;
     239              :     int r;
     240              : 
     241            0 :     r = bf_wpack_new(&wpack);
     242            0 :     if (r)
     243              :         return r;
     244              : 
     245            0 :     bf_wpack_kv_str(wpack, "name", name);
     246            0 :     if (!bf_wpack_is_valid(wpack))
     247              :         return -EINVAL;
     248              : 
     249            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_GET,
     250              :                                  wpack);
     251            0 :     if (r < 0)
     252            0 :         return bf_err_r(r, "failed to init request");
     253              : 
     254            0 :     r = bf_send(request, &response);
     255            0 :     if (r < 0)
     256            0 :         return bf_err_r(r, "failed to send a ruleset get request");
     257              : 
     258            0 :     if (bf_response_status(response) != 0)
     259            0 :         return bf_response_status(response);
     260              : 
     261            0 :     r = bf_rpack_new(&rpack, bf_response_data(response),
     262              :                      bf_response_data_len(response));
     263            0 :     if (r)
     264              :         return r;
     265              : 
     266            0 :     r = bf_rpack_kv_obj(bf_rpack_root(rpack), "chain", &child);
     267            0 :     if (r)
     268              :         return r;
     269            0 :     r = bf_chain_new_from_pack(&_chain, child);
     270            0 :     if (r)
     271              :         return r;
     272              : 
     273            0 :     r = bf_rpack_kv_node(bf_rpack_root(rpack), "hookopts", &child);
     274            0 :     if (r)
     275              :         return r;
     276            0 :     if (!bf_rpack_is_nil(child)) {
     277            0 :         r = bf_hookopts_new_from_pack(&_hookopts, child);
     278            0 :         if (r)
     279              :             return r;
     280              :     }
     281              : 
     282            0 :     r = bf_rpack_kv_array(bf_rpack_root(rpack), "counters", &child);
     283            0 :     if (r)
     284              :         return r;
     285            0 :     bf_rpack_array_foreach (child, array_node) {
     286            0 :         _free_bf_counter_ struct bf_counter *counter = NULL;
     287              : 
     288            0 :         r = bf_list_emplace(&_counters, bf_counter_new_from_pack, counter,
     289              :                             array_node);
     290              :         if (r)
     291              :             return r;
     292              :     }
     293              : 
     294            0 :     *chain = TAKE_PTR(_chain);
     295            0 :     *hookopts = TAKE_PTR(_hookopts);
     296            0 :     *counters = bf_list_move(_counters);
     297              : 
     298            0 :     return 0;
     299              : }
     300              : 
     301            0 : int bf_chain_prog_fd(const char *name)
     302              : {
     303            0 :     _free_bf_request_ struct bf_request *request = NULL;
     304            0 :     _free_bf_response_ struct bf_response *response = NULL;
     305            0 :     _cleanup_close_ int fd = -1;
     306            0 :     _free_bf_wpack_ bf_wpack_t *wpack = NULL;
     307              :     int r;
     308              : 
     309            0 :     if (!name)
     310              :         return -EINVAL;
     311              : 
     312            0 :     r = bf_wpack_new(&wpack);
     313            0 :     if (r)
     314              :         return r;
     315              : 
     316            0 :     bf_wpack_kv_str(wpack, "name", name);
     317            0 :     if (!bf_wpack_is_valid(wpack))
     318              :         return -EINVAL;
     319              : 
     320            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_PROG_FD,
     321              :                                  wpack);
     322            0 :     if (r < 0)
     323            0 :         return bf_err_r(r, "failed to init request");
     324              : 
     325            0 :     fd = bf_send_with_fd(request, &response);
     326            0 :     if (fd < 0)
     327            0 :         return bf_err_r(fd, "failed to request prog FD from the daemon");
     328              : 
     329            0 :     if (bf_response_status(response) != 0)
     330            0 :         return bf_err_r(bf_response_status(response),
     331              :                         "BF_REQ_CHAIN_PROG_FD failed");
     332              : 
     333            0 :     return TAKE_FD(fd);
     334              : }
     335              : 
     336            0 : int bf_chain_logs_fd(const char *name)
     337              : {
     338            0 :     _free_bf_request_ struct bf_request *request = NULL;
     339            0 :     _free_bf_response_ struct bf_response *response = NULL;
     340            0 :     _cleanup_close_ int fd = -1;
     341            0 :     _free_bf_wpack_ bf_wpack_t *wpack = NULL;
     342              :     int r;
     343              : 
     344            0 :     if (!name)
     345              :         return -EINVAL;
     346              : 
     347            0 :     r = bf_wpack_new(&wpack);
     348            0 :     if (r)
     349              :         return r;
     350              : 
     351            0 :     bf_wpack_kv_str(wpack, "name", name);
     352            0 :     if (!bf_wpack_is_valid(wpack))
     353              :         return -EINVAL;
     354              : 
     355            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_LOGS_FD,
     356              :                                  wpack);
     357            0 :     if (r < 0)
     358            0 :         return bf_err_r(r, "failed to init request");
     359              : 
     360            0 :     fd = bf_send_with_fd(request, &response);
     361            0 :     if (fd < 0)
     362            0 :         return bf_err_r(fd, "failed to request logs FD from the daemon");
     363              : 
     364            0 :     if (bf_response_status(response) != 0)
     365            0 :         return bf_err_r(bf_response_status(response),
     366              :                         "BF_REQ_CHAIN_LOGS failed");
     367              : 
     368            0 :     return TAKE_FD(fd);
     369              : }
     370              : 
     371            0 : int bf_chain_load(struct bf_chain *chain)
     372              : {
     373            0 :     _free_bf_request_ struct bf_request *request = NULL;
     374            0 :     _free_bf_response_ struct bf_response *response = NULL;
     375            0 :     _free_bf_wpack_ bf_wpack_t *wpack = NULL;
     376              :     int r;
     377              : 
     378            0 :     r = bf_wpack_new(&wpack);
     379            0 :     if (r)
     380              :         return r;
     381              : 
     382            0 :     bf_wpack_open_object(wpack, "chain");
     383            0 :     r = bf_chain_pack(chain, wpack);
     384            0 :     if (r)
     385              :         return r;
     386            0 :     bf_wpack_close_object(wpack);
     387              : 
     388            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_LOAD,
     389              :                                  wpack);
     390            0 :     if (r)
     391            0 :         return bf_err_r(r, "bf_chain_load: failed to create a new request");
     392              : 
     393            0 :     r = bf_send(request, &response);
     394            0 :     if (r)
     395            0 :         return bf_err_r(r, "bf_chain_set: failed to send request");
     396              : 
     397            0 :     return bf_response_status(response);
     398              : }
     399              : 
     400            0 : int bf_chain_attach(const char *name, const struct bf_hookopts *hookopts)
     401              : {
     402            0 :     _free_bf_request_ struct bf_request *request = NULL;
     403            0 :     _free_bf_response_ struct bf_response *response = NULL;
     404            0 :     _free_bf_wpack_ bf_wpack_t *wpack = NULL;
     405              :     int r;
     406              : 
     407            0 :     r = bf_wpack_new(&wpack);
     408            0 :     if (r)
     409              :         return r;
     410              : 
     411            0 :     bf_wpack_kv_str(wpack, "name", name);
     412            0 :     bf_wpack_open_object(wpack, "hookopts");
     413            0 :     r = bf_hookopts_pack(hookopts, wpack);
     414            0 :     if (r)
     415              :         return r;
     416            0 :     bf_wpack_close_object(wpack);
     417              : 
     418            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_ATTACH,
     419              :                                  wpack);
     420            0 :     if (r)
     421            0 :         return bf_err_r(r, "bf_chain_attach: failed to create a new request");
     422              : 
     423            0 :     r = bf_send(request, &response);
     424            0 :     if (r)
     425            0 :         return bf_err_r(r, "bf_chain_attach: failed to send request");
     426              : 
     427            0 :     return bf_response_status(response);
     428              : }
     429              : 
     430            0 : int bf_chain_update(const struct bf_chain *chain)
     431              : {
     432            0 :     _free_bf_request_ struct bf_request *request = NULL;
     433            0 :     _free_bf_response_ struct bf_response *response = NULL;
     434            0 :     _free_bf_wpack_ bf_wpack_t *wpack = NULL;
     435              :     int r;
     436              : 
     437            0 :     r = bf_wpack_new(&wpack);
     438            0 :     if (r)
     439              :         return r;
     440              : 
     441            0 :     bf_wpack_open_object(wpack, "chain");
     442            0 :     r = bf_chain_pack(chain, wpack);
     443            0 :     if (r)
     444              :         return r;
     445            0 :     bf_wpack_close_object(wpack);
     446              : 
     447            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_UPDATE,
     448              :                                  wpack);
     449            0 :     if (r)
     450            0 :         return bf_err_r(r, "bf_chain_update: failed to create a new request");
     451              : 
     452            0 :     r = bf_send(request, &response);
     453            0 :     if (r)
     454            0 :         return bf_err_r(r, "bf_chain_update: failed to send request");
     455              : 
     456            0 :     return bf_response_status(response);
     457              : }
     458              : 
     459            0 : int bf_chain_flush(const char *name)
     460              : {
     461            0 :     _free_bf_request_ struct bf_request *request = NULL;
     462            0 :     _free_bf_response_ struct bf_response *response = NULL;
     463            0 :     _free_bf_wpack_ bf_wpack_t *wpack = NULL;
     464              :     int r;
     465              : 
     466            0 :     r = bf_wpack_new(&wpack);
     467            0 :     if (r)
     468              :         return r;
     469              : 
     470            0 :     bf_wpack_kv_str(wpack, "name", name);
     471              : 
     472            0 :     r = bf_request_new_from_pack(&request, BF_FRONT_CLI, BF_REQ_CHAIN_FLUSH,
     473              :                                  wpack);
     474            0 :     if (r)
     475            0 :         return bf_err_r(r, "failed to create request for chain");
     476              : 
     477            0 :     r = bf_send(request, &response);
     478            0 :     if (r)
     479            0 :         return bf_err_r(r, "failed to send chain to the daemon");
     480              : 
     481            0 :     return bf_response_status(response);
     482              : }
        

Generated by: LCOV version 2.0-1