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