gateway: store current gateway(s) in a struct
authorFerry Huberts <ferry.huberts@pelagic.nl>
Mon, 5 Nov 2012 12:47:40 +0000 (13:47 +0100)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Mon, 10 Dec 2012 14:18:24 +0000 (15:18 +0100)
This simplifies the administration of the currently
active gateways.

Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
Reviewed-by: Henning Rogge <hrogge@googlemail.com>
src/gateway.c

index c7bdcd2..93120e4 100644 (file)
 #include <assert.h>
 #include <net/if.h>
 
+/** A container for a gateway and its tunnel */
+struct gw_container_entry {
+               struct gateway_entry * gw; /**< the gateway entry */
+               struct olsr_iptunnel_entry * tunnel; /**< the gateway tunnel */
+};
+
 /** the gateway tree */
 struct avl_tree gateway_tree;
 
 /** gateway cookie */
 static struct olsr_cookie_info *gateway_entry_mem_cookie = NULL;
 
+/** gateway container cookie */
+static struct olsr_cookie_info *gw_container_entry_mem_cookie = NULL;
+
 /** the gateway netmask for the HNA */
 static uint8_t smart_gateway_netmask[sizeof(union olsr_ip_addr)];
 
@@ -38,16 +47,10 @@ static uint8_t smart_gateway_netmask[sizeof(union olsr_ip_addr)];
 static struct olsr_gw_handler *gw_handler;
 
 /** the current IPv4 gateway */
-static struct gateway_entry *current_ipv4_gw;
-
-/** the tunnel of the current IPv4  gateway */
-static struct olsr_iptunnel_entry *v4gw_tunnel;
+static struct gw_container_entry *current_ipv4_gw;
 
 /** the current IPv6 gateway */
-static struct gateway_entry *current_ipv6_gw;
-
-/** the tunnel of the current IPv6  gateway */
-static struct olsr_iptunnel_entry *v6gw_tunnel;
+static struct gw_container_entry *current_ipv6_gw;
 
 /*
  * Forward Declarations
@@ -160,13 +163,13 @@ int olsr_init_gateways(void) {
   gateway_entry_mem_cookie = olsr_alloc_cookie("gateway_entry_mem_cookie", OLSR_COOKIE_TYPE_MEMORY);
   olsr_cookie_set_memory_size(gateway_entry_mem_cookie, sizeof(struct gateway_entry));
 
-  avl_init(&gateway_tree, avl_comp_default);
+  gw_container_entry_mem_cookie = olsr_alloc_cookie("gw_container_entry_mem_cookie", OLSR_COOKIE_TYPE_MEMORY);
+  olsr_cookie_set_memory_size(gw_container_entry_mem_cookie, sizeof(struct gw_container_entry));
 
-  current_ipv4_gw = NULL;
-  v4gw_tunnel = NULL;
+  avl_init(&gateway_tree, avl_comp_default);
 
-  current_ipv6_gw = NULL;
-  v6gw_tunnel = NULL;
+  current_ipv4_gw = olsr_cookie_malloc(gw_container_entry_mem_cookie);
+  current_ipv6_gw = olsr_cookie_malloc(gw_container_entry_mem_cookie);
 
   gw_handler = NULL;
 
@@ -211,11 +214,16 @@ void olsr_cleanup_gateways(void) {
 
   /* there should be no more gateways */
   assert(!avl_walk_first(&gateway_tree));
+  assert(!current_ipv4_gw->gw);
+  assert(!current_ipv4_gw->tunnel);
+  assert(!current_ipv6_gw->gw);
+  assert(!current_ipv6_gw->tunnel);
 
   assert(gw_handler);
   gw_handler->cleanup();
   gw_handler = NULL;
 
+  olsr_free_cookie(gw_container_entry_mem_cookie);
   olsr_free_cookie(gateway_entry_mem_cookie);
 }
 
