]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - include/linux/netfilter/ipset/ip_set.h
Merge remote-tracking branch 'net-next/master'
[karo-tx-linux.git] / include / linux / netfilter / ipset / ip_set.h
index 66d6bd404d64e758b13f4ac239681cbba5c939c9..7967516adc0d1ba2335111e863cc8c1899050bc3 100644 (file)
@@ -49,25 +49,33 @@ enum ip_set_feature {
 
 /* Set extensions */
 enum ip_set_extension {
-       IPSET_EXT_NONE = 0,
-       IPSET_EXT_BIT_TIMEOUT = 1,
+       IPSET_EXT_BIT_TIMEOUT = 0,
        IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT),
-       IPSET_EXT_BIT_COUNTER = 2,
+       IPSET_EXT_BIT_COUNTER = 1,
        IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER),
+       IPSET_EXT_BIT_COMMENT = 2,
+       IPSET_EXT_COMMENT = (1 << IPSET_EXT_BIT_COMMENT),
+       /* Mark set with an extension which needs to call destroy */
+       IPSET_EXT_BIT_DESTROY = 7,
+       IPSET_EXT_DESTROY = (1 << IPSET_EXT_BIT_DESTROY),
 };
 
 #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)
 
 /* Extension id, in size order */
 enum ip_set_ext_id {
        IPSET_EXT_ID_COUNTER = 0,
        IPSET_EXT_ID_TIMEOUT,
+       IPSET_EXT_ID_COMMENT,
        IPSET_EXT_ID_MAX,
 };
 
 /* Extension type */
 struct ip_set_ext_type {
+       /* Destroy extension private data (can be NULL) */
+       void (*destroy)(void *ext);
        enum ip_set_extension type;
        enum ipset_cadt_flags flag;
        /* Size and minimal alignment */
@@ -81,6 +89,7 @@ struct ip_set_ext {
        u64 packets;
        u64 bytes;
        u32 timeout;
+       char *comment;
 };
 
 struct ip_set_counter {
@@ -88,12 +97,19 @@ struct ip_set_counter {
        atomic64_t packets;
 };
 
+struct ip_set_comment {
+       char *str;
+};
+
+struct ip_set;
+
 #define ext_timeout(e, s)      \
 (unsigned long *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_TIMEOUT])
 #define ext_counter(e, s)      \
 (struct ip_set_counter *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_COUNTER])
+#define ext_comment(e, s)      \
+(struct ip_set_comment *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_COMMENT])
 
-struct ip_set;
 
 typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
                           const struct ip_set_ext *ext,
@@ -168,7 +184,8 @@ struct ip_set_type {
        u8 revision_min, revision_max;
 
        /* Create set */
-       int (*create)(struct ip_set *set, struct nlattr *tb[], u32 flags);
+       int (*create)(struct net *net, struct ip_set *set,
+                     struct nlattr *tb[], u32 flags);
 
        /* Attribute policies */
        const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1];
@@ -210,6 +227,36 @@ struct ip_set {
        void *data;
 };
 
+static inline void
+ip_set_ext_destroy(struct ip_set *set, void *data)
+{
+       /* Check that the extension is enabled for the set and
+        * call it's destroy function for its extension part in data.
+        */
+       if (SET_WITH_COMMENT(set))
+               ip_set_extensions[IPSET_EXT_ID_COMMENT].destroy(
+                       ext_comment(data, set));
+}
+
+static inline int
+ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
+{
+       u32 cadt_flags = 0;
+
+       if (SET_WITH_TIMEOUT(set))
+               if (unlikely(nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+                                          htonl(set->timeout))))
+                       return -EMSGSIZE;
+       if (SET_WITH_COUNTER(set))
+               cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
+       if (SET_WITH_COMMENT(set))
+               cadt_flags |= IPSET_FLAG_WITH_COMMENT;
+
+       if (!cadt_flags)
+               return 0;
+       return nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(cadt_flags));
+}
+
 static inline void
 ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
 {
@@ -270,12 +317,13 @@ ip_set_init_counter(struct ip_set_counter *counter,
 }
 
 /* register and unregister set references */
-extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set);
-extern void ip_set_put_byindex(ip_set_id_t index);
-extern const char *ip_set_name_byindex(ip_set_id_t index);
-extern ip_set_id_t ip_set_nfnl_get(const char *name);
-extern ip_set_id_t ip_set_nfnl_get_byindex(ip_set_id_t index);
-extern void ip_set_nfnl_put(ip_set_id_t index);
+extern ip_set_id_t ip_set_get_byname(struct net *net,
+                                    const char *name, struct ip_set **set);
+extern void ip_set_put_byindex(struct net *net, ip_set_id_t index);
+extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index);
+extern ip_set_id_t ip_set_nfnl_get(struct net *net, const char *name);
+extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index);
+extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index);
 
 /* API for iptables set match, and SET target */
 
@@ -413,6 +461,28 @@ bitmap_bytes(u32 a, u32 b)
 }
 
 #include <linux/netfilter/ipset/ip_set_timeout.h>
+#include <linux/netfilter/ipset/ip_set_comment.h>
+
+static inline int
+ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
+                     const void *e, bool active)
+{
+       if (SET_WITH_TIMEOUT(set)) {
+               unsigned long *timeout = ext_timeout(e, set);
+
+               if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+                       htonl(active ? ip_set_timeout_get(timeout)
+                               : *timeout)))
+                       return -EMSGSIZE;
+       }
+       if (SET_WITH_COUNTER(set) &&
+           ip_set_put_counter(skb, ext_counter(e, set)))
+               return -EMSGSIZE;
+       if (SET_WITH_COMMENT(set) &&
+           ip_set_put_comment(skb, ext_comment(e, set)))
+               return -EMSGSIZE;
+       return 0;
+}
 
 #define IP_SET_INIT_KEXT(skb, opt, set)                        \
        { .bytes = (skb)->len, .packets = 1,            \