19 #include <sys/types.h>
20 #include <linux/netfilter/nfnetlink_queue.h>
22 #include <netlink-private/netlink.h>
23 #include <netlink/attr.h>
24 #include <netlink/netfilter/nfnl.h>
25 #include <netlink/netfilter/queue.h>
27 struct nl_sock *nfnl_queue_socket_alloc(
void)
37 static int send_queue_request(
struct nl_sock *sk,
struct nl_msg *msg)
46 return wait_for_ack(sk);
54 static int build_queue_cmd_request(uint8_t family, uint16_t queuenum,
55 uint8_t command,
struct nl_msg **result)
58 struct nfqnl_msg_config_cmd cmd;
65 cmd.pf = htons(family);
67 cmd.command = command;
68 if (
nla_put(msg, NFQA_CFG_CMD,
sizeof(cmd), &cmd) < 0)
79 int nfnl_queue_build_pf_bind(uint8_t pf,
struct nl_msg **result)
81 return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_BIND, result);
84 int nfnl_queue_pf_bind(
struct nl_sock *nlh, uint8_t pf)
89 if ((err = nfnl_queue_build_pf_bind(pf, &msg)) < 0)
92 return send_queue_request(nlh, msg);
95 int nfnl_queue_build_pf_unbind(uint8_t pf,
struct nl_msg **result)
97 return build_queue_cmd_request(pf, 0, NFQNL_CFG_CMD_PF_UNBIND, result);
100 int nfnl_queue_pf_unbind(
struct nl_sock *nlh, uint8_t pf)
105 if ((err = nfnl_queue_build_pf_unbind(pf, &msg)) < 0)
108 return send_queue_request(nlh, msg);
111 static int nfnl_queue_build_request(
const struct nfnl_queue *queue,
112 struct nl_msg **result)
116 if (!nfnl_queue_test_group(queue))
117 return -NLE_MISSING_ATTR;
120 0, nfnl_queue_get_group(queue));
124 if (nfnl_queue_test_maxlen(queue) &&
126 htonl(nfnl_queue_get_maxlen(queue))) < 0)
127 goto nla_put_failure;
132 if (nfnl_queue_test_copy_mode(queue)) {
133 struct nfqnl_msg_config_params params;
135 switch (nfnl_queue_get_copy_mode(queue)) {
136 case NFNL_QUEUE_COPY_NONE:
137 params.copy_mode = NFQNL_COPY_NONE;
139 case NFNL_QUEUE_COPY_META:
140 params.copy_mode = NFQNL_COPY_META;
142 case NFNL_QUEUE_COPY_PACKET:
143 params.copy_mode = NFQNL_COPY_PACKET;
146 params.copy_range = htonl(nfnl_queue_get_copy_range(queue));
148 if (
nla_put(msg, NFQA_CFG_PARAMS,
sizeof(params), ¶ms) < 0)
149 goto nla_put_failure;
160 int nfnl_queue_build_create_request(
const struct nfnl_queue *queue,
161 struct nl_msg **result)
163 struct nfqnl_msg_config_cmd cmd;
166 if ((err = nfnl_queue_build_request(queue, result)) < 0)
171 cmd.command = NFQNL_CFG_CMD_BIND;
173 NLA_PUT(*result, NFQA_CFG_CMD,
sizeof(cmd), &cmd);
182 int nfnl_queue_create(
struct nl_sock *nlh,
const struct nfnl_queue *queue)
187 if ((err = nfnl_queue_build_create_request(queue, &msg)) < 0)
190 return send_queue_request(nlh, msg);
193 int nfnl_queue_build_change_request(
const struct nfnl_queue *queue,
194 struct nl_msg **result)
196 return nfnl_queue_build_request(queue, result);
199 int nfnl_queue_change(
struct nl_sock *nlh,
const struct nfnl_queue *queue)
204 if ((err = nfnl_queue_build_change_request(queue, &msg)) < 0)
207 return send_queue_request(nlh, msg);
210 int nfnl_queue_build_delete_request(
const struct nfnl_queue *queue,
211 struct nl_msg **result)
213 if (!nfnl_queue_test_group(queue))
214 return -NLE_MISSING_ATTR;
216 return build_queue_cmd_request(0, nfnl_queue_get_group(queue),
217 NFQNL_CFG_CMD_UNBIND, result);
220 int nfnl_queue_delete(
struct nl_sock *nlh,
const struct nfnl_queue *queue)
225 if ((err = nfnl_queue_build_delete_request(queue, &msg)) < 0)
228 return send_queue_request(nlh, msg);
233 static struct nl_cache_ops nfnl_queue_ops = {
234 .co_name =
"netfilter/queue",
235 .co_obj_ops = &queue_obj_ops,
237 END_OF_MSGTYPES_LIST,
241 static void __init nfnl_queue_init(
void)
246 static void __exit nfnl_queue_exit(
void)