diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-09-30 01:57:18 -0400 |
---|---|---|
committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-09-30 15:33:26 -0400 |
commit | 5e04c0c38c90f1f11a0e87800e4c22d4aba1d733 (patch) | |
tree | 8b8f3229e3934a0c0ff49ba12ea59899d944fe55 | |
parent | bd3129fc5e8868df74ffa803c7fec527976bbf1c (diff) |
netfilter: ipset: Introduce new operation to get both setname and family
ip[6]tables set match and SET target need to know the family of the set
in order to reject adding rules which refer to a set with a non-mathcing
family. Currently such rules are silently accepted and then ignored
instead of generating a clear error message to the user, which is not
helpful.
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-rw-r--r-- | include/uapi/linux/netfilter/ipset/ip_set.h | 8 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_core.c | 17 |
2 files changed, 25 insertions, 0 deletions
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h index 8024cdf13b70..2b61ac44dcc1 100644 --- a/include/uapi/linux/netfilter/ipset/ip_set.h +++ b/include/uapi/linux/netfilter/ipset/ip_set.h | |||
@@ -250,6 +250,14 @@ struct ip_set_req_get_set { | |||
250 | #define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ | 250 | #define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ |
251 | /* Uses ip_set_req_get_set */ | 251 | /* Uses ip_set_req_get_set */ |
252 | 252 | ||
253 | #define IP_SET_OP_GET_FNAME 0x00000008 /* Get set index and family */ | ||
254 | struct ip_set_req_get_set_family { | ||
255 | unsigned int op; | ||
256 | unsigned int version; | ||
257 | unsigned int family; | ||
258 | union ip_set_name_index set; | ||
259 | }; | ||
260 | |||
253 | #define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ | 261 | #define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ |
254 | struct ip_set_req_version { | 262 | struct ip_set_req_version { |
255 | unsigned int op; | 263 | unsigned int op; |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index f2e30fb31e78..428c30a8586f 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
@@ -1788,6 +1788,23 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len) | |||
1788 | nfnl_unlock(NFNL_SUBSYS_IPSET); | 1788 | nfnl_unlock(NFNL_SUBSYS_IPSET); |
1789 | goto copy; | 1789 | goto copy; |
1790 | } | 1790 | } |
1791 | case IP_SET_OP_GET_FNAME: { | ||
1792 | struct ip_set_req_get_set_family *req_get = data; | ||
1793 | ip_set_id_t id; | ||
1794 | |||
1795 | if (*len != sizeof(struct ip_set_req_get_set_family)) { | ||
1796 | ret = -EINVAL; | ||
1797 | goto done; | ||
1798 | } | ||
1799 | req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0'; | ||
1800 | nfnl_lock(NFNL_SUBSYS_IPSET); | ||
1801 | find_set_and_id(req_get->set.name, &id); | ||
1802 | req_get->set.index = id; | ||
1803 | if (id != IPSET_INVALID_ID) | ||
1804 | req_get->family = nfnl_set(id)->family; | ||
1805 | nfnl_unlock(NFNL_SUBSYS_IPSET); | ||
1806 | goto copy; | ||
1807 | } | ||
1791 | case IP_SET_OP_GET_BYINDEX: { | 1808 | case IP_SET_OP_GET_BYINDEX: { |
1792 | struct ip_set_req_get_set *req_get = data; | 1809 | struct ip_set_req_get_set *req_get = data; |
1793 | struct ip_set *set; | 1810 | struct ip_set *set; |