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 : #include <stdlib.h>
8 :
9 : #include "bpfilter/cgen/cgen.h"
10 : #include "bpfilter/ctx.h"
11 : #include "bpfilter/xlate/front.h"
12 : #include "core/chain.h"
13 : #include "core/front.h"
14 : #include "core/helper.h"
15 : #include "core/logger.h"
16 : #include "core/marsh.h"
17 : #include "core/request.h"
18 : #include "core/response.h"
19 :
20 : static int _bf_cli_setup(void);
21 : static int _bf_cli_teardown(void);
22 : static int _bf_cli_request_handler(struct bf_request *request,
23 : struct bf_response **response);
24 : static int _bf_cli_marsh(struct bf_marsh **marsh);
25 : static int _bf_cli_unmarsh(struct bf_marsh *marsh);
26 :
27 : const struct bf_front_ops cli_front = {
28 : .setup = _bf_cli_setup,
29 : .teardown = _bf_cli_teardown,
30 : .request_handler = _bf_cli_request_handler,
31 : .marsh = _bf_cli_marsh,
32 : .unmarsh = _bf_cli_unmarsh,
33 : };
34 :
35 0 : static int _bf_cli_setup(void)
36 : {
37 0 : return 0;
38 : }
39 :
40 0 : static int _bf_cli_teardown(void)
41 : {
42 0 : return 0;
43 : }
44 :
45 0 : int _bf_cli_ruleset_flush(const struct bf_request *request,
46 : struct bf_response **response)
47 : {
48 : int r;
49 :
50 : UNUSED(request);
51 :
52 0 : r = bf_ctx_flush();
53 0 : if (r)
54 0 : return bf_err_r(r, "failed to flush the context");
55 :
56 0 : return bf_response_new_success(response, NULL, 0);
57 : }
58 :
59 0 : int _bf_cli_set_rules(const struct bf_request *request,
60 : struct bf_response **response)
61 : {
62 0 : _cleanup_bf_chain_ struct bf_chain *chain = NULL;
63 : struct bf_cgen *cgen;
64 : int r;
65 :
66 0 : bf_assert(request);
67 0 : bf_assert(response);
68 :
69 0 : if (request->data_len < sizeof(struct bf_marsh))
70 0 : return bf_response_new_failure(response, -EINVAL);
71 :
72 0 : r = bf_chain_new_from_marsh(&chain, (void *)request->data);
73 0 : if (r)
74 0 : return bf_err_r(r, "failed to create chain from marsh");
75 :
76 0 : cgen = bf_ctx_get_cgen(chain->hook, &chain->hook_opts);
77 0 : if (!cgen) {
78 0 : r = bf_cgen_new(&cgen, BF_FRONT_CLI, &chain);
79 0 : if (r)
80 : return r;
81 :
82 0 : r = bf_cgen_up(cgen);
83 0 : if (r < 0) {
84 0 : bf_cgen_free(&cgen);
85 0 : return bf_err_r(r, "failed to generate and load new program");
86 : }
87 :
88 0 : r = bf_ctx_set_cgen(cgen);
89 0 : if (r < 0) {
90 0 : bf_cgen_free(&cgen);
91 0 : return bf_err_r(r, "failed to store codegen in runtime context");
92 : }
93 : } else {
94 0 : r = bf_cgen_update(cgen, &chain);
95 0 : if (r < 0)
96 0 : return bf_warn_r(r, "failed to update existing codegen");
97 : }
98 :
99 0 : return bf_response_new_success(response, NULL, 0);
100 : }
101 :
102 0 : static int _bf_cli_request_handler(struct bf_request *request,
103 : struct bf_response **response)
104 : {
105 : int r;
106 :
107 0 : bf_assert(request);
108 0 : bf_assert(response);
109 :
110 0 : switch (request->cmd) {
111 0 : case BF_REQ_RULESET_FLUSH:
112 0 : r = _bf_cli_ruleset_flush(request, response);
113 0 : break;
114 0 : case BF_REQ_RULES_SET:
115 0 : r = _bf_cli_set_rules(request, response);
116 0 : break;
117 0 : default:
118 0 : r = bf_err_r(-EINVAL, "unsupported command %d for CLI front-end",
119 : request->cmd);
120 0 : break;
121 : }
122 :
123 0 : return r;
124 : }
125 :
126 0 : static int _bf_cli_marsh(struct bf_marsh **marsh)
127 : {
128 : UNUSED(marsh);
129 :
130 0 : return 0;
131 : }
132 :
133 0 : static int _bf_cli_unmarsh(struct bf_marsh *marsh)
134 : {
135 : UNUSED(marsh);
136 :
137 0 : return 0;
138 : }
|