summaryrefslogtreecommitdiffstats
path: root/lib/netfilter/queue_obj.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/netfilter/queue_obj.c')
-rw-r--r--lib/netfilter/queue_obj.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/lib/netfilter/queue_obj.c b/lib/netfilter/queue_obj.c
new file mode 100644
index 0000000..ee03836
--- /dev/null
+++ b/lib/netfilter/queue_obj.c
@@ -0,0 +1,215 @@
+/*
+ * lib/netfilter/queue_obj.c Netfilter Queue
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
+ */
+
+/**
+ * @ingroup nfnl
+ * @defgroup queue Queue
+ * @brief
+ * @{
+ */
+
+#include <netlink-local.h>
+#include <netlink/netfilter/nfnl.h>
+#include <netlink/netfilter/queue.h>
+
+/** @cond SKIP */
+#define QUEUE_ATTR_GROUP (1UL << 0)
+#define QUEUE_ATTR_MAXLEN (1UL << 1)
+#define QUEUE_ATTR_COPY_MODE (1UL << 2)
+#define QUEUE_ATTR_COPY_RANGE (1UL << 3)
+/** @endcond */
+
+
+static void nfnl_queue_dump(struct nl_object *a, struct nl_dump_params *p)
+{
+ struct nfnl_queue *queue = (struct nfnl_queue *) a;
+ char buf[64];
+
+ nl_new_line(p);
+
+ if (queue->ce_mask & QUEUE_ATTR_GROUP)
+ nl_dump(p, "group=%u ", queue->queue_group);
+
+ if (queue->ce_mask & QUEUE_ATTR_MAXLEN)
+ nl_dump(p, "maxlen=%u ", queue->queue_maxlen);
+
+ if (queue->ce_mask & QUEUE_ATTR_COPY_MODE)
+ nl_dump(p, "copy_mode=%s ",
+ nfnl_queue_copy_mode2str(queue->queue_copy_mode,
+ buf, sizeof(buf)));
+
+ if (queue->ce_mask & QUEUE_ATTR_COPY_RANGE)
+ nl_dump(p, "copy_range=%u ", queue->queue_copy_range);
+
+ nl_dump(p, "\n");
+}
+
+static struct trans_tbl copy_modes[] = {
+ __ADD(NFNL_QUEUE_COPY_NONE, none)
+ __ADD(NFNL_QUEUE_COPY_META, meta)
+ __ADD(NFNL_QUEUE_COPY_PACKET, packet)
+};
+
+char *nfnl_queue_copy_mode2str(enum nfnl_queue_copy_mode copy_mode, char *buf,
+ size_t len)
+{
+ return __type2str(copy_mode, buf, len, copy_modes,
+ ARRAY_SIZE(copy_modes));
+}
+
+enum nfnl_queue_copy_mode nfnl_queue_str2copy_mode(const char *name)
+{
+ return __str2type(name, copy_modes, ARRAY_SIZE(copy_modes));
+}
+
+/**
+ * @name Allocation/Freeing
+ * @{
+ */
+
+struct nfnl_queue *nfnl_queue_alloc(void)
+{
+ return (struct nfnl_queue *) nl_object_alloc(&queue_obj_ops);
+}
+
+void nfnl_queue_get(struct nfnl_queue *queue)
+{
+ nl_object_get((struct nl_object *) queue);
+}
+
+void nfnl_queue_put(struct nfnl_queue *queue)
+{
+ nl_object_put((struct nl_object *) queue);
+}
+
+/** @} */
+
+/**
+ * @name Attributes
+ * @{
+ */
+
+void nfnl_queue_set_group(struct nfnl_queue *queue, uint16_t group)
+{
+ queue->queue_group = group;
+ queue->ce_mask |= QUEUE_ATTR_GROUP;
+}
+
+int nfnl_queue_test_group(const struct nfnl_queue *queue)
+{
+ return !!(queue->ce_mask & QUEUE_ATTR_GROUP);
+}
+
+uint16_t nfnl_queue_get_group(const struct nfnl_queue *queue)
+{
+ return queue->queue_group;
+}
+
+void nfnl_queue_set_maxlen(struct nfnl_queue *queue, uint32_t maxlen)
+{
+ queue->queue_maxlen = maxlen;
+ queue->ce_mask |= QUEUE_ATTR_MAXLEN;
+}
+
+int nfnl_queue_test_maxlen(const struct nfnl_queue *queue)
+{
+ return !!(queue->ce_mask & QUEUE_ATTR_MAXLEN);
+}
+
+uint32_t nfnl_queue_get_maxlen(const struct nfnl_queue *queue)
+{
+ return queue->queue_maxlen;
+}
+
+void nfnl_queue_set_copy_mode(struct nfnl_queue *queue, enum nfnl_queue_copy_mode mode)
+{
+ queue->queue_copy_mode = mode;
+ queue->ce_mask |= QUEUE_ATTR_COPY_MODE;
+}
+
+int nfnl_queue_test_copy_mode(const struct nfnl_queue *queue)
+{
+ return !!(queue->ce_mask & QUEUE_ATTR_COPY_MODE);
+}
+
+enum nfnl_queue_copy_mode nfnl_queue_get_copy_mode(const struct nfnl_queue *queue)
+{
+ return queue->queue_copy_mode;
+}
+
+void nfnl_queue_set_copy_range(struct nfnl_queue *queue, uint32_t copy_range)
+{
+ queue->queue_copy_range = copy_range;
+ queue->ce_mask |= QUEUE_ATTR_COPY_RANGE;
+}
+
+int nfnl_queue_test_copy_range(const struct nfnl_queue *queue)
+{
+ return !!(queue->ce_mask & QUEUE_ATTR_COPY_RANGE);
+}
+
+uint32_t nfnl_queue_get_copy_range(const struct nfnl_queue *queue)
+{
+ return queue->queue_copy_range;
+}
+
+static int nfnl_queue_compare(struct nl_object *_a, struct nl_object *_b,
+ uint32_t attrs, int flags)
+{
+ struct nfnl_queue *a = (struct nfnl_queue *) _a;
+ struct nfnl_queue *b = (struct nfnl_queue *) _b;
+ int diff = 0;
+
+#define NFNL_QUEUE_DIFF(ATTR, EXPR) \
+ ATTR_DIFF(attrs, QUEUE_ATTR_##ATTR, a, b, EXPR)
+#define NFNL_QUEUE_DIFF_VAL(ATTR, FIELD) \
+ NFNL_QUEUE_DIFF(ATTR, a->FIELD != b->FIELD)
+
+ diff |= NFNL_QUEUE_DIFF_VAL(GROUP, queue_group);
+ diff |= NFNL_QUEUE_DIFF_VAL(MAXLEN, queue_maxlen);
+ diff |= NFNL_QUEUE_DIFF_VAL(COPY_MODE, queue_copy_mode);
+ diff |= NFNL_QUEUE_DIFF_VAL(COPY_RANGE, queue_copy_range);
+
+#undef NFNL_QUEUE_DIFF
+#undef NFNL_QUEUE_DIFF_VAL
+
+ return diff;
+}
+
+static struct trans_tbl nfnl_queue_attrs[] = {
+ __ADD(QUEUE_ATTR_GROUP, group)
+ __ADD(QUEUE_ATTR_MAXLEN, maxlen)
+ __ADD(QUEUE_ATTR_COPY_MODE, copy_mode)
+ __ADD(QUEUE_ATTR_COPY_RANGE, copy_range)
+};
+
+static char *nfnl_queue_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nfnl_queue_attrs,
+ ARRAY_SIZE(nfnl_queue_attrs));
+}
+
+/** @} */
+
+struct nl_object_ops queue_obj_ops = {
+ .oo_name = "netfilter/queue",
+ .oo_size = sizeof(struct nfnl_queue),
+ .oo_dump = {
+ [NL_DUMP_LINE] = nfnl_queue_dump,
+ [NL_DUMP_DETAILS] = nfnl_queue_dump,
+ [NL_DUMP_STATS] = nfnl_queue_dump,
+ },
+ .oo_compare = nfnl_queue_compare,
+ .oo_attrs2str = nfnl_queue_attrs2str,
+ .oo_id_attrs = QUEUE_ATTR_GROUP,
+};
+
+/** @} */