retry route updates, and failure counter
authorMarkus Kittenberger <markus@markit.unassigned-domain>
Thu, 11 Nov 2010 23:18:47 +0000 (00:18 +0100)
committerMarkus Kittenberger <markus@markit.unassigned-domain>
Thu, 11 Nov 2010 23:18:47 +0000 (00:18 +0100)
lib/txtinfo/src/olsrd_txtinfo.c
src/process_routes.c
src/routing_table.h

index 100b059..185ea76 100644 (file)
@@ -137,6 +137,7 @@ static const char KEY_2HOP[] = "2hop";
 static const char KEY_LINKCOST[] = "linkcost";
 static const char KEY_RAWLINKCOST[] = "rawlinkcost";
 static const char KEY_HOPCOUNT[] = "hopcount";
+static const char KEY_FAILCOUNT[] = "failcount";
 static const char KEY_INTERFACE[] = "interface";
 static const char KEY_VTIME[] = "vtime";
 static const char KEY_STATE[] = "state";
@@ -152,6 +153,7 @@ static char buf_2hop[6];
 static char buf_rawlinkcost[11];
 static char buf_linkcost[LQTEXT_MAXLENGTH];
 static char buf_hopcount[4];
+static char buf_failcount[8];
 static char buf_state[5];
 static char buf_mtu[5];
 static char buf_interface[IF_NAMESIZE];
@@ -181,14 +183,14 @@ static char *values_neigh[] = {
   buf_neighip.buf, buf_sym, buf_mprs, buf_mprs, buf_willingness, buf_2hop
 };
 
-static const char *tmpl_routes = "%destprefix%\t%neighip%\t%hopcount%\t%linkcost%\t%interface%\n";
+static const char *tmpl_routes = "%destprefix%\t%neighip%\t%hopcount%\t%linkcost%\t%interface%\t%failcount%\n";
 static const char *keys_routes[] = {
   KEY_DESTPREFIX, KEY_NEIGHIP, KEY_HOPCOUNT, KEY_VTIME,
-  KEY_INTERFACE, KEY_RAWLINKCOST, KEY_LINKCOST
+  KEY_INTERFACE, KEY_RAWLINKCOST, KEY_LINKCOST, KEY_FAILCOUNT
 };
 static char *values_routes[] = {
   buf_destprefix.buf, buf_neighip.buf, buf_hopcount, buf_vtime.buf,
-  buf_interface, buf_rawlinkcost, buf_linkcost
+  buf_interface, buf_rawlinkcost, buf_linkcost, buf_failcount
 };
 
 static const char *tmpl_topology = "%neighip%\t%localip%\t%isvirtual%\t%linkcost%\n";
@@ -481,6 +483,11 @@ txtinfo_routes(struct comport_connection *con,
     }
     olsr_ip_prefix_to_string(&buf_destprefix, &rt->rt_dst);
     olsr_ip_to_string(&buf_neighip, &rt->rt_best->rtp_nexthop.gateway);
+
+    if (rt->failure_count < 0)  snprintf(buf_failcount, sizeof(buf_failcount), "%d del", rt->failure_count*(-1));
+    else if (rt->failure_count == 0) snprintf(buf_failcount, sizeof(buf_failcount), "0");
+    else snprintf(buf_failcount, sizeof(buf_failcount), "%d add", rt->failure_count);
+
     snprintf(buf_hopcount, sizeof(buf_hopcount), "%d", rt->rt_best->rtp_metric.hops);
     snprintf(buf_rawlinkcost, sizeof(buf_rawlinkcost), "%ud", rt->rt_best->rtp_metric.cost);
     olsr_get_linkcost_text(rt->rt_best->rtp_metric.cost, true, buf_linkcost, sizeof(buf_linkcost));
index dad6f1a..1a55c36 100644 (file)
@@ -46,7 +46,6 @@
 #include <errno.h>
 
 static struct list_entity chg_kernel_list;
