LCOV - code coverage report
Current view: top level - libbpfilter - cli.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 267 0
Test Date: 2025-05-09 14:41:07 Functions: 0.0 % 9 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 <stdio.h>
       8              : #include <string.h>
       9              : 
      10              : #include "core/chain.h"
      11              : #include "core/counter.h"
      12              : #include "core/front.h"
      13              : #include "core/helper.h"
      14              : #include "core/hook.h"
      15              : #include "core/list.h"
      16              : #include "core/logger.h"
      17              : #include "core/marsh.h"
      18              : #include "core/request.h"
      19              : #include "core/response.h"
      20              : #include "core/rule.h"
      21              : #include "libbpfilter/generic.h"
      22              : 
      23            0 : int bf_cli_ruleset_get(bf_list *chains, bf_list *hookopts, bf_list *counters)
      24              : {
      25            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
      26            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
      27            0 :     _clean_bf_list_ bf_list _chains = bf_list_default_from(*chains);
      28            0 :     _clean_bf_list_ bf_list _hookopts = bf_list_default_from(*hookopts);
      29            0 :     _clean_bf_list_ bf_list _counters = bf_list_default_from(*counters);
      30              :     struct bf_marsh *marsh = NULL;
      31              :     struct bf_marsh *child = NULL;
      32              :     int r;
      33              : 
      34            0 :     r = bf_request_new(&request, NULL, 0);
      35            0 :     if (r < 0)
      36            0 :         return bf_err_r(r, "failed to init request");
      37              : 
      38            0 :     request->front = BF_FRONT_CLI;
      39            0 :     request->cmd = BF_REQ_RULESET_GET;
      40              : 
      41            0 :     r = bf_send(request, &response);
      42            0 :     if (r < 0)
      43            0 :         return bf_err_r(r, "failed to send a ruleset get request");
      44              : 
      45            0 :     if (response->type == BF_RES_FAILURE)
      46            0 :         return response->error;
      47              : 
      48            0 :     if (response->data_len == 0)
      49              :         return 0;
      50              : 
      51            0 :     marsh = (struct bf_marsh *)response->data;
      52              : 
      53            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
      54              :         return -EINVAL;
      55            0 :     for (struct bf_marsh *schild = bf_marsh_next_child(child, NULL); schild;
      56            0 :          schild = bf_marsh_next_child(child, schild)) {
      57            0 :         _cleanup_bf_chain_ struct bf_chain *chain = NULL;
      58              : 
      59            0 :         r = bf_chain_new_from_marsh(&chain, schild);
      60            0 :         if (r)
      61              :             return r;
      62              : 
      63            0 :         r = bf_list_add_tail(&_chains, chain);
      64            0 :         if (r)
      65              :             return r;
      66              : 
      67            0 :         TAKE_PTR(chain);
      68              :     }
      69              : 
      70            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
      71              :         return -EINVAL;
      72            0 :     for (struct bf_marsh *schild = bf_marsh_next_child(child, NULL); schild;
      73            0 :          schild = bf_marsh_next_child(child, schild)) {
      74            0 :         _free_bf_hookopts_ struct bf_hookopts *hookopts = NULL;
      75              : 
      76            0 :         if (!bf_marsh_is_empty(schild)) {
      77            0 :             r = bf_hookopts_new_from_marsh(&hookopts, schild);
      78            0 :             if (r)
      79              :                 return r;
      80              :         }
      81              : 
      82            0 :         r = bf_list_add_tail(&_hookopts, hookopts);
      83            0 :         if (r)
      84              :             return r;
      85              : 
      86            0 :         TAKE_PTR(hookopts);
      87              :     }
      88              : 
      89            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
      90              :         return -EINVAL;
      91            0 :     for (struct bf_marsh *schild = bf_marsh_next_child(child, NULL); schild;
      92            0 :          schild = bf_marsh_next_child(child, schild)) {
      93            0 :         _cleanup_bf_list_ bf_list *nested = NULL;
      94              : 
      95            0 :         r = bf_list_new(
      96            0 :             &nested, &bf_list_ops_default(bf_counter_free, bf_counter_marsh));
      97            0 :         if (r)
      98              :             return r;
      99              : 
     100            0 :         for (struct bf_marsh *counter_marsh = bf_marsh_next_child(schild, NULL);
     101            0 :              counter_marsh;
     102            0 :              counter_marsh = bf_marsh_next_child(schild, counter_marsh)) {
     103            0 :             _cleanup_bf_counter_ struct bf_counter *counter = NULL;
     104              : 
     105            0 :             r = bf_counter_new_from_marsh(&counter, counter_marsh);
     106            0 :             if (r)
     107              :                 return r;
     108              : 
     109            0 :             r = bf_list_add_tail(nested, counter);
     110            0 :             if (r)
     111              :                 return r;
     112              : 
     113            0 :             TAKE_PTR(counter);
     114              :         }
     115              : 
     116            0 :         r = bf_list_add_tail(&_counters, nested);
     117            0 :         if (r)
     118              :             return r;
     119              : 
     120            0 :         TAKE_PTR(nested);
     121              :     }
     122              : 
     123            0 :     *chains = bf_list_move(_chains);
     124            0 :     *hookopts = bf_list_move(_hookopts);
     125            0 :     *counters = bf_list_move(_counters);
     126              : 
     127            0 :     return 0;
     128              : }
     129              : 
     130            0 : int bf_cli_ruleset_flush(void)
     131              : {
     132            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     133            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     134              :     int r;
     135              : 
     136            0 :     r = bf_request_new(&request, NULL, 0);
     137            0 :     if (r)
     138            0 :         return bf_err_r(r, "failed to create a ruleset flush request");
     139              : 
     140            0 :     request->front = BF_FRONT_CLI;
     141            0 :     request->cmd = BF_REQ_RULESET_FLUSH;
     142              : 
     143            0 :     r = bf_send(request, &response);
     144            0 :     if (r)
     145            0 :         return bf_err_r(r, "failed to send a ruleset flush request");
     146              : 
     147            0 :     return response->type == BF_RES_FAILURE ? response->error : 0;
     148              : }
     149              : 
     150            0 : int bf_cli_ruleset_set(bf_list *chains, bf_list *hookopts)
     151              : {
     152            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     153            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     154            0 :     _cleanup_bf_marsh_ struct bf_marsh *marsh = NULL;
     155            0 :     struct bf_list_node *chain_node = bf_list_get_head(chains);
     156            0 :     struct bf_list_node *hookopts_node = bf_list_get_head(hookopts);
     157              :     int r;
     158              : 
     159            0 :     if (bf_list_size(chains) != bf_list_size(hookopts))
     160              :         return -EINVAL;
     161              : 
     162            0 :     r = bf_marsh_new(&marsh, NULL, 0);
     163            0 :     if (r)
     164              :         return r;
     165              : 
     166            0 :     while (chain_node && hookopts_node) {
     167            0 :         _cleanup_bf_marsh_ struct bf_marsh *chain_marsh = NULL;
     168            0 :         _cleanup_bf_marsh_ struct bf_marsh *hook_marsh = NULL;
     169            0 :         _cleanup_bf_marsh_ struct bf_marsh *_marsh = NULL;
     170            0 :         struct bf_chain *chain = bf_list_node_get_data(chain_node);
     171            0 :         struct bf_hookopts *hookopts = bf_list_node_get_data(hookopts_node);
     172              : 
     173            0 :         r = bf_marsh_new(&_marsh, NULL, 0);
     174            0 :         if (r)
     175              :             return r;
     176              : 
     177            0 :         r = bf_chain_marsh(chain, &chain_marsh);
     178            0 :         if (r)
     179              :             return r;
     180              : 
     181            0 :         r = bf_marsh_add_child_obj(&_marsh, chain_marsh);
     182            0 :         if (r)
     183              :             return r;
     184              : 
     185            0 :         if (hookopts) {
     186            0 :             r = bf_hookopts_marsh(hookopts, &hook_marsh);
     187            0 :             if (r)
     188              :                 return r;
     189              : 
     190            0 :             r = bf_marsh_add_child_obj(&_marsh, hook_marsh);
     191            0 :             if (r)
     192              :                 return r;
     193              :         } else {
     194            0 :             r = bf_marsh_add_child_raw(&_marsh, NULL, 0);
     195            0 :             if (r)
     196              :                 return r;
     197              :         }
     198              : 
     199            0 :         r = bf_marsh_add_child_obj(&marsh, _marsh);
     200            0 :         if (r)
     201              :             return r;
     202              : 
     203            0 :         chain_node = bf_list_node_next(chain_node);
     204            0 :         hookopts_node = bf_list_node_next(hookopts_node);
     205              :     }
     206              : 
     207            0 :     r = bf_request_new(&request, marsh, bf_marsh_size(marsh));
     208            0 :     if (r)
     209            0 :         return bf_err_r(r, "failed to create request for chain");
     210              : 
     211            0 :     request->front = BF_FRONT_CLI;
     212            0 :     request->cmd = BF_REQ_RULESET_SET;
     213              : 
     214            0 :     r = bf_send(request, &response);
     215            0 :     if (r)
     216            0 :         return bf_err_r(r, "failed to send chain to the daemon");
     217              : 
     218            0 :     return response->type == BF_RES_FAILURE ? response->error : 0;
     219              : }
     220              : 
     221            0 : int bf_chain_set(struct bf_chain *chain, struct bf_hookopts *hookopts)
     222              : {
     223            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     224            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     225            0 :     _cleanup_bf_marsh_ struct bf_marsh *marsh = NULL;
     226            0 :     _cleanup_bf_marsh_ struct bf_marsh *chain_marsh = NULL;
     227            0 :     _cleanup_bf_marsh_ struct bf_marsh *hook_marsh = NULL;
     228              :     int r;
     229              : 
     230            0 :     r = bf_marsh_new(&marsh, NULL, 0);
     231            0 :     if (r)
     232              :         return r;
     233              : 
     234            0 :     r = bf_chain_marsh(chain, &chain_marsh);
     235            0 :     if (r)
     236              :         return r;
     237              : 
     238            0 :     r = bf_marsh_add_child_obj(&marsh, chain_marsh);
     239            0 :     if (r)
     240              :         return r;
     241              : 
     242            0 :     if (hookopts) {
     243            0 :         r = bf_hookopts_marsh(hookopts, &hook_marsh);
     244            0 :         if (r)
     245              :             return r;
     246              : 
     247            0 :         r = bf_marsh_add_child_obj(&marsh, hook_marsh);
     248            0 :         if (r)
     249              :             return r;
     250              :     } else {
     251            0 :         r = bf_marsh_add_child_raw(&marsh, NULL, 0);
     252            0 :         if (r)
     253              :             return r;
     254              :     }
     255              : 
     256            0 :     r = bf_request_new(&request, marsh, bf_marsh_size(marsh));
     257            0 :     if (r)
     258            0 :         return bf_err_r(r, "bf_chain_set: failed to create request");
     259              : 
     260            0 :     request->front = BF_FRONT_CLI;
     261            0 :     request->cmd = BF_REQ_CHAIN_SET;
     262              : 
     263            0 :     r = bf_send(request, &response);
     264            0 :     if (r)
     265            0 :         return bf_err_r(r, "bf_chain_set: failed to send request");
     266              : 
     267            0 :     return response->type == BF_RES_FAILURE ? response->error : 0;
     268              : }
     269              : 
     270            0 : int bf_chain_get(const char *name, struct bf_chain **chain,
     271              :                  struct bf_hookopts **hookopts, bf_list *counters)
     272              : {
     273            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     274            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     275            0 :     _cleanup_bf_chain_ struct bf_chain *_chain = NULL;
     276            0 :     _free_bf_hookopts_ struct bf_hookopts *_hookopts = NULL;
     277            0 :     _clean_bf_list_ bf_list _counters = bf_list_default_from(*counters);
     278              :     struct bf_marsh *marsh, *child = NULL;
     279            0 :     _cleanup_bf_marsh_ struct bf_marsh *req_marsh = NULL;
     280              :     int r;
     281              : 
     282            0 :     r = bf_marsh_new(&req_marsh, NULL, 0);
     283            0 :     if (r)
     284              :         return r;
     285              : 
     286            0 :     r = bf_marsh_add_child_raw(&req_marsh, name, strlen(name) + 1);
     287            0 :     if (r)
     288              :         return r;
     289              : 
     290            0 :     r = bf_request_new(&request, req_marsh, bf_marsh_size(req_marsh));
     291            0 :     if (r < 0)
     292            0 :         return bf_err_r(r, "failed to init request");
     293              : 
     294            0 :     request->front = BF_FRONT_CLI;
     295            0 :     request->cmd = BF_REQ_CHAIN_GET;
     296              : 
     297            0 :     r = bf_send(request, &response);
     298            0 :     if (r < 0)
     299            0 :         return bf_err_r(r, "failed to send a ruleset get request");
     300              : 
     301            0 :     if (response->type == BF_RES_FAILURE)
     302            0 :         return response->error;
     303              : 
     304            0 :     marsh = (struct bf_marsh *)response->data;
     305            0 :     if (bf_marsh_size(marsh) != response->data_len) {
     306            0 :         return bf_err_r(
     307              :             -EINVAL,
     308              :             "response payload is expected to have the same size as the marsh");
     309              :     }
     310              : 
     311            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
     312              :         return -EINVAL;
     313            0 :     r = bf_chain_new_from_marsh(&_chain, child);
     314            0 :     if (r)
     315              :         return r;
     316              : 
     317            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
     318              :         return -EINVAL;
     319            0 :     if (child->data_len) {
     320            0 :         r = bf_hookopts_new_from_marsh(&_hookopts, child);
     321            0 :         if (r)
     322              :             return r;
     323              :     }
     324              : 
     325            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
     326              :         return -EINVAL;
     327            0 :     for (struct bf_marsh *counter_marsh = bf_marsh_next_child(child, NULL);
     328            0 :          counter_marsh;
     329            0 :          counter_marsh = bf_marsh_next_child(child, counter_marsh)) {
     330            0 :         _cleanup_bf_counter_ struct bf_counter *counter = NULL;
     331              : 
     332            0 :         r = bf_counter_new_from_marsh(&counter, counter_marsh);
     333            0 :         if (r)
     334              :             return r;
     335              : 
     336            0 :         r = bf_list_add_tail(&_counters, counter);
     337            0 :         if (r)
     338              :             return r;
     339              : 
     340            0 :         TAKE_PTR(counter);
     341              :     }
     342              : 
     343            0 :     *chain = TAKE_PTR(_chain);
     344            0 :     *hookopts = TAKE_PTR(_hookopts);
     345            0 :     *counters = bf_list_move(_counters);
     346              : 
     347            0 :     return 0;
     348              : }
     349              : 
     350            0 : int bf_chain_load(struct bf_chain *chain)
     351              : {
     352            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     353            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     354            0 :     _cleanup_bf_marsh_ struct bf_marsh *marsh = NULL;
     355              :     int r;
     356              : 
     357            0 :     r = bf_marsh_new(&marsh, NULL, 0);
     358            0 :     if (r)
     359              :         return r;
     360              : 
     361              :     {
     362            0 :         _cleanup_bf_marsh_ struct bf_marsh *child = NULL;
     363              : 
     364            0 :         r = bf_chain_marsh(chain, &child);
     365            0 :         if (r)
     366              :             return r;
     367              : 
     368            0 :         r = bf_marsh_add_child_obj(&marsh, child);
     369            0 :         if (r)
     370              :             return r;
     371              :     }
     372              : 
     373            0 :     r = bf_request_new(&request, marsh, bf_marsh_size(marsh));
     374            0 :     if (r)
     375            0 :         return bf_err_r(r, "bf_chain_load: failed to create a new request");
     376              : 
     377            0 :     request->front = BF_FRONT_CLI;
     378            0 :     request->cmd = BF_REQ_CHAIN_LOAD;
     379              : 
     380            0 :     r = bf_send(request, &response);
     381            0 :     if (r)
     382            0 :         return bf_err_r(r, "bf_chain_set: failed to send request");
     383              : 
     384            0 :     return response->type == BF_RES_FAILURE ? response->error : 0;
     385              : }
     386              : 
     387            0 : int bf_chain_attach(const char *name, const struct bf_hookopts *hookopts)
     388              : {
     389            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     390            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     391            0 :     _cleanup_bf_marsh_ struct bf_marsh *marsh = NULL;
     392              :     int r;
     393              : 
     394            0 :     r = bf_marsh_new(&marsh, NULL, 0);
     395            0 :     if (r)
     396              :         return r;
     397              : 
     398            0 :     r = bf_marsh_add_child_raw(&marsh, name, strlen(name) + 1);
     399            0 :     if (r)
     400              :         return r;
     401              : 
     402              :     {
     403            0 :         _cleanup_bf_marsh_ struct bf_marsh *child = NULL;
     404              : 
     405            0 :         r = bf_hookopts_marsh(hookopts, &child);
     406            0 :         if (r)
     407              :             return r;
     408              : 
     409            0 :         r = bf_marsh_add_child_obj(&marsh, child);
     410            0 :         if (r)
     411              :             return r;
     412              :     }
     413              : 
     414            0 :     r = bf_request_new(&request, marsh, bf_marsh_size(marsh));
     415            0 :     if (r)
     416            0 :         return bf_err_r(r, "bf_chain_attach: failed to create a new request");
     417              : 
     418            0 :     request->front = BF_FRONT_CLI;
     419            0 :     request->cmd = BF_REQ_CHAIN_ATTACH;
     420              : 
     421            0 :     r = bf_send(request, &response);
     422            0 :     if (r)
     423            0 :         return bf_err_r(r, "bf_chain_attach: failed to send request");
     424              : 
     425            0 :     return response->type == BF_RES_FAILURE ? response->error : 0;
     426              : }
     427              : 
     428            0 : int bf_chain_update(const struct bf_chain *chain)
     429              : {
     430            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     431            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     432            0 :     _cleanup_bf_marsh_ struct bf_marsh *marsh = NULL;
     433            0 :     _cleanup_bf_marsh_ struct bf_marsh *child = NULL;
     434              :     int r;
     435              : 
     436            0 :     r = bf_marsh_new(&marsh, NULL, 0);
     437            0 :     if (r)
     438              :         return r;
     439              : 
     440            0 :     r = bf_chain_marsh(chain, &child);
     441            0 :     if (r)
     442              :         return r;
     443              : 
     444            0 :     r = bf_marsh_add_child_obj(&marsh, child);
     445            0 :     if (r)
     446              :         return r;
     447              : 
     448            0 :     r = bf_request_new(&request, marsh, bf_marsh_size(marsh));
     449            0 :     if (r)
     450            0 :         return bf_err_r(r, "bf_chain_update: failed to create a new request");
     451              : 
     452            0 :     request->front = BF_FRONT_CLI;
     453            0 :     request->cmd = BF_REQ_CHAIN_UPDATE;
     454              : 
     455            0 :     r = bf_send(request, &response);
     456            0 :     if (r)
     457            0 :         return bf_err_r(r, "bf_chain_update: failed to send request");
     458              : 
     459            0 :     return response->type == BF_RES_FAILURE ? response->error : 0;
     460              : }
     461              : 
     462            0 : int bf_chain_flush(const char *name)
     463              : {
     464            0 :     _cleanup_bf_request_ struct bf_request *request = NULL;
     465            0 :     _cleanup_bf_response_ struct bf_response *response = NULL;
     466            0 :     _cleanup_bf_marsh_ struct bf_marsh *marsh = NULL;
     467              :     int r;
     468              : 
     469            0 :     r = bf_marsh_new(&marsh, NULL, 0);
     470            0 :     if (r)
     471              :         return r;
     472              : 
     473            0 :     r = bf_marsh_add_child_raw(&marsh, name, strlen(name) + 1);
     474            0 :     if (r)
     475              :         return r;
     476              : 
     477            0 :     r = bf_marsh_add_child_raw(&marsh, name, strlen(name) + 1);
     478            0 :     if (r)
     479              :         return r;
     480              : 
     481            0 :     r = bf_request_new(&request, marsh, bf_marsh_size(marsh));
     482            0 :     if (r)
     483            0 :         return bf_err_r(r, "failed to create request for chain");
     484              : 
     485            0 :     request->front = BF_FRONT_CLI;
     486            0 :     request->cmd = BF_REQ_CHAIN_FLUSH;
     487              : 
     488            0 :     r = bf_send(request, &response);
     489            0 :     if (r)
     490            0 :         return bf_err_r(r, "failed to send chain to the daemon");
     491              : 
     492            0 :     return response->type == BF_RES_FAILURE ? response->error : 0;
     493              : }
        

Generated by: LCOV version 2.0-1