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