sgw: remove any left-over sgw tunnels during startup and shutdown
authorFerry Huberts <ferry.huberts@pelagic.nl>
Sun, 29 May 2016 10:18:51 +0000 (12:18 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Sun, 29 May 2016 10:26:57 +0000 (12:26 +0200)
With hard crashes, some sgw tunnel interfaces might not have been
cleaned up.

Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
src/gateway.c

index eb6a0f5..19882ce 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/rtnetlink.h>
 #include <net/if.h>
 #include <sys/ioctl.h>
+#include <net/if.h>
 
 /*
  * Defines for the multi-gateway script
@@ -421,6 +422,30 @@ static bool multiGwRunScript(const char * mode, bool addMode, const char * ifNam
 }
 
 /**
+ * Remove all sgw tunnel interfaces
+ */
+static void multiGwTunnelsCleanup(bool add) {
+  bool ipv4 = (olsr_cnf->ip_version == AF_INET);
+
+  unsigned int i = 0;
+  uint8_t count = olsr_cnf->smart_gw_use_count;
+
+  while (++i <= count) {
+    struct interfaceName * ifn = ipv4 ? &sgwTunnel4InterfaceNames[count - i] : &sgwTunnel6InterfaceNames[count - i];
+
+    unsigned int ifindex = if_nametoindex(ifn->name);
+    if (!ifindex) {
+      continue;
+    }
+    olsr_syslog(OLSR_LOG_ERR, "Smart-gateway tunnel '%s' %s exists, removing it", ifn->name, !add ? "still" : "already");
+
+    olsr_os_inetgw_tunnel_route(ifindex, ipv4, false, ifn->tableNr);
+    olsr_if_set_state(ifn->name, false);
+    os_ip_tunnel(ifn->name, NULL);
+  }
+}
+
+/**
  * Cleanup multi-gateway iptables and ip rules
  *
  * @param add true to add policy routing, false to remove it
@@ -910,6 +935,7 @@ int olsr_startup_gateways(void) {
     return 0;
   }
 
+  multiGwTunnelsCleanup(true);
   ok = ok && multiGwRulesCleanup(true);
   ok = ok && multiGwRulesOlsrInterfaces(true);
   ok = ok && multiGwRulesSgwTunnels(true);
@@ -1007,6 +1033,8 @@ void olsr_cleanup_gateways(void) {
   struct gateway_entry * tree_gw;
   struct gw_container_entry * gw;
 
+  multiGwTunnelsCleanup(false);
+
   while (olsr_cnf->smart_gw_egress_interfaces) {
     struct sgw_egress_if * next = olsr_cnf->smart_gw_egress_interfaces->next;
     free(olsr_cnf->smart_gw_egress_interfaces->name);