return rv;
}
+ if (!print_rules)
+ fw3_hotplug_zones(false, state);
+
for (family = FW3_FAMILY_V4; family <= FW3_FAMILY_V6; family++)
{
if (!complete && !family_running(state, family))
{
fw3_set_defaults(state);
- if (!reload && !print_rules)
- fw3_run_includes(state);
-
if (!print_rules)
+ {
+ if (!reload)
+ fw3_run_includes(state);
+
+ fw3_hotplug_zones(true, state);
fw3_write_statefile(state);
+ }
}
return rv;
FW3_FLAG_SYN_FLOOD = 16,
FW3_FLAG_MTU_FIX = 17,
FW3_FLAG_DROP_INVALID = 18,
+ FW3_FLAG_HOTPLUG = 19,
__FW3_FLAG_MAX
};
signal(SIGPIPE, SIG_IGN);
pipe_pid = pid;
close(pfds[0]);
+ fcntl(pfds[1], F_SETFD, fcntl(pfds[1], F_GETFD) | FD_CLOEXEC);
}
pipe_fd = fdopen(pfds[1], "w");
return rv;
}
+
+
+bool
+fw3_hotplug(bool add, void *zone, void *device)
+{
+ struct fw3_zone *z = zone;
+ struct fw3_device *d = device;
+
+ if (!d->network)
+ return false;
+
+ switch (fork())
+ {
+ case -1:
+ warn("Unable to fork(): %s\n", strerror(errno));
+ return false;
+
+ case 0:
+ break;
+
+ default:
+ return true;
+ }
+
+ close(0);
+ close(1);
+ close(2);
+ chdir("/");
+
+ clearenv();
+ setenv("ACTION", add ? "add" : "remove", 1);
+ setenv("ZONE", z->name, 1);
+ setenv("INTERFACE", d->network->name, 1);
+ setenv("DEVICE", d->name, 1);
+
+ execl(FW3_HOTPLUG, FW3_HOTPLUG, "firewall", NULL);
+
+ /* unreached */
+ return false;
+}
#define FW3_STATEFILE "/var/run/fw3.state"
#define FW3_LOCKFILE "/var/run/fw3.lock"
+#define FW3_HOTPLUG "/sbin/hotplug-call"
extern bool fw3_pr_debug;
bool fw3_pr_rulespec(int table, int family, uint32_t *flags, uint32_t mask,
const struct fw3_rule_spec *r, const char *fmt, ...);
+bool fw3_hotplug(bool add, void *zone, void *device);
+
#endif
}
}
+void
+fw3_hotplug_zones(bool add, struct fw3_state *state)
+{
+ struct fw3_zone *z;
+ struct fw3_device *d;
+
+ if (add)
+ {
+ list_for_each_entry(z, &state->running_zones, running_list)
+ {
+ if (!hasbit(z->flags[0], FW3_FLAG_HOTPLUG))
+ {
+ list_for_each_entry(d, &z->devices, list)
+ fw3_hotplug(add, z, d);
+
+ setbit(z->flags[0], FW3_FLAG_HOTPLUG);
+ }
+ }
+ }
+ else
+ {
+ list_for_each_entry(z, &state->running_zones, running_list)
+ {
+ if (hasbit(z->flags[0], FW3_FLAG_HOTPLUG))
+ {
+ list_for_each_entry(d, &z->running_devices, list)
+ fw3_hotplug(add, z, d);
+
+ delbit(z->flags[0], FW3_FLAG_HOTPLUG);
+ }
+ }
+ }
+}
+
struct fw3_zone *
fw3_lookup_zone(struct fw3_state *state, const char *name, bool running)
{
return NULL;
}
+
+void
+fw3_free_zone(struct fw3_zone *zone)
+{
+ struct fw3_device *dev, *tmp;
+
+ list_for_each_entry_safe(dev, tmp, &zone->running_devices, list)
+ {
+ list_del(&dev->list);
+ free(dev);
+ }
+
+ list_for_each_entry_safe(dev, tmp, &zone->running_networks, list)
+ {
+ list_del(&dev->list);
+ free(dev);
+ }
+
+ fw3_free_object(zone, fw3_zone_opts);
+}
void fw3_flush_zones(enum fw3_table table, enum fw3_family family,
bool pass2, bool reload, struct fw3_state *state);
+void fw3_hotplug_zones(bool add, struct fw3_state *state);
+
struct fw3_zone * fw3_lookup_zone(struct fw3_state *state, const char *name,
bool running);
+void fw3_free_zone(struct fw3_zone *zone);
+
#define fw3_to_src_target(t) \
(FW3_FLAG_SRC_ACCEPT - FW3_FLAG_ACCEPT + t)
-#define fw3_free_zone(zone) \
- fw3_free_object(zone, fw3_zone_opts)
-
#endif