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 "core/front.h"
13 : #include "core/request.h"
14 : #include "core/response.h"
15 : #include "libbpfilter/generic.h"
16 :
17 0 : int bf_nft_send(const void *data, size_t len)
18 : {
19 0 : _cleanup_bf_request_ struct bf_request *request = NULL;
20 0 : _cleanup_bf_response_ struct bf_response *response = NULL;
21 : int r;
22 :
23 0 : if (!data || !len)
24 : return -EINVAL;
25 :
26 0 : r = bf_request_new(&request, data, len);
27 0 : if (r < 0)
28 : return r;
29 :
30 0 : request->front = BF_FRONT_NFT;
31 :
32 0 : r = bf_send(request, &response);
33 0 : if (r < 0)
34 : return r;
35 :
36 0 : return response->type == BF_RES_FAILURE ? response->error : 0;
37 : }
38 :
39 0 : int bf_nft_sendrecv(const struct nlmsghdr *req, size_t req_len,
40 : struct nlmsghdr *res, size_t *res_len)
41 : {
42 0 : _cleanup_bf_request_ struct bf_request *request = NULL;
43 0 : _cleanup_bf_response_ struct bf_response *response = NULL;
44 : int r;
45 :
46 0 : if (!req || !req_len || !res || !res_len)
47 : return -EINVAL;
48 :
49 0 : if (req_len != req->nlmsg_len)
50 : return -EINVAL;
51 :
52 0 : r = bf_request_new(&request, req, req_len);
53 0 : if (r < 0)
54 : return r;
55 :
56 0 : request->front = BF_FRONT_NFT;
57 :
58 0 : r = bf_send(request, &response);
59 0 : if (r < 0)
60 : return r;
61 :
62 0 : if (response->type == BF_RES_FAILURE)
63 0 : return response->error;
64 :
65 : // The response should be a netlink message
66 0 : if (response->data_len < NLMSG_HDRLEN)
67 : return -EMSGSIZE;
68 :
69 0 : if (((struct nlmsghdr *)response->data)->nlmsg_len != response->data_len)
70 : return -EMSGSIZE;
71 :
72 0 : if (response->data_len > *res_len) {
73 0 : *res_len = response->data_len;
74 0 : return -EMSGSIZE;
75 : }
76 :
77 0 : memcpy(res, response->data, response->data_len);
78 0 : *res_len = response->data_len;
79 :
80 0 : return 0;
81 : }
|