* [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries @ 2013-09-02 6:35 Oliver 2013-09-02 6:35 ` [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core Oliver ` (7 more replies) 0 siblings, 8 replies; 13+ messages in thread From: Oliver @ 2013-09-02 6:35 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> The following patch series provides a new extension that can be enabled on any of the bitmap/hash ipsets to provide the ability to annotate each entry with an arbitrary string comment. Comments are allocated dynamically rather than consuming fixed space in the settype struct. This does come with the cost of having to walk all the entries when flushing/deleting, but otherwise has no bearing on the general operation of ipsets. Currently I have the maximum comment length hardcoded with a preprocessor symbol, it could be easily removed within the kernel if userspace was altered to dynamically allocate also. Right now it's using kmalloc and GFP_KERNEL, I imagine that would need to be changed if someone wanted to modify xt_SET to apply comments to entries that it creates. This patch series depends on an earlier one which I sent that reworks and simplifies the extensions handling tree in order to successfully apply. (see netfilter patchwork 271643 & 271644) I have not increased the revision of the hash:net,net type in this series since, given that it's not released (yet!), there's not all that much point in doing so. Additionally, I haven't written any unit tests for this since I'm not really sure exactly what you'd want to test, so please let me know your ideas. (Related: I hate writing unit tests) I may have misunderstood the library version incrementing info in Make_global.am so if that's completely wrong, let me know :) TL;DR: added comments for ipset entries, please test and give feedback, make sure you have my earlier patches if you try to use it. Cheers! Oliver Smith (6): netfilter: ipset: Support comments for ipset entries in the core. netfilter: ipset: Support comments in hash-type ipsets. netfilter: ipset: Support comments in bitmap-type ipsets. ipset: Rework the "fake" argument parsing for ipset restore. ipset: Support comments in the userspace library. ipset: Add new userspace set revisions for comment support Make_global.am | 2 +- include/libipset/data.h | 6 +- include/libipset/linux_ip_set.h | 9 + include/libipset/parse.h | 2 + include/libipset/print.h | 3 + kernel/include/linux/netfilter/ipset/ip_set.h | 12 ++ .../include/linux/netfilter/ipset/ip_set_comment.h | 52 ++++++ kernel/include/uapi/linux/netfilter/ipset/ip_set.h | 4 + kernel/net/netfilter/ipset/ip_set_bitmap_gen.h | 77 ++++++-- kernel/net/netfilter/ipset/ip_set_bitmap_ip.c | 31 +++- kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c | 47 ++++- kernel/net/netfilter/ipset/ip_set_bitmap_port.c | 30 +++- kernel/net/netfilter/ipset/ip_set_core.c | 6 + kernel/net/netfilter/ipset/ip_set_hash_gen.h | 72 ++++++-- kernel/net/netfilter/ipset/ip_set_hash_ip.c | 51 +++++- kernel/net/netfilter/ipset/ip_set_hash_ipport.c | 75 +++++++- kernel/net/netfilter/ipset/ip_set_hash_ipportip.c | 83 ++++++++- kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c | 91 +++++++++- kernel/net/netfilter/ipset/ip_set_hash_net.c | 75 +++++++- kernel/net/netfilter/ipset/ip_set_hash_netiface.c | 91 +++++++++- kernel/net/netfilter/ipset/ip_set_hash_netnet.c | 88 ++++++++++ kernel/net/netfilter/ipset/ip_set_hash_netport.c | 83 ++++++++- lib/data.c | 34 ++++ lib/debug.c | 1 + lib/errcode.c | 2 + lib/ipset_bitmap_ip.c | 114 ++++++++++++ lib/ipset_bitmap_ipmac.c | 118 +++++++++++++ lib/ipset_bitmap_port.c | 107 +++++++++++ lib/ipset_hash_ip.c | 138 +++++++++++++++ lib/ipset_hash_ipport.c | 161 +++++++++++++++++ lib/ipset_hash_ipportnet.c | 195 +++++++++++++++++++++ lib/ipset_hash_net.c | 145 +++++++++++++++ lib/ipset_hash_netnet.c | 14 +- lib/ipset_hash_netport.c | 158 +++++++++++++++++ lib/libipset.map | 6 + lib/parse.c | 27 +++ lib/print.c | 31 ++++ lib/session.c | 8 +- lib/types.c | 4 +- src/ipset.c | 32 +++- 40 files changed, 2232 insertions(+), 53 deletions(-) create mode 100644 kernel/include/linux/netfilter/ipset/ip_set_comment.h -- 1.8.3.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core. 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver @ 2013-09-02 6:35 ` Oliver 2013-09-02 8:17 ` Oliver 2013-09-02 8:35 ` Oliver 2013-09-02 6:35 ` [PATCH 2/6] netfilter: ipset: Support comments in hash-type ipsets Oliver ` (6 subsequent siblings) 7 siblings, 2 replies; 13+ messages in thread From: Oliver @ 2013-09-02 6:35 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> This adds the core support for having comments on ipset entries. The comments are stored as standard null-terminated strings in dynamically allocated memory after being passed to the kernel. As a result of this, any ipset using comments MUST perform cleanup of individual entries when being flushed or destroyed in order to ensure the allocated memory is released. Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> --- kernel/include/linux/netfilter/ipset/ip_set.h | 12 +++++ .../include/linux/netfilter/ipset/ip_set_comment.h | 52 ++++++++++++++++++++++ kernel/include/uapi/linux/netfilter/ipset/ip_set.h | 4 ++ kernel/net/netfilter/ipset/ip_set_core.c | 6 +++ 4 files changed, 74 insertions(+) create mode 100644 kernel/include/linux/netfilter/ipset/ip_set_comment.h diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h index f974f35..7543d5c 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/linux/netfilter/ipset/ip_set.h @@ -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, \ diff --git a/kernel/include/linux/netfilter/ipset/ip_set_comment.h b/kernel/include/linux/netfilter/ipset/ip_set_comment.h new file mode 100644 index 0000000..9576504 --- /dev/null +++ b/kernel/include/linux/netfilter/ipset/ip_set_comment.h @@ -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 diff --git a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h index 17779ca..bc01f05 100644 --- a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h @@ -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, }; diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c index 4c95bb8..292596f 100644 --- a/kernel/net/netfilter/ipset/ip_set_core.c +++ b/kernel/net/netfilter/ipset/ip_set_core.c @@ -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); -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core. 2013-09-02 6:35 ` [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core Oliver @ 2013-09-02 8:17 ` Oliver 2013-09-02 8:35 ` Oliver 1 sibling, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 8:17 UTC (permalink / raw) To: netfilter-devel On Monday 02 September 2013 08:35:52 Oliver wrote: > From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> > > This adds the core support for having comments on ipset entries. > > The comments are stored as standard null-terminated strings in > dynamically allocated memory after being passed to the kernel. As a > result of this, any ipset using comments MUST perform cleanup of > individual entries when being flushed or destroyed in order to ensure > the allocated memory is released. > > Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> Ignore this patch, it's bad, I'll send a fixed one shortly. Thanks, Oliver. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core. 2013-09-02 6:35 ` [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core Oliver 2013-09-02 8:17 ` Oliver @ 2013-09-02 8:35 ` Oliver 1 sibling, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 8:35 UTC (permalink / raw) To: netfilter-devel On Monday 02 September 2013 08:35:52 Oliver wrote: > From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> > > This adds the core support for having comments on ipset entries. > > The comments are stored as standard null-terminated strings in > dynamically allocated memory after being passed to the kernel. As a > result of this, any ipset using comments MUST perform cleanup of > individual entries when being flushed or destroyed in order to ensure > the allocated memory is released. > > Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> Ignore this patch, it's bad, I've sent through a fixed one as part of the series, I hope that's considered better etiquette then re-mailing the entire series. Thanks, Oliver. ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/6] netfilter: ipset: Support comments in hash-type ipsets. 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver 2013-09-02 6:35 ` [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core Oliver @ 2013-09-02 6:35 ` Oliver 2013-09-02 6:35 ` [PATCH 3/6] netfilter: ipset: Support comments in bitmap-type ipsets Oliver ` (5 subsequent siblings) 7 siblings, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 6:35 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> This provides kernel support for creating ipsets with comment support. This does incur a penalty to flushing/destroying an ipset since all entries are walked in order to free the allocated strings, this penalty is of course less expensive than the operation of listing an ipset to userspace, so for general-purpose usage the overall impact is expected to be little to none. Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> --- kernel/net/netfilter/ipset/ip_set_hash_gen.h | 72 +++++++++++++---- kernel/net/netfilter/ipset/ip_set_hash_ip.c | 51 +++++++++++- kernel/net/netfilter/ipset/ip_set_hash_ipport.c | 75 +++++++++++++++++- kernel/net/netfilter/ipset/ip_set_hash_ipportip.c | 83 +++++++++++++++++++- kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c | 91 +++++++++++++++++++++- kernel/net/netfilter/ipset/ip_set_hash_net.c | 75 +++++++++++++++++- kernel/net/netfilter/ipset/ip_set_hash_netiface.c | 91 +++++++++++++++++++++- kernel/net/netfilter/ipset/ip_set_hash_netnet.c | 88 +++++++++++++++++++++ kernel/net/netfilter/ipset/ip_set_hash_netport.c | 83 +++++++++++++++++++- 9 files changed, 688 insertions(+), 21 deletions(-) diff --git a/kernel/net/netfilter/ipset/ip_set_hash_gen.h b/kernel/net/netfilter/ipset/ip_set_hash_gen.h index 72e098f..cfeef09 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_gen.h +++ b/kernel/net/netfilter/ipset/ip_set_hash_gen.h @@ -184,6 +184,8 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize) (unsigned long *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_TIMEOUT]) #define ext_counter(e, h) \ (struct ip_set_counter *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_COUNTER]) +#define ext_comment(e, h) \ +(struct ip_set_comment *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_COMMENT]) #endif /* _IP_SET_HASH_GEN_H */ @@ -419,6 +421,10 @@ mtype_ahash_memsize(const struct htype *h, const struct htable *t, return memsize; } +/* Get the ith element from the array block n */ +#define ahash_data(n, i, dsize) \ + ((struct mtype_elem *)((n)->value + ((i) * (dsize)))) + /* Flush a hash type of set: destroy all elements */ static void mtype_flush(struct ip_set *set) @@ -426,12 +432,19 @@ mtype_flush(struct ip_set *set) struct htype *h = set->data; struct htable *t; struct hbucket *n; - u32 i; + struct mtype_elem *data; + u32 i, j; t = rcu_dereference_bh_nfnl(h->table); for (i = 0; i < jhash_size(t->htable_bits); i++) { n = hbucket(t, i); if (n->size) { + if (SET_WITH_COMMENT(set)) { + for (j = 0; j < n->pos; j++) { + data = ahash_data(n, j, h->dsize); + ip_set_comment_free(ext_comment(data, h)); + } + } n->size = n->pos = 0; /* FIXME: use slab cache */ kfree(n->value); @@ -453,6 +466,9 @@ mtype_destroy(struct ip_set *set) if (set->extensions & IPSET_EXT_TIMEOUT) del_timer_sync(&h->gc); + if (SET_WITH_COMMENT(set)) + mtype_flush(set); + ahash_destroy(rcu_dereference_bh_nfnl(h->table)); #ifdef IP_SET_HASH_WITH_RBTREE rbtree_destroy(&h->rbtree); @@ -491,10 +507,6 @@ mtype_same_set(const struct ip_set *a, const struct ip_set *b) a->extensions == b->extensions; } -/* Get the ith element from the array block n */ -#define ahash_data(n, i, dsize) \ - ((struct mtype_elem *)((n)->value + ((i) * (dsize)))) - /* Delete expired elements from the hashtable */ static void mtype_expire(struct htype *h, u8 nets_length, size_t dsize) @@ -740,6 +752,8 @@ reuse_slot: ip_set_timeout_set(ext_timeout(data, h), ext->timeout); if (SET_WITH_COUNTER(set)) ip_set_init_counter(ext_counter(data, h), ext); + if(SET_WITH_COMMENT(set)) + ip_set_init_comment(ext_comment(data, h), ext); out: rcu_read_unlock_bh(); @@ -785,6 +799,8 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, mtype_del_cidr2(h, CIDR(d->cidr2), NETS_LENGTH(set->family)); #endif #endif + if(SET_WITH_COMMENT(set)) + ip_set_comment_free(ext_comment(data, h)); if (n->pos + AHASH_INIT_SIZE < n->size) { void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) * h->dsize, @@ -949,7 +965,10 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))) || ((set->extensions & IPSET_EXT_COUNTER) && nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, - htonl(IPSET_FLAG_WITH_COUNTERS)))) + htonl(IPSET_FLAG_WITH_COUNTERS))) || + ((set->extensions & IPSET_EXT_COMMENT) && + nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, + htonl(IPSET_FLAG_WITH_COMMENTS)))) goto nla_put_failure; ipset_nest_end(skb, nested); @@ -1006,6 +1025,9 @@ mtype_list(const struct ip_set *set, if (SET_WITH_COUNTER(set) && ip_set_put_counter(skb, ext_counter(e, h))) goto nla_put_failure; + if (SET_WITH_COMMENT(set) && + ip_set_put_comment(skb, ext_comment(e,h))) + goto nla_put_failure; ipset_nest_end(skb, nested); } } @@ -1059,7 +1081,7 @@ IPSET_TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags) u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; u32 cadt_flags = 0; u8 hbits; - int i = IPSET_FLAG_EXT_BEGIN, t_off = 0, c_off = 0; + int i = IPSET_FLAG_EXT_BEGIN, t_off = 0, c_off = 0, m_off = 0; #ifdef IP_SET_HASH_WITH_NETMASK u8 netmask; #endif @@ -1144,33 +1166,55 @@ IPSET_TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags) /* Due to the inherent limitations of a preprocessor macro, all vars are set * and we simply use the ones we need during the flag iteration stage. */ -#define generate_offsets(X,C,T) \ +#define generate_offsets(X,C,T,M) \ if(set->family == NFPROTO_IPV4) { \ h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, X))); \ c_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, C)), counter);\ t_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, T)), timeout);\ + m_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, M)), comment);\ } else { \ h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, X))); \ c_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, C)), counter);\ t_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, T)), timeout);\ + m_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(6, M)), comment);\ } if(!cadt_flags) { - generate_offsets(_elem,c_elem,t_elem); + generate_offsets(_elem,c_elem,t_elem,m_elem); } else { switch(cadt_flags) { case (IPSET_FLAG_WITH_COUNTERS | + IPSET_FLAG_WITH_TIMEOUTS | + IPSET_FLAG_WITH_COMMENTS) : + generate_offsets(ctm_elem, ctm_elem, ctm_elem, ctm_elem); + break; + case (IPSET_FLAG_WITH_COUNTERS | IPSET_FLAG_WITH_TIMEOUTS) : - generate_offsets(ct_elem, ct_elem, ct_elem); + generate_offsets(ct_elem, ct_elem, ct_elem, m_elem); break; - case IPSET_FLAG_WITH_TIMEOUTS : - generate_offsets(t_elem, c_elem, t_elem); + case (IPSET_FLAG_WITH_TIMEOUTS | + IPSET_FLAG_WITH_COMMENTS) : + generate_offsets(tm_elem, c_elem, tm_elem, tm_elem); break; - case IPSET_FLAG_WITH_COUNTERS : - generate_offsets(c_elem, c_elem, t_elem); + case (IPSET_FLAG_WITH_COUNTERS | + IPSET_FLAG_WITH_COMMENTS) : + generate_offsets(cm_elem, cm_elem, t_elem, cm_elem); + break; + case IPSET_FLAG_WITH_TIMEOUTS : + generate_offsets(t_elem, c_elem, t_elem, m_elem); + break; + case IPSET_FLAG_WITH_COUNTERS : + generate_offsets(c_elem, c_elem, t_elem, m_elem); + break; + case IPSET_FLAG_WITH_COMMENTS : + generate_offsets(m_elem, c_elem, t_elem, m_elem); break; } for(; i < (1 << IPSET_FLAG_CADT_MAX); i = (i << 1)) { switch(cadt_flags & i) { + case IPSET_FLAG_WITH_COMMENTS: + set->extensions |= IPSET_EXT_COMMENT; + h->offset[IPSET_OFFSET_COMMENT] = m_off; + break; case IPSET_FLAG_WITH_COUNTERS: set->extensions |= IPSET_EXT_COUNTER; h->offset[IPSET_OFFSET_COUNTER] = c_off; diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ip.c b/kernel/net/netfilter/ipset/ip_set_hash_ip.c index 260c9a8..9746cf8 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_ip.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_ip.c @@ -24,7 +24,8 @@ #include <linux/netfilter/ipset/ip_set_hash.h> #define IPSET_TYPE_REV_MIN 0 -#define IPSET_TYPE_REV_MAX 1 /* Counters support */ +/* 1 Counters support */ +#define IPSET_TYPE_REV_MAX 2 /* Comments support */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -53,12 +54,36 @@ struct hash_ip4c_elem { struct ip_set_counter counter; }; +struct hash_ip4m_elem { + __be32 ip; + struct ip_set_comment comment; +}; + struct hash_ip4ct_elem { __be32 ip; struct ip_set_counter counter; unsigned long timeout; }; +struct hash_ip4tm_elem { + __be32 ip; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ip4cm_elem { + __be32 ip; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ip4ctm_elem { + __be32 ip; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool @@ -195,12 +220,36 @@ struct hash_ip6c_elem { struct ip_set_counter counter; }; +struct hash_ip6m_elem { + union nf_inet_addr ip; + struct ip_set_comment comment; +}; + struct hash_ip6ct_elem { union nf_inet_addr ip; struct ip_set_counter counter; unsigned long timeout; }; +struct hash_ip6tm_elem { + union nf_inet_addr ip; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ip6cm_elem { + union nf_inet_addr ip; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ip6ctm_elem { + union nf_inet_addr ip; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c index 64caad3..5acef50 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_ipport.c @@ -26,7 +26,8 @@ #define IPSET_TYPE_REV_MIN 0 /* 1 SCTP and UDPLITE support added */ -#define IPSET_TYPE_REV_MAX 2 /* Counters support added */ +/* 2 Counters support added */ +#define IPSET_TYPE_REV_MAX 3 /* Comments support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -62,6 +63,14 @@ struct hash_ipport4c_elem { struct ip_set_counter counter; }; +struct hash_ipport4m_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; +}; + struct hash_ipport4ct_elem { __be32 ip; __be16 port; @@ -71,6 +80,34 @@ struct hash_ipport4ct_elem { unsigned long timeout; }; +struct hash_ipport4tm_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ipport4cm_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ipport4ctm_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool @@ -247,6 +284,14 @@ struct hash_ipport6c_elem { struct ip_set_counter counter; }; +struct hash_ipport6m_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; +}; + struct hash_ipport6ct_elem { union nf_inet_addr ip; __be16 port; @@ -256,6 +301,34 @@ struct hash_ipport6ct_elem { unsigned long timeout; }; +struct hash_ipport6tm_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ipport6cm_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ipport6ctm_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c index 2873bbc..1863d20 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -26,7 +26,8 @@ #define IPSET_TYPE_REV_MIN 0 /* 1 SCTP and UDPLITE support added */ -#define IPSET_TYPE_REV_MAX 2 /* Counters support added */ +/* 2 Counters support added */ +#define IPSET_TYPE_REV_MAX 3 /* Comments support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -65,6 +66,15 @@ struct hash_ipportip4c_elem { struct ip_set_counter counter; }; +struct hash_ipportip4m_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; +}; + struct hash_ipportip4ct_elem { __be32 ip; __be32 ip2; @@ -75,6 +85,37 @@ struct hash_ipportip4ct_elem { unsigned long timeout; }; +struct hash_ipportip4tm_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ipportip4cm_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ipportip4ctm_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + static inline bool hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1, const struct hash_ipportip4_elem *ip2, @@ -259,6 +300,15 @@ struct hash_ipportip6c_elem { struct ip_set_counter counter; }; +struct hash_ipportip6m_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; +}; + struct hash_ipportip6ct_elem { union nf_inet_addr ip; union nf_inet_addr ip2; @@ -269,6 +319,37 @@ struct hash_ipportip6ct_elem { unsigned long timeout; }; +struct hash_ipportip6tm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ipportip6cm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ipportip6ctm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 proto; + u8 padding; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c index f111558..b66177d 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -28,7 +28,8 @@ /* 1 SCTP and UDPLITE support added */ /* 2 Range as input support for IPv4 added */ /* 3 nomatch flag support added */ -#define IPSET_TYPE_REV_MAX 4 /* Counters support added */ +/* 4 Counters support added */ +#define IPSET_TYPE_REV_MAX 5 /* Comments support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -78,6 +79,16 @@ struct hash_ipportnet4c_elem { struct ip_set_counter counter; }; +struct hash_ipportnet4m_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_comment comment; +}; + struct hash_ipportnet4ct_elem { __be32 ip; __be32 ip2; @@ -89,6 +100,40 @@ struct hash_ipportnet4ct_elem { unsigned long timeout; }; +struct hash_ipportnet4tm_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ipportnet4cm_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ipportnet4ctm_elem { + __be32 ip; + __be32 ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool @@ -359,6 +404,16 @@ struct hash_ipportnet6c_elem { struct ip_set_counter counter; }; +struct hash_ipportnet6m_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_comment comment; +}; + struct hash_ipportnet6ct_elem { union nf_inet_addr ip; union nf_inet_addr ip2; @@ -370,6 +425,40 @@ struct hash_ipportnet6ct_elem { unsigned long timeout; }; +struct hash_ipportnet6tm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_ipportnet6cm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_ipportnet6ctm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + __be16 port; + u8 cidr:7; + u8 nomatch:1; + u8 proto; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool diff --git a/kernel/net/netfilter/ipset/ip_set_hash_net.c b/kernel/net/netfilter/ipset/ip_set_hash_net.c index 0a64dad..3990b3f 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_net.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_net.c @@ -25,7 +25,8 @@ #define IPSET_TYPE_REV_MIN 0 /* 1 Range as input support for IPv4 added */ /* 2 nomatch flag support added */ -#define IPSET_TYPE_REV_MAX 3 /* Counters support added */ +/* 3 Counters support added */ +#define IPSET_TYPE_REV_MAX 4 /* Comments support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -62,6 +63,14 @@ struct hash_net4c_elem { struct ip_set_counter counter; }; +struct hash_net4m_elem { + __be32 ip; + u16 padding0; + u8 nomatch; + u8 cidr; + struct ip_set_comment comment; +}; + struct hash_net4ct_elem { __be32 ip; u16 padding0; @@ -71,6 +80,34 @@ struct hash_net4ct_elem { unsigned long timeout; }; +struct hash_net4tm_elem { + __be32 ip; + u16 padding0; + u8 nomatch; + u8 cidr; + unsigned long timeout; + struct ip_set_comment comment; +}; + +struct hash_net4cm_elem { + __be32 ip; + u16 padding0; + u8 nomatch; + u8 cidr; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_net4ctm_elem { + __be32 ip; + u16 padding0; + u8 nomatch; + u8 cidr; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool @@ -253,6 +290,14 @@ struct hash_net6c_elem { struct ip_set_counter counter; }; +struct hash_net6m_elem { + union nf_inet_addr ip; + u16 padding0; + u8 nomatch; + u8 cidr; + struct ip_set_comment comment; +}; + struct hash_net6ct_elem { union nf_inet_addr ip; u16 padding0; @@ -262,6 +307,34 @@ struct hash_net6ct_elem { unsigned long timeout; }; +struct hash_net6tm_elem { + union nf_inet_addr ip; + u16 padding0; + u8 nomatch; + u8 cidr; + unsigned long timeout; + struct ip_set_comment comment; +}; + +struct hash_net6cm_elem { + union nf_inet_addr ip; + u16 padding0; + u8 nomatch; + u8 cidr; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_net6ctm_elem { + union nf_inet_addr ip; + u16 padding0; + u8 nomatch; + u8 cidr; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netiface.c b/kernel/net/netfilter/ipset/ip_set_hash_netiface.c index 846371b..390490d 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_netiface.c @@ -26,7 +26,8 @@ #define IPSET_TYPE_REV_MIN 0 /* 1 nomatch flag support added */ /* 2 /0 support added */ -#define IPSET_TYPE_REV_MAX 3 /* Counters support added */ +/* 3 Counters support added */ +#define IPSET_TYPE_REV_MAX 4 /* Comments support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -174,6 +175,16 @@ struct hash_netiface4c_elem { struct ip_set_counter counter; }; +struct hash_netiface4m_elem { + __be32 ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_comment comment; +}; + struct hash_netiface4ct_elem { __be32 ip; u8 physdev; @@ -185,6 +196,40 @@ struct hash_netiface4ct_elem { unsigned long timeout; }; +struct hash_netiface4tm_elem { + __be32 ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_netiface4cm_elem { + __be32 ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_netiface4ctm_elem { + __be32 ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool @@ -438,6 +483,16 @@ struct hash_netiface6c_elem { struct ip_set_counter counter; }; +struct hash_netiface6m_elem { + union nf_inet_addr ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_comment comment; +}; + struct hash_netiface6ct_elem { union nf_inet_addr ip; u8 physdev; @@ -449,6 +504,40 @@ struct hash_netiface6ct_elem { unsigned long timeout; }; +struct hash_netiface6tm_elem { + union nf_inet_addr ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_netiface6cm_elem { + union nf_inet_addr ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_netiface6ctm_elem { + union nf_inet_addr ip; + u8 physdev; + u8 cidr; + u8 nomatch; + u8 elem; + const char *iface; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netnet.c b/kernel/net/netfilter/ipset/ip_set_hash_netnet.c index de8e634..dc96604 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_netnet.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_netnet.c @@ -68,6 +68,38 @@ struct hash_netnet4c_elem { struct ip_set_counter counter; }; +struct hash_netnet4m_elem { + __be32 ip; + __be32 ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + struct ip_set_comment comment; +}; + +struct hash_netnet4cm_elem { + __be32 ip; + __be32 ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + struct ip_set_comment comment; + struct ip_set_counter counter; +}; + +struct hash_netnet4tm_elem { + __be32 ip; + __be32 ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + struct ip_set_comment comment; + unsigned long timeout; +}; + struct hash_netnet4ct_elem { __be32 ip; __be32 ip2; @@ -79,6 +111,18 @@ struct hash_netnet4ct_elem { unsigned long timeout; }; +struct hash_netnet4ctm_elem { + __be32 ip; + __be32 ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + struct ip_set_comment comment; + struct ip_set_counter counter; + unsigned long timeout; +}; + /* Common functions */ static inline bool @@ -316,6 +360,38 @@ struct hash_netnet6c_elem { struct ip_set_counter counter; }; +struct hash_netnet6m_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + struct ip_set_comment comment; +}; + +struct hash_netnet6tm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + unsigned long timeout; + struct ip_set_comment comment; +}; + +struct hash_netnet6cm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + struct hash_netnet6ct_elem { union nf_inet_addr ip; union nf_inet_addr ip2; @@ -327,6 +403,18 @@ struct hash_netnet6ct_elem { unsigned long timeout; }; +struct hash_netnet6ctm_elem { + union nf_inet_addr ip; + union nf_inet_addr ip2; + u8 padding0; + u8 nomatch; + u8 cidr; + u8 cidr2; + struct ip_set_comment comment; + struct ip_set_counter counter; + unsigned long timeout; +}; + /* Common functions */ static inline bool diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netport.c b/kernel/net/netfilter/ipset/ip_set_hash_netport.c index d98a685..1ba5bc5 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_netport.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_netport.c @@ -27,7 +27,8 @@ /* 1 SCTP and UDPLITE support added */ /* 2 Range as input support for IPv4 added */ /* 3 nomatch flag support added */ -#define IPSET_TYPE_REV_MAX 4 /* Counters support added */ +/* 4 Counters support added */ +#define IPSET_TYPE_REV_MAX 5 /* Comments support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -74,6 +75,15 @@ struct hash_netport4c_elem { struct ip_set_counter counter; }; +struct hash_netport4m_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_comment comment; +}; + struct hash_netport4ct_elem { __be32 ip; __be16 port; @@ -84,6 +94,37 @@ struct hash_netport4ct_elem { unsigned long timeout; }; +struct hash_netport4tm_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_netport4cm_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_netport4ctm_elem { + __be32 ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool @@ -315,6 +356,15 @@ struct hash_netport6c_elem { struct ip_set_counter counter; }; +struct hash_netport6m_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_comment comment; +}; + struct hash_netport6ct_elem { union nf_inet_addr ip; __be16 port; @@ -325,6 +375,37 @@ struct hash_netport6ct_elem { unsigned long timeout; }; +struct hash_netport6tm_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_comment comment; + unsigned long timeout; +}; + +struct hash_netport6cm_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +struct hash_netport6ctm_elem { + union nf_inet_addr ip; + __be16 port; + u8 proto; + u8 cidr:7; + u8 nomatch:1; + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Common functions */ static inline bool -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/6] netfilter: ipset: Support comments in bitmap-type ipsets. 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver 2013-09-02 6:35 ` [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core Oliver 2013-09-02 6:35 ` [PATCH 2/6] netfilter: ipset: Support comments in hash-type ipsets Oliver @ 2013-09-02 6:35 ` Oliver 2013-09-02 6:35 ` [PATCH 4/6] ipset: Rework the "fake" argument parsing for ipset restore Oliver ` (4 subsequent siblings) 7 siblings, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 6:35 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> This provides kernel support for creating bitmap ipsets with comment support. As is the case for hashes, this incurs a penalty when flushing or destroying the entire ipset as the entries must first be walked in order to free the comment strings. This penalty is of course far less than the cost of listing an ipset to userspace. Any set created without support for comments will be flushed/destroyed as before. Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> --- kernel/net/netfilter/ipset/ip_set_bitmap_gen.h | 77 +++++++++++++++++++----- kernel/net/netfilter/ipset/ip_set_bitmap_ip.c | 31 +++++++++- kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c | 47 ++++++++++++++- kernel/net/netfilter/ipset/ip_set_bitmap_port.c | 30 ++++++++- 4 files changed, 167 insertions(+), 18 deletions(-) diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h b/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h index 097da65..42c84fb 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h @@ -37,6 +37,8 @@ (unsigned long *)((e) + (m)->offset[IPSET_OFFSET_TIMEOUT]) #define ext_counter(e, m) \ (struct ip_set_counter *)((e) + (m)->offset[IPSET_OFFSET_COUNTER]) +#define ext_comment(e, m) \ + (struct ip_set_comment *)((e) + (m)->offset[IPSET_OFFSET_COMMENT]) #define get_ext(map, id) ((map)->extensions + (map)->dsize * (id)) static void @@ -52,6 +54,25 @@ mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set)) } static void +mtype_flush(struct ip_set *set) +{ + struct mtype *map = set->data; + int id = 0; + void *x; + + if (SET_WITH_COMMENT(set)) { + for (; id < map->elements; id++) { + if (test_bit(id, map->members)) { + x = get_ext(map, id); + ip_set_comment_free(ext_comment(x, map)); + } + } + } + + memset(map->members, 0, map->memsize); +} + +static void mtype_destroy(struct ip_set *set) { struct mtype *map = set->data; @@ -59,6 +80,9 @@ mtype_destroy(struct ip_set *set) if (SET_WITH_TIMEOUT(set)) del_timer_sync(&map->gc); + if (SET_WITH_COMMENT(set)) + mtype_flush(set); + ip_set_free(map->members); if (map->dsize) ip_set_free(map->extensions); @@ -67,14 +91,6 @@ mtype_destroy(struct ip_set *set) set->data = NULL; } -static void -mtype_flush(struct ip_set *set) -{ - struct mtype *map = set->data; - - memset(map->members, 0, map->memsize); -} - static int mtype_head(struct ip_set *set, struct sk_buff *skb) { @@ -94,7 +110,10 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) || (SET_WITH_COUNTER(set) && nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, - htonl(IPSET_FLAG_WITH_COUNTERS)))) + htonl(IPSET_FLAG_WITH_COUNTERS))) || + (SET_WITH_COMMENT(set) && + nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, + htonl(IPSET_FLAG_WITH_COMMENTS)))) goto nla_put_failure; ipset_nest_end(skb, nested); @@ -148,6 +167,8 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, if (SET_WITH_COUNTER(set)) ip_set_init_counter(ext_counter(x, map), ext); + if (SET_WITH_COMMENT(set)) + ip_set_init_comment(ext_comment(x, map), ext); return 0; } @@ -164,6 +185,8 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, ip_set_timeout_expired(ext_timeout(x, map)))) return -IPSET_ERR_EXIST; + if (SET_WITH_COMMENT(set)) + ip_set_comment_free(ext_comment(x, map)); return 0; } @@ -215,6 +238,9 @@ mtype_list(const struct ip_set *set, if (SET_WITH_COUNTER(set) && ip_set_put_counter(skb, ext_counter(x, map))) goto nla_put_failure; + if (SET_WITH_COMMENT(set) && + ip_set_put_comment(skb, ext_comment(x, map))) + goto nla_put_failure; ipset_nest_end(skb, nested); } ipset_nest_end(skb, adt); @@ -257,16 +283,17 @@ mtype_gc(unsigned long ul_set) add_timer(&map->gc); } -#define generate_offsets(X,C,T) \ +#define generate_offsets(X,C,T,M) \ map->dsize = sizeof(struct IPSET_TOKEN(mtype, X)); \ c_off = offsetof(struct IPSET_TOKEN(mtype, C), counter); \ - t_off = offsetof(struct IPSET_TOKEN(mtype, T), timeout); + t_off = offsetof(struct IPSET_TOKEN(mtype, T), timeout); \ + m_off = offsetof(struct IPSET_TOKEN(mtype, M), comment); static inline int mtype_do_create(struct mtype *map, struct nlattr *tb[], struct ip_set *set, create_args) { unsigned int cadt_flags = 0, i = IPSET_FLAG_EXT_BEGIN; - int c_off = 0, t_off = 0; + int c_off = 0, t_off = 0, m_off = 0; if(tb[IPSET_ATTR_CADT_FLAGS]) cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]) & ~IPSET_FLAG_EXT_BEGIN; @@ -279,14 +306,30 @@ mtype_do_create(struct mtype *map, struct nlattr *tb[], struct ip_set *set, crea } else { switch (cadt_flags) { case (IPSET_FLAG_WITH_COUNTERS | + IPSET_FLAG_WITH_COMMENTS | IPSET_FLAG_WITH_TIMEOUTS) : - generate_offsets(ct_elem, ct_elem, ct_elem); + generate_offsets(ctm_elem, ctm_elem, ctm_elem, ctm_elem); + break; + case (IPSET_FLAG_WITH_COUNTERS | + IPSET_FLAG_WITH_TIMEOUTS) : + generate_offsets(ct_elem, ct_elem, ct_elem, m_elem); + break; + case (IPSET_FLAG_WITH_TIMEOUTS | + IPSET_FLAG_WITH_COMMENTS) : + generate_offsets(tm_elem, c_elem, tm_elem, tm_elem); + break; + case (IPSET_FLAG_WITH_COUNTERS | + IPSET_FLAG_WITH_COMMENTS) : + generate_offsets(cm_elem, cm_elem, t_elem, cm_elem); break; case IPSET_FLAG_WITH_TIMEOUTS : - generate_offsets(t_elem, c_elem, t_elem); + generate_offsets(t_elem, c_elem, t_elem, m_elem); break; case IPSET_FLAG_WITH_COUNTERS : - generate_offsets(c_elem, c_elem, t_elem); + generate_offsets(c_elem, c_elem, t_elem, m_elem); + break; + case IPSET_FLAG_WITH_COMMENTS : + generate_offsets(m_elem, c_elem, t_elem, m_elem); break; } for(; i < (1 << IPSET_FLAG_CADT_MAX) ; i = (i << 1)) { @@ -295,6 +338,10 @@ mtype_do_create(struct mtype *map, struct nlattr *tb[], struct ip_set *set, crea map->offset[IPSET_OFFSET_COUNTER] = c_off; set->extensions |= IPSET_EXT_COUNTER; break; + case IPSET_FLAG_WITH_COMMENTS: + map->offset[IPSET_OFFSET_COMMENT] = m_off; + set->extensions |= IPSET_EXT_COMMENT; + break; case IPSET_FLAG_WITH_TIMEOUTS: map->offset[IPSET_OFFSET_TIMEOUT] = t_off; set->extensions |= IPSET_EXT_TIMEOUT; diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c b/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c index 8736e75..33fbeb6 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c @@ -26,7 +26,8 @@ #include <linux/netfilter/ipset/ip_set_bitmap.h> #define IPSET_TYPE_REV_MIN 0 -#define IPSET_TYPE_REV_MAX 1 /* Counter support added */ +/* 1 Counter support added */ +#define IPSET_TYPE_REV_MAX 2 /* Comment support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -221,6 +222,12 @@ struct bitmap_ipc_elem { struct ip_set_counter counter; }; +/* Comment variant */ + +struct bitmap_ipm_elem { + struct ip_set_comment comment; +}; + /* Timeout variant with counter */ struct bitmap_ipct_elem { @@ -228,6 +235,28 @@ struct bitmap_ipct_elem { struct ip_set_counter counter; }; +/* Timeout variant with comment */ + +struct bitmap_iptm_elem { + unsigned long timeout; + struct ip_set_comment comment; +}; + +/* Counter variant with comment */ + +struct bitmap_ipcm_elem { + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +/* Timeout + Counter + Comment */ + +struct bitmap_ipctm_elem { + struct ip_set_counter counter; + struct ip_set_comment comment; + unsigned long timeout; +}; + /* Create bitmap:ip type of sets */ static bool diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c index ba2cd3e..235d314 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c @@ -26,7 +26,8 @@ #include <linux/netfilter/ipset/ip_set_bitmap.h> #define IPSET_TYPE_REV_MIN 0 -#define IPSET_TYPE_REV_MAX 1 /* Counter support added */ +/* 1 Counter support added */ +#define IPSET_TYPE_REV_MAX 2 /* Comment support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -311,6 +312,16 @@ struct bitmap_ipmacc_elem { struct ip_set_counter counter; }; +/* Plain variant with comment */ + +struct bitmap_ipmacm_elem { + struct { + unsigned char ether[ETH_ALEN]; + unsigned char filled; + } __attribute__ ((aligned)); + struct ip_set_comment comment; +}; + /* Timeout variant with counter */ struct bitmap_ipmacct_elem { @@ -322,6 +333,40 @@ struct bitmap_ipmacct_elem { struct ip_set_counter counter; }; +/* Timeout variant with comment */ + +struct bitmap_ipmactm_elem { + struct { + unsigned char ether[ETH_ALEN]; + unsigned char filled; + } __attribute__ ((aligned)); + unsigned long timeout; + struct ip_set_comment comment; +}; + +/* Counter variant with comment */ + +struct bitmap_ipmaccm_elem { + struct { + unsigned char ether[ETH_ALEN]; + unsigned char filled; + } __attribute__ ((aligned)); + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +/* Timeout + Counter + Comment */ + +struct bitmap_ipmacctm_elem { + struct { + unsigned char ether[ETH_ALEN]; + unsigned char filled; + } __attribute__ ((aligned)); + unsigned long timeout; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + /* Create bitmap:ip,mac type of sets */ static bool diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_port.c b/kernel/net/netfilter/ipset/ip_set_bitmap_port.c index 70a9c09..76e98b5 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_port.c +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_port.c @@ -21,7 +21,8 @@ #include <linux/netfilter/ipset/ip_set_getport.h> #define IPSET_TYPE_REV_MIN 0 -#define IPSET_TYPE_REV_MAX 1 /* Counter support added */ +/* 1 Counter support added */ +#define IPSET_TYPE_REV_MAX 2 /* Comment support added */ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); @@ -212,6 +213,12 @@ struct bitmap_portc_elem { struct ip_set_counter counter; }; +/* Plain variant with comment */ + +struct bitmap_portm_elem { + struct ip_set_comment comment; +}; + /* Timeout variant with counter */ struct bitmap_portct_elem { @@ -219,6 +226,27 @@ struct bitmap_portct_elem { struct ip_set_counter counter; }; +/* Timeout variant with comment */ + +struct bitmap_porttm_elem { + unsigned long timeout; + struct ip_set_comment comment; +}; + +/* Counter variant with comment */ + +struct bitmap_portcm_elem { + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + +/* Timeout + Counter + Comment */ +struct bitmap_portctm_elem { + unsigned long timeout; + struct ip_set_counter counter; + struct ip_set_comment comment; +}; + /* Create bitmap:ip type of sets */ static bool -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/6] ipset: Rework the "fake" argument parsing for ipset restore. 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver ` (2 preceding siblings ...) 2013-09-02 6:35 ` [PATCH 3/6] netfilter: ipset: Support comments in bitmap-type ipsets Oliver @ 2013-09-02 6:35 ` Oliver 2013-09-02 6:35 ` [PATCH 5/6] ipset: Support comments in the userspace library Oliver ` (3 subsequent siblings) 7 siblings, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 6:35 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> This reworks the argument parsing functionality of ipset to handle quote-delimited lines in such a way that they are considered to be a single argument. This commit is necessary for ipset to successfully restore sets that have comments. Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> --- src/ipset.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/ipset.c b/src/ipset.c index 4f308da..cff1e55 100644 --- a/src/ipset.c +++ b/src/ipset.c @@ -159,20 +159,36 @@ ipset_print_file(const char *fmt, ...) static void build_argv(char *buffer) { - char *ptr; + char *ptr, *tmp; int i; /* Reset */ - for (i = 1; i < newargc; i++) + for (i = 1; i < newargc; i++) { + if(newargv[i]) + free(newargv[i]); newargv[i] = NULL; + } newargc = 1; ptr = strtok(buffer, " \t\r\n"); - newargv[newargc++] = ptr; + newargv[newargc] = calloc(strlen(ptr) + 1, sizeof(*ptr)); + ipset_strlcpy(newargv[newargc++], ptr, strlen(ptr) + 1); while ((ptr = strtok(NULL, " \t\r\n")) != NULL) { - if ((newargc + 1) < (int)(sizeof(newargv)/sizeof(char *))) - newargv[newargc++] = ptr; - else { + if ((newargc + 1) < (int)(sizeof(newargv)/sizeof(char *))) { + tmp = newargv[newargc] = calloc(strlen(ptr) + 1, sizeof(*ptr)); + if(*ptr == '"') { + ipset_strlcpy(tmp, ptr + 1, (strlen(ptr) + 1) * sizeof(*ptr)); + ipset_strlcat(tmp, " ", (strlen(ptr) + 1) * sizeof(*ptr)); + while((ptr = strtok(NULL, "\"")) != NULL) { + if(*ptr == '\n' || *ptr == '\r') + continue; + tmp = realloc(tmp, (strlen(tmp) + strlen(ptr) + 1) * sizeof(*ptr)); + ipset_strlcat(tmp, ptr, (strlen(tmp) + strlen(ptr) + 1) * sizeof(*ptr)); + } + } else + ipset_strlcpy(tmp, ptr, (strlen(ptr) + 1) * sizeof(*ptr)); + newargv[newargc++] = tmp; + } else { exit_error(PARAMETER_PROBLEM, "Line is too long to parse."); return; @@ -195,7 +211,8 @@ restore(char *argv0) /* Initialize newargv/newargc */ newargc = 0; - newargv[newargc++] = argv0; + newargv[newargc] = calloc(strlen(argv0) + 1, sizeof(*argv0)); + ipset_strlcpy(newargv[newargc++], argv0, strlen(argv0) + 1); if (filename) { fd = fopen(filename, "r"); if (!fd) { @@ -232,6 +249,7 @@ restore(char *argv0) if (ret < 0) handle_error(); + free(newargv[0]); return ret; } -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/6] ipset: Support comments in the userspace library. 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver ` (3 preceding siblings ...) 2013-09-02 6:35 ` [PATCH 4/6] ipset: Rework the "fake" argument parsing for ipset restore Oliver @ 2013-09-02 6:35 ` Oliver 2013-09-02 6:35 ` [PATCH 6/6] ipset: Add new userspace set revisions for comment support Oliver ` (2 subsequent siblings) 7 siblings, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 6:35 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> This adds support to the userspace portion of ipset for handling ipsets with the comment extension enabled. The library revision has been raised accordingly. Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> --- Make_global.am | 2 +- include/libipset/data.h | 6 +++++- include/libipset/linux_ip_set.h | 9 +++++++++ include/libipset/parse.h | 2 ++ include/libipset/print.h | 3 +++ lib/data.c | 34 ++++++++++++++++++++++++++++++++++ lib/debug.c | 1 + lib/errcode.c | 2 ++ lib/libipset.map | 6 ++++++ lib/parse.c | 27 +++++++++++++++++++++++++++ lib/print.c | 31 +++++++++++++++++++++++++++++++ lib/session.c | 8 +++++++- lib/types.c | 4 ++-- 13 files changed, 130 insertions(+), 5 deletions(-) diff --git a/Make_global.am b/Make_global.am index 29b5678..9c228cc 100644 --- a/Make_global.am +++ b/Make_global.am @@ -69,7 +69,7 @@ # interface. # curr:rev:age -LIBVERSION = 4:0:1 +LIBVERSION = 4:1:2 AM_CPPFLAGS = $(kinclude_CFLAGS) $(all_includes) -I$(top_srcdir)/include \ -I/usr/local/include diff --git a/include/libipset/data.h b/include/libipset/data.h index 2b6b8cd..ae0d099 100644 --- a/include/libipset/data.h +++ b/include/libipset/data.h @@ -57,6 +57,8 @@ enum ipset_opt { IPSET_OPT_COUNTERS, IPSET_OPT_PACKETS, IPSET_OPT_BYTES, + IPSET_OPT_COMMENTS, + IPSET_OPT_COMMENT, /* Internal options */ IPSET_OPT_FLAGS = 48, /* IPSET_FLAG_EXIST| */ IPSET_OPT_CADT_FLAGS, /* IPSET_FLAG_BEFORE| */ @@ -106,11 +108,13 @@ enum ipset_opt { | IPSET_FLAG(IPSET_OPT_CADT_FLAGS)\ | IPSET_FLAG(IPSET_OPT_BEFORE) \ | IPSET_FLAG(IPSET_OPT_PHYSDEV) \ - | IPSET_FLAG(IPSET_OPT_NOMATCH)) + | IPSET_FLAG(IPSET_OPT_NOMATCH) \ + | IPSET_FLAG(IPSET_OPT_COMMENT)) struct ipset_data; extern void ipset_strlcpy(char *dst, const char *src, size_t len); +extern void ipset_strlcat(char *dst, const char *src, size_t len); extern bool ipset_data_flags_test(const struct ipset_data *data, uint64_t flags); extern void ipset_data_flags_set(struct ipset_data *data, uint64_t flags); diff --git a/include/libipset/linux_ip_set.h b/include/libipset/linux_ip_set.h index 8024cdf..8163d6d 100644 --- a/include/libipset/linux_ip_set.h +++ b/include/libipset/linux_ip_set.h @@ -19,6 +19,9 @@ /* The max length of strings including NUL: set and type identifiers */ #define IPSET_MAXNAMELEN 32 +/* The maximum permissible length we will accept over netlink (inc. comments) */ +#define IPSET_MAXSTRLEN 255 + /* Message types and commands */ enum ipset_cmd { IPSET_CMD_NONE, @@ -110,6 +113,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 +144,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, @@ -174,8 +179,12 @@ enum ipset_cadt_flags { IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV), IPSET_FLAG_BIT_NOMATCH = 2, IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH), + IPSET_FLAG_EXT_BEGIN = 2, + 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, }; diff --git a/include/libipset/parse.h b/include/libipset/parse.h index 014c62f..5c46a88 100644 --- a/include/libipset/parse.h +++ b/include/libipset/parse.h @@ -90,6 +90,8 @@ extern int ipset_parse_typename(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_iface(struct ipset_session *session, enum ipset_opt opt, const char *str); +extern int ipset_parse_comment(struct ipset_session *session, + enum ipset_opt opt, const char *str); extern int ipset_parse_output(struct ipset_session *session, int opt, const char *str); extern int ipset_parse_ignored(struct ipset_session *session, diff --git a/include/libipset/print.h b/include/libipset/print.h index 1d537bd..f2a6095 100644 --- a/include/libipset/print.h +++ b/include/libipset/print.h @@ -40,6 +40,9 @@ extern int ipset_print_port(char *buf, unsigned int len, extern int ipset_print_iface(char *buf, unsigned int len, const struct ipset_data *data, enum ipset_opt opt, uint8_t env); +extern int ipset_print_comment(char *buf, unsigned int len, + const struct ipset_data *data, + enum ipset_opt opt, uint8_t env); extern int ipset_print_proto(char *buf, unsigned int len, const struct ipset_data *data, enum ipset_opt opt, uint8_t env); diff --git a/lib/data.c b/lib/data.c index 04a5997..9aaa550 100644 --- a/lib/data.c +++ b/lib/data.c @@ -75,6 +75,7 @@ struct ipset_data { char iface[IFNAMSIZ]; uint64_t packets; uint64_t bytes; + char comment[IPSET_MAXSTRLEN]; } adt; }; }; @@ -108,6 +109,25 @@ ipset_strlcpy(char *dst, const char *src, size_t len) } /** + * ipset_strlcat - concatenate the string from src to the end of dst + * @dst: the target string buffer + * @src: the source string buffer + * @len: the length of bytes to concat, including the terminating null byte. + * + * Cooncatenate the string in src to destination, but at most len bytes are + * copied. The target is unconditionally terminated by the null byte. + */ +void +ipset_strlcat(char *dst, const char *src, size_t len) +{ + assert(dst); + assert(src); + + strncat(dst, src, len); + dst[len - 1] = '\0'; +} + +/** * ipset_data_flags_test - test option bits in the data blob * @data: data blob * @flags: the option flags to test @@ -278,6 +298,9 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value) case IPSET_OPT_COUNTERS: cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_COUNTERS); break; + case IPSET_OPT_COMMENTS: + cadt_flag_type_attr(data, opt, IPSET_FLAG_WITH_COMMENTS); + break; /* Create-specific options, filled out by the kernel */ case IPSET_OPT_ELEMENTS: data->create.elements = *(const uint32_t *) value; @@ -336,6 +359,9 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value) case IPSET_OPT_BYTES: data->adt.bytes = *(const uint64_t *) value; break; + case IPSET_OPT_COMMENT: + ipset_strlcpy(data->adt.comment, value, IPSET_MAXSTRLEN); + break; /* Swap/rename */ case IPSET_OPT_SETNAME2: ipset_strlcpy(data->setname2, value, IPSET_MAXNAMELEN); @@ -370,6 +396,9 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value) if (data->cadt_flags & IPSET_FLAG_WITH_COUNTERS) ipset_data_flags_set(data, IPSET_FLAG(IPSET_OPT_COUNTERS)); + if (data->cadt_flags & IPSET_FLAG_WITH_COMMENTS) + ipset_data_flags_set(data, + IPSET_FLAG(IPSET_OPT_COMMENTS)); break; default: return -1; @@ -472,6 +501,8 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt) return &data->adt.packets; case IPSET_OPT_BYTES: return &data->adt.bytes; + case IPSET_OPT_COMMENT: + return &data->adt.comment; /* Swap/rename */ case IPSET_OPT_SETNAME2: return data->setname2; @@ -484,6 +515,7 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt) case IPSET_OPT_PHYSDEV: case IPSET_OPT_NOMATCH: case IPSET_OPT_COUNTERS: + case IPSET_OPT_COMMENTS: return &data->cadt_flags; default: return NULL; @@ -543,6 +575,8 @@ ipset_data_sizeof(enum ipset_opt opt, uint8_t family) case IPSET_OPT_NOMATCH: case IPSET_OPT_COUNTERS: return sizeof(uint32_t); + case IPSET_OPT_COMMENT: + return IPSET_MAXSTRLEN; default: return 0; }; diff --git a/lib/debug.c b/lib/debug.c index 3aa5a99..a204940 100644 --- a/lib/debug.c +++ b/lib/debug.c @@ -64,6 +64,7 @@ static const struct ipset_attrname adtattr2name[] = { [IPSET_ATTR_CIDR2] = { .name = "CIDR2" }, [IPSET_ATTR_IP2_TO] = { .name = "IP2_TO" }, [IPSET_ATTR_IFACE] = { .name = "IFACE" }, + [IPSET_ATTR_COMMENT] = { .name = "COMMENT" }, }; static void diff --git a/lib/errcode.c b/lib/errcode.c index c939949..c824cc3 100644 --- a/lib/errcode.c +++ b/lib/errcode.c @@ -72,6 +72,8 @@ static const struct ipset_errcode_table core_errcode_table[] = { "An IPv6 address is expected, but not received" }, { IPSET_ERR_COUNTER, 0, "Packet/byte counters cannot be used: set was created without counter support" }, + { IPSET_ERR_COMMENT, 0, + "Comment too long!" }, /* ADD specific error codes */ { IPSET_ERR_EXIST, IPSET_CMD_ADD, diff --git a/lib/libipset.map b/lib/libipset.map index 271fe59..06216e7 100644 --- a/lib/libipset.map +++ b/lib/libipset.map @@ -127,3 +127,9 @@ LIBIPSET_4.0 { global: ipset_parse_uint64; } LIBIPSET_3.0; + +LIBIPSET_4.1 { +global: + ipset_parse_comment; + ipset_strlcat; +} LIBIPSET_4.0; diff --git a/lib/parse.c b/lib/parse.c index 112b273..bde56b3 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -1739,6 +1739,33 @@ ipset_parse_iface(struct ipset_session *session, } /** + * ipset_parse_comment - parse string as a comment + * @session: session structure + * @opt: option kind of the data + * @str: string to parse + * + * Parse string for use as a comment on an ipset entry. + * Gets stored in the data blob as usual. + * + * Returns 0 on success or a negative error code. + */ +int ipset_parse_comment(struct ipset_session *session, + enum ipset_opt opt, const char *str) +{ + struct ipset_data *data; + + assert(session); + assert(opt == IPSET_OPT_COMMENT); + assert(str); + + data = ipset_session_data(session); + if (strlen(str) > IPSET_MAXSTRLEN) + return syntax_err("comment is longer than the maximum permitted"); + + return ipset_data_set(data, opt, str); +} + +/** * ipset_parse_output - parse output format name * @session: session structure * @opt: option kind of the data diff --git a/lib/print.c b/lib/print.c index 86a7674..9ccc3c8 100644 --- a/lib/print.c +++ b/lib/print.c @@ -530,6 +530,37 @@ ipset_print_iface(char *buf, unsigned int len, } /** + * ipset_print_comment - print arbitrary parameter string + * @buf: printing buffer + * @len: length of available buffer space + * @data: data blob + * @opt: the option kind + * @env: environment flags + * + * Print arbitrary string to output buffer. + * + * Return length of printed string or error size. + */ +int ipset_print_comment(char *buf, unsigned int len, + const struct ipset_data *data, enum ipset_opt opt, + uint8_t env UNUSED) +{ + const char *comment; + int size, offset = 0; + + assert(buf); + assert(len > 0); + assert(data); + assert(opt == IPSET_OPT_COMMENT); + + comment = ipset_data_get(data, opt); + assert(comment); + size = snprintf(buf + offset, len, "\"%s\"", comment); + SNPRINTF_FAILURE(size, len, offset); + return offset; +} + +/** * ipset_print_proto - print protocol name * @buf: printing buffer * @len: length of available buffer space diff --git a/lib/session.c b/lib/session.c index f1df515..94aa9a7 100644 --- a/lib/session.c +++ b/lib/session.c @@ -488,6 +488,11 @@ static const struct ipset_attr_policy adt_attrs[] = { .type = MNL_TYPE_U64, .opt = IPSET_OPT_BYTES, }, + [IPSET_ATTR_COMMENT] = { + .type = MNL_TYPE_NUL_STRING, + .opt = IPSET_OPT_COMMENT, + .len = IPSET_MAXSTRLEN, + }, }; static const struct ipset_attr_policy ipaddr_attrs[] = { @@ -522,8 +527,9 @@ generic_data_attr_cb(const struct nlattr *attr, void *data, return MNL_CB_ERROR; } if (policy[type].type == MNL_TYPE_NUL_STRING && - mnl_attr_get_payload_len(attr) > IPSET_MAXNAMELEN) + mnl_attr_get_payload_len(attr) > IPSET_MAXSTRLEN) { return MNL_CB_ERROR; + } tb[type] = attr; return MNL_CB_OK; } diff --git a/lib/types.c b/lib/types.c index adaba83..b95114f 100644 --- a/lib/types.c +++ b/lib/types.c @@ -607,7 +607,7 @@ ipset_load_types(void) len = snprintf(path, sizeof(path), "%.*s", (unsigned int)(next - dir), dir); - if (len >= sizeof(path) || len < 0) + if (len >= (int)sizeof(path) || len < (int)0) continue; n = scandir(path, &list, NULL, alphasort); @@ -620,7 +620,7 @@ ipset_load_types(void) len = snprintf(file, sizeof(file), "%s/%s", path, list[n]->d_name); - if (len >= sizeof(file) || len < 0) + if (len >= (int)sizeof(file) || len < (int)0) goto nextf; if (dlopen(file, RTLD_NOW) == NULL) -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/6] ipset: Add new userspace set revisions for comment support 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver ` (4 preceding siblings ...) 2013-09-02 6:35 ` [PATCH 5/6] ipset: Support comments in the userspace library Oliver @ 2013-09-02 6:35 ` Oliver 2013-09-02 8:21 ` [PATCH 1/6 v2] netfilter: ipset: Support comments for ipset entries in the core Oliver 2013-09-02 20:08 ` [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Jozsef Kadlecsik 7 siblings, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 6:35 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> This introduces new revisions of all hash and bitmap ipsets to complement the comment functionality introduced into the kernel modules. Currently all sets have a compile-time limit of 255 characters including \0. This can otherwise be arbitrarily modified. Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> --- lib/ipset_bitmap_ip.c | 114 ++++++++++++++++++++++++++ lib/ipset_bitmap_ipmac.c | 118 +++++++++++++++++++++++++++ lib/ipset_bitmap_port.c | 107 +++++++++++++++++++++++++ lib/ipset_hash_ip.c | 138 ++++++++++++++++++++++++++++++++ lib/ipset_hash_ipport.c | 161 +++++++++++++++++++++++++++++++++++++ lib/ipset_hash_ipportnet.c | 195 +++++++++++++++++++++++++++++++++++++++++++++ lib/ipset_hash_net.c | 145 +++++++++++++++++++++++++++++++++ lib/ipset_hash_netnet.c | 14 +++- lib/ipset_hash_netport.c | 158 ++++++++++++++++++++++++++++++++++++ 9 files changed, 1148 insertions(+), 2 deletions(-) diff --git a/lib/ipset_bitmap_ip.c b/lib/ipset_bitmap_ip.c index a4726db..3b58661 100644 --- a/lib/ipset_bitmap_ip.c +++ b/lib/ipset_bitmap_ip.c @@ -201,9 +201,123 @@ static struct ipset_type ipset_bitmap_ip1 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg bitmap_ip_create_args2[] = { + { .name = { "range", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_netrange, .print = ipset_print_ip, + }, + { .name = { "netmask", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NETMASK, + .parse = ipset_parse_netmask, .print = ipset_print_number, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + /* Backward compatibility */ + { .name = { "from", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_single_ip, + }, + { .name = { "to", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, + .parse = ipset_parse_single_ip, + }, + { .name = { "network", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_net, + }, + { }, +}; + +static const struct ipset_arg bitmap_ip_add_args2[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const char bitmap_ip_usage2[] = +"create SETNAME bitmap:ip range IP/CIDR|FROM-TO\n" +" [netmask CIDR] [timeout VALUE] [counters] [comments]\n" +"add SETNAME IP|IP/CIDR|FROM-TO [timeout VALUE]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME IP|IP/CIDR|FROM-TO\n" +"test SETNAME IP\n\n" +"where IP, FROM and TO are IPv4 addresses (or hostnames),\n" +" CIDR is a valid IPv4 CIDR prefix.\n"; + +static struct ipset_type ipset_bitmap_ip2 = { + .name = "bitmap:ip", + .alias = { "ipmap", NULL }, + .revision = 2, + .family = NFPROTO_IPV4, + .dimension = IPSET_DIM_ONE, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_ip, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP + }, + }, + .args = { + [IPSET_CREATE] = bitmap_ip_create_args2, + [IPSET_ADD] = bitmap_ip_add_args2, + }, + .mandatory = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_NETMASK) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), + }, + + .usage = bitmap_ip_usage2, + .description = "comments support", +}; void _init(void); void _init(void) { ipset_type_add(&ipset_bitmap_ip0); ipset_type_add(&ipset_bitmap_ip1); + ipset_type_add(&ipset_bitmap_ip2); } diff --git a/lib/ipset_bitmap_ipmac.c b/lib/ipset_bitmap_ipmac.c index 67217a9..34f9b24 100644 --- a/lib/ipset_bitmap_ipmac.c +++ b/lib/ipset_bitmap_ipmac.c @@ -207,9 +207,127 @@ static struct ipset_type ipset_bitmap_ipmac1 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg bitmap_ipmac_create_args2[] = { + { .name = { "range", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_netrange, .print = ipset_print_ip, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + /* Backward compatibility */ + { .name = { "from", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_single_ip, + }, + { .name = { "to", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, + .parse = ipset_parse_single_ip, + }, + { .name = { "network", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_net, + }, + { }, +}; + +static const struct ipset_arg bitmap_ipmac_add_args2[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const char bitmap_ipmac_usage2[] = +"create SETNAME bitmap:ip,mac range IP/CIDR|FROM-TO\n" +" [matchunset] [timeout VALUE] [counters] [comments]\n" +"add SETNAME IP[,MAC] [timeout VALUE]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME IP[,MAC]\n" +"test SETNAME IP[,MAC]\n\n" +"where IP, FROM and TO are IPv4 addresses (or hostnames),\n" +" CIDR is a valid IPv4 CIDR prefix,\n" +" MAC is a valid MAC address.\n"; + +static struct ipset_type ipset_bitmap_ipmac2 = { + .name = "bitmap:ip,mac", + .alias = { "macipmap", NULL }, + .revision = 2, + .family = NFPROTO_IPV4, + .dimension = IPSET_DIM_TWO, + .last_elem_optional = true, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_single_ip, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP + }, + [IPSET_DIM_TWO - 1] = { + .parse = ipset_parse_ether, + .print = ipset_print_ether, + .opt = IPSET_OPT_ETHER + }, + }, + .args = { + [IPSET_CREATE] = bitmap_ipmac_create_args2, + [IPSET_ADD] = bitmap_ipmac_add_args2, + }, + .mandatory = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_ETHER) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_ETHER), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_ETHER), + }, + + .usage = bitmap_ipmac_usage2, + .description = "comments support", +}; + void _init(void); void _init(void) { ipset_type_add(&ipset_bitmap_ipmac0); ipset_type_add(&ipset_bitmap_ipmac1); + ipset_type_add(&ipset_bitmap_ipmac2); } diff --git a/lib/ipset_bitmap_port.c b/lib/ipset_bitmap_port.c index a706d80..f42a3d2 100644 --- a/lib/ipset_bitmap_port.c +++ b/lib/ipset_bitmap_port.c @@ -185,9 +185,116 @@ static struct ipset_type ipset_bitmap_port1 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg bitmap_port_create_args2[] = { + { .name = { "range", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT, + .parse = ipset_parse_tcp_udp_port, .print = ipset_print_port, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + /* Backward compatibility */ + { .name = { "from", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT, + .parse = ipset_parse_single_tcp_port, + }, + { .name = { "to", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT_TO, + .parse = ipset_parse_single_tcp_port, + }, + { }, +}; + +static const struct ipset_arg bitmap_port_add_args2[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const char bitmap_port_usage2[] = +"create SETNAME bitmap:port range [PROTO:]FROM-TO\n" +" [timeout VALUE] [counters] [comments]\n" +"add SETNAME [PROTO:]PORT|FROM-TO [timeout VALUE]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME [PROTO:]PORT|FROM-TO\n" +"test SETNAME [PROTO:]PORT\n\n" +"where PORT, FROM and TO are port numbers or port names from /etc/services.\n" +"PROTO is only needed if a service name is used and it does not exist as a TCP service;\n" +"it isn't used otherwise with the bitmap.\n"; + +static struct ipset_type ipset_bitmap_port2 = { + .name = "bitmap:port", + .alias = { "portmap", NULL }, + .revision = 2, + .family = NFPROTO_UNSPEC, + .dimension = IPSET_DIM_ONE, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_tcp_udp_port, + .print = ipset_print_port, + .opt = IPSET_OPT_PORT + }, + }, + .args = { + [IPSET_CREATE] = bitmap_port_create_args2, + [IPSET_ADD] = bitmap_port_add_args2, + }, + .mandatory = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_PORT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_PORT), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_PORT), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_PORT), + }, + + .usage = bitmap_port_usage2, + .description = "comments support", +}; + void _init(void); void _init(void) { ipset_type_add(&ipset_bitmap_port0); ipset_type_add(&ipset_bitmap_port1); + ipset_type_add(&ipset_bitmap_port2); } diff --git a/lib/ipset_hash_ip.c b/lib/ipset_hash_ip.c index 19688db..d910d1f 100644 --- a/lib/ipset_hash_ip.c +++ b/lib/ipset_hash_ip.c @@ -246,9 +246,147 @@ static struct ipset_type ipset_hash_ip1 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg hash_ip_create_args2[] = { + { .name = { "family", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, .print = ipset_print_family, + }, + /* Alias: family inet */ + { .name = { "-4", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + /* Alias: family inet6 */ + { .name = { "-6", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + { .name = { "hashsize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "maxelem", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "netmask", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NETMASK, + .parse = ipset_parse_netmask, .print = ipset_print_number, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + /* Ignored options: backward compatibilty */ + { .name = { "probes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { .name = { "resize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { .name = { "gc", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_GC, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { }, +}; + +static const struct ipset_arg hash_ip_add_args2[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const char hash_ip_usage2[] = +"create SETNAME hash:ip\n" +" [family inet|inet6]\n" +" [hashsize VALUE] [maxelem VALUE]\n" +" [netmask CIDR] [timeout VALUE]\n" +" [counters] [comments]\n" +"add SETNAME IP [timeout VALUE]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME IP\n" +"test SETNAME IP\n\n" +"where depending on the INET family\n" +" IP is a valid IPv4 or IPv6 address (or hostname),\n" +" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" +" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" +" is supported for IPv4.\n"; + +static struct ipset_type ipset_hash_ip2 = { + .name = "hash:ip", + .alias = { "iphash", NULL }, + .revision = 2, + .family = NFPROTO_IPSET_IPV46, + .dimension = IPSET_DIM_ONE, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_ip4_single6, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP + }, + }, + .args = { + [IPSET_CREATE] = hash_ip_create_args2, + [IPSET_ADD] = hash_ip_add_args2, + }, + .mandatory = { + [IPSET_CREATE] = 0, + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) + | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_NETMASK) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), + }, + + .usage = hash_ip_usage2, + .description = "comments support", +}; + void _init(void); void _init(void) { ipset_type_add(&ipset_hash_ip0); ipset_type_add(&ipset_hash_ip1); + ipset_type_add(&ipset_hash_ip2); } diff --git a/lib/ipset_hash_ipport.c b/lib/ipset_hash_ipport.c index b1c9f72..61848d5 100644 --- a/lib/ipset_hash_ipport.c +++ b/lib/ipset_hash_ipport.c @@ -294,9 +294,170 @@ static struct ipset_type ipset_hash_ipport2 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg hash_ipport_create_args3[] = { + { .name = { "family", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, .print = ipset_print_family, + }, + /* Alias: family inet */ + { .name = { "-4", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + /* Alias: family inet6 */ + { .name = { "-6", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + { .name = { "hashsize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "maxelem", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + /* Backward compatibility */ + { .name = { "probes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { .name = { "resize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { .name = { "from", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_ignored, + }, + { .name = { "to", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, + .parse = ipset_parse_ignored, + }, + { .name = { "network", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_ignored, + }, + { }, +}; + +static const struct ipset_arg hash_ipport_add_args3[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const char hash_ipport_usage3[] = +"create SETNAME hash:ip,port\n" +" [family inet|inet6]\n" +" [hashsize VALUE] [maxelem VALUE]\n" +" [timeout VALUE] [counters] [comments]\n" +"add SETNAME IP,PROTO:PORT [timeout VALUE]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME IP,PROTO:PORT\n" +"test SETNAME IP,PROTO:PORT\n\n" +"where depending on the INET family\n" +" IP is a valid IPv4 or IPv6 address (or hostname).\n" +" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" +" is supported for IPv4.\n" +" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" +" port range is supported both for IPv4 and IPv6.\n"; + +static struct ipset_type ipset_hash_ipport3 = { + .name = "hash:ip,port", + .alias = { "ipporthash", NULL }, + .revision = 3, + .family = NFPROTO_IPSET_IPV46, + .dimension = IPSET_DIM_TWO, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_ip4_single6, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP + }, + [IPSET_DIM_TWO - 1] = { + .parse = ipset_parse_proto_port, + .print = ipset_print_proto_port, + .opt = IPSET_OPT_PORT + }, + }, + .args = { + [IPSET_CREATE] = hash_ipport_create_args3, + [IPSET_ADD] = hash_ipport_add_args3, + }, + .mandatory = { + [IPSET_CREATE] = 0, + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_PORT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_PORT), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_PORT), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) + | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_PROTO), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO), + }, + + .usage = hash_ipport_usage3, + .usagefn = ipset_port_usage, + .description = "comments support", +}; + void _init(void); void _init(void) { ipset_type_add(&ipset_hash_ipport1); ipset_type_add(&ipset_hash_ipport2); + ipset_type_add(&ipset_hash_ipport3); } diff --git a/lib/ipset_hash_ipportnet.c b/lib/ipset_hash_ipportnet.c index 2c2e014..0ea1f96 100644 --- a/lib/ipset_hash_ipportnet.c +++ b/lib/ipset_hash_ipportnet.c @@ -544,6 +544,200 @@ static struct ipset_type ipset_hash_ipportnet4 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg hash_ipportnet_create_args5[] = { + { .name = { "family", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, .print = ipset_print_family, + }, + /* Alias: family inet */ + { .name = { "-4", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + /* Alias: family inet6 */ + { .name = { "-6", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + { .name = { "hashsize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "maxelem", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + /* Backward compatibility */ + { .name = { "probes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { .name = { "resize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { .name = { "from", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_ignored, + }, + { .name = { "to", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, + .parse = ipset_parse_ignored, + }, + { .name = { "network", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, + .parse = ipset_parse_ignored, + }, + { }, +}; + +static const struct ipset_arg hash_ipportnet_add_args5[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "nomatch", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const struct ipset_arg hash_ipportnet_test_args5[] = { + { .name = { "nomatch", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { }, +}; + +static const char hash_ipportnet_usage5[] = +"create SETNAME hash:ip,port,net\n" +" [family inet|inet6]\n" +" [hashsize VALUE] [maxelem VALUE]\n" +" [timeout VALUE] [counters] [comments]\n" +"add SETNAME IP,PROTO:PORT,IP[/CIDR] [timeout VALUE] [nomatch]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME IP,PROTO:PORT,IP[/CIDR]\n" +"test SETNAME IP,PROTO:PORT,IP[/CIDR]\n\n" +"where depending on the INET family\n" +" IP are valid IPv4 or IPv6 addresses (or hostnames),\n" +" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" +" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" +" in both IP components are supported for IPv4.\n" +" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" +" port range is supported both for IPv4 and IPv6.\n"; + +static struct ipset_type ipset_hash_ipportnet5 = { + .name = "hash:ip,port,net", + .alias = { "ipportnethash", NULL }, + .revision = 5, + .family = NFPROTO_IPSET_IPV46, + .dimension = IPSET_DIM_THREE, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_ip4_single6, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP + }, + [IPSET_DIM_TWO - 1] = { + .parse = ipset_parse_proto_port, + .print = ipset_print_proto_port, + .opt = IPSET_OPT_PORT + }, + [IPSET_DIM_THREE - 1] = { + .parse = ipset_parse_ip4_net6, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP2 + }, + }, + .args = { + [IPSET_CREATE] = hash_ipportnet_create_args5, + [IPSET_ADD] = hash_ipportnet_add_args5, + [IPSET_TEST] = hash_ipportnet_test_args5, + }, + .mandatory = { + [IPSET_CREATE] = 0, + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_IP2), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_IP2), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_IP2), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) + | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_IP2) + | IPSET_FLAG(IPSET_OPT_CIDR2) + | IPSET_FLAG(IPSET_OPT_IP2_TO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_NOMATCH) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_IP2) + | IPSET_FLAG(IPSET_OPT_CIDR2) + | IPSET_FLAG(IPSET_OPT_IP2_TO), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_IP2) + | IPSET_FLAG(IPSET_OPT_CIDR2) + | IPSET_FLAG(IPSET_OPT_NOMATCH), + }, + + .usage = hash_ipportnet_usage5, + .usagefn = ipset_port_usage, + .description = "comments support", +}; + void _init(void); void _init(void) { @@ -551,4 +745,5 @@ void _init(void) ipset_type_add(&ipset_hash_ipportnet2); ipset_type_add(&ipset_hash_ipportnet3); ipset_type_add(&ipset_hash_ipportnet4); + ipset_type_add(&ipset_hash_ipportnet5); } diff --git a/lib/ipset_hash_net.c b/lib/ipset_hash_net.c index a80d732..0b13304 100644 --- a/lib/ipset_hash_net.c +++ b/lib/ipset_hash_net.c @@ -366,6 +366,150 @@ static struct ipset_type ipset_hash_net3 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg hash_net_create_args4[] = { + { .name = { "family", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, .print = ipset_print_family, + }, + /* Alias: family inet */ + { .name = { "-4", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + /* Alias: family inet6 */ + { .name = { "-6", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + { .name = { "hashsize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "maxelem", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + /* Ignored options: backward compatibilty */ + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "probes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { .name = { "resize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, + .parse = ipset_parse_ignored, .print = ipset_print_number, + }, + { }, +}; + +static const struct ipset_arg hash_net_add_args4[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "nomatch", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const struct ipset_arg hash_net_test_args4[] = { + { .name = { "nomatch", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { }, +}; + +static const char hash_net_usage4[] = +"create SETNAME hash:net\n" +" [family inet|inet6]\n" +" [hashsize VALUE] [maxelem VALUE]\n" +" [timeout VALUE] [counters] [comments]\n" +"add SETNAME IP[/CIDR]|FROM-TO [timeout VALUE] [nomatch]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME IP[/CIDR]|FROM-TO\n" +"test SETNAME IP[/CIDR]\n\n" +"where depending on the INET family\n" +" IP is an IPv4 or IPv6 address (or hostname),\n" +" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" +" IP range is not supported with IPv6.\n"; + +static struct ipset_type ipset_hash_net4 = { + .name = "hash:net", + .alias = { "nethash", NULL }, + .revision = 4, + .family = NFPROTO_IPSET_IPV46, + .dimension = IPSET_DIM_ONE, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_ip4_net6, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP + }, + }, + .args = { + [IPSET_CREATE] = hash_net_create_args4, + [IPSET_ADD] = hash_net_add_args4, + [IPSET_TEST] = hash_net_test_args4, + }, + .mandatory = { + [IPSET_CREATE] = 0, + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) + | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_NOMATCH) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_IP_TO), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_NOMATCH), + }, + + .usage = hash_net_usage4, + .description = "comments support", +}; + void _init(void); void _init(void) { @@ -373,4 +517,5 @@ void _init(void) ipset_type_add(&ipset_hash_net1); ipset_type_add(&ipset_hash_net2); ipset_type_add(&ipset_hash_net3); + ipset_type_add(&ipset_hash_net4); } diff --git a/lib/ipset_hash_netnet.c b/lib/ipset_hash_netnet.c index 5cc5a40..fff7909 100644 --- a/lib/ipset_hash_netnet.c +++ b/lib/ipset_hash_netnet.c @@ -42,6 +42,10 @@ static const struct ipset_arg hash_netnet_create_args0[] = { .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, .parse = ipset_parse_flag, .print = ipset_print_flag, }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, { }, }; @@ -62,6 +66,10 @@ static const struct ipset_arg hash_netnet_add_args0[] = { .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, .parse = ipset_parse_uint64, .print = ipset_print_number, }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, { }, }; @@ -123,7 +131,8 @@ static struct ipset_type ipset_hash_netnet0 = { [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) | IPSET_FLAG(IPSET_OPT_MAXELEM) | IPSET_FLAG(IPSET_OPT_TIMEOUT) - | IPSET_FLAG(IPSET_OPT_COUNTERS), + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_CIDR) | IPSET_FLAG(IPSET_OPT_IP_TO) @@ -133,7 +142,8 @@ static struct ipset_type ipset_hash_netnet0 = { | IPSET_FLAG(IPSET_OPT_TIMEOUT) | IPSET_FLAG(IPSET_OPT_NOMATCH) | IPSET_FLAG(IPSET_OPT_PACKETS) - | IPSET_FLAG(IPSET_OPT_BYTES), + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) | IPSET_FLAG(IPSET_OPT_CIDR) | IPSET_FLAG(IPSET_OPT_IP_TO) diff --git a/lib/ipset_hash_netport.c b/lib/ipset_hash_netport.c index 2b26cf2..a9fe4eb 100644 --- a/lib/ipset_hash_netport.c +++ b/lib/ipset_hash_netport.c @@ -437,6 +437,163 @@ static struct ipset_type ipset_hash_netport4 = { .description = "counters support", }; +/* Parse commandline arguments */ +static const struct ipset_arg hash_netport_create_args5[] = { + { .name = { "family", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, .print = ipset_print_family, + }, + /* Alias: family inet */ + { .name = { "-4", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + /* Alias: family inet6 */ + { .name = { "-6", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + { .name = { "hashsize", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "maxelem", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, + .parse = ipset_parse_uint32, .print = ipset_print_number, + }, + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "counters", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COUNTERS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "comments", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_COMMENTS, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { }, +}; + +static const struct ipset_arg hash_netport_add_args5[] = { + { .name = { "timeout", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, + .parse = ipset_parse_timeout, .print = ipset_print_number, + }, + { .name = { "nomatch", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { .name = { "packets", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PACKETS, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "bytes", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_BYTES, + .parse = ipset_parse_uint64, .print = ipset_print_number, + }, + { .name = { "comment", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_COMMENT, + .parse = ipset_parse_comment, .print = ipset_print_comment, + }, + { }, +}; + +static const struct ipset_arg hash_netport_test_args5[] = { + { .name = { "nomatch", NULL }, + .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_NOMATCH, + .parse = ipset_parse_flag, .print = ipset_print_flag, + }, + { }, +}; + +static const char hash_netport_usage5[] = +"create SETNAME hash:net,port\n" +" [family inet|inet6]\n" +" [hashsize VALUE] [maxelem VALUE]\n" +" [timeout VALUE] [counters] [comments]\n" +"add SETNAME IP[/CIDR]|FROM-TO,PROTO:PORT [timeout VALUE] [nomatch]\n" +" [packets VALUE] [bytes VALUE] [comment \"string\"]\n" +"del SETNAME IP[/CIDR]|FROM-TO,PROTO:PORT\n" +"test SETNAME IP[/CIDR],PROTO:PORT\n\n" +"where depending on the INET family\n" +" IP is a valid IPv4 or IPv6 address (or hostname),\n" +" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" +" Adding/deleting multiple elements with IPv4 is supported.\n" +" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" +" port range is supported both for IPv4 and IPv6.\n"; + +static struct ipset_type ipset_hash_netport5 = { + .name = "hash:net,port", + .alias = { "netporthash", NULL }, + .revision = 5, + .family = NFPROTO_IPSET_IPV46, + .dimension = IPSET_DIM_TWO, + .elem = { + [IPSET_DIM_ONE - 1] = { + .parse = ipset_parse_ip4_net6, + .print = ipset_print_ip, + .opt = IPSET_OPT_IP + }, + [IPSET_DIM_TWO - 1] = { + .parse = ipset_parse_proto_port, + .print = ipset_print_proto_port, + .opt = IPSET_OPT_PORT + }, + }, + .args = { + [IPSET_CREATE] = hash_netport_create_args5, + [IPSET_ADD] = hash_netport_add_args5, + [IPSET_TEST] = hash_netport_test_args5, + }, + .mandatory = { + [IPSET_CREATE] = 0, + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_PORT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_PORT), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_PORT), + }, + .full = { + [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) + | IPSET_FLAG(IPSET_OPT_MAXELEM) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_COUNTERS) + | IPSET_FLAG(IPSET_OPT_COMMENTS), + [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_TIMEOUT) + | IPSET_FLAG(IPSET_OPT_NOMATCH) + | IPSET_FLAG(IPSET_OPT_PACKETS) + | IPSET_FLAG(IPSET_OPT_BYTES) + | IPSET_FLAG(IPSET_OPT_COMMENT), + [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_IP_TO) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PORT_TO) + | IPSET_FLAG(IPSET_OPT_PROTO), + [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) + | IPSET_FLAG(IPSET_OPT_CIDR) + | IPSET_FLAG(IPSET_OPT_PORT) + | IPSET_FLAG(IPSET_OPT_PROTO) + | IPSET_FLAG(IPSET_OPT_NOMATCH), + }, + + .usage = hash_netport_usage5, + .usagefn = ipset_port_usage, + .description = "comments support", +}; + void _init(void); void _init(void) { @@ -444,4 +601,5 @@ void _init(void) ipset_type_add(&ipset_hash_netport2); ipset_type_add(&ipset_hash_netport3); ipset_type_add(&ipset_hash_netport4); + ipset_type_add(&ipset_hash_netport5); } -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 1/6 v2] netfilter: ipset: Support comments for ipset entries in the core. 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver ` (5 preceding siblings ...) 2013-09-02 6:35 ` [PATCH 6/6] ipset: Add new userspace set revisions for comment support Oliver @ 2013-09-02 8:21 ` Oliver 2013-09-02 20:08 ` [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Jozsef Kadlecsik 7 siblings, 0 replies; 13+ messages in thread From: Oliver @ 2013-09-02 8:21 UTC (permalink / raw) To: netfilter-devel From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> This adds the core support for having comments on ipset entries. The comments are stored as standard null-terminated strings in dynamically allocated memory after being passed to the kernel. As a result of this, any ipset using comments MUST perform cleanup of individual entries when being flushed or destroyed in order to ensure the allocated memory is released. Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> --- kernel/include/linux/netfilter/ipset/ip_set.h | 12 +++++ .../include/linux/netfilter/ipset/ip_set_comment.h | 54 ++++++++++++++++++++++ kernel/include/uapi/linux/netfilter/ipset/ip_set.h | 4 ++ kernel/net/netfilter/ipset/ip_set_core.c | 6 +++ 4 files changed, 76 insertions(+) create mode 100644 kernel/include/linux/netfilter/ipset/ip_set_comment.h diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h index f974f35..7543d5c 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/linux/netfilter/ipset/ip_set.h @@ -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, \ diff --git a/kernel/include/linux/netfilter/ipset/ip_set_comment.h b/kernel/include/linux/netfilter/ipset/ip_set_comment.h new file mode 100644 index 0000000..981a41e --- /dev/null +++ b/kernel/include/linux/netfilter/ipset/ip_set_comment.h @@ -0,0 +1,54 @@ +#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 = ext->comment ? strlen(ext->comment) : 0; + if (!len) + return; + 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 diff --git a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h index 17779ca..bc01f05 100644 --- a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h @@ -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, }; diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c index 4c95bb8..292596f 100644 --- a/kernel/net/netfilter/ipset/ip_set_core.c +++ b/kernel/net/netfilter/ipset/ip_set_core.c @@ -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); -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver ` (6 preceding siblings ...) 2013-09-02 8:21 ` [PATCH 1/6 v2] netfilter: ipset: Support comments for ipset entries in the core Oliver @ 2013-09-02 20:08 ` Jozsef Kadlecsik 2013-09-02 21:05 ` Oliver 7 siblings, 1 reply; 13+ messages in thread From: Jozsef Kadlecsik @ 2013-09-02 20:08 UTC (permalink / raw) To: Oliver; +Cc: netfilter-devel Hi Oliver, On Mon, 2 Sep 2013, Oliver wrote: > From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> > > The following patch series provides a new extension that can be > enabled on any of the bitmap/hash ipsets to provide the ability > to annotate each entry with an arbitrary string comment. I'd really like to know where it's useful and required. The comments are not used for anything at all in the kernel, those are just extra baggage. Static sets (not updated by the SET target) are created from userspace, where all these comments belong to. Dynamic sets (updated by the SET target) are just dynamic and I don't really see how the comments could be useful there. So what are the user cases where it's useful? Best regards, Jozsef > Comments are allocated dynamically rather than consuming fixed > space in the settype struct. This does come with the cost of > having to walk all the entries when flushing/deleting, but > otherwise has no bearing on the general operation of ipsets. > > Currently I have the maximum comment length hardcoded with a > preprocessor symbol, it could be easily removed within the > kernel if userspace was altered to dynamically allocate also. > > Right now it's using kmalloc and GFP_KERNEL, I imagine that > would need to be changed if someone wanted to modify xt_SET to > apply comments to entries that it creates. > > This patch series depends on an earlier one which I sent that > reworks and simplifies the extensions handling tree in order > to successfully apply. (see netfilter patchwork 271643 & 271644) > > I have not increased the revision of the hash:net,net type in > this series since, given that it's not released (yet!), there's > not all that much point in doing so. > > Additionally, I haven't written any unit tests for this since I'm > not really sure exactly what you'd want to test, so please let me > know your ideas. (Related: I hate writing unit tests) > > I may have misunderstood the library version incrementing info > in Make_global.am so if that's completely wrong, let me know :) > > TL;DR: added comments for ipset entries, please test and give > feedback, make sure you have my earlier patches if you try to > use it. > > Cheers! > > Oliver Smith (6): > netfilter: ipset: Support comments for ipset entries in the core. > netfilter: ipset: Support comments in hash-type ipsets. > netfilter: ipset: Support comments in bitmap-type ipsets. > ipset: Rework the "fake" argument parsing for ipset restore. > ipset: Support comments in the userspace library. > ipset: Add new userspace set revisions for comment support > > Make_global.am | 2 +- > include/libipset/data.h | 6 +- > include/libipset/linux_ip_set.h | 9 + > include/libipset/parse.h | 2 + > include/libipset/print.h | 3 + > kernel/include/linux/netfilter/ipset/ip_set.h | 12 ++ > .../include/linux/netfilter/ipset/ip_set_comment.h | 52 ++++++ > kernel/include/uapi/linux/netfilter/ipset/ip_set.h | 4 + > kernel/net/netfilter/ipset/ip_set_bitmap_gen.h | 77 ++++++-- > kernel/net/netfilter/ipset/ip_set_bitmap_ip.c | 31 +++- > kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c | 47 ++++- > kernel/net/netfilter/ipset/ip_set_bitmap_port.c | 30 +++- > kernel/net/netfilter/ipset/ip_set_core.c | 6 + > kernel/net/netfilter/ipset/ip_set_hash_gen.h | 72 ++++++-- > kernel/net/netfilter/ipset/ip_set_hash_ip.c | 51 +++++- > kernel/net/netfilter/ipset/ip_set_hash_ipport.c | 75 +++++++- > kernel/net/netfilter/ipset/ip_set_hash_ipportip.c | 83 ++++++++- > kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c | 91 +++++++++- > kernel/net/netfilter/ipset/ip_set_hash_net.c | 75 +++++++- > kernel/net/netfilter/ipset/ip_set_hash_netiface.c | 91 +++++++++- > kernel/net/netfilter/ipset/ip_set_hash_netnet.c | 88 ++++++++++ > kernel/net/netfilter/ipset/ip_set_hash_netport.c | 83 ++++++++- > lib/data.c | 34 ++++ > lib/debug.c | 1 + > lib/errcode.c | 2 + > lib/ipset_bitmap_ip.c | 114 ++++++++++++ > lib/ipset_bitmap_ipmac.c | 118 +++++++++++++ > lib/ipset_bitmap_port.c | 107 +++++++++++ > lib/ipset_hash_ip.c | 138 +++++++++++++++ > lib/ipset_hash_ipport.c | 161 +++++++++++++++++ > lib/ipset_hash_ipportnet.c | 195 +++++++++++++++++++++ > lib/ipset_hash_net.c | 145 +++++++++++++++ > lib/ipset_hash_netnet.c | 14 +- > lib/ipset_hash_netport.c | 158 +++++++++++++++++ > lib/libipset.map | 6 + > lib/parse.c | 27 +++ > lib/print.c | 31 ++++ > lib/session.c | 8 +- > lib/types.c | 4 +- > src/ipset.c | 32 +++- > 40 files changed, 2232 insertions(+), 53 deletions(-) > create mode 100644 kernel/include/linux/netfilter/ipset/ip_set_comment.h > > -- > 1.8.3.2 > > -- > To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > - E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries 2013-09-02 20:08 ` [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Jozsef Kadlecsik @ 2013-09-02 21:05 ` Oliver 2013-09-03 8:43 ` Jozsef Kadlecsik 0 siblings, 1 reply; 13+ messages in thread From: Oliver @ 2013-09-02 21:05 UTC (permalink / raw) To: Jozsef Kadlecsik; +Cc: netfilter-devel On Monday 02 September 2013 22:08:46 Jozsef Kadlecsik wrote: > Hi Oliver, > > On Mon, 2 Sep 2013, Oliver wrote: > > From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> > > > > The following patch series provides a new extension that can be > > enabled on any of the bitmap/hash ipsets to provide the ability > > to annotate each entry with an arbitrary string comment. > > I'd really like to know where it's useful and required. > > The comments are not used for anything at all in the kernel, those are > just extra baggage. Static sets (not updated by the SET target) are > created from userspace, where all these comments belong to. Dynamic sets > (updated by the SET target) are just dynamic and I don't really see how > the comments could be useful there. > > So what are the user cases where it's useful? Same as the user cases where -m comment is useful in iptables... Granted that I can't see a use for dynamically setting them via -j SET, but there may be a case for that if you wanted to be able to discern manually entered comments from dynamic ones in a single ipset. Anyhow, the use case is simple: If you're using a system for firewalling, very often comments are applied to iptables rules in order to explain why they are there, or whatever unblocking/blocking/mangling request they relate to. If you're leveraging ipset to avoid massive, unwieldly, slow chains of iptables rules, you've then lost the ability to annotate entries that you've added. So, the use case is exactly as it is for xt_comment in ip(6)tables-land; Namely to enable documentation of why an entry is present. Kind Regards, Oliver. > > Best regards, > Jozsef > > > Comments are allocated dynamically rather than consuming fixed > > space in the settype struct. This does come with the cost of > > having to walk all the entries when flushing/deleting, but > > otherwise has no bearing on the general operation of ipsets. > > > > Currently I have the maximum comment length hardcoded with a > > preprocessor symbol, it could be easily removed within the > > kernel if userspace was altered to dynamically allocate also. > > > > Right now it's using kmalloc and GFP_KERNEL, I imagine that > > would need to be changed if someone wanted to modify xt_SET to > > apply comments to entries that it creates. > > > > This patch series depends on an earlier one which I sent that > > reworks and simplifies the extensions handling tree in order > > to successfully apply. (see netfilter patchwork 271643 & 271644) > > > > I have not increased the revision of the hash:net,net type in > > this series since, given that it's not released (yet!), there's > > not all that much point in doing so. > > > > Additionally, I haven't written any unit tests for this since I'm > > not really sure exactly what you'd want to test, so please let me > > know your ideas. (Related: I hate writing unit tests) > > > > I may have misunderstood the library version incrementing info > > in Make_global.am so if that's completely wrong, let me know :) > > > > TL;DR: added comments for ipset entries, please test and give > > feedback, make sure you have my earlier patches if you try to > > use it. > > > > Cheers! > > > > Oliver Smith (6): > > netfilter: ipset: Support comments for ipset entries in the core. > > netfilter: ipset: Support comments in hash-type ipsets. > > netfilter: ipset: Support comments in bitmap-type ipsets. > > ipset: Rework the "fake" argument parsing for ipset restore. > > ipset: Support comments in the userspace library. > > ipset: Add new userspace set revisions for comment support > > > > Make_global.am | 2 +- > > include/libipset/data.h | 6 +- > > include/libipset/linux_ip_set.h | 9 + > > include/libipset/parse.h | 2 + > > include/libipset/print.h | 3 + > > kernel/include/linux/netfilter/ipset/ip_set.h | 12 ++ > > .../include/linux/netfilter/ipset/ip_set_comment.h | 52 ++++++ > > kernel/include/uapi/linux/netfilter/ipset/ip_set.h | 4 + > > kernel/net/netfilter/ipset/ip_set_bitmap_gen.h | 77 ++++++-- > > kernel/net/netfilter/ipset/ip_set_bitmap_ip.c | 31 +++- > > kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c | 47 ++++- > > kernel/net/netfilter/ipset/ip_set_bitmap_port.c | 30 +++- > > kernel/net/netfilter/ipset/ip_set_core.c | 6 + > > kernel/net/netfilter/ipset/ip_set_hash_gen.h | 72 ++++++-- > > kernel/net/netfilter/ipset/ip_set_hash_ip.c | 51 +++++- > > kernel/net/netfilter/ipset/ip_set_hash_ipport.c | 75 +++++++- > > kernel/net/netfilter/ipset/ip_set_hash_ipportip.c | 83 ++++++++- > > kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c | 91 +++++++++- > > kernel/net/netfilter/ipset/ip_set_hash_net.c | 75 +++++++- > > kernel/net/netfilter/ipset/ip_set_hash_netiface.c | 91 +++++++++- > > kernel/net/netfilter/ipset/ip_set_hash_netnet.c | 88 ++++++++++ > > kernel/net/netfilter/ipset/ip_set_hash_netport.c | 83 ++++++++- > > lib/data.c | 34 ++++ > > lib/debug.c | 1 + > > lib/errcode.c | 2 + > > lib/ipset_bitmap_ip.c | 114 ++++++++++++ > > lib/ipset_bitmap_ipmac.c | 118 +++++++++++++ > > lib/ipset_bitmap_port.c | 107 +++++++++++ > > lib/ipset_hash_ip.c | 138 +++++++++++++++ > > lib/ipset_hash_ipport.c | 161 > > +++++++++++++++++ > > lib/ipset_hash_ipportnet.c | 195 > > +++++++++++++++++++++ lib/ipset_hash_net.c > > | 145 +++++++++++++++ lib/ipset_hash_netnet.c > > | 14 +- > > lib/ipset_hash_netport.c | 158 > > +++++++++++++++++ > > lib/libipset.map | 6 + > > lib/parse.c | 27 +++ > > lib/print.c | 31 ++++ > > lib/session.c | 8 +- > > lib/types.c | 4 +- > > src/ipset.c | 32 +++- > > 40 files changed, 2232 insertions(+), 53 deletions(-) > > create mode 100644 kernel/include/linux/netfilter/ipset/ip_set_comment.h > > - > E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu > PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt > Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences > H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries 2013-09-02 21:05 ` Oliver @ 2013-09-03 8:43 ` Jozsef Kadlecsik 0 siblings, 0 replies; 13+ messages in thread From: Jozsef Kadlecsik @ 2013-09-03 8:43 UTC (permalink / raw) To: Oliver; +Cc: netfilter-devel On Mon, 2 Sep 2013, Oliver wrote: > On Monday 02 September 2013 22:08:46 Jozsef Kadlecsik wrote: > > > > On Mon, 2 Sep 2013, Oliver wrote: > > > From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> > > > > > > The following patch series provides a new extension that can be > > > enabled on any of the bitmap/hash ipsets to provide the ability > > > to annotate each entry with an arbitrary string comment. > > > > I'd really like to know where it's useful and required. > > > > The comments are not used for anything at all in the kernel, those are > > just extra baggage. Static sets (not updated by the SET target) are > > created from userspace, where all these comments belong to. Dynamic sets > > (updated by the SET target) are just dynamic and I don't really see how > > the comments could be useful there. > > > > So what are the user cases where it's useful? > > Same as the user cases where -m comment is useful in iptables... Granted > that I can't see a use for dynamically setting them via -j SET, but > there may be a case for that if you wanted to be able to discern > manually entered comments from dynamic ones in a single ipset. -m comment in ip[6]tables was a step in a slippery slope... In a similar way one could argue for comment fields in routing or traffic shaping entries too. > Anyhow, the use case is simple: > > If you're using a system for firewalling, very often comments are > applied to iptables rules in order to explain why they are there, or > whatever unblocking/blocking/mangling request they relate to. If you're > leveraging ipset to avoid massive, unwieldly, slow chains of iptables > rules, you've then lost the ability to annotate entries that you've > added. So, the use case is exactly as it is for xt_comment in > ip(6)tables-land; Namely to enable documentation of why an entry is > present. In my opinion complex cases where rules/entries are best annotated with comments should be implemented in a meta language on top of ip[6]tables/ipset. The configuration is then viewed entirely in userspace, without any kernel queries and the task of the kernel is just to run the rules/sets translated from the language and pushed into kernel. Anyway, I'll review your patches on the comment extension. However it'll depend on the internal reorganization of the extensions, so reworking will be required. Best regards, Jozsef - E-mail : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences H-1525 Budapest 114, POB. 49, Hungary ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2013-09-03 8:43 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-09-02 6:35 [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Oliver 2013-09-02 6:35 ` [PATCH 1/6] netfilter: ipset: Support comments for ipset entries in the core Oliver 2013-09-02 8:17 ` Oliver 2013-09-02 8:35 ` Oliver 2013-09-02 6:35 ` [PATCH 2/6] netfilter: ipset: Support comments in hash-type ipsets Oliver 2013-09-02 6:35 ` [PATCH 3/6] netfilter: ipset: Support comments in bitmap-type ipsets Oliver 2013-09-02 6:35 ` [PATCH 4/6] ipset: Rework the "fake" argument parsing for ipset restore Oliver 2013-09-02 6:35 ` [PATCH 5/6] ipset: Support comments in the userspace library Oliver 2013-09-02 6:35 ` [PATCH 6/6] ipset: Add new userspace set revisions for comment support Oliver 2013-09-02 8:21 ` [PATCH 1/6 v2] netfilter: ipset: Support comments for ipset entries in the core Oliver 2013-09-02 20:08 ` [PATCH 0/6] Ipset comment extension - provide annotation of ipset entries Jozsef Kadlecsik 2013-09-02 21:05 ` Oliver 2013-09-03 8:43 ` Jozsef Kadlecsik
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).