netfilter: ipset: Introduce new operation to get both setname and family
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Mon, 30 Sep 2013 05:57:18 +0000 (07:57 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Mon, 30 Sep 2013 19:33:26 +0000 (21:33 +0200)
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>
include/uapi/linux/netfilter/ipset/ip_set.h
net/netfilter/ipset/ip_set_core.c

index 8024cdf13b700560e9bd0c1f3df1bacbdd90b900..2b61ac44dcc1ee8831932588ae311828f323e0ed 100644 (file)
@@ -250,6 +250,14 @@ struct ip_set_req_get_set {
 #define IP_SET_OP_GET_BYINDEX  0x00000007      /* Get set name by index */
 /* Uses ip_set_req_get_set */
 
+#define IP_SET_OP_GET_FNAME    0x00000008      /* Get set index and family */
+struct ip_set_req_get_set_family {
+       unsigned int op;
+       unsigned int version;
+       unsigned int family;
+       union ip_set_name_index set;
+};
+
 #define IP_SET_OP_VERSION      0x00000100      /* Ask kernel version */
 struct ip_set_req_version {
        unsigned int op;
index f2e30fb31e78efa405156ca99ba9aeaded3ea49c..428c30a8586f3387d3c6da455232f7f1e9b1d1eb 100644 (file)
@@ -1788,6 +1788,23 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
                nfnl_unlock(NFNL_SUBSYS_IPSET);
                goto copy;
        }
+       case IP_SET_OP_GET_FNAME: {
+               struct ip_set_req_get_set_family *req_get = data;
+               ip_set_id_t id;
+
+               if (*len != sizeof(struct ip_set_req_get_set_family)) {
+                       ret = -EINVAL;
+                       goto done;
+               }
+               req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
+               nfnl_lock(NFNL_SUBSYS_IPSET);
+               find_set_and_id(req_get->set.name, &id);
+               req_get->set.index = id;
+               if (id != IPSET_INVALID_ID)
+                       req_get->family = nfnl_set(id)->family;
+               nfnl_unlock(NFNL_SUBSYS_IPSET);
+               goto copy;
+       }
        case IP_SET_OP_GET_BYINDEX: {
                struct ip_set_req_get_set *req_get = data;
                struct ip_set *set;