LCOV - code coverage report
Current view: top level - bpfilter/xlate - cli.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 313 0
Test Date: 2025-08-19 17:27:08 Functions: 0.0 % 15 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 <errno.h>
       7              : 
       8              : #include "bpfilter/cgen/cgen.h"
       9              : #include "bpfilter/cgen/prog/link.h"
      10              : #include "bpfilter/cgen/prog/map.h"
      11              : #include "bpfilter/cgen/program.h"
      12              : #include "bpfilter/ctx.h"
      13              : #include "bpfilter/xlate/front.h"
      14              : #include "core/chain.h"
      15              : #include "core/counter.h"
      16              : #include "core/front.h"
      17              : #include "core/helper.h"
      18              : #include "core/hook.h"
      19              : #include "core/io.h"
      20              : #include "core/list.h"
      21              : #include "core/logger.h"
      22              : #include "core/marsh.h"
      23              : #include "core/request.h"
      24              : #include "core/response.h"
      25              : #include "core/rule.h"
      26              : 
      27              : static int _bf_cli_setup(void);
      28              : static int _bf_cli_teardown(void);
      29              : static int _bf_cli_request_handler(struct bf_request *request,
      30              :                                    struct bf_response **response);
      31              : static int _bf_cli_marsh(struct bf_marsh **marsh);
      32              : static int _bf_cli_unmarsh(struct bf_marsh *marsh);
      33              : 
      34              : const struct bf_front_ops cli_front = {
      35              :     .setup = _bf_cli_setup,
      36              :     .teardown = _bf_cli_teardown,
      37              :     .request_handler = _bf_cli_request_handler,
      38              :     .marsh = _bf_cli_marsh,
      39              :     .unmarsh = _bf_cli_unmarsh,
      40              : };
      41              : 
      42            0 : static int _bf_cli_setup(void)
      43              : {
      44            0 :     return 0;
      45              : }
      46              : 
      47            0 : static int _bf_cli_teardown(void)
      48              : {
      49            0 :     return 0;
      50              : }
      51              : 
      52            0 : int _bf_cli_ruleset_flush(const struct bf_request *request,
      53              :                           struct bf_response **response)
      54              : {
      55              :     UNUSED(request);
      56              :     UNUSED(response);
      57              : 
      58            0 :     bf_ctx_flush(BF_FRONT_CLI);
      59              : 
      60            0 :     return 0;
      61              : }
      62              : 
      63            0 : static int _bf_cli_ruleset_get(const struct bf_request *request,
      64              :                                struct bf_response **response)
      65              : {
      66            0 :     _free_bf_marsh_ struct bf_marsh *marsh = NULL;
      67            0 :     _free_bf_marsh_ struct bf_marsh *chain_marsh = NULL;
      68            0 :     _free_bf_marsh_ struct bf_marsh *hookopts_marsh = NULL;
      69            0 :     _free_bf_marsh_ struct bf_marsh *counters_marsh = NULL;
      70            0 :     _clean_bf_list_ bf_list cgens = bf_list_default(NULL, NULL);
      71            0 :     _clean_bf_list_ bf_list chains = bf_list_default(NULL, bf_chain_marsh);
      72            0 :     _clean_bf_list_ bf_list hookopts = bf_list_default(NULL, bf_hookopts_marsh);
      73            0 :     _clean_bf_list_ bf_list counters =
      74              :         bf_list_default(bf_list_free, bf_list_marsh);
      75              :     int r;
      76              : 
      77              :     UNUSED(request);
      78              : 
      79            0 :     r = bf_marsh_new(&marsh, NULL, 0);
      80            0 :     if (r < 0)
      81            0 :         return bf_err_r(r, "failed to get new marsh");
      82              : 
      83            0 :     r = bf_ctx_get_cgens_for_front(&cgens, BF_FRONT_CLI);
      84            0 :     if (r < 0)
      85            0 :         return bf_err_r(r, "failed to get cgen list");
      86              : 
      87            0 :     bf_list_foreach (&cgens, cgen_node) {
      88            0 :         struct bf_cgen *cgen = bf_list_node_get_data(cgen_node);
      89            0 :         _free_bf_list_ bf_list *cgen_counters = NULL;
      90              : 
      91            0 :         r = bf_list_add_tail(&chains, cgen->chain);
      92            0 :         if (r)
      93            0 :             return bf_err_r(r, "failed to add chain to list");
      94              : 
      95            0 :         r = bf_list_add_tail(&hookopts, cgen->program->link->hookopts);
      96            0 :         if (r)
      97            0 :             return bf_err_r(r, "failed to add hookopts to list");
      98              : 
      99            0 :         r = bf_list_new(&cgen_counters, &bf_list_ops_default(bf_counter_free,
     100              :                                                              bf_counter_marsh));
     101            0 :         if (r)
     102              :             return r;
     103              : 
     104            0 :         r = bf_cgen_get_counters(cgen, cgen_counters);
     105            0 :         if (r)
     106              :             return r;
     107              : 
     108            0 :         r = bf_list_add_tail(&counters, cgen_counters);
     109            0 :         if (r)
     110              :             return r;
     111              : 
     112            0 :         TAKE_PTR(cgen_counters);
     113              :     }
     114              : 
     115              :     // Marsh the chain list
     116            0 :     r = bf_list_marsh(&chains, &chain_marsh);
     117            0 :     if (r < 0)
     118            0 :         return bf_err_r(r, "failed to marshal chains list");
     119              : 
     120            0 :     r = bf_marsh_add_child_obj(&marsh, chain_marsh);
     121            0 :     if (r < 0)
     122            0 :         return bf_err_r(r, "failed to add chain list to marsh");
     123              : 
     124              :     // Marsh the hookopts list
     125            0 :     r = bf_marsh_new(&hookopts_marsh, NULL, 0);
     126            0 :     bf_list_foreach (&hookopts, hookopts_node) {
     127            0 :         struct bf_hookopts *hookopts = bf_list_node_get_data(hookopts_node);
     128            0 :         _free_bf_marsh_ struct bf_marsh *child = NULL;
     129              : 
     130            0 :         if (hookopts) {
     131            0 :             r = bf_hookopts_marsh(bf_list_node_get_data(hookopts_node), &child);
     132            0 :             if (r < 0)
     133              :                 return r;
     134              : 
     135            0 :             r = bf_marsh_add_child_obj(&hookopts_marsh, child);
     136            0 :             if (r < 0)
     137              :                 return r;
     138              :         } else {
     139            0 :             r = bf_marsh_add_child_raw(&hookopts_marsh, NULL, 0);
     140            0 :             if (r)
     141              :                 return r;
     142              :         }
     143              :     }
     144              : 
     145            0 :     r = bf_marsh_add_child_obj(&marsh, hookopts_marsh);
     146            0 :     if (r < 0)
     147            0 :         return bf_err_r(r, "failed to add chain list to marsh");
     148              : 
     149              :     // Marsh the counters list
     150            0 :     r = bf_list_marsh(&counters, &counters_marsh);
     151            0 :     if (r < 0)
     152            0 :         return bf_err_r(r, "failed to marshal counters list");
     153              : 
     154            0 :     r = bf_marsh_add_child_obj(&marsh, counters_marsh);
     155            0 :     if (r < 0)
     156            0 :         return bf_err_r(r, "failed to add counters list to marsh");
     157              : 
     158            0 :     return bf_response_new_success(response, (void *)marsh,
     159              :                                    bf_marsh_size(marsh));
     160              : }
     161              : 
     162            0 : int _bf_cli_ruleset_set(const struct bf_request *request,
     163              :                         struct bf_response **response)
     164              : {
     165            0 :     _clean_bf_list_ bf_list cgens = bf_list_default(NULL, NULL);
     166              :     struct bf_marsh *marsh, *list_elem = NULL;
     167              :     int r;
     168              : 
     169            0 :     bf_assert(request && response);
     170              : 
     171              :     // Unmarsh the list of chains
     172            0 :     marsh = (struct bf_marsh *)request->data;
     173            0 :     if (bf_marsh_size(marsh) != request->data_len) {
     174            0 :         return bf_err_r(
     175              :             -EINVAL,
     176              :             "request payload is expected to have the same size as the marsh");
     177              :     }
     178              : 
     179            0 :     bf_ctx_flush(BF_FRONT_CLI);
     180              : 
     181            0 :     while ((list_elem = bf_marsh_next_child(marsh, list_elem))) {
     182            0 :         _free_bf_cgen_ struct bf_cgen *cgen = NULL;
     183            0 :         _free_bf_chain_ struct bf_chain *chain = NULL;
     184            0 :         _free_bf_hookopts_ struct bf_hookopts *hookopts = NULL;
     185              :         struct bf_marsh *child = NULL;
     186              : 
     187            0 :         child = bf_marsh_next_child(list_elem, child);
     188            0 :         if (!child)
     189            0 :             return bf_err_r(-ENOENT, "expecting marsh for chain, none found");
     190              : 
     191            0 :         r = bf_chain_new_from_marsh(&chain, child);
     192            0 :         if (r)
     193            0 :             goto err_load;
     194              : 
     195            0 :         child = bf_marsh_next_child(list_elem, child);
     196            0 :         if (!child)
     197            0 :             return bf_err_r(-ENOENT, "expecting marsh for hook, none found");
     198            0 :         if (child->data_len) {
     199            0 :             r = bf_hookopts_new_from_marsh(&hookopts, child);
     200            0 :             if (r)
     201            0 :                 goto err_load;
     202              :         }
     203              : 
     204            0 :         r = bf_cgen_new(&cgen, BF_FRONT_CLI, &chain);
     205            0 :         if (r)
     206            0 :             goto err_load;
     207              : 
     208            0 :         r = bf_cgen_set(cgen, request->ns, hookopts ? &hookopts : NULL);
     209            0 :         if (r) {
     210            0 :             bf_err_r(r, "failed to set chain '%s'", cgen->chain->name);
     211            0 :             goto err_load;
     212              :         }
     213              : 
     214            0 :         r = bf_ctx_set_cgen(cgen);
     215            0 :         if (r) {
     216              :             /* The codegen is loaded already, if the daemon runs in persistent
     217              :              * mode, cleaning the codegen won't be sufficient to discard the
     218              :              * chain, it must be unpinned. */
     219            0 :             bf_cgen_unload(cgen);
     220            0 :             goto err_load;
     221              :         }
     222              : 
     223            0 :         TAKE_PTR(cgen);
     224              :     }
     225              : 
     226              :     return 0;
     227              : 
     228              : err_load:
     229            0 :     bf_ctx_flush(BF_FRONT_CLI);
     230            0 :     return r;
     231              : }
     232              : 
     233            0 : int _bf_cli_chain_set(const struct bf_request *request,
     234              :                       struct bf_response **response)
     235              : {
     236              :     struct bf_cgen *old_cgen;
     237              :     struct bf_marsh *marsh, *child = NULL;
     238            0 :     _free_bf_cgen_ struct bf_cgen *new_cgen = NULL;
     239            0 :     _free_bf_chain_ struct bf_chain *chain = NULL;
     240            0 :     _free_bf_hookopts_ struct bf_hookopts *hookopts = NULL;
     241              :     int r;
     242              : 
     243            0 :     bf_assert(request && response);
     244              : 
     245            0 :     marsh = (struct bf_marsh *)request->data;
     246            0 :     if (bf_marsh_size(marsh) != request->data_len) {
     247            0 :         return bf_err_r(
     248              :             -EINVAL,
     249              :             "request payload is expected to have the same size as the marsh");
     250              :     }
     251              : 
     252            0 :     child = bf_marsh_next_child(marsh, child);
     253            0 :     if (!child)
     254            0 :         return bf_err_r(-ENOENT, "expecting marsh for chain, none found");
     255            0 :     r = bf_chain_new_from_marsh(&chain, child);
     256            0 :     if (r)
     257              :         return r;
     258              : 
     259            0 :     child = bf_marsh_next_child(marsh, child);
     260            0 :     if (!child)
     261            0 :         return bf_err_r(-ENOENT, "expecting marsh for hookopts, none found");
     262            0 :     if (child->data_len) {
     263            0 :         r = bf_hookopts_new_from_marsh(&hookopts, child);
     264            0 :         if (r)
     265              :             return r;
     266              :     }
     267              : 
     268            0 :     r = bf_cgen_new(&new_cgen, BF_FRONT_CLI, &chain);
     269            0 :     if (r)
     270              :         return r;
     271              : 
     272            0 :     old_cgen = bf_ctx_get_cgen(new_cgen->chain->name);
     273            0 :     if (old_cgen) {
     274              :         /* bf_ctx_delete_cgen() can only fail if the codegen is not found,
     275              :          * but we know this codegen exist. */
     276            0 :         (void)bf_ctx_delete_cgen(old_cgen, true);
     277              :     }
     278              : 
     279            0 :     r = bf_cgen_set(new_cgen, request->ns, hookopts ? &hookopts : NULL);
     280            0 :     if (r)
     281              :         return r;
     282              : 
     283            0 :     r = bf_ctx_set_cgen(new_cgen);
     284            0 :     if (r) {
     285            0 :         bf_cgen_unload(new_cgen);
     286            0 :         return r;
     287              :     }
     288              : 
     289            0 :     TAKE_PTR(new_cgen);
     290              : 
     291            0 :     return r;
     292              : }
     293              : 
     294            0 : static int _bf_cli_chain_get(const struct bf_request *request,
     295              :                              struct bf_response **response)
     296              : {
     297            0 :     _free_bf_marsh_ struct bf_marsh *marsh = NULL;
     298            0 :     _clean_bf_list_ bf_list counters =
     299              :         bf_list_default(bf_counter_free, bf_counter_marsh);
     300              :     struct bf_cgen *cgen;
     301              :     struct bf_marsh *req_marsh, *child = NULL;
     302              :     int r;
     303              : 
     304            0 :     req_marsh = (struct bf_marsh *)request->data;
     305            0 :     if (bf_marsh_size(req_marsh) != request->data_len) {
     306            0 :         return bf_err_r(
     307              :             -EINVAL,
     308              :             "request payload is expected to have the same size as the marsh");
     309              :     }
     310              : 
     311            0 :     if (!(child = bf_marsh_next_child(req_marsh, child)))
     312              :         return -EINVAL;
     313            0 :     if (child->data_len < 2)
     314            0 :         return bf_err_r(-EINVAL, "_bf_cli_chain_get: chain name is empty");
     315            0 :     if (child->data[child->data_len - 1]) {
     316            0 :         return bf_err_r(-EINVAL,
     317              :                         "_bf_cli_chain_get: chain name if not nul-terminated");
     318              :     }
     319              : 
     320            0 :     cgen = bf_ctx_get_cgen(child->data);
     321            0 :     if (!cgen)
     322            0 :         return bf_err_r(-ENOENT, "chain '%s' not found", req_marsh->data);
     323              : 
     324            0 :     r = bf_marsh_new(&marsh, NULL, 0);
     325            0 :     if (r < 0)
     326            0 :         return bf_err_r(r, "failed to get new marsh");
     327              : 
     328              :     {
     329            0 :         _free_bf_marsh_ struct bf_marsh *child = NULL;
     330              : 
     331            0 :         r = bf_chain_marsh(cgen->chain, &child);
     332            0 :         if (r)
     333              :             return r;
     334              : 
     335            0 :         r = bf_marsh_add_child_obj(&marsh, child);
     336            0 :         if (r)
     337              :             return r;
     338              :     }
     339              : 
     340            0 :     if (cgen->program->link->hookopts) {
     341            0 :         _free_bf_marsh_ struct bf_marsh *child = NULL;
     342              : 
     343            0 :         r = bf_hookopts_marsh(cgen->program->link->hookopts, &child);
     344            0 :         if (r)
     345              :             return r;
     346              : 
     347            0 :         r = bf_marsh_add_child_obj(&marsh, child);
     348            0 :         if (r < 0)
     349              :             return r;
     350              :     } else {
     351            0 :         r = bf_marsh_add_child_raw(&marsh, NULL, 0);
     352            0 :         if (r)
     353              :             return r;
     354              :     }
     355              : 
     356              :     {
     357            0 :         _free_bf_marsh_ struct bf_marsh *child = NULL;
     358              : 
     359            0 :         r = bf_cgen_get_counters(cgen, &counters);
     360            0 :         if (r)
     361              :             return r;
     362              : 
     363            0 :         r = bf_list_marsh(&counters, &child);
     364            0 :         if (r)
     365              :             return r;
     366              : 
     367            0 :         r = bf_marsh_add_child_obj(&marsh, child);
     368            0 :         if (r)
     369              :             return r;
     370              :     }
     371              : 
     372            0 :     return bf_response_new_success(response, (void *)marsh,
     373              :                                    bf_marsh_size(marsh));
     374              : }
     375              : 
     376            0 : int _bf_cli_chain_logs_fd(const struct bf_request *request,
     377              :                           struct bf_response **response)
     378              : {
     379              :     struct bf_cgen *cgen;
     380              :     struct bf_marsh *marsh, *child = NULL;
     381              :     int r;
     382              : 
     383              :     UNUSED(response);
     384              : 
     385            0 :     marsh = (struct bf_marsh *)request->data;
     386            0 :     if (bf_marsh_size(marsh) != request->data_len) {
     387            0 :         return bf_err_r(
     388              :             -EINVAL,
     389              :             "request payload is expected to have the same size as the marsh");
     390              :     }
     391              : 
     392            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
     393              :         return -EINVAL;
     394            0 :     if (child->data_len < 2)
     395            0 :         return bf_err_r(-EINVAL, "_bf_cli_chain_logs_fd: chain name is empty");
     396            0 :     if (child->data[child->data_len - 1]) {
     397            0 :         return bf_err_r(
     398              :             -EINVAL, "_bf_cli_chain_logs_fd: chain name if not nul-terminated");
     399              :     }
     400              : 
     401            0 :     cgen = bf_ctx_get_cgen(child->data);
     402            0 :     if (!cgen)
     403            0 :         return bf_err_r(-ENOENT, "failed to find chain '%s'", child->data);
     404              : 
     405            0 :     if (!cgen->program || !cgen->program->lmap->fd)
     406            0 :         return bf_err_r(-ENOENT, "chain '%s' has no logs buffer", child->data);
     407              : 
     408            0 :     r = bf_send_fd(request->fd, cgen->program->lmap->fd);
     409            0 :     if (r < 0)
     410            0 :         return bf_err_r(errno, "failed to send logs FD for '%s'", child->data);
     411              : 
     412              :     return 0;
     413              : }
     414              : 
     415            0 : int _bf_cli_chain_load(const struct bf_request *request,
     416              :                        struct bf_response **response)
     417              : {
     418              :     struct bf_marsh *marsh, *child = NULL;
     419            0 :     _free_bf_cgen_ struct bf_cgen *cgen = NULL;
     420            0 :     _free_bf_chain_ struct bf_chain *chain = NULL;
     421              :     int r;
     422              : 
     423            0 :     bf_assert(request && response);
     424              : 
     425            0 :     marsh = (struct bf_marsh *)request->data;
     426            0 :     if (bf_marsh_size(marsh) != request->data_len) {
     427            0 :         return bf_err_r(
     428              :             -EINVAL,
     429              :             "request payload is expected to have the same size as the marsh");
     430              :     }
     431              : 
     432            0 :     child = bf_marsh_next_child(marsh, child);
     433            0 :     if (!child)
     434            0 :         return bf_err_r(-ENOENT, "expecting marsh for chain, none found");
     435              : 
     436            0 :     r = bf_chain_new_from_marsh(&chain, child);
     437            0 :     if (r)
     438              :         return r;
     439              : 
     440            0 :     if (bf_ctx_get_cgen(chain->name)) {
     441            0 :         return bf_err_r(-EEXIST,
     442              :                         "_bf_cli_chain_load: chain '%s' already exists",
     443              :                         chain->name);
     444              :     }
     445              : 
     446            0 :     r = bf_cgen_new(&cgen, BF_FRONT_CLI, &chain);
     447            0 :     if (r)
     448              :         return r;
     449              : 
     450            0 :     r = bf_cgen_load(cgen);
     451            0 :     if (r)
     452              :         return r;
     453              : 
     454            0 :     r = bf_ctx_set_cgen(cgen);
     455            0 :     if (r) {
     456            0 :         bf_cgen_unload(cgen);
     457            0 :         return bf_err_r(
     458              :             r, "bf_ctx_set_cgen: failed to add cgen to the runtime context");
     459              :     }
     460              : 
     461            0 :     TAKE_PTR(cgen);
     462              : 
     463            0 :     return r;
     464              : }
     465              : 
     466            0 : int _bf_cli_chain_attach(const struct bf_request *request,
     467              :                          struct bf_response **response)
     468              : {
     469              :     struct bf_marsh *marsh, *child = NULL;
     470            0 :     _free_bf_chain_ struct bf_chain *chain = NULL;
     471              :     struct bf_cgen *cgen = NULL;
     472              :     const char *name;
     473            0 :     _free_bf_hookopts_ struct bf_hookopts *hookopts = NULL;
     474              :     int r;
     475              : 
     476            0 :     bf_assert(request && response);
     477              : 
     478            0 :     marsh = (struct bf_marsh *)request->data;
     479            0 :     if (bf_marsh_size(marsh) != request->data_len) {
     480            0 :         return bf_err_r(
     481              :             -EINVAL,
     482              :             "request payload is expected to have the same size as the marsh");
     483              :     }
     484              : 
     485            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
     486              :         return -EINVAL;
     487            0 :     if (marsh->data[marsh->data_len - 1]) {
     488            0 :         return bf_err_r(
     489              :             -EINVAL, "_bf_cli_chain_attach: chain name if not nul-terminated");
     490              :     }
     491            0 :     name = child->data;
     492              : 
     493            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
     494              :         return -EINVAL;
     495            0 :     r = bf_hookopts_new_from_marsh(&hookopts, child);
     496            0 :     if (r)
     497              :         return r;
     498              : 
     499            0 :     cgen = bf_ctx_get_cgen(name);
     500            0 :     if (!cgen)
     501            0 :         return bf_err_r(-ENOENT, "chain '%s' does not exist", name);
     502            0 :     if (cgen->program->link->hookopts)
     503            0 :         return bf_err_r(-EBUSY, "chain '%s' is already linked to a hook", name);
     504              : 
     505            0 :     r = bf_hookopts_validate(hookopts, cgen->chain->hook);
     506            0 :     if (r)
     507            0 :         return bf_err_r(r, "failed to validate hook options");
     508              : 
     509            0 :     r = bf_cgen_attach(cgen, request->ns, &hookopts);
     510            0 :     if (r)
     511            0 :         return bf_err_r(r, "failed to attach codegen to hook");
     512              : 
     513              :     return r;
     514              : }
     515              : 
     516            0 : int _bf_cli_chain_update(const struct bf_request *request,
     517              :                          struct bf_response **response)
     518              : {
     519              :     struct bf_marsh *marsh, *child = NULL;
     520            0 :     _free_bf_chain_ struct bf_chain *chain = NULL;
     521              :     struct bf_cgen *cgen = NULL;
     522              :     int r;
     523              : 
     524            0 :     bf_assert(request && response);
     525              : 
     526            0 :     marsh = (struct bf_marsh *)request->data;
     527            0 :     if (bf_marsh_size(marsh) != request->data_len) {
     528            0 :         return bf_err_r(
     529              :             -EINVAL,
     530              :             "request payload is expected to have the same size as the marsh");
     531              :     }
     532              : 
     533            0 :     child = bf_marsh_next_child(marsh, child);
     534            0 :     if (!child)
     535              :         return -EINVAL;
     536            0 :     r = bf_chain_new_from_marsh(&chain, child);
     537            0 :     if (r)
     538              :         return r;
     539              : 
     540            0 :     cgen = bf_ctx_get_cgen(chain->name);
     541            0 :     if (!cgen)
     542              :         return -ENOENT;
     543              : 
     544            0 :     if (!cgen->program->link->hookopts) {
     545            0 :         return bf_err_r(-EINVAL, "chain '%s' is not attached", chain->name);
     546              :     }
     547              : 
     548            0 :     r = bf_cgen_update(cgen, &chain);
     549            0 :     if (r)
     550              :         return -EINVAL;
     551              : 
     552              :     return r;
     553              : }
     554              : 
     555            0 : int _bf_cli_chain_flush(const struct bf_request *request,
     556              :                         struct bf_response **response)
     557              : {
     558              :     struct bf_marsh *marsh, *child = NULL;
     559              :     struct bf_cgen *cgen = NULL;
     560              : 
     561            0 :     bf_assert(request && response);
     562              : 
     563            0 :     marsh = (struct bf_marsh *)request->data;
     564            0 :     if (bf_marsh_size(marsh) != request->data_len) {
     565            0 :         return bf_err_r(
     566              :             -EINVAL,
     567              :             "request payload is expected to have the same size as the marsh");
     568              :     }
     569              : 
     570            0 :     if (!(child = bf_marsh_next_child(marsh, child)))
     571              :         return -EINVAL;
     572            0 :     if (child->data_len < 2)
     573            0 :         return bf_err_r(-EINVAL, "_bf_cli_chain_flush: chain name is empty");
     574            0 :     if (child->data[child->data_len - 1]) {
     575            0 :         return bf_err_r(
     576              :             -EINVAL, "_bf_cli_chain_flush: chain name if not nul-terminated");
     577              :     }
     578              : 
     579            0 :     cgen = bf_ctx_get_cgen(child->data);
     580            0 :     if (!cgen)
     581              :         return -ENOENT;
     582              : 
     583            0 :     return bf_ctx_delete_cgen(cgen, true);
     584              : }
     585              : 
     586            0 : static int _bf_cli_request_handler(struct bf_request *request,
     587              :                                    struct bf_response **response)
     588              : {
     589              :     int r;
     590              : 
     591            0 :     bf_assert(request);
     592            0 :     bf_assert(response);
     593              : 
     594            0 :     switch (request->cmd) {
     595            0 :     case BF_REQ_RULESET_FLUSH:
     596            0 :         r = _bf_cli_ruleset_flush(request, response);
     597            0 :         break;
     598            0 :     case BF_REQ_RULESET_SET:
     599            0 :         r = _bf_cli_ruleset_set(request, response);
     600            0 :         break;
     601            0 :     case BF_REQ_RULESET_GET:
     602            0 :         r = _bf_cli_ruleset_get(request, response);
     603            0 :         break;
     604            0 :     case BF_REQ_CHAIN_SET:
     605            0 :         r = _bf_cli_chain_set(request, response);
     606            0 :         break;
     607            0 :     case BF_REQ_CHAIN_GET:
     608            0 :         r = _bf_cli_chain_get(request, response);
     609            0 :         break;
     610            0 :     case BF_REQ_CHAIN_LOGS_FD:
     611            0 :         r = _bf_cli_chain_logs_fd(request, response);
     612            0 :         break;
     613            0 :     case BF_REQ_CHAIN_LOAD:
     614            0 :         r = _bf_cli_chain_load(request, response);
     615            0 :         break;
     616            0 :     case BF_REQ_CHAIN_ATTACH:
     617            0 :         r = _bf_cli_chain_attach(request, response);
     618            0 :         break;
     619            0 :     case BF_REQ_CHAIN_UPDATE:
     620            0 :         r = _bf_cli_chain_update(request, response);
     621            0 :         break;
     622            0 :     case BF_REQ_CHAIN_FLUSH:
     623            0 :         r = _bf_cli_chain_flush(request, response);
     624            0 :         break;
     625            0 :     default:
     626            0 :         r = bf_err_r(-EINVAL, "unsupported command %d for CLI front-end",
     627              :                      request->cmd);
     628              :         break;
     629              :     }
     630              : 
     631              :     /* If the callback don't need to send data back to the client, it can skip
     632              :      * the response creation and return a status code instead (0 on success,
     633              :      * negative errno value on error). The response is created based on the
     634              :      * status code. */
     635            0 :     if (!*response) {
     636            0 :         if (!r)
     637            0 :             r = bf_response_new_success(response, NULL, 0);
     638              :         else
     639            0 :             r = bf_response_new_failure(response, r);
     640              :     }
     641              : 
     642            0 :     return r;
     643              : }
     644              : 
     645            0 : static int _bf_cli_marsh(struct bf_marsh **marsh)
     646              : {
     647              :     UNUSED(marsh);
     648              : 
     649            0 :     return 0;
     650              : }
     651              : 
     652            0 : static int _bf_cli_unmarsh(struct bf_marsh *marsh)
     653              : {
     654              :     UNUSED(marsh);
     655              : 
     656            0 :     return 0;
     657              : }
        

Generated by: LCOV version 2.0-1