ipsets: add support for specifying entries
authorJo-Philipp Wich <jo@mein.io>
Sat, 10 Mar 2018 12:45:44 +0000 (13:45 +0100)
committerJo-Philipp Wich <jo@mein.io>
Sat, 10 Mar 2018 12:47:18 +0000 (13:47 +0100)
Introduce a new list option "entry" which can be used to specify entries
to add to the ipset, e.g.

    config ipset
      option name test
      ...
      list entry 1.2.3.4,8080
      list entry 5.6.7.8,8081

Also introduce a new option "loadfile" which refers to an external file
containing set entries to add, with one item per line.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
ipsets.c
options.c
options.h

index 30c6463ff05a73e73fb9a99b2812f738577f7f86..b73c3d28c64d99d7769f44ca9ad0da6a19241111 100644 (file)
--- a/ipsets.c
+++ b/ipsets.c
@@ -38,6 +38,9 @@ const struct fw3_option fw3_ipset_opts[] = {
 
        FW3_OPT("external",      string,         ipset,     external),
 
+       FW3_LIST("entry",        setentry,       ipset,     entries),
+       FW3_OPT("loadfile",      string,         ipset,     loadfile),
+
        { }
 };
 
@@ -247,6 +250,7 @@ fw3_alloc_ipset(struct fw3_state *state)
                return NULL;
 
        INIT_LIST_HEAD(&ipset->datatypes);
+       INIT_LIST_HEAD(&ipset->entries);
 
        ipset->enabled = true;
        ipset->family  = FW3_FAMILY_V4;
@@ -318,11 +322,35 @@ fw3_load_ipsets(struct fw3_state *state, struct uci_package *p,
 }
 
 
+static void
+load_file(struct fw3_ipset *ipset)
+{
+       FILE *f;
+       char line[128];
+
+       if (!ipset->loadfile)
+               return;
+
+       info("   * Loading file %s", ipset->loadfile);
+
+       f = fopen(ipset->loadfile, "r");
+
+       if (!f) {
+               info("     ! Skipping due to open error: %s", strerror(errno));
+               return;
+       }
+
+       while (fgets(line, sizeof(line), f))
+               fw3_pr("add %s %s", ipset->name, line);
+
+       fclose(f);
+}
+
 static void
 create_ipset(struct fw3_ipset *ipset, struct fw3_state *state)
 {
        bool first = true;
-
+       struct fw3_setentry *entry;
        struct fw3_ipset_datatype *type;
 
        info(" * Creating ipset %s", ipset->name);
@@ -362,6 +390,11 @@ create_ipset(struct fw3_ipset *ipset, struct fw3_state *state)
                fw3_pr(" hashsize %u", ipset->hashsize);
 
        fw3_pr("\n");
+
+       list_for_each_entry(entry, &ipset->entries, list)
+               fw3_pr("add %s %s\n", ipset->name, entry->value);
+
+       load_file(ipset);
 }
 
 void
index d990cada687277c12a92efb26817785b21001975..b5d5c02ff2fa24f0c1f6bc057b56dd1c64451cb8 100644 (file)
--- a/options.c
+++ b/options.c
@@ -920,6 +920,17 @@ fw3_parse_cthelper(void *ptr, const char *val, bool is_list)
        return false;
 }
 
+bool
+fw3_parse_setentry(void *ptr, const char *val, bool is_list)
+{
+       struct fw3_setentry e = { };
+
+       e.value = val;
+       put_value(ptr, &e, sizeof(e), is_list);
+
+       return true;
+}
+
 
 bool
 fw3_parse_options(void *s, const struct fw3_option *opts,
index 2d1080101014565b92c15d90509387c44fdfdc9f..5b2a7693c020566a0d23e7f4a25f7b1e8f58b647 100644 (file)
--- a/options.h
+++ b/options.h
@@ -495,6 +495,9 @@ struct fw3_ipset
 
        const char *external;
 
+       struct list_head entries;
+       const char *loadfile;
+
        uint32_t flags[2];
 };
 
@@ -525,6 +528,12 @@ struct fw3_cthelper
        struct fw3_port port;
 };
 
+struct fw3_setentry
+{
+       struct list_head list;
+       const char *value;
+};
+
 struct fw3_state
 {
        struct uci_context *uci;
@@ -593,6 +602,7 @@ bool fw3_parse_mark(void *ptr, const char *val, bool is_list);
 bool fw3_parse_setmatch(void *ptr, const char *val, bool is_list);
 bool fw3_parse_direction(void *ptr, const char *val, bool is_list);
 bool fw3_parse_cthelper(void *ptr, const char *val, bool is_list);
+bool fw3_parse_setentry(void *ptr, const char *val, bool is_list);
 
 bool fw3_parse_options(void *s, const struct fw3_option *opts,
                        struct uci_section *section);