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 <linux/netlink.h>
7 : :
8 : : #include <errno.h>
9 : : #include <stdio.h>
10 : : #include <string.h>
11 : :
12 : : #include "bpfilter/front.h"
13 : : #include "bpfilter/io.h"
14 : : #include "bpfilter/request.h"
15 : : #include "bpfilter/response.h"
16 : :
17 : 3 : int bf_nft_send(const void *data, size_t len)
18 : : {
19 : 3 : _cleanup_close_ int fd = -1;
20 : 3 : _free_bf_request_ struct bf_request *request = NULL;
21 : 3 : _free_bf_response_ struct bf_response *response = NULL;
22 : : int r;
23 : :
24 [ + + ]: 3 : if (!data || !len)
25 : : return -EINVAL;
26 : :
27 : 1 : r = bf_request_new(&request, BF_FRONT_NFT, 0, data, len);
28 [ + - ]: 1 : if (r < 0)
29 : : return r;
30 : :
31 : 1 : fd = bf_connect_to_daemon();
32 [ + - ]: 1 : if (fd < 0)
33 [ + - ]: 1 : return bf_err_r(fd, "failed to connect to the daemon");
34 : :
35 : 0 : r = bf_send(fd, request, &response, NULL);
36 [ # # ]: 0 : if (r < 0)
37 : : return r;
38 : :
39 : 0 : return bf_response_status(response);
40 : : }
41 : :
42 : 6 : int bf_nft_sendrecv(const struct nlmsghdr *req, size_t req_len,
43 : : struct nlmsghdr *res, size_t *res_len)
44 : : {
45 : 6 : _cleanup_close_ int fd = -1;
46 : 6 : _free_bf_request_ struct bf_request *request = NULL;
47 : 6 : _free_bf_response_ struct bf_response *response = NULL;
48 : : int r;
49 : :
50 [ + + + + ]: 6 : if (!req || !req_len || !res || !res_len)
51 : : return -EINVAL;
52 : :
53 [ + + ]: 2 : if (req_len != req->nlmsg_len)
54 : : return -EINVAL;
55 : :
56 : 1 : r = bf_request_new(&request, BF_FRONT_NFT, 0, req, req_len);
57 [ + - ]: 1 : if (r < 0)
58 : : return r;
59 : :
60 : 1 : fd = bf_connect_to_daemon();
61 [ + - ]: 1 : if (fd < 0)
62 [ + - ]: 1 : return bf_err_r(fd, "failed to connect to the daemon");
63 : :
64 : 0 : r = bf_send(fd, request, &response, NULL);
65 [ # # ]: 0 : if (r < 0)
66 : : return r;
67 : :
68 [ # # ]: 0 : if (bf_response_status(response) != 0)
69 : 0 : return bf_response_status(response);
70 : :
71 : : // The response should be a netlink message
72 [ # # ]: 0 : if (bf_response_data_len(response) < NLMSG_HDRLEN)
73 : : return -EMSGSIZE;
74 : :
75 [ # # ]: 0 : if (((const struct nlmsghdr *)bf_response_data(response))->nlmsg_len !=
76 : 0 : bf_response_data_len(response))
77 : : return -EMSGSIZE;
78 : :
79 [ # # ]: 0 : if (bf_response_data_len(response) > *res_len) {
80 : 0 : *res_len = bf_response_data_len(response);
81 : 0 : return -EMSGSIZE;
82 : : }
83 : :
84 : 0 : memcpy(res, bf_response_data(response), bf_response_data_len(response));
85 : 0 : *res_len = bf_response_data_len(response);
86 : :
87 : 0 : return 0;
88 : : }
|