firewall3: ipset: Handle reload_set properly
[project/firewall3.git] / utils.c
diff --git a/utils.c b/utils.c
index 684b2c32c25eb5d3123151cce472413c6a9daa04..b465878a71f2bfc4cb3f872fbf23b5d28aec4766 100644 (file)
--- a/utils.c
+++ b/utils.c
  */
 
 #define _GNU_SOURCE
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+
 #include "utils.h"
 #include "options.h"
 
@@ -581,6 +585,14 @@ write_ipset_uci(struct uci_context *ctx, struct fw3_ipset *s,
        ptr.value  = s->name;
        uci_set(ctx, &ptr);
 
+       ptr.o      = NULL;
+       ptr.option = "family";
+       if (s->family == FW3_FAMILY_V4)
+               ptr.value = "ipv4";
+       else
+               ptr.value = "ipv6";
+       uci_set(ctx, &ptr);
+
        ptr.o      = NULL;
        ptr.option = "storage";
        ptr.value  = fw3_ipset_method_names[s->method];
@@ -935,3 +947,43 @@ fw3_protoname(void *proto)
 
        return pe->p_name;
 }
+
+bool
+fw3_check_loopback_dev(const char *name)
+{
+       struct ifreq ifr;
+       int s;
+       bool rv = false;
+
+       s = socket(AF_LOCAL, SOCK_DGRAM, 0);
+
+       if (s < 0)
+               return false;
+
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
+
+       if (ioctl(s, SIOCGIFFLAGS, &ifr) >= 0) {
+               if (ifr.ifr_flags & IFF_LOOPBACK)
+                       rv = true;
+       }
+
+       close(s);
+
+       return rv;
+}
+
+bool
+fw3_check_loopback_addr(struct fw3_address *addr)
+{
+       if (addr->family == FW3_FAMILY_V4 &&
+           (ntohl(addr->address.v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+               return true;
+
+       if (addr->family == FW3_FAMILY_V6 && !addr->range &&
+           fw3_netmask2bitlen(FW3_FAMILY_V6, &addr->mask.v6) == 128 &&
+           IN6_IS_ADDR_LOOPBACK(&addr->address.v6))
+               return true;
+
+       return false;
+}