@@ -55,22 +55,29 @@ enum ip_set_extension {
IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT),
IPSET_EXT_BIT_COUNTER = 2,
IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER),
+ IPSET_EXT_BIT_COMMENT = 3,
+ IPSET_EXT_COMMENT = (1 << IPSET_EXT_BIT_COMMENT),
};
/* Extension offsets */
enum ip_set_offset {
IPSET_OFFSET_TIMEOUT = 0,
IPSET_OFFSET_COUNTER,
+ IPSET_OFFSET_COMMENT,
IPSET_OFFSET_MAX,
};
#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
+#define SET_WITH_COMMENT(s) ((s)->extensions & IPSET_EXT_COMMENT)
+
+/* Comment struct */
struct ip_set_ext {
u32 timeout;
u64 packets;
u64 bytes;
+ char *comment;
};
struct ip_set;
@@ -189,6 +196,10 @@ struct ip_set_counter {
atomic64_t packets;
};
+struct ip_set_comment {
+ char *str;
+};
+
static inline void
ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
{
@@ -390,6 +401,7 @@ bitmap_bytes(u32 a, u32 b)
}
#include <linux/netfilter/ipset/ip_set_timeout.h>
+#include <linux/netfilter/ipset/ip_set_comment.h>
#define IP_SET_INIT_KEXT(skb, opt, map) \
{ .bytes = (skb)->len, .packets = 1, \
new file mode 100644
@@ -0,0 +1,52 @@
+#ifndef _IP_SET_COMMENT_H
+#define _IP_SET_COMMENT_H
+
+/* Copyright (C) 2013 Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define IP_SET_MAX_COMMENT_SIZE 255
+
+#ifdef __KERNEL__
+
+static inline char*
+ip_set_comment_uget(struct nlattr *tb)
+{
+ return nla_data(tb);
+}
+
+static inline void
+ip_set_init_comment(struct ip_set_comment *comment,
+ const struct ip_set_ext *ext)
+{
+ size_t len = strlen(ext->comment);
+ if (unlikely(len > IP_SET_MAX_COMMENT_SIZE))
+ len = IP_SET_MAX_COMMENT_SIZE;
+ if (unlikely(comment->str))
+ kfree(comment->str);
+ comment->str = kzalloc(len + 1, GFP_KERNEL);
+ strlcpy(comment->str, ext->comment, len + 1);
+}
+
+static inline bool
+ip_set_put_comment(struct sk_buff *skb, struct ip_set_comment *comment)
+{
+ if(!comment->str)
+ return NULL;
+ return nla_put_string(skb, IPSET_ATTR_COMMENT, comment->str);
+}
+
+static inline void
+ip_set_comment_free(struct ip_set_comment *comment)
+{
+ if(unlikely(!comment->str))
+ return;
+ kfree(comment->str);
+ comment->str = NULL;
+}
+
+#endif
+#endif
@@ -110,6 +110,7 @@ enum {
IPSET_ATTR_IFACE,
IPSET_ATTR_BYTES,
IPSET_ATTR_PACKETS,
+ IPSET_ATTR_COMMENT,
__IPSET_ATTR_ADT_MAX,
};
#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1)
@@ -140,6 +141,7 @@ enum ipset_errno {
IPSET_ERR_IPADDR_IPV4,
IPSET_ERR_IPADDR_IPV6,
IPSET_ERR_COUNTER,
+ IPSET_ERR_COMMENT,
/* Type specific error codes */
IPSET_ERR_TYPE_SPECIFIC = 4352,
@@ -182,6 +184,8 @@ enum ipset_cadt_flags {
IPSET_FLAG_WITH_TIMEOUTS = (1 << IPSET_FLAG_EXT_BEGIN),
IPSET_FLAG_BIT_WITH_COUNTERS = 3,
IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
+ IPSET_FLAG_BIT_WITH_COMMENTS = 4,
+ IPSET_FLAG_WITH_COMMENTS = (1 << IPSET_FLAG_BIT_WITH_COMMENTS),
IPSET_FLAG_CADT_MAX = 15,
};
@@ -340,6 +340,12 @@ ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
ext->packets = be64_to_cpu(nla_get_be64(
tb[IPSET_ATTR_PACKETS]));
}
+ if(tb[IPSET_ATTR_COMMENT]) {
+ if(!(set->extensions & IPSET_EXT_COMMENT))
+ return -IPSET_ERR_COMMENT;
+ ext->comment = ip_set_comment_uget(tb[IPSET_ATTR_COMMENT]);
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(ip_set_get_extensions);