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