From: Jo-Philipp Wich <jow@openwrt.org>
Date: Tue, 12 Mar 2013 18:34:16 +0000 (+0100)
Subject: Track used networks and devices in state file
X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=061fdb168b98f6d4f23bebf5153d51bb3a85611e;p=oweals%2Ffirewall3.git

Track used networks and devices in state file
---

diff --git a/options.h b/options.h
index 9422f81..1838a01 100644
--- a/options.h
+++ b/options.h
@@ -135,6 +135,7 @@ struct fw3_device
 	bool any;
 	bool invert;
 	char name[32];
+	struct fw3_device *network;
 };
 
 struct fw3_address
@@ -262,6 +263,9 @@ struct fw3_zone
 	struct list_head devices;
 	struct list_head subnets;
 
+	struct list_head running_networks;
+	struct list_head running_devices;
+
 	const char *extra_src;
 	const char *extra_dest;
 
diff --git a/utils.c b/utils.c
index 4314f91..1942cbc 100644
--- a/utils.c
+++ b/utils.c
@@ -361,6 +361,7 @@ fw3_read_statefile(void *state)
 	struct fw3_state *s = state;
 	struct fw3_zone *zone;
 	struct fw3_ipset *ipset;
+	struct fw3_device *net, *dev;
 
 	sf = fopen(FW3_STATEFILE, "r");
 
@@ -430,6 +431,28 @@ fw3_read_statefile(void *state)
 			ipset->flags[1] = flags[1];
 			list_add_tail(&ipset->running_list, &s->running_ipsets);
 			break;
+
+		case FW3_TYPE_NETWORK:
+			if (!(zone = fw3_lookup_zone(state, name, false)))
+				continue;
+
+			if (!(p = strtok(NULL, " \t\n")) || !(name = strtok(NULL, " \t\n")))
+				continue;
+
+			if (!(net = malloc(sizeof(*net))))
+				continue;
+
+			memset(net, 0, sizeof(*net));
+			snprintf(net->name, sizeof(net->name), "%s", p);
+			list_add_tail(&net->list, &zone->running_networks);
+
+			if (!(dev = malloc(sizeof(*dev))))
+				continue;
+
+			memset(dev, 0, sizeof(*dev));
+			dev->network = net;
+			snprintf(dev->name, sizeof(dev->name), "%s", name);
+			list_add_tail(&dev->list, &zone->running_devices);
 		}
 	}
 
@@ -443,11 +466,12 @@ fw3_write_statefile(void *state)
 {
 	FILE *sf;
 	struct fw3_state *s = state;
-	struct fw3_defaults *d = &s->defaults;
+	struct fw3_defaults *defs = &s->defaults;
 	struct fw3_zone *z;
 	struct fw3_ipset *i;
+	struct fw3_device *d;
 
-	if (fw3_no_table(d->flags[0]) && fw3_no_table(d->flags[1]))
+	if (fw3_no_table(defs->flags[0]) && fw3_no_table(defs->flags[1]))
 	{
 		if (unlink(FW3_STATEFILE))
 			warn("Unable to remove state %s: %s",
@@ -464,14 +488,24 @@ fw3_write_statefile(void *state)
 		return;
 	}
 
-	fprintf(sf, "%x - %x %x\n", FW3_TYPE_DEFAULTS, d->flags[0], d->flags[1]);
+	fprintf(sf, "%x - %x %x\n",
+	        FW3_TYPE_DEFAULTS, defs->flags[0], defs->flags[1]);
 
 	list_for_each_entry(z, &s->running_zones, running_list)
 	{
-		if (!fw3_no_table(z->flags[0]) || !fw3_no_table(z->flags[1]))
+		if (fw3_no_table(z->flags[0]) && fw3_no_table(z->flags[1]))
+			continue;
+
+		fprintf(sf, "%x %s %x %x\n",
+		        FW3_TYPE_ZONE, z->name, z->flags[0], z->flags[1]);
+
+		list_for_each_entry(d, &z->devices, list)
 		{
-			fprintf(sf, "%x %s %x %x\n",
-					FW3_TYPE_ZONE, z->name, z->flags[0], z->flags[1]);
+			if (!d->network)
+				continue;
+
+			fprintf(sf, "%x %s 0 0 %s %s\n",
+			        FW3_TYPE_NETWORK, z->name, d->network->name, d->name);
 		}
 	}
 
diff --git a/utils.h b/utils.h
index 60e87c2..e28408b 100644
--- a/utils.h
+++ b/utils.h
@@ -87,7 +87,8 @@ enum fw3_statefile_type
 {
 	FW3_TYPE_DEFAULTS = 0,
 	FW3_TYPE_ZONE     = 1,
-	FW3_TYPE_IPSET    = 2,
+	FW3_TYPE_NETWORK  = 2,
+	FW3_TYPE_IPSET    = 3,
 };
 
 bool fw3_read_statefile(void *state);
diff --git a/zones.c b/zones.c
index 1506c01..cb91827 100644
--- a/zones.c
+++ b/zones.c
@@ -129,6 +129,7 @@ resolve_networks(struct uci_element *e, struct fw3_zone *zone)
 			continue;
 		}
 
+		tmp->network = net;
 		list_add_tail(&tmp->list, &zone->devices);
 	}
 }
@@ -151,6 +152,9 @@ fw3_alloc_zone(void)
 	INIT_LIST_HEAD(&zone->masq_src);
 	INIT_LIST_HEAD(&zone->masq_dest);
 
+	INIT_LIST_HEAD(&zone->running_networks);
+	INIT_LIST_HEAD(&zone->running_devices);
+
 	zone->enabled = true;
 	zone->custom_chains = true;
 	zone->log_limit.rate = 10;