libnl 3.10.0
log.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
4 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
5 * Copyright (c) 2007 Secure Computing Corporation
6 */
7
8/**
9 * @ingroup nfnl
10 * @defgroup log Log
11 * @brief
12 * @{
13 */
14
15#include "nl-default.h"
16
17#include <sys/types.h>
18
19#include <linux/netfilter/nfnetlink_log.h>
20
21#include <netlink/attr.h>
22#include <netlink/netfilter/nfnl.h>
23#include <netlink/netfilter/log.h>
24
25#include "nl-priv-dynamic-core/nl-core.h"
26#include "nl-priv-dynamic-core/cache-api.h"
27
28/**
29 * @name Log Commands
30 * @{
31 */
32
33static int build_log_cmd_request(uint8_t family, uint16_t queuenum,
34 uint8_t command, struct nl_msg **result)
35{
36 struct nl_msg *msg;
37 struct nfulnl_msg_config_cmd cmd;
38
39 msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
40 family, queuenum);
41 if (msg == NULL)
42 return -NLE_NOMEM;
43
44 cmd.command = command;
45 if (nla_put(msg, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
46 goto nla_put_failure;
47
48 *result = msg;
49 return 0;
50
51nla_put_failure:
52 nlmsg_free(msg);
53 return -NLE_MSGSIZE;
54}
55
56static int send_log_request(struct nl_sock *sk, struct nl_msg *msg)
57{
58 int err;
59
60 err = nl_send_auto_complete(sk, msg);
61 nlmsg_free(msg);
62 if (err < 0)
63 return err;
64
65 return wait_for_ack(sk);
66}
67
68int nfnl_log_build_pf_bind(uint8_t pf, struct nl_msg **result)
69{
70 return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_BIND, result);
71}
72
73int nfnl_log_pf_bind(struct nl_sock *nlh, uint8_t pf)
74{
75 struct nl_msg *msg;
76 int err;
77
78 if ((err = nfnl_log_build_pf_bind(pf, &msg)) < 0)
79 return err;
80
81 return send_log_request(nlh, msg);
82}
83
84int nfnl_log_build_pf_unbind(uint8_t pf, struct nl_msg **result)
85{
86 return build_log_cmd_request(pf, 0, NFULNL_CFG_CMD_PF_UNBIND, result);
87}
88
89int nfnl_log_pf_unbind(struct nl_sock *nlh, uint8_t pf)
90{
91 struct nl_msg *msg;
92 int err;
93
94 if ((err = nfnl_log_build_pf_unbind(pf, &msg)) < 0)
95 return err;
96
97 return send_log_request(nlh, msg);
98}
99
100static int nfnl_log_build_request(const struct nfnl_log *log,
101 struct nl_msg **result)
102{
103 struct nl_msg *msg;
104
105 if (!nfnl_log_test_group(log))
106 return -NLE_MISSING_ATTR;
107
108 msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_ULOG, NFULNL_MSG_CONFIG, 0,
109 0, nfnl_log_get_group(log));
110 if (msg == NULL)
111 return -NLE_NOMEM;
112
113 /* This sucks. The nfnetlink_log interface always expects both
114 * parameters to be present. Needs to be done properly.
115 */
116 if (nfnl_log_test_copy_mode(log)) {
117 struct nfulnl_msg_config_mode mode;
118
119 switch (nfnl_log_get_copy_mode(log)) {
120 case NFNL_LOG_COPY_NONE:
121 mode.copy_mode = NFULNL_COPY_NONE;
122 break;
123 case NFNL_LOG_COPY_META:
124 mode.copy_mode = NFULNL_COPY_META;
125 break;
126 case NFNL_LOG_COPY_PACKET:
127 mode.copy_mode = NFULNL_COPY_PACKET;
128 break;
129 }
130 mode.copy_range = htonl(nfnl_log_get_copy_range(log));
131 mode._pad = 0;
132
133 if (nla_put(msg, NFULA_CFG_MODE, sizeof(mode), &mode) < 0)
134 goto nla_put_failure;
135 }
136
137 if (nfnl_log_test_flush_timeout(log) &&
138 nla_put_u32(msg, NFULA_CFG_TIMEOUT,
139 htonl(nfnl_log_get_flush_timeout(log))) < 0)
140 goto nla_put_failure;
141
142 if (nfnl_log_test_alloc_size(log) &&
143 nla_put_u32(msg, NFULA_CFG_NLBUFSIZ,
144 htonl(nfnl_log_get_alloc_size(log))) < 0)
145 goto nla_put_failure;
146
147 if (nfnl_log_test_queue_threshold(log) &&
148 nla_put_u32(msg, NFULA_CFG_QTHRESH,
149 htonl(nfnl_log_get_queue_threshold(log))) < 0)
150 goto nla_put_failure;
151
152 if (nfnl_log_get_flags(log) &&
153 nla_put_u16(msg, NFULA_CFG_FLAGS,
154 htons(nfnl_log_get_flags(log))) < 0)
155 goto nla_put_failure;
156
157 *result = msg;
158 return 0;
159
160nla_put_failure:
161 nlmsg_free(msg);
162 return -NLE_MSGSIZE;
163}
164
165int nfnl_log_build_create_request(const struct nfnl_log *log,
166 struct nl_msg **result)
167{
168 struct nfulnl_msg_config_cmd cmd;
169 int err;
170
171 if ((err = nfnl_log_build_request(log, result)) < 0)
172 return err;
173
174 cmd.command = NFULNL_CFG_CMD_BIND;
175
176 if (nla_put(*result, NFULA_CFG_CMD, sizeof(cmd), &cmd) < 0)
177 goto nla_put_failure;
178
179 return 0;
180
181nla_put_failure:
182 nlmsg_free(*result);
183 return -NLE_MSGSIZE;
184}
185
186int nfnl_log_create(struct nl_sock *nlh, const struct nfnl_log *log)
187{
188 struct nl_msg *msg;
189 int err;
190
191 if ((err = nfnl_log_build_create_request(log, &msg)) < 0)
192 return err;
193
194 return send_log_request(nlh, msg);
195}
196
197int nfnl_log_build_change_request(const struct nfnl_log *log,
198 struct nl_msg **result)
199{
200 return nfnl_log_build_request(log, result);
201}
202
203int nfnl_log_change(struct nl_sock *nlh, const struct nfnl_log *log)
204{
205 struct nl_msg *msg;
206 int err;
207
208 if ((err = nfnl_log_build_change_request(log, &msg)) < 0)
209 return err;
210
211 return send_log_request(nlh, msg);
212}
213
214int nfnl_log_build_delete_request(const struct nfnl_log *log,
215 struct nl_msg **result)
216{
217 if (!nfnl_log_test_group(log))
218 return -NLE_MISSING_ATTR;
219
220 return build_log_cmd_request(0, nfnl_log_get_group(log),
221 NFULNL_CFG_CMD_UNBIND, result);
222}
223
224int nfnl_log_delete(struct nl_sock *nlh, const struct nfnl_log *log)
225{
226 struct nl_msg *msg;
227 int err;
228
229 if ((err = nfnl_log_build_delete_request(log, &msg)) < 0)
230 return err;
231
232 return send_log_request(nlh, msg);
233}
234
235/** @} */
236
237static struct nl_cache_ops nfnl_log_ops = {
238 .co_name = "netfilter/log",
239 .co_obj_ops = &log_obj_ops,
240 .co_msgtypes = {
241 END_OF_MSGTYPES_LIST,
242 },
243};
244
245static void _nl_init log_init(void)
246{
247 nl_cache_mngt_register(&nfnl_log_ops);
248}
249
250static void _nl_exit log_exit(void)
251{
252 nl_cache_mngt_unregister(&nfnl_log_ops);
253}
254
255/** @} */
int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
Add 16 bit integer attribute to netlink message.
Definition attr.c:651
int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
Add 32 bit integer attribute to netlink message.
Definition attr.c:701
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
Add a unspecific attribute to netlink message.
Definition attr.c:503
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Definition cache_mngt.c:287
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
Definition cache_mngt.c:252
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition msg.c:572
struct nl_msg * nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id)
Allocate a new netfilter netlink message.
Definition nfnl.c:202
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition nl.c:1247