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