Fixing default behavior of routing core to ignore links that are not initialized...
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Tue, 17 May 2016 14:18:21 +0000 (16:18 +0200)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Tue, 17 May 2016 14:18:21 +0000 (16:18 +0200)
Force IPv6 linklocal IP addresses for binding socket

src-plugins/nhdp/ff_dat_metric/ff_dat_metric.c
src-plugins/nhdp/ff_dat_metric/ff_dat_metric.h
src-plugins/nhdp/mpr/mpr.c
src-plugins/nhdp/nhdp/nhdp_domain.c
src-plugins/nhdp/nhdp/nhdp_domain.h
src-plugins/nhdp/nhdp/nhdp_writer.c
src-plugins/olsrv2/lan_import/lan_import.c
src-plugins/olsrv2/olsrv2/olsrv2_reader.c
src-plugins/olsrv2/olsrv2/olsrv2_routing.c
src-plugins/olsrv2/olsrv2/olsrv2_writer.c
src-plugins/subsystems/oonf_rfc5444.c

index 09df780..2e09f68 100644 (file)
@@ -312,8 +312,6 @@ static struct nhdp_domain_metric _datff_handler = {
   .metric_minimum = DATFF_LINKCOST_MINIMUM,
   .metric_maximum = DATFF_LINKCOST_MAXIMUM,
 
-  .incoming_link_start = DATFF_LINKCOST_START,
-
   .link_to_string = _link_to_string,
   .path_to_string = _path_to_string,
   .internal_link_to_string = _int_link_to_string,
index 8258ba4..41b1d38 100644 (file)
@@ -64,7 +64,6 @@ enum {
   DATFF_LINKSPEED_RANGE = 1<<21,
 
   /* basic statistics of the metric */
-  DATFF_LINKCOST_START    = RFC7181_METRIC_MAX,
   DATFF_LINKCOST_MINIMUM  = RFC7181_METRIC_MIN,
   DATFF_LINKCOST_MAXIMUM  = RFC7181_METRIC_MAX,
 };
index fa9392b..ca82c49 100644 (file)
@@ -99,8 +99,6 @@ DECLARE_OONF_PLUGIN(_nhdp_mpr_subsystem);
 static struct nhdp_domain_mpr _mpr_handler = {
   .name = OONF_MPR_SUBSYSTEM,
   .update_mpr = _cb_update_mpr,
-  .mpr_start = false,
-  .mprs_start = false,
 };
 
 /**
index a20e566..01cdd50 100644 (file)
@@ -101,9 +101,6 @@ static struct nhdp_domain_metric _no_metric = {
 static struct nhdp_domain_mpr _everyone_mprs = {
   .name = "Everyone MPR",
 
-  .mpr_start = true,
-  .mprs_start = true,
-
   .update_mpr = _cb_update_everyone_mpr,
 };
 
@@ -336,14 +333,16 @@ nhdp_domain_init_link(struct nhdp_link *lnk) {
 
   /* initialize metrics */
   for (i=0; i<NHDP_MAXIMUM_DOMAINS; i++) {
-    lnk->_domaindata[i].metric.in = RFC7181_METRIC_MAX;
-    lnk->_domaindata[i].metric.out = RFC7181_METRIC_MAX;
+    lnk->_domaindata[i].metric.in = RFC7181_METRIC_INFINITE;
+    lnk->_domaindata[i].metric.out = RFC7181_METRIC_INFINITE;
   }
   list_for_each_element(&_domain_list, domain, _node) {
     data = nhdp_domain_get_linkdata(domain, lnk);
 
-    data->metric.in = domain->metric->incoming_link_start;
-    data->metric.out = domain->metric->outgoing_link_start;
+    if (domain->metric->no_default_handling) {
+      data->metric.in = domain->metric->incoming_link_start;
+      data->metric.out = domain->metric->outgoing_link_start;
+    }
   }
 }
 
