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

Generated by: LCOV version 2.0-1