From d5aa4e5d12fe80cf82da0ae4a0da595a8bfd83bb Mon Sep 17 00:00:00 2001
From: Jo-Philipp Wich <jow@openwrt.org>
Date: Tue, 30 Apr 2013 20:09:20 +0200
Subject: [PATCH] Track ipsets in state file

---
 utils.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/utils.c b/utils.c
index 0094ae7..3558450 100644
--- a/utils.c
+++ b/utils.c
@@ -486,12 +486,61 @@ write_zone_uci(struct uci_context *ctx, struct fw3_zone *z,
 	uci_set(ctx, &ptr);
 }
 
+static void
+write_ipset_uci(struct uci_context *ctx, struct fw3_ipset *s,
+                struct uci_package *dest)
+{
+	enum fw3_family fam = FW3_FAMILY_ANY;
+
+	char buf[sizeof("0xffffffff\0")];
+
+	struct uci_ptr ptr = { .p = dest };
+
+	if (!s->enabled || (s->external && *s->external))
+		return;
+
+	if (fw3_no_family(s->flags[0]) && !fw3_no_family(s->flags[1]))
+		fam = FW3_FAMILY_V6;
+	else if (!fw3_no_family(s->flags[0]) && fw3_no_family(s->flags[1]))
+		fam = FW3_FAMILY_V4;
+	else if (fw3_no_family(s->flags[0]) && fw3_no_family(s->flags[1]))
+		return;
+
+	uci_add_section(ctx, dest, "ipset", &ptr.s);
+
+	ptr.o      = NULL;
+	ptr.option = "name";
+	ptr.value  = s->name;
+	uci_set(ctx, &ptr);
+
+	if (fam != FW3_FAMILY_ANY)
+	{
+		ptr.o      = NULL;
+		ptr.option = "family";
+		ptr.value  = fw3_flag_names[fam];
+		uci_set(ctx, &ptr);
+	}
+
+	sprintf(buf, "0x%x", s->flags[0]);
+	ptr.o      = NULL;
+	ptr.option = "__flags_v4";
+	ptr.value  = buf;
+	uci_set(ctx, &ptr);
+
+	sprintf(buf, "0x%x", s->flags[1]);
+	ptr.o      = NULL;
+	ptr.option = "__flags_v6";
+	ptr.value  = buf;
+	uci_set(ctx, &ptr);
+}
+
 void
 fw3_write_statefile(void *state)
 {
 	FILE *sf;
 	struct fw3_state *s = state;
 	struct fw3_zone *z;
+	struct fw3_ipset *i;
 
 	struct uci_package *p;
 
@@ -522,6 +571,9 @@ fw3_write_statefile(void *state)
 			list_for_each_entry(z, &s->zones, list)
 				write_zone_uci(s->uci, z, p);
 
+			list_for_each_entry(i, &s->ipsets, list)
+				write_ipset_uci(s->uci, i, p);
+
 			uci_export(s->uci, sf, p, true);
 			uci_unload(s->uci, p);
 		}
-- 
2.25.1