@@ -359,15 +358,17 @@ nhdp_domain_init_l2hop(struct nhdp_l2hop *l2hop) {
 
   /* initialize metrics */
   for (i=0; i<NHDP_MAXIMUM_DOMAINS; i++) {
-    l2hop->_domaindata[i].metric.in = RFC7181_METRIC_MAX;
-    l2hop->_domaindata[i].metric.out = RFC7181_METRIC_MAX;
+    l2hop->_domaindata[i].metric.in = RFC7181_METRIC_INFINITE;
+    l2hop->_domaindata[i].metric.out = RFC7181_METRIC_INFINITE;
   }
 
   list_for_each_element(&_domain_list, domain, _node) {
     data = nhdp_domain_get_l2hopdata(domain, l2hop);
 
-    data->metric.in = domain->metric->incoming_2hop_start;
-    data->metric.out = domain->metric->outgoing_2hop_start;
+    if (domain->metric->no_default_handling) {
+      data->metric.in = domain->metric->incoming_2hop_start;
+      data->metric.out = domain->metric->outgoing_2hop_start;
+    }
   }
 }
 
@@ -383,26 +384,29 @@ nhdp_domain_init_neighbor(struct nhdp_neighbor *neigh) {
 
   /* initialize flooding MPR settings */
   neigh->flooding_willingness = RFC7181_WILLINGNESS_NEVER;
-  neigh->local_is_flooding_mpr = _flooding_domain.mpr->mprs_start;
-  neigh->neigh_is_flooding_mpr = _flooding_domain.mpr->mpr_start;
+  neigh->local_is_flooding_mpr = false;
+  neigh->neigh_is_flooding_mpr = false;
 
   for (i=0; i<NHDP_MAXIMUM_DOMAINS; i++) {
-    neigh->_domaindata[i].metric.in = RFC7181_METRIC_MAX;
-    neigh->_domaindata[i].metric.out = RFC7181_METRIC_MAX;
+    neigh->_domaindata[i].metric.in = RFC7181_METRIC_INFINITE;
+    neigh->_domaindata[i].metric.out = RFC7181_METRIC_INFINITE;
+
+    neigh->_domaindata[i].best_link = NULL;
+    neigh->_domaindata[i].willingness = RFC7181_WILLINGNESS_NEVER;
+
+
+    neigh->_domaindata[i].local_is_mpr = false;
+    neigh->_domaindata[i].neigh_is_mpr = false;
   }
 
   /* initialize metrics and mprs */
   list_for_each_element(&_domain_list, domain, _node) {
     data = nhdp_domain_get_neighbordata(domain, neigh);
 
-    data->metric.in = domain->metric->incoming_link_start;
-    data->metric.out = domain->metric->outgoing_link_start;
-
-    data->best_link = NULL;
-
-    data->willingness = RFC7181_WILLINGNESS_NEVER;
-    data->local_is_mpr = domain->mpr->mprs_start;
-    data->neigh_is_mpr = domain->mpr->mpr_start;
+    if (domain->metric->no_default_handling) {
+      data->metric.in = domain->metric->incoming_link_start;
+      data->metric.out = domain->metric->outgoing_link_start;
+    }
   }
 }
 
