Implement delayed MPR recalculation
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Wed, 15 Feb 2017 12:42:11 +0000 (13:42 +0100)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Wed, 15 Feb 2017 12:42:11 +0000 (13:42 +0100)
src-plugins/nhdp/nhdp/nhdp_db.c
src-plugins/nhdp/nhdp/nhdp_domain.c
src-plugins/nhdp/nhdp/nhdp_domain.h
src-plugins/nhdp/nhdp/nhdp_reader.c
src-plugins/nhdp/nhdp/nhdp_writer.c

index 2c099de..55d48d8 100644 (file)
@@ -277,7 +277,7 @@ nhdp_db_neighbor_remove(struct nhdp_neighbor *neigh) {
 
   if (was_mpr) {
     /* all domains might have changed */
-    nhdp_domain_recalculate_mpr(NULL, neigh);
+    nhdp_domain_delayed_mpr_recalculation(NULL, neigh);
   }
 
   /* remove from global list and free memory */
@@ -856,7 +856,7 @@ nhdp_db_link_update_status(struct nhdp_link *lnk) {
     /* link status was changed */
     lnk->last_status_change = oonf_clock_getNow();
     nhdp_domain_recalculate_metrics(NULL, lnk->neigh);
-    nhdp_domain_recalculate_mpr(NULL, lnk->neigh);
+    nhdp_domain_delayed_mpr_recalculation(NULL, lnk->neigh);
 
     /* trigger change event */
     oonf_class_event(&_link_info, lnk, OONF_OBJECT_CHANGED);
index 0339620..c0247e2 100644 (file)
@@ -72,8 +72,7 @@ static void _cb_update_everyone_flooding_mpr(struct nhdp_domain *domain);
 
 static bool _recalculate_neighbor_metric(struct nhdp_domain *domain,
         struct nhdp_neighbor *neigh);
-static bool _recalculate_routing_mpr_set(struct nhdp_domain *domain,
-    struct nhdp_neighbor *neigh);
+static bool _recalculate_routing_mpr_set(struct nhdp_domain *domain);
 static bool _recalculate_flooding_mpr_set(void);
 
 static const char *_link_to_string(struct nhdp_metric_str *, uint32_t);
@@ -539,51 +538,58 @@ nhdp_domain_recalculate_metrics(struct nhdp_domain *domain, struct nhdp_neighbor
   return _recalculate_metrics(domain, neigh, true);
 }
 
-static bool
-_recalculate_mpr(struct nhdp_domain *domain, struct nhdp_neighbor *neigh, bool trigger) {
+static void
+_fire_mpr_changed(struct nhdp_domain *domain) {
   struct nhdp_domain_listener *listener;
-  bool changed_mpr;
-
-  if (trigger) {
-    OONF_DEBUG(LOG_NHDP, "Recalculating MPR set for domain %d",
-        domain ? domain->index : -1);
+  list_for_each_element(&_domain_listener_list, listener, _node) {
+    /* trigger domain listeners */
+    if (listener->mpr_update) {
+      listener->mpr_update(domain);
+    }
   }
+}
 
-  changed_mpr = false;
-  if (!domain) {
-    list_for_each_element(&_domain_list, domain, _node) {
-      changed_mpr |= _recalculate_mpr(domain, neigh, false);
+void
+nhdp_domain_recalculate_mpr(void) {
+  struct nhdp_domain *domain;
+
+  list_for_each_element(&_domain_list, domain, _node) {
+    if (domain->_mpr_outdated) {
+      if (_recalculate_routing_mpr_set(domain)) {
+        domain->mpr->update_routing_mpr(domain);
+        _fire_mpr_changed(domain);
+      }
+      domain->_mpr_outdated = false;
     }
-    changed_mpr |= _recalculate_mpr(&_flooding_domain, neigh, false);
   }
-  else {
-    if (&_flooding_domain == domain) {
-      changed_mpr = _recalculate_flooding_mpr_set();
-    }
-    else {
-      changed_mpr = _recalculate_routing_mpr_set(domain, neigh);
+  if (_flooding_domain._mpr_outdated) {
+    if (_recalculate_flooding_mpr_set()) {
+      _flooding_domain.mpr->update_flooding_mpr(&_flooding_domain);
+      _fire_mpr_changed(&_flooding_domain);
     }
+    _flooding_domain._mpr_outdated = false;
   }
+}
 
-  if (trigger && changed_mpr) {
-    list_for_each_element(&_domain_listener_list, listener, _node) {
-      /* trigger domain listeners */
-      if (listener->mpr_update) {
-        listener->mpr_update(domain);
-      }
+/**
+ * This marks a MPR domain as 'to be recalculated' as soon as a Hello is sent
+ * @param domain NHDP domain
+ * @param neigh neighbor that triggered the recalculation,
+ *   NULL for unspecified neighbor
+ * @return
+ */
+void
+nhdp_domain_delayed_mpr_recalculation(struct nhdp_domain *domain,
+    struct nhdp_neighbor *neigh __attribute__((unused))) {
+  if (!domain) {
+    list_for_each_element(&_domain_list, domain, _node) {
+      nhdp_domain_delayed_mpr_recalculation(domain, neigh);
     }
+    nhdp_domain_delayed_mpr_recalculation(&_flooding_domain, neigh);
+    return;
   }
 
-  if (trigger) {
-    OONF_INFO(LOG_NHDP, "MPR changed for domain %d: %s",
-        domain ? domain->index : -1, changed_mpr ? "true" : "false");
-  }
-  return changed_mpr;
-}
-
-bool
-nhdp_domain_recalculate_mpr(struct nhdp_domain *domain, struct nhdp_neighbor *neigh) {
-  return _recalculate_mpr(domain, neigh, true);
+  domain->_mpr_outdated = true;
 }
 
 /**
@@ -975,24 +981,17 @@ _recalculate_flooding_mpr_set(void) {
 /**
  * Recalculate the MPR set of a NHDP domain
  * @param domain nhdp domain
- * @param neigh only recalculate if this neighbor is MPR
  * @return true if the MPR set changed
  */
 static bool
-_recalculate_routing_mpr_set(struct nhdp_domain *domain, struct nhdp_neighbor *neigh) {
+_recalculate_routing_mpr_set(struct nhdp_domain *domain) {
   struct nhdp_neighbor_domaindata *neighdata;
+  struct nhdp_neighbor *neigh;
 
   if (!domain->mpr->update_routing_mpr) {
     return false;
   }
 
-  if (neigh) {
-    neighdata = nhdp_domain_get_neighbordata(domain, neigh);
-    if (!neighdata->neigh_is_mpr) {
-      return false;
-    }
-  }
-
   /* remember old MPR set */
   list_for_each_element(nhdp_db_get_neigh_list(), neigh, _global_node) {
     neighdata = nhdp_domain_get_neighbordata(domain, neigh);
index 0c4012f..5d06d70 100644 (file)
@@ -215,6 +215,9 @@ struct nhdp_domain {
   /*! index in the domain array */
   int index;
 
+  /*! true if MPR should be recalculated */
+  bool _mpr_outdated;
+
   /*! temporary storage for willingness processing */
   uint8_t _tmp_willingness;
 
@@ -231,15 +234,13 @@ struct nhdp_domain {
 struct nhdp_domain_listener {
     /**
      * Callback to inform about a NHDP neighbor MPR update
-     * @param domain NHDP domain of which the MPR set changed,
-     *   NULL for all domains
+     * @param domain NHDP domain of which the MPR set changed
      */
     void (*mpr_update)(struct nhdp_domain *domain);
 
     /**
      * Callback to inform about a NHDP neighbor metric update
-     * @param domain NHDP domain of which the metric changed,
-     *   NULL for all domains
+     * @param domain NHDP domain of which the metric changed
      */
     void (*metric_update)(struct nhdp_domain *domain);
 
@@ -319,8 +320,9 @@ EXPORT bool nhdp_domain_recalculate_metrics(
     struct nhdp_domain *domain, struct nhdp_neighbor *neigh);
 
 EXPORT bool nhdp_domain_node_is_mpr(void);
-EXPORT bool nhdp_domain_recalculate_mpr(
+EXPORT void nhdp_domain_delayed_mpr_recalculation(
     struct nhdp_domain *domain, struct nhdp_neighbor *neigh);
+EXPORT void nhdp_domain_recalculate_mpr(void);
 
 EXPORT struct list_entity *nhdp_domain_get_list(void);
 EXPORT struct list_entity *nhdp_domain_get_listener_list(void);
index f9b119c..5158d0b 100644 (file)
@@ -976,8 +976,9 @@ _cb_msg_pass2_end(struct rfc5444_reader_tlvblock_context *context, bool dropped)
   /* update link status */
   nhdp_db_link_update_status(_current.link);
 
-  /* update link metrics */
+  /* update link metrics and MPR */
   nhdp_domain_recalculate_metrics(NULL, _current.neighbor);
+  nhdp_domain_delayed_mpr_recalculation(NULL, _current.neighbor);
 
   return RFC5444_OKAY;
 }
index 8b0a17e..40e7f06 100644 (file)
@@ -172,7 +172,7 @@ nhdp_writer_send_hello(struct nhdp_interface *ninterf) {
   OONF_DEBUG(LOG_NHDP_W, "Sending Hello to interface %s",
       nhdp_interface_get_name(ninterf));
 
-  nhdp_domain_recalculate_mpr(NULL, NULL);
+  nhdp_domain_recalculate_mpr();
 
   /* store NHDP interface */
   _nhdp_if = ninterf;