Add basic link-id capability to DLEP
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Wed, 11 Apr 2018 07:34:23 +0000 (09:34 +0200)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Wed, 11 Apr 2018 07:34:23 +0000 (09:34 +0200)
22 files changed:
configuration/dlep_radio.conf
src-plugins/generic/dlep/CMakeLists.txt
src-plugins/generic/dlep/dlep_extension.c
src-plugins/generic/dlep/dlep_extension.h
src-plugins/generic/dlep/dlep_iana.h
src-plugins/generic/dlep/dlep_reader.c
src-plugins/generic/dlep/dlep_reader.h
src-plugins/generic/dlep/dlep_session.c
src-plugins/generic/dlep/dlep_session.h
src-plugins/generic/dlep/dlep_writer.c
src-plugins/generic/dlep/dlep_writer.h
src-plugins/generic/dlep/ext_base_ip/ip.c
src-plugins/generic/dlep/ext_base_proto/proto.c
src-plugins/generic/dlep/ext_base_proto/proto_radio.c
src-plugins/generic/dlep/ext_base_proto/proto_router.c
src-plugins/generic/dlep/ext_lid/lid.c [new file with mode: 0644]
src-plugins/generic/dlep/ext_lid/lid.h [new file with mode: 0644]
src-plugins/generic/dlep/radio/dlep_radio_interface.c
src-plugins/generic/dlep/router/dlep_router_interface.c
src-plugins/generic/layer2_config/layer2_config.c
src-plugins/generic/layer2info/layer2info.c
src-plugins/subsystems/oonf_layer2.c

index 25e2121..e423d29 100644 (file)
@@ -14,6 +14,6 @@
 
 [nl80211_listener=wlan0]
 # activate the following option to write the broadcast speed into a neighbor entry with
-# the broadcast MAC
+# the broadcast MAC (ff:ff:ff:ff:ff:ff)
 
 #        report_mc_rate  true
index 2fd137c..9a474ef 100644 (file)
@@ -13,6 +13,7 @@ SET (common_source      ext_base_metric/metric.c
                         ext_l1_statistics/l1_statistics.c
                         ext_l2_statistics/l2_statistics.c
                         ext_radio_attributes/radio_attributes.c
+                        ext_lid/lid.c
                         dlep_extension.c
                         dlep_interface.c
                         dlep_session.c
index 16607e3..20a877c 100644 (file)
@@ -196,6 +196,41 @@ dlep_extension_router_process_session_update(struct dlep_extension *ext, struct
   return _process_interface_specific_update(ext, session);
 }
 
+int
+dlep_extension_get_l2_neighbor_key(struct oonf_layer2_neigh_key *key, struct dlep_session *session) {
+  memset(key, 0, sizeof(*key));
+  if (dlep_reader_mac_tlv(key, session, NULL)) {
+    OONF_INFO(session->log_source, "mac tlv missing");
+    return -1;
+  }
+
+  if (dlep_reader_lid_tlv(key, session, NULL)) {
+    OONF_DEBUG(session->log_source, "lid tlv not present");
+  }
+  else if (!session->allow_lids) {
+    OONF_INFO(session->log_source, "LID TLV is not allowed");
+    return -1;
+  }
+  return 0;
+}
+
+struct oonf_layer2_neigh *
+dlep_extension_get_l2_neighbor(struct dlep_session *session) {
+  struct oonf_layer2_net *l2net;
+
+  struct oonf_layer2_neigh_key key;
+
+  if (dlep_extension_get_l2_neighbor_key(&key, session)) {
+    return NULL;
+  }
+
+  l2net = oonf_layer2_net_get(session->l2_listener.name);
+  if (!l2net) {
+    return NULL;
+  }
+  return oonf_layer2_neigh_get_lid(l2net, &key);
+}
+
 /**
  * Handle handle destination up/update for DLEP extension
  * by automatically mapping oonf_layer2_data to DLEP TLVs
@@ -205,9 +240,7 @@ dlep_extension_router_process_session_update(struct dlep_extension *ext, struct
  */
 int
 dlep_extension_router_process_destination(struct dlep_extension *ext, struct dlep_session *session) {
-  struct oonf_layer2_net *l2net;
   struct oonf_layer2_neigh *l2neigh;
-  struct netaddr mac;
   int result;
 
   if (session->restrict_signal != DLEP_ALL_SIGNALS) {
@@ -215,16 +248,7 @@ dlep_extension_router_process_destination(struct dlep_extension *ext, struct dle
     return 0;
   }
 
-  if (dlep_reader_mac_tlv(&mac, session, NULL)) {
-    OONF_INFO(session->log_source, "mac tlv missing");
-    return -1;
-  }
-
-  l2net = oonf_layer2_net_get(session->l2_listener.name);
-  if (!l2net) {
-    return 0;
-  }
-  l2neigh = oonf_layer2_neigh_add(l2net, &mac);
+  l2neigh = dlep_extension_get_l2_neighbor(session);
   if (!l2neigh) {
     return 0;
   }
index 8e7d943..66687a9 100644 (file)
@@ -313,6 +313,18 @@ struct dlep_extension {
   void (*cb_session_apply_router)(struct dlep_session *session);
 
   /**
+   * Callback to deactivate an extension for a radio session
+   * @param session dlep session
+   */
+  void (*cb_session_deactivate_radio)(struct dlep_session *session);
+
+  /**
+   * Callback to deactivate an extension for a router session
+   * @param session dlep session
+   */
+  void (*cb_session_deactivate_router)(struct dlep_session *session);
+
+  /**
    * Callback to cleanup all resources of a radio session
    * @param session dlep session
    */
@@ -337,6 +349,9 @@ EXPORT void dlep_extension_add_processing(
   struct dlep_extension *, bool radio, struct dlep_extension_implementation *proc, size_t proc_count);
 EXPORT const uint16_t *dlep_extension_get_ids(uint16_t *length);
 
+EXPORT int dlep_extension_get_l2_neighbor_key(struct oonf_layer2_neigh_key *key, struct dlep_session *session);
+EXPORT struct oonf_layer2_neigh *dlep_extension_get_l2_neighbor(struct dlep_session *session);
+
 EXPORT int dlep_extension_router_process_session_init_ack(struct dlep_extension *, struct dlep_session *session);
 EXPORT int dlep_extension_router_process_session_update(struct dlep_extension *, struct dlep_session *session);
 EXPORT int dlep_extension_router_process_destination(struct dlep_extension *, struct dlep_session *session);
index 6f00e35..afa6915 100644 (file)
@@ -94,6 +94,12 @@ enum dlep_extensions
 
   /*! Additional boolean radio attributes */
   DLEP_EXTENSION_RADIO_ATTRIBUTES = 65522,
+
+  /*! DLEP Link ID */
+  DLEP_EXTENSION_LINK_ID = 65523,
+
+  /*! number of supported (non-base) DLEP extensions */
+  DLEP_EXTENSION_COUNT = 4,
 };
 
 /**
index 123dfe8..af3619c 100644 (file)
@@ -121,14 +121,14 @@ dlep_reader_peer_type(
 
 /**
  * Parse a DLEP mac address TLV
- * @param mac pointer to mac address storage
+ * @param key pointer to link-id storage
  * @param session dlep session
  * @param value dlep value to parse, NULL for using the first
  *   DLEP_MAC_ADDRESS_TLV value
  * @return -1 if an error happened, 0 otherwise
  */
 int
-dlep_reader_mac_tlv(struct netaddr *mac, struct dlep_session *session, struct dlep_parser_value *value) {
+dlep_reader_mac_tlv(struct oonf_layer2_neigh_key *key, struct dlep_session *session, struct dlep_parser_value *value) {
   const uint8_t *ptr;
 
   if (!value) {
@@ -139,7 +139,7 @@ dlep_reader_mac_tlv(struct netaddr *mac, struct dlep_session *session, struct dl
   }
 
   ptr = dlep_session_get_tlv_binary(session, value);
-  return netaddr_from_binary(mac, ptr, value->length, 0);
+  return netaddr_from_binary(&key->addr, ptr, value->length, 0);
 }
 
 /**
index 69fb933..7b2f9ff 100644 (file)
@@ -56,7 +56,7 @@
 int dlep_reader_heartbeat_tlv(uint64_t *interval, struct dlep_session *session, struct dlep_parser_value *value);
 int dlep_reader_peer_type(
   char *text, size_t text_length, bool *secured, struct dlep_session *session, struct dlep_parser_value *value);
-int dlep_reader_mac_tlv(struct netaddr *mac, struct dlep_session *session, struct dlep_parser_value *value);
+int dlep_reader_mac_tlv(struct oonf_layer2_neigh_key *lid, struct dlep_session *session, struct dlep_parser_value *value);
 int dlep_reader_lid_tlv(struct oonf_layer2_neigh_key *lid, struct dlep_session *session, struct dlep_parser_value *value);
 int dlep_reader_ipv4_tlv(
   struct netaddr *ipv4, bool *add, struct dlep_session *session, struct dlep_parser_value *value);
index c0a18e2..1b450c2 100644 (file)
@@ -124,7 +124,6 @@ dlep_session_add(struct dlep_session *session, const char *l2_ifname, const stru
   int (*if_changed)(struct os_interface_listener *), enum oonf_log_source log_source) {
   struct dlep_session_parser *parser;
   struct dlep_extension *ext;
-  int32_t i;
 
   parser = &session->parser;
 
@@ -149,17 +148,6 @@ dlep_session_add(struct dlep_session *session, const char *l2_ifname, const stru
     return -1;
   }
 
-  /* allocate memory for the pointers */
-  parser->extensions = calloc(dlep_extension_get_tree()->count, sizeof(struct dlep_extension *));
-  if (!parser->extensions) {
-    OONF_WARN(session->log_source, "Cannot allocate extension buffer for %s", l2_ifname);
-    dlep_session_remove(session);
-    return -1;
-  }
-
-  /* remember the sessions */
-  parser->extension_count = dlep_extension_get_tree()->count;
-
   parser->values = calloc(SESSION_VALUE_STEP, sizeof(struct dlep_parser_value));
   if (!parser->values) {
     OONF_WARN(session->log_source, "Cannot allocate values buffer for %s", l2_ifname);
@@ -167,11 +155,11 @@ dlep_session_add(struct dlep_session *session, const char *l2_ifname, const stru
     return -1;
   }
 
-  i = 0;
+  /* generate full list of extensions */
   avl_for_each_element(dlep_extension_get_tree(), ext, _node) {
     OONF_DEBUG(session->log_source, "Add extension %d to session", ext->id);
-    parser->extensions[i] = ext;
-    i++;
+    parser->extensions[parser->extension_count] = ext;
+    parser->extension_count++;
   }
 
   if (_update_allowed_tlvs(session)) {
@@ -212,8 +200,7 @@ dlep_session_remove(struct dlep_session *session) {
   oonf_timer_stop(&session->local_event_timer);
   oonf_timer_stop(&session->remote_heartbeat_timeout);
 
-  free(parser->extensions);
-  parser->extensions = NULL;
+  parser->extension_count = 0;
 
   free(parser->values);
   parser->values = NULL;
@@ -244,43 +231,48 @@ dlep_session_terminate(struct dlep_session *session, enum dlep_status status, co
  * @return -1 if an error happened, 0 otherwise
  */
 int
-dlep_session_update_extensions(struct dlep_session *session, const uint8_t *extvalues, size_t extcount) {
-  struct dlep_extension **ext_array, *ext;
-  size_t count, i;
+dlep_session_update_extensions(struct dlep_session *session, const uint8_t *extvalues, size_t extcount, bool radio) {
+  struct dlep_extension *ext;
+  size_t i, j;
+  bool deactivate;
   uint16_t extid;
-
   OONF_INFO(session->log_source, "Update session extension list");
 
-  /* keep entry a few entries untouched, these are the base extensions */
-  count = DLEP_EXTENSION_BASE_COUNT;
-  for (i = 0; i < extcount; i++) {
-    memcpy(&extid, &extvalues[i * 2], sizeof(extid));
+  /* deactivate all extensions not present anymore  */
+  for (j = DLEP_EXTENSION_BASE_COUNT; j < session->parser.extension_count; j++) {
+    deactivate = true;
 
-    if (dlep_extension_get(ntohs(extid))) {
-      count++;
-      OONF_INFO(session->log_source, "Add extension: %d", ntohs(extid));
+    for (i = 0; i < extcount; i++) {
+      memcpy(&extid, &extvalues[i * 2], sizeof(extid));
+      if (ntohs(extid) == session->parser.extensions[j]->id) {
+        deactivate = false;
+        break;
+      }
     }
-  }
 
-  if (count != session->parser.extension_count) {
-    ext_array = realloc(session->parser.extensions, sizeof(struct dlep_extension *) * count);
-    if (!ext_array) {
-      return -1;
+    if (deactivate) {
+      if (radio) {
+        session->parser.extensions[j]->cb_session_deactivate_radio(session);
+      }
+      else {
+        session->parser.extensions[j]->cb_session_deactivate_router(session);
+      }
     }
-
-    session->parser.extensions = ext_array;
-    session->parser.extension_count = count;
   }
 
-  count = DLEP_EXTENSION_BASE_COUNT;
+  /* generate new session extension list */
+  session->parser.extension_count = DLEP_EXTENSION_BASE_COUNT;
   for (i = 0; i < extcount; i++) {
     memcpy(&extid, &extvalues[i * 2], sizeof(extid));
-    if ((ext = dlep_extension_get(ntohs(extid)))) {
-      session->parser.extensions[count] = ext;
-      count++;
+
+    ext = dlep_extension_get(ntohs(extid));
+    if (ext) {
+      OONF_INFO(session->log_source, "Add extension: %d", ntohs(extid));
+
+      session->parser.extensions[session->parser.extension_count] = ext;
+      session->parser.extension_count++;
     }
   }
-
   return _update_allowed_tlvs(session);
 }
 
@@ -466,6 +458,10 @@ dlep_session_add_local_neighbor(struct dlep_session *session, const struct oonf_
     return local;
   }
 
+  if (key->link_id_length > 0 && !session->allow_lids) {
+    /* LIDs not allowed */
+    return NULL;
+  }
   local = oonf_class_malloc(&_local_neighbor_class);
   if (!local) {
     return NULL;
@@ -1075,13 +1071,13 @@ _call_extension_processing(struct dlep_session *session, struct dlep_extension *
     }
 
     if (session->radio) {
-      if (ext->signals[s].process_radio(ext, session)) {
+      if (ext->signals[s].process_radio && ext->signals[s].process_radio(ext, session)) {
         OONF_DEBUG(session->log_source, "Error in radio signal processing of extension '%s'", ext->name);
         return -1;
       }
     }
     else {
-      if (ext->signals[s].process_router(ext, session)) {
+      if (ext->signals[s].process_router && ext->signals[s].process_router(ext, session)) {
         OONF_DEBUG(session->log_source, "Error in router signal processing of extension '%s'", ext->name);
         return -1;
       }
index bd79366..f9dfeb9 100644 (file)
@@ -151,7 +151,7 @@ struct dlep_session_parser {
   size_t value_max_count;
 
   /*! array of active dlep extensions */
-  struct dlep_extension **extensions;
+  struct dlep_extension *extensions[DLEP_EXTENSION_BASE_COUNT + DLEP_EXTENSION_COUNT];
 
   /*! number of active dlep extensions */
   size_t extension_count;
@@ -283,6 +283,9 @@ struct dlep_session {
   /*! true if this is a radio session */
   bool radio;
 
+  /*! true if LID tagged neighbor information can be transmitted over the link */
+  bool allow_lids;
+
   /*! parser for this dlep session */
   struct dlep_session_parser parser;
 
@@ -343,7 +346,7 @@ int dlep_session_add(struct dlep_session *session, const char *l2_ifname, const
 void dlep_session_remove(struct dlep_session *session);
 void dlep_session_terminate(struct dlep_session *session, enum dlep_status status, const char *status_text);
 
-int dlep_session_update_extensions(struct dlep_session *session, const uint8_t *extvalues, size_t extcount);
+int dlep_session_update_extensions(struct dlep_session *session, const uint8_t *extvalues, size_t extcount, bool radio);
 enum oonf_stream_session_state dlep_session_process_tcp(
   struct oonf_stream_session *tcp_session, struct dlep_session *session);
 ssize_t dlep_session_process_buffer(struct dlep_session *session, const void *buffer, size_t length, bool is_udp);
index d5c59c4..3bd099d 100644 (file)
@@ -176,7 +176,7 @@ dlep_writer_add_peer_type_tlv(struct dlep_writer *writer, const char *peer_type,
  * @return -1 if address was wrong type, 0 otherwise
  */
 int
-dlep_writer_add_mac_lid_tlv(struct dlep_writer *writer, const struct oonf_layer2_neigh_key *mac_lid) {
+dlep_writer_add_mac_tlv(struct dlep_writer *writer, const struct oonf_layer2_neigh_key *mac_lid) {
   uint8_t value[8];
 
   switch (netaddr_get_address_family(&mac_lid->addr)) {
@@ -190,6 +190,25 @@ dlep_writer_add_mac_lid_tlv(struct dlep_writer *writer, const struct oonf_layer2
   netaddr_to_binary(value, &mac_lid->addr, 8);
 
   dlep_writer_add_tlv(writer, DLEP_MAC_ADDRESS_TLV, value, netaddr_get_binlength(&mac_lid->addr));
+  return 0;
+}
+
+/**
+ * Write a DLEP Link-ID TLV
+ * @param writer dlep writer
+ * @param mac_lid mac address/LID
+ * @return -1 if address was wrong type, 0 otherwise
+ */
+int
+dlep_writer_add_lid_tlv(struct dlep_writer *writer, const struct oonf_layer2_neigh_key *mac_lid) {
+  switch (netaddr_get_address_family(&mac_lid->addr)) {
+    case AF_MAC48:
+    case AF_EUI64:
+      break;
+    default:
+      return -1;
+  }
+
   dlep_writer_add_tlv(writer, DLEP_LID_TLV, mac_lid->link_id, mac_lid->link_id_length);
   return 0;
 }
index ff4ded0..c0020dd 100644 (file)
@@ -61,7 +61,8 @@ void dlep_writer_add_tlv2(
 int dlep_writer_finish_signal(struct dlep_writer *writer, enum oonf_log_source source);
 void dlep_writer_add_heartbeat_tlv(struct dlep_writer *writer, uint64_t interval);
 void dlep_writer_add_peer_type_tlv(struct dlep_writer *writer, const char *peer_type, bool access_control);
-int dlep_writer_add_mac_lid_tlv(struct dlep_writer *writer, const struct oonf_layer2_neigh_key *mac_lid);
+int dlep_writer_add_mac_tlv(struct dlep_writer *writer, const struct oonf_layer2_neigh_key *mac_lid);
+int dlep_writer_add_lid_tlv(struct dlep_writer *writer, const struct oonf_layer2_neigh_key *mac_lid);
 int dlep_writer_add_ip_tlv(struct dlep_writer *writer, const struct netaddr *ipv4, bool add);
 void dlep_writer_add_ipv4_conpoint_tlv(struct dlep_writer *writer, const struct netaddr *addr, uint16_t port, bool tls);
 void dlep_writer_add_ipv6_conpoint_tlv(struct dlep_writer *writer, const struct netaddr *addr, uint16_t port, bool tls);
index 6f89c94..4b54269 100644 (file)
@@ -383,22 +383,12 @@ _process_destination_ip_tlv(
 
 static enum dlep_parser_error
 _router_process_destination_update(struct dlep_extension *ext __attribute((unused)), struct dlep_session *session) {
-  struct oonf_layer2_net *l2net;
   struct oonf_layer2_neigh *l2neigh;
-  struct netaddr mac, ip;
+  struct netaddr ip;
   struct dlep_parser_value *value;
   bool add_ip;
 
-  if (dlep_reader_mac_tlv(&mac, session, NULL)) {
-    OONF_INFO(session->log_source, "mac tlv missing");
-    return -1;
-  }
-
-  l2net = oonf_layer2_net_get(session->l2_listener.name);
-  if (!l2net) {
-    return 0;
-  }
-  l2neigh = oonf_layer2_neigh_add(l2net, &mac);
+  l2neigh = dlep_extension_get_l2_neighbor(session);
   if (!l2neigh) {
     return 0;
   }
index 17ff8d0..1f561cb 100644 (file)
@@ -536,16 +536,16 @@ dlep_base_proto_process_heartbeat(struct dlep_extension *ext __attribute__((unus
 }
 
 /**
- * Write the mac address (and LID) TLV into the DLEP message
+ * Write the mac address TLV into the DLEP message
  * @param ext (this) dlep extension
  * @param session dlep session
- * @param neigh mac address to write into TLV
+ * @param neigh layer2 neighbor key to write into TLV
  * @return -1 if an error happened, 0 otherwise
  */
 int
 dlep_base_proto_write_mac_only(
   struct dlep_extension *ext __attribute__((unused)), struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh) {
-  if (dlep_writer_add_mac_lid_tlv(&session->writer, neigh)) {
+  if (dlep_writer_add_mac_tlv(&session->writer, neigh)) {
     return -1;
   }
   return 0;
index 2003f66..5beb2b0 100644 (file)
@@ -282,11 +282,11 @@ _radio_process_session_init(struct dlep_extension *ext __attribute__((unused)),
   value = dlep_session_get_tlv_value(session, DLEP_EXTENSIONS_SUPPORTED_TLV);
   if (value) {
     ptr = dlep_session_get_tlv_binary(session, value);
-    if (dlep_session_update_extensions(session, ptr, value->length / 2)) {
+    if (dlep_session_update_extensions(session, ptr, value->length / 2, true)) {
       return -1;
     }
   }
-  else if (dlep_session_update_extensions(session, NULL, 0)) {
+  else if (dlep_session_update_extensions(session, NULL, 0, true)) {
     return -1;
   }
 
@@ -365,11 +365,9 @@ _radio_process_destination_up_ack(struct dlep_extension *ext __attribute__((unus
   struct dlep_local_neighbor *local;
   struct oonf_layer2_neigh_key mac_lid;
 
-  memset(&mac_lid, 0, sizeof(mac_lid));
-  if (dlep_reader_mac_tlv(&mac_lid.addr, session, NULL)) {
+  if (dlep_extension_get_l2_neighbor_key(&mac_lid, session)) {
     return -1;
   }
-  dlep_reader_lid_tlv(&mac_lid, session, NULL);
 
   if (dlep_base_proto_print_status(session) == DLEP_STATUS_OKAY) {
     local = dlep_session_get_local_neighbor(session, &mac_lid);
@@ -397,11 +395,9 @@ _radio_process_destination_down_ack(struct dlep_extension *ext __attribute__((un
   struct dlep_local_neighbor *local;
   struct oonf_layer2_neigh_key mac_lid;
 
-  memset(&mac_lid, 0, sizeof(mac_lid));
-  if (dlep_reader_mac_tlv(&mac_lid.addr, session, NULL)) {
+  if (dlep_extension_get_l2_neighbor_key(&mac_lid, session)) {
     return -1;
   }
-  dlep_reader_lid_tlv(&mac_lid, session, NULL);
 
   if (dlep_base_proto_print_status(session) == DLEP_STATUS_OKAY) {
     local = dlep_session_get_local_neighbor(session, &mac_lid);
index 783f4b0..e2eaa98 100644 (file)
@@ -369,11 +369,11 @@ _router_process_session_init_ack(struct dlep_extension *ext __attribute__((unuse
   value = dlep_session_get_tlv_value(session, DLEP_EXTENSIONS_SUPPORTED_TLV);
   if (value) {
     ptr = dlep_session_get_tlv_binary(session, value);
-    if (dlep_session_update_extensions(session, ptr, value->length / 2)) {
+    if (dlep_session_update_extensions(session, ptr, value->length / 2, true)) {
       return -1;
     }
   }
-  else if (dlep_session_update_extensions(session, NULL, 0)) {
+  else if (dlep_session_update_extensions(session, NULL, 0, true)) {
     return -1;
   }
 
@@ -456,11 +456,9 @@ _router_process_destination_up(struct dlep_extension *ext __attribute__((unused)
   int result;
   struct oonf_layer2_neigh_key mac_lid;
 
-  memset(&mac_lid, 0, sizeof(mac_lid));
-  if (dlep_reader_mac_tlv(&mac_lid.addr, session, NULL)) {
+  if (dlep_extension_get_l2_neighbor_key(&mac_lid, session)) {
     return -1;
   }
-  dlep_reader_lid_tlv(&mac_lid, session, NULL);
 
   l2net = oonf_layer2_net_add(session->l2_listener.name);
   if (!l2net) {
@@ -507,11 +505,9 @@ _router_process_destination_down(struct dlep_extension *ext __attribute__((unuse
   struct oonf_layer2_neigh *l2neigh;
   struct oonf_layer2_neigh_key mac_lid;
 
-  memset(&mac_lid, 0, sizeof(mac_lid));
-  if (dlep_reader_mac_tlv(&mac_lid.addr, session, NULL)) {
+  if (dlep_extension_get_l2_neighbor_key(&mac_lid, session)) {
     return -1;
   }
-  dlep_reader_lid_tlv(&mac_lid, session, NULL);
 
   l2net = oonf_layer2_net_get(session->l2_listener.name);
   if (!l2net) {
@@ -552,10 +548,10 @@ static int
 _router_process_destination_update(struct dlep_extension *ext __attribute__((unused)), struct dlep_session *session) {
   struct oonf_layer2_net *l2net;
   struct oonf_layer2_neigh *l2neigh;
-  struct netaddr mac;
+  struct oonf_layer2_neigh_key mac_lid;
   int result;
 
-  if (dlep_reader_mac_tlv(&mac, session, NULL)) {
+  if (dlep_extension_get_l2_neighbor_key(&mac_lid, session)) {
     return -1;
   }
 
@@ -564,7 +560,7 @@ _router_process_destination_update(struct dlep_extension *ext __attribute__((unu
     return 0;
   }
 
-  l2neigh = oonf_layer2_neigh_get(l2net, &mac);
+  l2neigh = oonf_layer2_neigh_get_lid(l2net, &mac_lid);
   if (!l2neigh) {
     /* we did not get the destination up signal */
     return 0;
diff --git a/src-plugins/generic/dlep/ext_lid/lid.c b/src-plugins/generic/dlep/ext_lid/lid.c
new file mode 100644 (file)
index 0000000..b3e3c7b
--- /dev/null
@@ -0,0 +1,235 @@
+
+/*
+ * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
+ * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of olsr.org, olsrd nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Visit http://www.olsr.org for more information.
+ *
+ * If you find this software useful feel free to make a donation
+ * to the project. For more information see the website or contact
+ * the copyright holders.
+ *
+ */
+
+/**
+ * @file
+ */
+
+#include "common/autobuf.h"
+#include "common/avl.h"
+#include "common/common_types.h"
+#include "subsystems/oonf_timer.h"
+
+#include "dlep/dlep_extension.h"
+#include "dlep/dlep_iana.h"
+#include "dlep/dlep_reader.h"
+#include "dlep/dlep_writer.h"
+
+#include "dlep/ext_lid/lid.h"
+
+static int _write_lid_only(struct dlep_extension *ext, struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh);
+static void _cb_session_init(struct dlep_session *session);
+static void _cb_session_deactivate(struct dlep_session *session);
+
+/* UDP peer discovery */
+
+/* destination up */
+static const uint16_t _dst_up_tlvs[] = {
+  DLEP_LID_TLV,
+};
+static const uint16_t _dst_up_mandatory[] = {
+  DLEP_LID_TLV,
+};
+
+/* destination up ack */
+static const uint16_t _dst_up_ack_tlvs[] = {
+  DLEP_LID_TLV,
+};
+static const uint16_t _dst_up_ack_mandatory[] = {
+  DLEP_LID_TLV,
+};
+
+/* destination down */
+static const uint16_t _dst_down_tlvs[] = {
+  DLEP_LID_TLV,
+};
+static const uint16_t _dst_down_mandatory[] = {
+  DLEP_LID_TLV,
+};
+
+/* destination down ack */
+static const uint16_t _dst_down_ack_tlvs[] = {
+  DLEP_LID_TLV,
+};
+static const uint16_t _dst_down_ack_mandatory[] = {
+  DLEP_LID_TLV,
+};
+
+/* destination update */
+static const uint16_t _dst_update_tlvs[] = {
+  DLEP_LID_TLV,
+};
+static const uint16_t _dst_update_mandatory[] = {
+  DLEP_MAC_ADDRESS_TLV,
+};
+
+/* link characteristics request */
+static const uint16_t _linkchar_req_tlvs[] = {
+  DLEP_LID_TLV,
+};
+static const uint16_t _linkchar_req_mandatory[] = {
+  DLEP_LID_TLV,
+};
+
+/* link characteristics ack */
+static const uint16_t _linkchar_ack_tlvs[] = {
+  DLEP_LID_TLV,
+};
+static const uint16_t _linkchar_ack_mandatory[] = {
+  DLEP_LID_TLV,
+};
+
+/* supported signals of this extension, parsing the LID TLV is done by dlep_extension */
+static struct dlep_extension_signal _signals[] = {
+  {
+    .id = DLEP_DESTINATION_UP,
+    .supported_tlvs = _dst_up_tlvs,
+    .supported_tlv_count = ARRAYSIZE(_dst_up_tlvs),
+    .mandatory_tlvs = _dst_up_mandatory,
+    .mandatory_tlv_count = ARRAYSIZE(_dst_up_mandatory),
+    .add_radio_tlvs = _write_lid_only,
+  },
+  {
+    .id = DLEP_DESTINATION_UP_ACK,
+    .supported_tlvs = _dst_up_ack_tlvs,
+    .supported_tlv_count = ARRAYSIZE(_dst_up_ack_tlvs),
+    .mandatory_tlvs = _dst_up_ack_mandatory,
+    .mandatory_tlv_count = ARRAYSIZE(_dst_up_ack_mandatory),
+    .add_router_tlvs = _write_lid_only,
+  },
+  {
+    .id = DLEP_DESTINATION_DOWN,
+    .supported_tlvs = _dst_down_tlvs,
+    .supported_tlv_count = ARRAYSIZE(_dst_down_tlvs),
+    .mandatory_tlvs = _dst_down_mandatory,
+    .mandatory_tlv_count = ARRAYSIZE(_dst_down_mandatory),
+    .add_radio_tlvs = _write_lid_only,
+  },
+  {
+    .id = DLEP_DESTINATION_DOWN_ACK,
+    .supported_tlvs = _dst_down_ack_tlvs,
+    .supported_tlv_count = ARRAYSIZE(_dst_down_ack_tlvs),
+    .mandatory_tlvs = _dst_down_ack_mandatory,
+    .mandatory_tlv_count = ARRAYSIZE(_dst_down_ack_mandatory),
+    .add_router_tlvs = _write_lid_only,
+  },
+  {
+    .id = DLEP_DESTINATION_UPDATE,
+    .supported_tlvs = _dst_update_tlvs,
+    .supported_tlv_count = ARRAYSIZE(_dst_update_tlvs),
+    .mandatory_tlvs = _dst_update_mandatory,
+    .mandatory_tlv_count = ARRAYSIZE(_dst_update_mandatory),
+    .add_radio_tlvs = _write_lid_only,
+  },
+  {
+    .id = DLEP_LINK_CHARACTERISTICS_REQUEST,
+    .supported_tlvs = _linkchar_req_tlvs,
+    .supported_tlv_count = ARRAYSIZE(_linkchar_req_tlvs),
+    .mandatory_tlvs = _linkchar_req_mandatory,
+    .mandatory_tlv_count = ARRAYSIZE(_linkchar_req_mandatory),
+    .add_router_tlvs = _write_lid_only,
+  },
+  {
+    .id = DLEP_LINK_CHARACTERISTICS_ACK,
+    .supported_tlvs = _linkchar_ack_tlvs,
+    .supported_tlv_count = ARRAYSIZE(_linkchar_ack_tlvs),
+    .mandatory_tlvs = _linkchar_ack_mandatory,
+    .mandatory_tlv_count = ARRAYSIZE(_linkchar_ack_mandatory),
+    .add_radio_tlvs = _write_lid_only,
+  },
+};
+
+/* supported TLVs of this extension */
+static struct dlep_extension_tlv _tlvs[] = {
+  { DLEP_LID_TLV, 1, OONF_LAYER2_MAX_LINK_ID },
+};
+
+/* DLEP base extension, radio side */
+static struct dlep_extension _lid = {
+  .id = DLEP_EXTENSION_LINK_ID,
+  .name = "linkid",
+
+  .signals = _signals,
+  .signal_count = ARRAYSIZE(_signals),
+  .tlvs = _tlvs,
+  .tlv_count = ARRAYSIZE(_tlvs),
+
+  .cb_session_init_radio = _cb_session_init,
+  .cb_session_init_router = _cb_session_init,
+  .cb_session_deactivate_radio = _cb_session_deactivate,
+  .cb_session_deactivate_router = _cb_session_deactivate,
+};
+
+/**
+ * Get link-id DLEP extension
+ * @return this extension
+ */
+struct dlep_extension *
+dlep_lid_init(void) {
+  dlep_extension_add(&_lid);
+  return &_lid;
+}
+
+/**
+ * Write the link-id TLV into the DLEP message
+ * @param ext (this) dlep extension
+ * @param session dlep session
+ * @param neigh layer2 neighbor key to write into TLV
+ * @return -1 if an error happened, 0 otherwise
+ */
+static int
+_write_lid_only(
+  struct dlep_extension *ext __attribute__((unused)), struct dlep_session *session, const struct oonf_layer2_neigh_key *neigh) {
+  if (dlep_writer_add_lid_tlv(&session->writer, neigh)) {
+    return -1;
+  }
+  return 0;
+}
+
+static void
+_cb_session_init(struct dlep_session *session) {
+  session->allow_lids = true;
+}
+
+static void
+_cb_session_deactivate(struct dlep_session *session) {
+  session->allow_lids = false;
+}
diff --git a/src-plugins/generic/dlep/ext_lid/lid.h b/src-plugins/generic/dlep/ext_lid/lid.h
new file mode 100644 (file)
index 0000000..6a75ebd
--- /dev/null
@@ -0,0 +1,55 @@
+
+/*
+ * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
+ * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of olsr.org, olsrd nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Visit http://www.olsr.org for more information.
+ *
+ * If you find this software useful feel free to make a donation
+ * to the project. For more information see the website or contact
+ * the copyright holders.
+ *
+ */
+
+/**
+ * @file
+ */
+
+#ifndef _DLEP_LID_H_
+#define _DLEP_LID_H_
+
+#include "common/common_types.h"
+
+#include "dlep/dlep_extension.h"
+
+struct dlep_extension *dlep_lid_init(void);
+
+#endif /* _DLEP_LID_H_ */
index 7c850d1..7cf1521 100644 (file)
@@ -66,6 +66,7 @@
 #include "dlep/ext_l1_statistics/l1_statistics.h"
 #include "dlep/ext_l2_statistics/l2_statistics.h"
 #include "dlep/ext_radio_attributes/radio_attributes.h"
+#include "dlep/ext_lid/lid.h"
 #include "dlep/radio/dlep_radio_internal.h"
 #include "dlep/radio/dlep_radio_session.h"
 
@@ -109,6 +110,7 @@ dlep_radio_interface_init(void) {
   dlep_l1_statistics_init();
   dlep_l2_statistics_init();
   dlep_radio_attributes_init();
+  dlep_lid_init();
 
   _shutting_down = false;
   return 0;
index 7ac2dc2..0c352ff 100644 (file)
@@ -72,6 +72,7 @@
 #include "dlep/ext_l1_statistics/l1_statistics.h"
 #include "dlep/ext_l2_statistics/l2_statistics.h"
 #include "dlep/ext_radio_attributes/radio_attributes.h"
+#include "dlep/ext_lid/lid.h"
 #include "dlep/router/dlep_router_internal.h"
 #include "dlep/router/dlep_router_session.h"
 
@@ -123,6 +124,7 @@ dlep_router_interface_init(void) {
   dlep_l1_statistics_init();
   dlep_l2_statistics_init();
   dlep_radio_attributes_init();
+  dlep_lid_init();
 
   _shutting_down = false;
 
index e6ab4a1..ec633c0 100644 (file)
@@ -497,6 +497,7 @@ _configure_if_data(struct l2_config_if_data *if_data) {
   struct oonf_layer2_neigh *l2neigh;
   struct oonf_layer2_net *l2net;
   struct l2_config_data *entry;
+  struct oonf_layer2_neigh_key key;
   size_t i;
 
   l2net = oonf_layer2_net_get(if_data->interf);
@@ -525,7 +526,11 @@ _configure_if_data(struct l2_config_if_data *if_data) {
           oonf_layer2_data_set(&l2net->neighdata[entry->data_idx], &_l2_origin_current, entry->data_type, &entry->data);
           break;
         case L2_NEIGH:
-          l2neigh = oonf_layer2_neigh_add(l2net, &entry->mac);
+          memset(&key, 0, sizeof(key));
+          memcpy(&key.addr, &entry->mac, sizeof(key.addr));
+          key.link_id[0] = 1;
+          key.link_id_length = 1;
+          l2neigh = oonf_layer2_neigh_add_lid(l2net, &key);
           if (l2neigh) {
             oonf_layer2_data_set(&l2neigh->data[entry->data_idx], &_l2_origin_current, entry->data_type, &entry->data);
           }
index 2c1c6be..0651a1c 100644 (file)
@@ -130,6 +130,9 @@ static int _cb_create_text_dst(struct oonf_viewer_template *);
 /*! template key for neighbor link-id */
 #define KEY_NEIGH_LID "neigh_lid"
 
+/*! template key for neighbor link-id length */
+#define KEY_NEIGH_LID_LEN "neigh_lid_length"
+
 /*! template key for last time neighbor was active */
 #define KEY_NEIGH_LASTSEEN "neigh_lastseen"
 
@@ -172,6 +175,7 @@ static char _value_if_data[OONF_LAYER2_NET_COUNT][64];
 static char _value_if_origin[OONF_LAYER2_NET_COUNT][IF_NAMESIZE];
 static struct netaddr_str _value_neigh_addr;
 static union oonf_layer2_neigh_key_str _value_neigh_key;
+static char _value_neigh_key_length[6];
 static struct isonumber_str _value_neigh_lastseen;
 static struct netaddr_str _value_neigh_remote_ip;
 static char _value_neigh_remote_ip_origin[IF_NAMESIZE];
@@ -207,6 +211,7 @@ static struct abuf_template_data_entry _tde_if_origin[OONF_LAYER2_NET_COUNT];
 static struct abuf_template_data_entry _tde_neigh_key[] = {
   { KEY_NEIGH_ADDR, _value_neigh_addr.buf, true },
   { KEY_NEIGH_LID, _value_neigh_key.buf, true },
+  { KEY_NEIGH_LID_LEN, _value_neigh_key_length, false },
 };
 
 static struct abuf_template_data_entry _tde_neigh[] = {
@@ -490,6 +495,7 @@ static void
 _initialize_neigh_values(struct oonf_layer2_neigh *neigh) {
   netaddr_to_string(&_value_neigh_addr, &neigh->key.addr);
   oonf_layer2_neigh_key_to_string(&_value_neigh_key, &neigh->key, false);
+  snprintf(_value_neigh_key_length, sizeof(_value_neigh_key_length), "%u", neigh->key.link_id_length);
 
   if (neigh->last_seen) {
     oonf_clock_toIntervalString(&_value_neigh_lastseen, -oonf_clock_get_relative(neigh->last_seen));
index 63c9026..7599783 100644 (file)
@@ -1118,7 +1118,18 @@ const char *
 oonf_layer2_neigh_key_to_string(union oonf_layer2_neigh_key_str *buf,
     const struct oonf_layer2_neigh_key *key, bool show_mac) {
   static const char HEX[17] = "0123456789ABCDEF";
+  static const char NONE[] = "-";
   size_t str_idx, lid_idx;
+  uint8_t af;
+
+  if (key == NULL) {
+    return NONE;
+  }
+
+  af = netaddr_get_address_family(&key->addr);
+  if (af != AF_MAC48 && af != AF_EUI64) {
+    return NONE;
+  }
 
   if (show_mac) {
     netaddr_to_string(&buf->nbuf, &key->addr);