@@ -901,6 +905,7 @@ _recalculate_neighbor_metric(
   struct nhdp_link_domaindata *linkdata;
   struct nhdp_neighbor_domaindata *neighdata;
   struct nhdp_metric oldmetric;
+  struct netaddr_str nbuf;
 
   neighdata = nhdp_domain_get_neighbordata(domain, neigh);
 
@@ -913,21 +918,33 @@ _recalculate_neighbor_metric(
 
   /* reset best link */
   neighdata->best_link = NULL;
+  neighdata->best_link_ifindex = 0;
+
+  OONF_DEBUG(LOG_NHDP, "Recalculate neighbor %s metrics (ext %u):",
+      netaddr_to_string(&nbuf, &neigh->originator), domain->ext);
 
   /* get best metric */
   list_for_each_element(&neigh->_links, lnk, _neigh_node) {
     linkdata = nhdp_domain_get_linkdata(domain, lnk);
-
     if (linkdata->metric.out < neighdata->metric.out) {
+      OONF_DEBUG(LOG_NHDP, "Link on if %s has better outgoing metric: %u",
+              lnk->local_if->os_if_listener.data->name,
+              linkdata->metric.out);
+
       neighdata->metric.out = linkdata->metric.out;
       neighdata->best_link = lnk;
     }
     if (linkdata->metric.in < neighdata->metric.in) {
+      OONF_DEBUG(LOG_NHDP, "Link on if %s has better incoming metric: %u",
+              lnk->local_if->os_if_listener.data->name,
+              linkdata->metric.in);
       neighdata->metric.in = linkdata->metric.in;
     }
   }
 
   if (neighdata->best_link != NULL) {
+    OONF_DEBUG(LOG_NHDP, "Best link if: %s",
+        nhdp_interface_get_if_listener(neighdata->best_link->local_if)->data->name);
     neighdata->best_link_ifindex =
         nhdp_interface_get_if_listener(neighdata->best_link->local_if)->data->index;
   }
index 79a25c3..7919df2 100644 (file)
@@ -88,16 +88,16 @@ struct nhdp_domain_metric {
   /*! maximum metric value */
   uint32_t metric_maximum;
 
-  /*! default incoming link metric */
+  /*! default incoming link metric for "no default handling" metrics */
   uint32_t incoming_link_start;
 
-  /*! default outgoing link metric */
+  /*! default outgoing link metric for "no default handling" metrics */
   uint32_t outgoing_link_start;
 
-  /*! default incoming 2-hop link metric */
+  /*! default incoming 2-hop link metric for "no default handling" metrics */
   uint32_t incoming_2hop_start;
 
-  /*! default outgoing 2-hop link metric */
+  /*! default outgoing 2-hop link metric for "no default handling" metrics */
   uint32_t outgoing_2hop_start;
 
   /*! true if metrics should not be handled by nhdp reader/writer */
@@ -170,12 +170,6 @@ struct nhdp_domain_mpr {
    */
   void (*disable)(void);
 
-  /*! default value for neighbor MPR setting */
-  bool mpr_start;
-
-  /*! default value for local MPR (selector) setting */
-  bool mprs_start;
-
   /*! reference count */
   int _refcount;
 
index 47f5d6b..7e04655 100644 (file)
@@ -463,6 +463,9 @@ _write_metric_tlv(struct rfc5444_writer *writer, struct rfc5444_writer_address *
       RFC7181_LINKMETRIC_INCOMING_NEIGH,
       RFC7181_LINKMETRIC_OUTGOING_NEIGH,
   };
+  static const char *lq_name[4] = {
+    "l_in", "l_out", "n_in", "n_out",
+  };
   struct nhdp_link_domaindata *linkdata;
   struct nhdp_neighbor_domaindata *neighdata;
   struct rfc7181_metric_field metric_encoded[4], tlv_value;
@@ -520,17 +523,20 @@ _write_metric_tlv(struct rfc5444_writer *writer, struct rfc5444_writer_address *
     rfc7181_metric_set_flag(&tlv_value, flags[i]);
 
     /* mark all metric pair that have the same linkmetric */
+    OONF_DEBUG(LOG_NHDP_W, "Add Metric %s (ext %u): 0x%02x%02x (%u)",
+        lq_name[i], domain->ext, tlv_value.b[0], tlv_value.b[1], metrics[i]);
+
     for (j=3; j>i; j--) {
       if (metrics[j] > 0 &&
           memcmp(&metric_encoded[i], &metric_encoded[j], sizeof(metric_encoded[0])) == 0) {
         rfc7181_metric_set_flag(&tlv_value, flags[j]);
         metrics[j] = 0;
+
+        OONF_DEBUG(LOG_NHDP_W, "Same metrics for %s (ext %u)",
+            lq_name[j], domain->ext);
       }
     }
 
-    OONF_DEBUG(LOG_NHDP_W, "Add Metric (ext %u): 0x%02x%02x (%u)",
-        domain->ext, tlv_value.b[0], tlv_value.b[1], metrics[i]);
-
     /* add to rfc5444 address */
     rfc5444_writer_add_addrtlv(writer, addr,
         &domain->_metric_addrtlvs[k++],
index 2ddb865..b5eee61 100644 (file)
@@ -110,8 +110,8 @@ static void _cb_cfg_changed(void);
 
 /* plugin declaration */
 static struct cfg_schema_entry _import_entries[] = {
-  CFG_MAP_INT32_MINMAX(_import_entry, domain, "domain", "0",
-      "Routing domain extension for filter", 0, false, 0, 255),
+  CFG_MAP_INT32_MINMAX(_import_entry, domain, "domain", "-1",
+      "Routing domain extension for filter, -1 for all domains", 0, false, -1, 255),
   CFG_MAP_ACL(_import_entry, filter, "matches",  ACL_DEFAULT_ACCEPT,
       "Ip addresses the filter should be applied to"
       " (the plugin will never import loopback, linklocal or multicast IPs)"),
@@ -244,6 +244,7 @@ _cb_rt_event(const struct os_route *route, bool set) {
   char ifname[IF_NAMESIZE];
   struct os_route_key ssprefix;
   const struct olsrv2_routing_domain *rtparam;
+  int metric;
 
 #ifdef OONF_LOG_DEBUG_INFO
   struct os_route_str rbuf;
@@ -313,6 +314,14 @@ _cb_rt_event(const struct os_route *route, bool set) {
     memcpy(&ssprefix.src, &route->p.key.src, sizeof(struct netaddr));
 
     if (set) {
+      metric = route->p.metric;
+      if (metric < 1) {
+        metric = 1;
+      }
+      if (metric > 255) {
+        metric = 255;
+      }
+
       list_for_each_element(nhdp_domain_get_list(), domain, _node) {
         rtparam = olsrv2_routing_get_parameters(domain);
         if (rtparam->protocol == route->p.protocol
@@ -324,16 +333,30 @@ _cb_rt_event(const struct os_route *route, bool set) {
       }
 
       OONF_DEBUG(LOG_LAN_IMPORT, "Add lan...");
-      domain = nhdp_domain_get_by_ext(import->domain);
-      if (domain) {
-        olsrv2_lan_add(domain, &ssprefix, 1, route->p.metric);
+      if (import->domain != -1) {
+        domain = nhdp_domain_get_by_ext(import->domain);
+        if (domain) {
+          olsrv2_lan_add(domain, &ssprefix, 1, (uint8_t)metric);
+        }
+      }
+      else {
+        list_for_each_element(nhdp_domain_get_list(), domain, _node) {
+          olsrv2_lan_add(domain, &ssprefix, 1, (uint8_t)metric);
+        }
       }
     }
     else {
       OONF_DEBUG(LOG_LAN_IMPORT, "Remove lan...");
-      domain = nhdp_domain_get_by_ext(import->domain);
-      if (domain) {
-        olsrv2_lan_remove(domain, &ssprefix);
+      if (import->domain != -1) {
+        domain = nhdp_domain_get_by_ext(import->domain);
+        if (domain) {
+          olsrv2_lan_remove(domain, &ssprefix);
+        }
+      }
+      else {
+        list_for_each_element(nhdp_domain_get_list(), domain, _node) {
+          olsrv2_lan_remove(domain, &ssprefix);
+        }
       }
     }
   }
index c9f27e3..bd54ef8 100644 (file)
@@ -412,7 +412,7 @@ _cb_addresstlvs(struct rfc5444_reader_tlvblock_context *context __attribute__((u
         OONF_DEBUG(LOG_OLSRV2_R, "Address is routable, but not originator");
         end->ansn = _current.node->ansn;
         for (i=0; i<NHDP_MAXIMUM_DOMAINS; i++) {
-          if (cost_out[i] < RFC7181_METRIC_INFINITE) {
+          if (cost_out[i] < RFC7181_METRIC_MAX) {
             end->cost[i] = cost_out[i];
           }
         }
@@ -489,8 +489,8 @@ _handle_gateways(struct rfc5444_reader_tlvblock_entry *tlv,
       end->distance[domain->index] = tlv->single_value[i];
     }
 
-    OONF_DEBUG(LOG_OLSRV2_R, "Address is Attached Network: dist=%u",
-        end->distance[domain->index]);
+    OONF_DEBUG(LOG_OLSRV2_R, "Address is Attached Network (domain %u): dist=%u",
+        domain->ext, end->distance[domain->index]);
   }
 }
 
index 38c6576..03fc225 100644 (file)
@@ -538,7 +538,7 @@ _update_routing_entry(struct nhdp_domain *domain,
   struct olsrv2_lan_entry *lan;
   struct olsrv2_lan_domaindata *landata;
 #ifdef OONF_LOG_DEBUG_INFO
-  struct netaddr_str nbuf1, nbuf2;
+  struct netaddr_str nbuf1, nbuf2, nbuf3;
 #endif
 
   /* test if destination is already part of the local node */
@@ -585,17 +585,18 @@ _update_routing_entry(struct nhdp_domain *domain,
   }
 
   neighdata = nhdp_domain_get_neighbordata(domain, first_hop);
-  OONF_DEBUG(LOG_OLSRV2_ROUTING, "Initialize route entry dst %s [%s] with pathcost %u",
-      netaddr_to_string(&nbuf1, &rtentry->route.p.key.dst),
-      netaddr_to_string(&nbuf2, &rtentry->route.p.key.src),
-      pathcost);
-
   /* copy route parameters into data structure */
   rtentry->route.p.if_index = neighdata->best_link_ifindex;
   rtentry->path_cost = pathcost;
   rtentry->path_hops = path_hops;
   rtentry->route.p.metric = distance;
 
+  OONF_DEBUG(LOG_OLSRV2_ROUTING, "Initialize route entry dst %s [%s] (firsthop %s, domain %u) with pathcost %u, if %s",
+      netaddr_to_string(&nbuf1, &rtentry->route.p.key.dst),
+      netaddr_to_string(&nbuf2, &rtentry->route.p.key.src),
+      netaddr_to_string(&nbuf3, &first_hop->originator),
+      domain->ext, pathcost, neighdata->best_link->local_if->os_if_listener.data->name);
+
   /* remember next hop originator */
   memcpy(&rtentry->next_originator, &first_hop->originator, sizeof(struct netaddr));
 
@@ -973,6 +974,7 @@ static void
 _process_dijkstra_result(struct nhdp_domain *domain) {
   struct olsrv2_routing_entry *rtentry;
   struct olsrv2_routing_filter *filter;
+  struct os_route_str rbuf1, rbuf2;
 
   avl_for_each_element(&_routing_tree[domain->index], rtentry, _node) {
     /* initialize rest of route parameters */
@@ -998,6 +1000,10 @@ _process_dijkstra_result(struct nhdp_domain *domain) {
     if (rtentry->set
         && memcmp(&rtentry->_old, &rtentry->route.p, sizeof(rtentry->_old)) == 0) {
       /* no change, ignore this entry */
+      OONF_INFO(LOG_OLSRV2_ROUTING,
+          "Ignore route change: %s -> %s",
+          os_routing_to_string(&rbuf1, &rtentry->_old),
+          os_routing_to_string(&rbuf2, &rtentry->route.p));
       continue;
     }
     _add_route_to_kernel_queue(rtentry);
index a0dc923..4c4462a 100644 (file)
@@ -502,7 +502,7 @@ _cb_addAddresses(struct rfc5444_writer *writer) {
     list_for_each_element(nhdp_domain_get_list(), domain, _node) {
       lan_data = olsrv2_lan_get_domaindata(domain, lan);
       metric_out = lan_data->outgoing_metric;
-      if (metric_out >= RFC7181_METRIC_INFINITE) {
+      if (metric_out > RFC7181_METRIC_MAX) {
         continue;
       }
 
index 716bbe0..8b61403 100644 (file)
@@ -188,7 +188,7 @@ static struct cfg_schema_entry _interface_entries[] = {
   CFG_MAP_ACL_V46(oonf_packet_managed_config, acl, "acl", ACL_DEFAULT_ACCEPT,
     "Access control list for RFC5444 interface"),
   CFG_MAP_ACL_V46(oonf_packet_managed_config, bindto, "bindto",
-      "-127.0.0.0/8\0" "-::1\0" ACL_DEFAULT_ACCEPT,
+      "-127.0.0.0/8\0" "-::1\0" "-2000::/3\0" ACL_DEFAULT_ACCEPT,
     "Bind RFC5444 socket to an address matching this filter (both IPv4 and IPv6)"),
   CFG_MAP_NETADDR_V4(oonf_packet_managed_config, multicast_v4, "multicast_v4", RFC5444_MANET_MULTICAST_V4_TXT,
     "ipv4 multicast address of this socket", false, true),