@@ -462,23 +470,23 @@ static void olsr_delete_gateway_tree_entry(struct gateway_entry * gw, uint8_t pr
       gw_handler->delete(gw);
 
       /* cleanup gateway if necessary */
-      if (current_ipv4_gw == gw) {
-        if (v4gw_tunnel) {
-          olsr_os_inetgw_tunnel_route(v4gw_tunnel->if_index, true, false);
-          olsr_os_del_ipip_tunnel(v4gw_tunnel);
-          v4gw_tunnel = NULL;
+      if (current_ipv4_gw->gw == gw) {
+        if (current_ipv4_gw->tunnel) {
+          olsr_os_inetgw_tunnel_route(current_ipv4_gw->tunnel->if_index, true, false);
+          olsr_os_del_ipip_tunnel(current_ipv4_gw->tunnel);
+          current_ipv4_gw->tunnel = NULL;
         }
 
-        current_ipv4_gw = NULL;
+        current_ipv4_gw->gw = NULL;
       }
-      if (current_ipv6_gw == gw) {
-        if (v6gw_tunnel) {
-          olsr_os_inetgw_tunnel_route(v6gw_tunnel->if_index, false, false);
-          olsr_os_del_ipip_tunnel(v6gw_tunnel);
-          v6gw_tunnel = NULL;
+      if (current_ipv6_gw->gw == gw) {
+        if (current_ipv6_gw->tunnel) {
+          olsr_os_inetgw_tunnel_route(current_ipv6_gw->tunnel->if_index, false, false);
+          olsr_os_del_ipip_tunnel(current_ipv6_gw->tunnel);
+          current_ipv6_gw->tunnel = NULL;
         }
 
-        current_ipv6_gw = NULL;
+        current_ipv6_gw->gw = NULL;
       }
 
       if (!immediate) {
@@ -502,12 +510,12 @@ void olsr_trigger_gatewayloss_check(void) {
   bool ipv4 = false;
   bool ipv6 = false;
 
-  if (current_ipv4_gw) {
-    struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv4_gw->originator);
+  if (current_ipv4_gw->gw) {
+    struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv4_gw->gw->originator);
     ipv4 = (tc == NULL || tc->path_cost == ROUTE_COST_BROKEN);
   }
-  if (current_ipv6_gw) {
-    struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv6_gw->originator);
+  if (current_ipv6_gw->gw) {
+    struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv6_gw->gw->originator);
     ipv6 = (tc == NULL || tc->path_cost == ROUTE_COST_BROKEN);
   }
 
@@ -545,16 +553,16 @@ bool olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6)
   }
 
   /* handle IPv4 */
-  if (ipv4 && new_gw->ipv4 && (!new_gw->ipv4nat || olsr_cnf->smart_gw_allow_nat) && current_ipv4_gw != new_gw) {
+  if (ipv4 && new_gw->ipv4 && (!new_gw->ipv4nat || olsr_cnf->smart_gw_allow_nat) && current_ipv4_gw->gw != new_gw) {
     struct olsr_iptunnel_entry *new_v4gw_tunnel = olsr_os_add_ipip_tunnel(&new_gw->originator, true);
     if (new_v4gw_tunnel) {
       olsr_os_inetgw_tunnel_route(new_v4gw_tunnel->if_index, true, true);
-      if (v4gw_tunnel) {
-        olsr_os_del_ipip_tunnel(v4gw_tunnel);
-        v4gw_tunnel = NULL;
+      if (current_ipv4_gw->tunnel) {
+        olsr_os_del_ipip_tunnel(current_ipv4_gw->tunnel);
+        current_ipv4_gw->tunnel = NULL;
       }
-      current_ipv4_gw = new_gw;
-      v4gw_tunnel = new_v4gw_tunnel;
+      current_ipv4_gw->gw = new_gw;
+      current_ipv4_gw->tunnel = new_v4gw_tunnel;
     } else {
       /* adding the tunnel failed, we try again in the next cycle */
       ipv4 = false;
@@ -562,16 +570,16 @@ bool olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6)
   }
 
   /* handle IPv6 */
-  if (ipv6 && new_gw->ipv6 && current_ipv6_gw != new_gw) {
+  if (ipv6 && new_gw->ipv6 && current_ipv6_gw->gw != new_gw) {
     struct olsr_iptunnel_entry *new_v6gw_tunnel = olsr_os_add_ipip_tunnel(&new_gw->originator, false);
                if (new_v6gw_tunnel) {
                        olsr_os_inetgw_tunnel_route(new_v6gw_tunnel->if_index, false, true);
-                       if (v6gw_tunnel) {
-                               olsr_os_del_ipip_tunnel(v6gw_tunnel);
-                               v6gw_tunnel = NULL;
+                       if (current_ipv6_gw->tunnel) {
+                               olsr_os_del_ipip_tunnel(current_ipv6_gw->tunnel);
+                               current_ipv6_gw->tunnel = NULL;
                        }
-                       current_ipv6_gw = new_gw;
-                       v6gw_tunnel = new_v6gw_tunnel;
+                       current_ipv6_gw->gw = new_gw;
+                       current_ipv6_gw->tunnel = new_v6gw_tunnel;
                } else {
                        /* adding the tunnel failed, we try again in the next cycle */
                        ipv6 = false;
@@ -589,10 +597,10 @@ bool olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6)
  */
 struct gateway_entry *olsr_get_inet_gateway(bool ipv6) {
        if (ipv6) {
-               return current_ipv6_gw;
+               return current_ipv6_gw->gw;
        }
 
-       return current_ipv4_gw;
+       return current_ipv4_gw->gw;
 }
 
 #endif /* __linux__ */