]> granicus.if.org Git - ipset/commitdiff
Suppress false syntax error messages
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Thu, 10 May 2012 07:30:36 +0000 (09:30 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Thu, 10 May 2012 07:30:36 +0000 (09:30 +0200)
If a create command fails at the kernel side, false syntax error
was also reported due to  the chicken and egg problem of the family
option.

include/libipset/data.h
lib/data.c
lib/libipset.map
lib/parse.c
lib/types.c

index 525cc6a78039c13619ccfb8ffffef4e553b572c6..5d801852126d896296f3f2f6e94ca95b65db5392 100644 (file)
@@ -113,6 +113,7 @@ extern bool ipset_data_flags_test(const struct ipset_data *data,
 extern void ipset_data_flags_set(struct ipset_data *data, uint64_t flags);
 extern void ipset_data_flags_unset(struct ipset_data *data, uint64_t flags);
 extern bool ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt);
+extern bool ipset_data_test_ignored(struct ipset_data *data, enum ipset_opt opt);
 
 extern int ipset_data_set(struct ipset_data *data, enum ipset_opt opt,
                          const void *value);
index 3bbb75b78f0406c4939a86aa0324bb1f45c1cecf..d74be4d56e854f955fb0e3f0f6a1d5229b2aad87 100644 (file)
@@ -166,7 +166,7 @@ do {                                                \
  * @data: data blob
  * @flags: the option flag to be ignored
  *
- * Returns true if the option was not already ignored.
+ * Returns true if the option was already ignored.
  */
 bool
 ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt)
@@ -180,6 +180,21 @@ ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt)
        return ignored;
 }
 
+/**
+ * ipset_data_test_ignored - test ignored bits in the data blob
+ * @data: data blob
+ * @flags: the option flag to be tested
+ *
+ * Returns true if the option is ignored.
+ */
+bool
+ipset_data_test_ignored(struct ipset_data *data, enum ipset_opt opt)
+{
+       assert(data);
+
+       return data->ignored & IPSET_FLAG(opt);
+}
+
 /**
  * ipset_data_set - put data into the data blob
  * @data: data blob
@@ -208,6 +223,7 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
                break;
        case IPSET_OPT_FAMILY:
                data->family = *(const uint8_t *) value;
+               data->ignored &= ~IPSET_FLAG(IPSET_OPT_FAMILY);
                D("family set to %u", data->family);
                break;
        /* CADT options */
index 0eb7fad984cc8fbc747cab75333efdcf9857012f..fd6b8c090cdcf1fb40747c17e55d6b9fd9fe566d 100644 (file)
@@ -115,4 +115,5 @@ global:
   ipset_load_types;
   ipset_port_usage;
   ipset_parse_timeout;
+  ipset_data_test_ignored;
 } LIBIPSET_1.0;
index 45937f0091a4659c33cac353e90bdf11cb5b5793..afbbbf9599826c8beee6cfbd2f6be159b280f60f 100644 (file)
@@ -651,7 +651,8 @@ ipset_parse_family(struct ipset_session *session,
        assert(str);
 
        data = ipset_session_data(session);
-       if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_FAMILY)))
+       if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_FAMILY))
+           && !ipset_data_test_ignored(data, IPSET_OPT_FAMILY))
                syntax_err("protocol family may not be specified "
                           "multiple times");
 
@@ -1637,8 +1638,11 @@ ipset_call_parser(struct ipset_session *session,
                                  const struct ipset_arg *arg,
                                  const char *str)
 {
-       if (ipset_data_flags_test(ipset_session_data(session),
-                                 IPSET_FLAG(arg->opt)))
+       struct ipset_data *data = ipset_session_data(session);
+
+       if (ipset_data_flags_test(data, IPSET_FLAG(arg->opt))
+           && !(arg->opt == IPSET_OPT_FAMILY
+                && ipset_data_test_ignored(data, IPSET_OPT_FAMILY)))
                syntax_err("%s already specified", arg->name[0]);
 
        return arg->parse(session, arg->opt, str);
index 64c9c8483a4d32c659fcb3ff00b28f222a502c1e..57217059258566bd1fe7f4384c4a8e5102d6a826 100644 (file)
@@ -207,6 +207,7 @@ create_type_get(struct ipset_session *session)
        uint8_t family, tmin = 0, tmax = 0;
        uint8_t kmin, kmax;
        int ret;
+       bool ignore_family = false;
 
        data = ipset_session_data(session);
        assert(data);
@@ -238,6 +239,8 @@ create_type_get(struct ipset_session *session)
                family = match->family == NFPROTO_IPSET_IPV46 ?
                         NFPROTO_IPV4 : match->family;
                ipset_data_set(data, IPSET_OPT_FAMILY, &family);
+               if (match->family == NFPROTO_IPSET_IPV46)
+                       ignore_family = true;
        }
 
        if (match->kernel_check == IPSET_KERNEL_OK)
@@ -294,6 +297,11 @@ create_type_get(struct ipset_session *session)
 found:
        ipset_data_set(data, IPSET_OPT_TYPE, match);
 
+       if (ignore_family) {
+               /* Overload ignored flag */
+               D("set ignored flag to FAMILY");
+               ipset_data_ignored(data, IPSET_OPT_FAMILY);
+       }
        return match;
 }
 
@@ -390,7 +398,11 @@ ipset_type_get(struct ipset_session *session, enum ipset_cmd cmd)
 
        switch (cmd) {
        case IPSET_CMD_CREATE:
-               return create_type_get(session);
+               return ipset_data_test(ipset_session_data(session),
+                                      IPSET_OPT_TYPE)
+                       ? ipset_data_get(ipset_session_data(session),
+                                        IPSET_OPT_TYPE)
+                       : create_type_get(session);
        case IPSET_CMD_ADD:
        case IPSET_CMD_DEL:
        case IPSET_CMD_TEST: