Allow "non-unicast" routes to be imported
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Mon, 6 Aug 2018 13:05:20 +0000 (15:05 +0200)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Mon, 6 Aug 2018 13:05:20 +0000 (15:05 +0200)
include/oonf/base/os_routing.h
src/base/os_generic/os_routing_generic_rt_to_string.c
src/generic/layer2_import/layer2_import.c

index 7b34548..e4d8960 100644 (file)
@@ -52,6 +52,8 @@
 #include <oonf/oonf.h>
 #include <oonf/libcommon/list.h>
 #include <oonf/libcommon/netaddr.h>
+#include <oonf/libconfig/cfg.h>
+#include <oonf/libconfig/cfg_schema.h>
 #include <oonf/libcore/oonf_logging.h>
 #include <oonf/base/os_interface.h>
 #include <oonf/base/os_system.h>
@@ -73,6 +75,7 @@ struct os_route_str;
 #define RT_TABLE_UNSPEC 0
 #endif
 
+
 /**
  * Struct for text representation of a route
  */
@@ -118,9 +121,34 @@ enum os_route_type
   OS_ROUTE_PROHIBIT,
   OS_ROUTE_BLACKHOLE,
   OS_ROUTE_NAT,
+  OS_ROUTE_COUNT
 };
 
 /**
+ * Creates a cfg_schema_entry for a parameter that can be choosen
+ * from the os routing types
+ * @param p_name parameter name
+ * @param p_def parameter default value
+ * @param p_help help text for configuration entry
+ * @param args variable list of additional arguments
+ */
+#define CFG_VALIDATE_OS_ROUTING_TYPE_KEY(p_name, p_def, p_help, args...)                                                    \
+  CFG_VALIDATE_CHOICE_CB_ARG(p_name, p_def, p_help, os_routing_cfg_get_rttype, OS_ROUTE_COUNT, NULL, ##args)
+
+/**
+ * Creates a cfg_schema_entry for a parameter that can be choosen
+ * from the os routing types and be mapped to an os_route_type
+ * @param p_reference reference to instance of struct
+ * @param p_field name of field in the struct for the parameter,
+ * @param p_name parameter name
+ * @param p_def parameter default value
+ * @param p_help help text for configuration entry
+ * @param args variable list of additional arguments
+ */
+#define CFG_MAP_OS_ROUTING_TYPE_KEY(p_reference, p_field, p_name, p_def, p_help, args...)                                                    \
+  CFG_MAP_CHOICE_CB_ARG(p_reference, p_field, p_name, p_def, p_help, os_routing_cfg_get_rttype, OS_ROUTE_COUNT, NULL, ##args)
+
+/**
  * key of a route, both source and destination prefix
  */
 struct os_route_key {
@@ -233,4 +261,6 @@ static INLINE void os_routing_init_sourcespec_src_prefix(struct os_route_key *pr
 /* AVL comparators are a special case so we don't do the INLINE trick here */
 EXPORT int os_routing_avl_cmp_route_key(const void *, const void *);
 
+EXPORT const char *os_routing_cfg_get_rttype(size_t index, const void *unused);
+
 #endif /* OS_ROUTING_H_ */
index caa5baa..dd8f685 100644 (file)
@@ -83,3 +83,18 @@ os_routing_generic_rt_to_string(struct os_route_str *buf, const struct os_route_
   }
   return buf->buf;
 }
+
+/**
+ * Returns the text name of a routing type. Used for configuration parameter
+ * @param idx index of routing type
+ * @param unused unused for this selector
+ * @return text name of routing type
+ */
+const char *
+os_routing_cfg_get_rttype(size_t idx, const void *unused __attribute__((unused))) {
+  static const char *UNKNOWN = "UNKNOWN";
+  if (idx >= OS_ROUTE_COUNT) {
+    return UNKNOWN;
+  }
+  return _route_types[idx];
+}
index 5d9d3d4..0b882d5 100644 (file)
@@ -96,6 +96,9 @@ struct _import_entry {
   /*! filter by routing metric, 0 to ignore */
   int32_t distance;
 
+  /*! routing type to be imported, nearly always unicast */
+  enum os_route_type rttype;
+
   /*! set MAC address of imported entries to this interface */
   char fixed_mac_if[IF_NAMESIZE];
 
@@ -144,6 +147,8 @@ static struct cfg_schema_entry _l2_entries[] = {
     _import_entry, protocol, "protocol", "-1", "Routing protocol of matching routes, 0 for all protocols", 0, -1, 255),
   CFG_MAP_INT32_MINMAX(
     _import_entry, distance, "metric", "-1", "Metric of matching routes, 0 for all metrics", 0, -1, INT32_MAX),
+  CFG_MAP_OS_ROUTING_TYPE_KEY(
+    _import_entry, rttype, "rttype", "unicast", "Type of routing metric to be imported"),
   CFG_MAP_STRING_ARRAY(_import_entry, fixed_mac_if, "fixed_mac_if", "",
     "Name of interface that will be used to fill in layer2 entry MAC addresses", IF_NAMESIZE),
   CFG_MAP_STRING_ARRAY(_import_entry, fixed_l2if_name, "fixed_l2if_name", "",
@@ -166,6 +171,12 @@ static struct cfg_schema_entry _lan_entries[] = {
     _import_entry, protocol, "protocol", "-1", "Routing protocol of matching routes, 0 for all protocols", 0, -1, 255),
   CFG_MAP_INT32_MINMAX(
     _import_entry, distance, "metric", "-1", "Metric of matching routes, 0 for all metrics", 0, -1, INT32_MAX),
+  CFG_MAP_OS_ROUTING_TYPE_KEY(
+    _import_entry, rttype, "rttype", "unicast", "Type of routing metric to be imported"),
+  CFG_MAP_STRING_ARRAY(_import_entry, fixed_mac_if, "fixed_mac_if", "",
+    "Name of interface that will be used to fill in layer2 entry MAC addresses", IF_NAMESIZE),
+  CFG_MAP_STRING_ARRAY(_import_entry, fixed_l2if_name, "fixed_l2if_name", "",
+    "Name of interface that will be used to fill in layer2 interface name", IF_NAMESIZE),
 };
 
 static struct cfg_schema_section _lan_import_section = {
@@ -264,7 +275,7 @@ _init(void) {
   os_routing_init_wildcard_route(&_unicast_query);
   _unicast_query.cb_get = _cb_query;
   _unicast_query.cb_finished = _cb_query_finished;
-  _unicast_query.p.type = OS_ROUTE_UNICAST;
+  _unicast_query.p.type = OS_ROUTE_UNDEFINED;
   return 0;
 }
 
@@ -372,25 +383,22 @@ _cb_rt_event(const struct os_route *route, bool set) {
     /* ignore multicast, linklocal and loopback */
     return;
   }
-  if (route->p.type != OS_ROUTE_UNICAST) {
-    /* return all non-unicast type routes */
-    return;
-  }
-
   OONF_DEBUG(
     LOG_L2_IMPORT, "Received route event (%s): %s", set ? "set" : "remove", os_routing_to_string(&rbuf, &route->p));
 
   /* get interface name for route */
-  if (!route->p.if_index) {
-    /* should not happen for unicast routes */
-    return;
+  if (route->p.if_index) {
+    if_indextoname(route->p.if_index, ifname);
   }
-
-  if_indextoname(route->p.if_index, ifname);
-
   avl_for_each_element(&_import_tree, import, _node) {
     OONF_DEBUG(LOG_L2_IMPORT, "Check for import: %s", import->name);
 
+    if (import->rttype != route->p.type) {
+      OONF_DEBUG(LOG_L2_IMPORT, "Bad routing type %u (filter was %d)",
+                 route->p.type, import->rttype);
+      return;
+    }
+
     /* check prefix length */
     if (import->prefix_length != -1 && import->prefix_length != netaddr_get_prefix_length(&route->p.key.dst)) {
       OONF_DEBUG(LOG_L2_IMPORT, "Bad prefix length %u (filter was %d)",
@@ -424,8 +432,8 @@ _cb_rt_event(const struct os_route *route, bool set) {
 
     /* check interface name */
     if (import->ifname[0]) {
-      if (route->p.if_index == 0) {
-        OONF_DEBUG(LOG_L2_IMPORT, "Route has no interface");
+      if (!route->p.if_index) {
+        OONF_DEBUG(LOG_L2_IMPORT, "No interface set (filter was '%s')", import->ifname);
         continue;
       }
       if (strcmp(import->ifname, ifname) != 0) {