-static struct list_entity del_kernel_list;
 
 /*
  * Function hooks for plugins to intercept
@@ -55,6 +54,8 @@ static struct list_entity del_kernel_list;
 export_route_function olsr_add_route_function;
 export_route_function olsr_del_route_function;
 
+#define MAX_FAILURE_COUNT 10000 //should be FAILURE_LESS_NOISE_COUNT * (int)x
+#define FAILURE_LESS_NOISE_COUNT 100 //after x errors only every x errors this is written to log
 
 void
 olsr_init_export_route(void)
@@ -63,7 +64,6 @@ olsr_init_export_route(void)
 
   /* the add/chg and del kernel queues */
   list_init_head(&chg_kernel_list);
-  list_init_head(&del_kernel_list);
 
   olsr_add_route_function = os_route_add_rtentry;
   olsr_del_route_function = os_route_del_rtentry;
@@ -90,14 +90,14 @@ olsr_delete_all_kernel_routes(void)
 /**
  * Enqueue a route on a kernel chg/del queue.
  */
-static void
+static int
 olsr_enqueue_rt(struct list_entity *head_node, struct rt_entry *rt)
 {
   const struct rt_nexthop *nh;
 
   /* if this node is already on some changelist we are done */
   if (list_node_added(&rt->rt_change_node)) {
-    return;
+    return -1;
   }
 
   /*
@@ -111,25 +111,52 @@ olsr_enqueue_rt(struct list_entity *head_node, struct rt_entry *rt)
   } else {
     list_add_before(head_node, &rt->rt_change_node);
   }
+
+  return 0;
 }
 
 /**
- * Process a route from the kernel deletion list.
+ * Process a route deletion
  *
- *@return nada
+ *@return actual error count
  */
-static void
+static int
 olsr_del_route(struct rt_entry *rt)
 {
-  int16_t error = olsr_del_route_function(rt, olsr_cnf->ip_version);
+  int16_t error;
+  if (rt->rt_nexthop.interface == NULL) return 0;
+
+  error = olsr_del_route_function(rt, olsr_cnf->ip_version);
+
+  if (error != 0) {
+    if (rt->failure_count>0) {
+      /*ignore if we failed to delete a route we never successfully created*/
+      OLSR_WARN(LOG_ROUTING, "KERN: SUCCESFULLY failed to delete unexisting %s: %s\n", olsr_rt_to_string(rt), strerror(errno));
+      rt->failure_count=0;
+    } else {
+     rt->failure_count--;
+
+     /*rate limit error messages*/
+     if ( (rt->failure_count >= -FAILURE_LESS_NOISE_COUNT ) || (rt->failure_count % FAILURE_LESS_NOISE_COUNT == 0) )
+       OLSR_ERROR(LOG_ROUTING, "KERN: ERROR on %d attempt to delete %s: %s\n", rt->failure_count*(-1), olsr_rt_to_string(rt), strerror(errno));
+
+     /*stop trying it*/
+     if (rt->failure_count <= -MAX_FAILURE_COUNT)  {
+       OLSR_ERROR(LOG_ROUTING, " WILL NOT TRY AGAIN!!\n==============\n");
+       rt->failure_count=0;
+     }
+    }
 
-  if (error < 0) {
-    OLSR_WARN(LOG_ROUTING, "KERN: ERROR deleting %s: %s\n", olsr_rt_to_string(rt), strerror(errno));
   } else {
+    if (rt->failure_count > 1)
+      OLSR_WARN(LOG_ROUTING, "KERN: SUCCESS on %d attempt to delete %s: %s\n", rt->failure_count*(-1), olsr_rt_to_string(rt), strerror(errno));
 
+    rt->failure_count=0;
     /* release the interface. */
     unlock_interface(rt->rt_nexthop.interface);
   }
+
+  return rt->failure_count;
 }
 
 /**
@@ -140,8 +167,18 @@ olsr_del_route(struct rt_entry *rt)
 static void
 olsr_add_route(struct rt_entry *rt)
 {
-  if (0 > olsr_add_route_function(rt, olsr_cnf->ip_version)) {
-    OLSR_WARN(LOG_ROUTING, "KERN: ERROR adding %s: %s\n", olsr_rtp_to_string(rt->rt_best), strerror(errno));
+  rt->failure_count++;
+
+  if (0 != olsr_add_route_function(rt, olsr_cnf->ip_version)) {
+    /*rate limit error messages*/
+    if ( (rt->failure_count <= FAILURE_LESS_NOISE_COUNT ) || (rt->failure_count % FAILURE_LESS_NOISE_COUNT == 0) )
+      OLSR_ERROR(LOG_ROUTING, "KERN: ERROR on %d attempt to add %s: %s\n", rt->failure_count, olsr_rtp_to_string(rt->rt_best), strerror(errno));
+
+    /*stop trying it*/
+    if (rt->failure_count >= MAX_FAILURE_COUNT)  {
+       OLSR_ERROR(LOG_ROUTING, " WILL NOT TRY AGAIN!!\n==============\n");
+       rt->failure_count=0;
+     }
   } else {
     /* route addition has suceeded */
 
@@ -151,6 +188,11 @@ olsr_add_route(struct rt_entry *rt)
 
     /* lock the interface such that it does not vanish underneath us */
     lock_interface(rt->rt_nexthop.interface);
+
+    /*reset failure_counter and print info if we needed more than once*/
+    if (rt->failure_count > 1)
+      OLSR_WARN(LOG_ROUTING, "KERN: SUCCESS on %d attmpt to add %s: %s\n", rt->failure_count, olsr_rtp_to_string(rt->rt_best), strerror(errno));
+    rt->failure_count=0;
   }
 }
 
@@ -186,34 +228,6 @@ olsr_chg_kernel_routes(struct list_entity *head_node)
   }
 }
 
-/**
- * process the kernel delete list.
- * the routes are already ordered such that nexthop routes
- * are on the head of the queue.
- * non-nexthop routes need to be deleted first and therefore
- * the queue needs to be traversed from tail to head.
- */
-static void
-olsr_del_kernel_routes(struct list_entity *head_node)
-{
-  struct rt_entry *rt;
-  struct list_iterator iterator;
-
-  OLSR_FOR_ALL_RTLIST_ENTRIES(head_node, rt, iterator) {
-    /*
-     * Only attempt to delete the route from kernel if it was
-     * installed previously. A reference to the interface gets
-     * set only when a route installation suceeds.
-     */
-    if (rt->rt_nexthop.interface) {
-      olsr_del_route(rt);
-    }
-
-    list_remove(&rt->rt_change_node);
-    olsr_cookie_free(rt_mem_cookie, rt);
-  }
-}
-
 /**
  * Check the version number of all route paths hanging off a route entry.
  * If a route does not match the current routing tree number, remove it
@@ -265,11 +279,9 @@ olsr_update_rib_routes(void)
     olsr_delete_outdated_routes(rt);
 
     if (!rt->rt_path_tree.count) {
-
       /* oops, all routes are gone - flush the route head */
-      avl_delete(&routingtree, &rt->rt_tree_node);
+      if (olsr_del_route(rt) == 0) avl_delete(&routingtree, &rt->rt_tree_node);
 
-      olsr_enqueue_rt(&del_kernel_list, rt);
       continue;
     }
 
@@ -293,9 +305,6 @@ void
 olsr_update_kernel_routes(void)
 {
 
-  /* delete unreachable routes */
-  olsr_del_kernel_routes(&del_kernel_list);
-
   /* route changes and additions */
   olsr_chg_kernel_routes(&chg_kernel_list);
 
index 2126212..9cede0a 100644 (file)
@@ -88,6 +88,7 @@ struct rt_entry {
   struct rt_metric rt_metric;          /* metric of FIB route */
   struct avl_tree rt_path_tree;
   struct list_entity rt_change_node;     /* queue for kernel FIB add/chg/del */
+  int failure_count;
 };
 
 #define OLSR_FOR_ALL_RTLIST_ENTRIES(head, rt_entry, iterator) list_for_each_element_safe(head, rt_entry, rt_change_node, iterator.loop, iterator.safe)