PATCH by Hannes Gredler <hannes@gredler.at>:
authorBernd Petrovitsch <bernd@firmix.at>
Fri, 16 Nov 2007 21:43:55 +0000 (21:43 +0000)
committerBernd Petrovitsch <bernd@firmix.at>
Fri, 16 Nov 2007 21:43:55 +0000 (21:43 +0000)
- refactoring of TC parsing to kill another pile of malloc()/free()s
  saving (again) code and especially run.time performance.

CHANGELOG
src/lq_packet.c
src/lq_packet.h
src/lq_route.c
src/process_package.c
src/process_package.h
src/rebuild_packet.c
src/rebuild_packet.h
src/tc_set.c
src/tc_set.h

index 75a3c65..836f24b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,11 +1,13 @@
 This file states changes as of version 0.2.4:
-$Id: CHANGELOG,v 1.115 2007/11/14 11:08:05 bernd67 Exp $
+$Id: CHANGELOG,v 1.116 2007/11/16 21:43:55 bernd67 Exp $
 
 0.5.5 ---------------------------------------------------------------------
 
-BUGFIX by Hannes Gredler <hannes@gredler.at>
+BUGFIXES and PATCHES by Hannes Gredler <hannes@gredler.at>
 - fix not deleted tc entry.
 - avoid setting routes with an invalid/impossible netmask.
+- refactoring of TC parsing to kill another pile of malloc()/free()s
+  saving (again) code and especially run.time performance.
 
 PATCH by John Hay <jhay@meraka.org.za>:
 - also printout our own HNAs in the dotdraw plugin.
index 6e892ad..ab2d70b 100644 (file)
@@ -38,7 +38,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: lq_packet.c,v 1.29 2007/11/08 22:47:41 bernd67 Exp $
+ * $Id: lq_packet.c,v 1.30 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 #include "olsr_protocol.h"
@@ -62,36 +62,6 @@ olsr_bool lq_tc_pending = OLSR_FALSE;
 
 static unsigned char msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
 
-static INLINE void        pkt_get_u8(const olsr_u8_t **p, olsr_u8_t  *var)         { *var =       *(olsr_u8_t *)(*p);   *p += sizeof(olsr_u8_t); }
-static INLINE void       pkt_get_u16(const olsr_u8_t **p, olsr_u16_t *var)         { *var = ntohs(*(olsr_u16_t *)(*p)); *p += sizeof(olsr_u16_t); }
-static INLINE void       pkt_get_u32(const olsr_u8_t **p, olsr_u32_t *var)         { *var = ntohl(*(olsr_u32_t *)(p));  *p += sizeof(olsr_u32_t); }
-static INLINE void        pkt_get_s8(const olsr_u8_t **p, olsr_8_t  *var)          { *var =       *(olsr_8_t *)(*p);    *p += sizeof(olsr_8_t); }
-static INLINE void       pkt_get_s16(const olsr_u8_t **p, olsr_16_t *var)          { *var = ntohs(*(olsr_16_t *)(*p));  *p += sizeof(olsr_16_t); }
-static INLINE void       pkt_get_s32(const olsr_u8_t **p, olsr_32_t *var)          { *var = ntohl(*(olsr_32_t *)(*p));  *p += sizeof(olsr_32_t); }
-static INLINE void    pkt_get_double(const olsr_u8_t **p, double *var)             { *var = me_to_double(**p);          *p += sizeof(olsr_u8_t); }
-static INLINE void pkt_get_ipaddress(const olsr_u8_t **p, union olsr_ip_addr *var) { memcpy(var, *p, olsr_cnf->ipsize); *p += olsr_cnf->ipsize; }
-static INLINE void        pkt_get_lq(const olsr_u8_t **p, double *var)             { *var = (double)**p / 255.0;        *p += sizeof(olsr_u8_t); }
-
-static INLINE void        pkt_ignore_u8(const olsr_u8_t **p) { *p += sizeof(olsr_u8_t); }
-static INLINE void       pkt_ignore_u16(const olsr_u8_t **p) { *p += sizeof(olsr_u16_t); }
-static INLINE void       pkt_ignore_u32(const olsr_u8_t **p) { *p += sizeof(olsr_u32_t); }
-static INLINE void        pkt_ignore_s8(const olsr_u8_t **p) { *p += sizeof(olsr_8_t); }
-static INLINE void       pkt_ignore_s16(const olsr_u8_t **p) { *p += sizeof(olsr_16_t); }
-static INLINE void       pkt_ignore_s32(const olsr_u8_t **p) { *p += sizeof(olsr_32_t); }
-static INLINE void pkt_ignore_ipaddress(const olsr_u8_t **p) { *p += olsr_cnf->ipsize; }
-
-static INLINE void        pkt_put_u8(olsr_u8_t **p, const olsr_u8_t  var)         { *(olsr_u8_t *)(*p)  = var;        *p += sizeof(olsr_u8_t); }
-static INLINE void       pkt_put_u16(olsr_u8_t **p, const olsr_u16_t var)         { *(olsr_u16_t *)(*p) = htons(var); *p += sizeof(olsr_u16_t); }
-static INLINE void       pkt_put_u32(olsr_u8_t **p, const olsr_u32_t var)         { *(olsr_u32_t *)(*p) = htonl(var); *p += sizeof(olsr_u32_t); }
-static INLINE void        pkt_put_s8(olsr_u8_t **p, const olsr_8_t  var)          { *(olsr_8_t *)(*p)   = var;        *p += sizeof(olsr_8_t); }
-static INLINE void       pkt_put_s16(olsr_u8_t **p, const olsr_16_t var)          { *(olsr_16_t *)(*p)  = htons(var); *p += sizeof(olsr_16_t); }
-static INLINE void       pkt_put_s32(olsr_u8_t **p, const olsr_32_t var)          { *(olsr_32_t *)(*p)  = htonl(var); *p += sizeof(olsr_32_t); }
-static INLINE void    pkt_put_double(olsr_u8_t **p, const double var)             { **p = double_to_me(var);          *p += sizeof(olsr_u8_t); }
-static INLINE void pkt_put_ipaddress(olsr_u8_t **p, const union olsr_ip_addr var) { memcpy(*p, &var, olsr_cnf->ipsize); *p += olsr_cnf->ipsize; }
-static INLINE void        pkt_put_lq(olsr_u8_t **p, const double var)             { **p  = var * 255.0;               *p += sizeof(olsr_u8_t); }
-
-
-
 static void
 create_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
 {
@@ -641,77 +611,6 @@ deserialize_lq_hello(struct hello_message *hello,
     return 0;
 }
 
-static int
-deserialize_lq_tc(struct tc_message *tc,
-                  const void *ser,
-                  union olsr_ip_addr *from)
-{
-    const union olsr_ip_addr *addr;
-    olsr_u8_t type;
-    olsr_u16_t size;
-    const unsigned char *limit;
-
-    // convert received packet from transmission format into internal format
-    const unsigned char *curr = ser;
-    pkt_get_u8(&curr, &type);
-    if (type != LQ_TC_MESSAGE) {
-        /* No need to do anything more */
-        return 1;
-    }
-    pkt_get_double(&curr, &tc->vtime);
-    pkt_get_u16(&curr, &size);
-    // Sven-Ola: Check the message source addr
-    if (!olsr_validate_address((const union olsr_ip_addr *)curr)) {
-        /* No need to do anything more */
-        return 1;
-    }
-    pkt_get_ipaddress(&curr, &tc->originator);
-
-    addr = mid_lookup_main_addr(from);
-    if (addr == NULL) {
-        addr = from;
-    }
-    // Sven-Ola: Check the message source addr
-    if (!olsr_validate_address(addr)) {
-        return 1;
-    }
-    //COPY_IP(&tc->source_addr, addr);
-    tc->source_addr = *addr;
-
-    pkt_get_u8(&curr, &tc->ttl);
-    pkt_get_u8(&curr, &tc->hop_count);
-    pkt_get_u16(&curr, &tc->packet_seq_number);
-    pkt_get_u16(&curr, &tc->ansn);
-    pkt_ignore_u16(&curr);
-
-    tc->multipoint_relay_selector_address = NULL;
-    limit = ser + size;
-    while (curr < limit) {
-        struct tc_mpr_addr *neigh;
-
-        if (!olsr_validate_address((const union olsr_ip_addr *)curr)) {
-            /* Ignore the same amount as below  */
-            pkt_ignore_ipaddress(&curr);
-            pkt_ignore_u8(&curr);
-            pkt_ignore_u8(&curr);
-            pkt_ignore_u16(&curr);
-            continue;
-        }
-
-        neigh = olsr_malloc(sizeof (struct tc_mpr_addr), "LQ_TC deserialization");
-
-        pkt_get_ipaddress(&curr, &neigh->address);
-
-        pkt_get_lq(&curr, &neigh->link_quality);
-        pkt_get_lq(&curr, &neigh->neigh_link_quality);
-        pkt_ignore_u16(&curr);
-
-        neigh->next = tc->multipoint_relay_selector_address;
-        tc->multipoint_relay_selector_address = neigh;
-    }
-    return 0;
-}
-
 void
 olsr_output_lq_hello(void *para)
 {
@@ -798,19 +697,3 @@ olsr_input_lq_hello(union olsr_message *ser,
   }
   olsr_hello_tap(&hello, inif, from);
 }
-
-void
-olsr_input_lq_tc(union olsr_message *ser,
-                 struct interface *inif,
-                 union olsr_ip_addr *from)
-{
-  struct tc_message tc;
-
-  if (ser == NULL) {
-    return;
-  }
-  if (deserialize_lq_tc(&tc, ser, from) != 0) {
-    return;
-  }
-  olsr_tc_tap(&tc, inif, from, ser);
-}
index 38e9116..23c6cf6 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: lq_packet.h,v 1.8 2007/08/29 22:57:17 bernd67 Exp $
+ * $Id: lq_packet.h,v 1.9 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 #ifndef _OLSR_LQ_PACKET_H
@@ -44,6 +44,7 @@
 
 #include "olsr_types.h"
 #include "packet.h"
+#include "mantissa.h"
 
 #define LQ_HELLO_MESSAGE      201
 #define LQ_TC_MESSAGE         202
@@ -140,6 +141,34 @@ struct lq_tc_header
   olsr_u16_t reserved;
 };
 
+static INLINE void        pkt_get_u8(const olsr_u8_t **p, olsr_u8_t  *var)         { *var =       *(olsr_u8_t *)(*p);   *p += sizeof(olsr_u8_t); }
+static INLINE void       pkt_get_u16(const olsr_u8_t **p, olsr_u16_t *var)         { *var = ntohs(*(olsr_u16_t *)(*p)); *p += sizeof(olsr_u16_t); }
+static INLINE void       pkt_get_u32(const olsr_u8_t **p, olsr_u32_t *var)         { *var = ntohl(*(olsr_u32_t *)(p));  *p += sizeof(olsr_u32_t); }
+static INLINE void        pkt_get_s8(const olsr_u8_t **p, olsr_8_t  *var)          { *var =       *(olsr_8_t *)(*p);    *p += sizeof(olsr_8_t); }
+static INLINE void       pkt_get_s16(const olsr_u8_t **p, olsr_16_t *var)          { *var = ntohs(*(olsr_16_t *)(*p));  *p += sizeof(olsr_16_t); }
+static INLINE void       pkt_get_s32(const olsr_u8_t **p, olsr_32_t *var)          { *var = ntohl(*(olsr_32_t *)(*p));  *p += sizeof(olsr_32_t); }
+static INLINE void    pkt_get_double(const olsr_u8_t **p, double *var)             { *var = me_to_double(**p);          *p += sizeof(olsr_u8_t); }
+static INLINE void pkt_get_ipaddress(const olsr_u8_t **p, union olsr_ip_addr *var) { memcpy(var, *p, olsr_cnf->ipsize); *p += olsr_cnf->ipsize; }
+static INLINE void        pkt_get_lq(const olsr_u8_t **p, double *var)             { *var = (double)**p / 255.0;        *p += sizeof(olsr_u8_t); }
+
+static INLINE void        pkt_ignore_u8(const olsr_u8_t **p) { *p += sizeof(olsr_u8_t); }
+static INLINE void       pkt_ignore_u16(const olsr_u8_t **p) { *p += sizeof(olsr_u16_t); }
+static INLINE void       pkt_ignore_u32(const olsr_u8_t **p) { *p += sizeof(olsr_u32_t); }
+static INLINE void        pkt_ignore_s8(const olsr_u8_t **p) { *p += sizeof(olsr_8_t); }
+static INLINE void       pkt_ignore_s16(const olsr_u8_t **p) { *p += sizeof(olsr_16_t); }
+static INLINE void       pkt_ignore_s32(const olsr_u8_t **p) { *p += sizeof(olsr_32_t); }
+static INLINE void pkt_ignore_ipaddress(const olsr_u8_t **p) { *p += olsr_cnf->ipsize; }
+
+static INLINE void        pkt_put_u8(olsr_u8_t **p, const olsr_u8_t  var)         { *(olsr_u8_t *)(*p)  = var;        *p += sizeof(olsr_u8_t); }
+static INLINE void       pkt_put_u16(olsr_u8_t **p, const olsr_u16_t var)         { *(olsr_u16_t *)(*p) = htons(var); *p += sizeof(olsr_u16_t); }
+static INLINE void       pkt_put_u32(olsr_u8_t **p, const olsr_u32_t var)         { *(olsr_u32_t *)(*p) = htonl(var); *p += sizeof(olsr_u32_t); }
+static INLINE void        pkt_put_s8(olsr_u8_t **p, const olsr_8_t  var)          { *(olsr_8_t *)(*p)   = var;        *p += sizeof(olsr_8_t); }
+static INLINE void       pkt_put_s16(olsr_u8_t **p, const olsr_16_t var)          { *(olsr_16_t *)(*p)  = htons(var); *p += sizeof(olsr_16_t); }
+static INLINE void       pkt_put_s32(olsr_u8_t **p, const olsr_32_t var)          { *(olsr_32_t *)(*p)  = htonl(var); *p += sizeof(olsr_32_t); }
+static INLINE void    pkt_put_double(olsr_u8_t **p, const double var)             { **p = double_to_me(var);          *p += sizeof(olsr_u8_t); }
+static INLINE void pkt_put_ipaddress(olsr_u8_t **p, const union olsr_ip_addr var) { memcpy(*p, &var, olsr_cnf->ipsize); *p += olsr_cnf->ipsize; }
+static INLINE void        pkt_put_lq(olsr_u8_t **p, const double var)             { **p  = var * 255.0;               *p += sizeof(olsr_u8_t); }
+
 void olsr_output_lq_hello(void *para);
 
 void olsr_output_lq_tc(void *para);
@@ -147,9 +176,6 @@ void olsr_output_lq_tc(void *para);
 void olsr_input_lq_hello(union olsr_message *ser, struct interface *inif,
                          union olsr_ip_addr *from);
 
-void olsr_input_lq_tc(union olsr_message *ser, struct interface *inif,
-                      union olsr_ip_addr *from);
-
 extern olsr_bool lq_tc_pending;
 
 #endif
index ead111b..9edf642 100644 (file)
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: lq_route.c,v 1.58 2007/11/16 19:12:55 bernd67 Exp $
+ * $Id: lq_route.c,v 1.59 2007/11/16 21:43:55 bernd67 Exp $
  */
 
+#define SPF_PROFILING 1
+
 #include "defs.h"
 #include "olsr.h"
 #include "tc_set.h"
@@ -489,7 +491,7 @@ olsr_calculate_routing_table (void)
   timersub(&t4, &t3, &route);
   timersub(&t5, &t4, &kernel);
   timersub(&t5, &t1, &total);
-  olsr_printf(1, "\n--- SPF-stats for %d nodes, %d routes (total/init/run/route/kern): "
+  OLSR_PRINTF(1, "\n--- SPF-stats for %d nodes, %d routes (total/init/run/route/kern): "
               "%d, %d, %d, %d, %d\n",
               path_count, routingtree.count,
               (int)total.tv_usec, (int)spf_init.tv_usec, (int)spf_run.tv_usec,
index 9abafe3..44d42b9 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: process_package.c,v 1.44 2007/11/09 00:11:01 bernd67 Exp $
+ * $Id: process_package.c,v 1.45 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 
@@ -66,12 +66,12 @@ olsr_init_package_process(void)
   if (olsr_cnf->lq_level == 0)
     {
       olsr_parser_add_function(&olsr_process_received_hello, HELLO_MESSAGE, 1);
-      olsr_parser_add_function(&olsr_process_received_tc, TC_MESSAGE, 1);
+      olsr_parser_add_function(&olsr_input_tc, TC_MESSAGE, 1);
     }
   else
     {
       olsr_parser_add_function(&olsr_input_lq_hello, LQ_HELLO_MESSAGE, 1);
-      olsr_parser_add_function(&olsr_input_lq_tc, LQ_TC_MESSAGE, 1);
+      olsr_parser_add_function(&olsr_input_tc, LQ_TC_MESSAGE, 1);
     }
 
   olsr_parser_add_function(&olsr_process_received_mid, MID_MESSAGE, 1);
@@ -222,116 +222,6 @@ olsr_process_received_hello(union olsr_message *m,
   olsr_hello_tap(&message, in_if, from_addr);
 }
 
-void
-olsr_tc_tap(struct tc_message *message,
-            struct interface *in_if,
-            union olsr_ip_addr *from_addr,
-            union olsr_message *m)
-{
-#ifndef NODEBUG
-  struct ipaddr_str                buf;
-#endif
-  struct tc_mpr_addr              *mpr;
-  struct tc_entry                 *tc_last;
-
-  if (olsr_check_dup_table_proc(&message->originator, 
-                               message->packet_seq_number)) {
-    OLSR_PRINTF(3, "Processing TC from %s, seq 0x%04x\n",
-                olsr_ip_to_string(&buf, &message->originator), message->ansn);
-
-    /*
-     *      If the sender interface (NB: not originator) of this message
-     *      is not in the symmetric 1-hop neighborhood of this node, the
-     *      message MUST be discarded.
-     */
-
-    if (check_neighbor_link(from_addr) != SYM_LINK) {
-      OLSR_PRINTF(2, "Received TC from NON SYM neighbor %s\n",
-                  olsr_ip_to_string(&buf, from_addr));
-      olsr_free_tc_packet(message);
-      return;
-    }
-
-    if (olsr_cnf->debug_level > 2) {
-      mpr = message->multipoint_relay_selector_address;
-      OLSR_PRINTF(3, "mpr_selector_list:[");
-
-      while (mpr != NULL) {
-          OLSR_PRINTF(3, "%s:", olsr_ip_to_string(&buf, &mpr->address));
-          mpr=mpr->next;
-      }
-
-      OLSR_PRINTF(3, "]\n");
-    }
-
-    tc_last = olsr_lookup_tc_entry(&message->originator);
-   
-    if(tc_last != NULL) {
-      /* Update entry */
-
-      /* Delete destinations with lower ANSN */
-      if(olsr_tc_delete_mprs(tc_last, message)) {
-        changes_topology = OLSR_TRUE; 
-      }
-      /* Update destinations */
-      if(olsr_tc_update_mprs(tc_last, message)) {
-        changes_topology = OLSR_TRUE;
-      }
-    } else {
-      /*if message is empty then skip it */
-      if (message->multipoint_relay_selector_address != NULL) {
-          /* New entry */
-          tc_last = olsr_add_tc_entry(&message->originator);      
-         
-          /* Update destinations */
-          olsr_tc_update_mprs(tc_last, message);
-         
-          changes_topology = OLSR_TRUE;
-      } else {
-        OLSR_PRINTF(3, "Dropping empty TC from %s\n",
-                    olsr_ip_to_string(&buf, &message->originator));
-      }
-    }
-
-  /* Process changes */
-  //olsr_process_changes();
-
-  }
-
-  olsr_forward_message(m, 
-                       &message->originator, 
-                       message->packet_seq_number, 
-                       in_if,
-                       from_addr);
-
-  olsr_free_tc_packet(message);
-}
-
-/**
- *Process a received TopologyControl message
- *
- *
- *@param m the incoming OLSR message
- *@return 0 on success
- */
-void
-olsr_process_received_tc(union olsr_message *m,
-                         struct interface *in_if,
-                         union olsr_ip_addr *from_addr)
-{ 
-  struct tc_message               message;
-
-  tc_chgestruct(&message, m, from_addr);
-
-  if(!olsr_validate_address(&message.source_addr))
-    {
-      olsr_free_tc_packet(&message);
-      return;
-    }
-
-  olsr_tc_tap(&message, in_if, from_addr, m);
-}
-
 /**
  *Process a received(and parsed) MID message
  *For every address check if there is a topology node
index 0a2178c..6547363 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: process_package.h,v 1.13 2007/11/08 22:47:41 bernd67 Exp $
+ * $Id: process_package.h,v 1.14 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 
@@ -57,12 +57,6 @@ void
 olsr_process_received_hello(union olsr_message *, struct interface *, union olsr_ip_addr *);
 
 void
-olsr_tc_tap(struct tc_message *, struct interface *, union olsr_ip_addr *, union olsr_message *);
-
-void
-olsr_process_received_tc(union olsr_message *, struct interface *, union olsr_ip_addr *);
-
-void
 olsr_process_received_mid(union olsr_message *, struct interface *, union olsr_ip_addr *);
 
 void
index 0f06ac2..9d4608b 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: rebuild_packet.c,v 1.23 2007/11/08 22:47:41 bernd67 Exp $
+ * $Id: rebuild_packet.c,v 1.24 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 
@@ -463,108 +463,3 @@ hello_chgestruct(struct hello_message *hmsg, const union olsr_message *m)
     }
 
 }
-
-
-/**
- *Process/rebuild TC message. Converts the OLSR
- *packet to the internal tc_message format.
- *@param tmsg the tc_message struct in wich infomation
- *is to be put.
- *@param m the entire OLSR message revieved.
- *@param from a sockaddr struct describing the 1 hop sender
- *@return negative on error
- */
-
-void
-tc_chgestruct(struct tc_message *tmsg, const union olsr_message *m, const union olsr_ip_addr *from_addr)
-{
-  struct tc_mpr_addr *mprs;
-
-  tmsg->multipoint_relay_selector_address = NULL;
-
-  if ((!m) || (m->v4.olsr_msgtype != TC_MESSAGE))
-    return;
-
-  if(olsr_cnf->ip_version == AF_INET)
-    {
-      /* IPv4 */
-      const struct olsr_tcmsg *tc = &m->v4.message.tc;
-      const struct neigh_info *mprsaddr = tc->neigh;
-      const struct neigh_info *maddr;
-      const union olsr_ip_addr * const tmp_addr = mid_lookup_main_addr(from_addr);
-
-      if(tmp_addr == NULL) {
-        //COPY_IP(&tmsg->source_addr, from_addr);
-        tmsg->source_addr = *from_addr;
-      } else {
-        //COPY_IP(&tmsg->source_addr, tmp_addr);
-        tmsg->source_addr = *tmp_addr;
-      }
-
-      /* Get vtime */
-      tmsg->vtime = me_to_double(m->v4.olsr_vtime);
-
-      OLSR_PRINTF(3, "Got TC vtime: %f\n", tmsg->vtime);
-
-      //COPY_IP(&tmsg->originator, &m->v4.originator);
-      tmsg->originator.v4.s_addr = m->v4.originator;
-      tmsg->packet_seq_number = ntohs(m->v4.seqno);
-      tmsg->hop_count =  m->v4.hopcnt;
-      tmsg->ansn =  ntohs(tc->ansn);
-
-      //printf("TC from %s seqno %d\n", olsr_ip_to_string(&buf, &tmsg->originator), tmsg->packet_seq_number);
-
-      for (maddr = mprsaddr; (char *)maddr < ((char *)m + (ntohs(m->v4.olsr_msgsize))); maddr++)
-       {
-         
-         mprs = olsr_malloc(sizeof(struct tc_mpr_addr), "TC chgestruct");
-
-         //COPY_IP(&mprs->address, &maddr->addr);
-         mprs->address.v4.s_addr = maddr->addr;
-         mprs->next = tmsg->multipoint_relay_selector_address;
-         tmsg->multipoint_relay_selector_address = mprs;
-       }
-    }
-  else
-    {
-      /* IPv6 */
-      const struct neigh_info6 *maddr6;
-      const struct olsr_tcmsg6 *tc6 = &m->v6.message.tc;
-      const struct neigh_info6 *mprsaddr6 = tc6->neigh;
-      const union olsr_ip_addr * const tmp_addr = mid_lookup_main_addr(from_addr);
-
-      if(tmp_addr == NULL) {
-        //COPY_IP(&tmsg->source_addr, from_addr);
-        tmsg->source_addr = *from_addr;
-      } else {
-        //COPY_IP(&tmsg->source_addr, tmp_addr);
-        tmsg->source_addr = *tmp_addr;
-      }
-
-      /* Check if sender is symmetric neighbor here !! */
-      
-      /* Get vtime */
-      tmsg->vtime = me_to_double(m->v6.olsr_vtime);
-
-      OLSR_PRINTF(3, "Got TC vtime: %f\n", tmsg->vtime);
-
-      //COPY_IP(&tmsg->originator, &m->v6.originator);
-      tmsg->originator.v6 = m->v6.originator;
-      tmsg->packet_seq_number = ntohs(m->v6.seqno);
-      tmsg->hop_count =  m->v6.hopcnt;
-      tmsg->ansn =  ntohs(tc6->ansn);
-
-      for (maddr6 = mprsaddr6; (char *)maddr6 < ((char *)m + (ntohs(m->v6.olsr_msgsize))); maddr6++)
-       {
-         
-         mprs = olsr_malloc(sizeof(struct tc_mpr_addr), "TC chgestruct 2");
-
-         //COPY_IP(&mprs->address, &maddr6->addr);
-          mprs->address.v6 = maddr6->addr;
-         mprs->next = tmsg->multipoint_relay_selector_address;
-         tmsg->multipoint_relay_selector_address = mprs;
-       }
-
-    }
-
-}
index c9cc0e7..765e693 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: rebuild_packet.h,v 1.9 2007/11/08 22:47:41 bernd67 Exp $
+ * $Id: rebuild_packet.h,v 1.10 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 
@@ -60,7 +60,4 @@ unk_chgestruct(struct unknown_message *, const union olsr_message *);
 void
 hello_chgestruct(struct hello_message *, const union olsr_message *);
 
-void
-tc_chgestruct(struct tc_message *, const union olsr_message *, const union olsr_ip_addr *);
-
 #endif
index a3a96a1..8e55cda 100644 (file)
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: tc_set.c,v 1.36 2007/11/08 22:47:41 bernd67 Exp $
+ * $Id: tc_set.c,v 1.37 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 #include "tc_set.h"
+#include "mid_set.h"
+#include "link_set.h"
 #include "olsr.h"
 #include "scheduler.h"
 #include "lq_route.h"
 #include "lq_avl.h"
+#include "lq_packet.h"
 #include "net_olsr.h"
 
 #include <assert.h>
@@ -279,7 +282,6 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr,
   memset(tc_edge, 0, sizeof(struct tc_edge_entry));
 
   /* Fill entry */
-  //COPY_IP(&tc_edge->T_dest_addr, addr);
   tc_edge->T_dest_addr = *addr;
   olsr_set_tc_edge_timer(tc_edge, vtime*1000);
   tc_edge->T_seq = ansn;
@@ -394,15 +396,14 @@ olsr_delete_tc_edge_entry(struct tc_edge_entry *tc_edge)
 
 
 /**
- * Delete all destinations that have a
- * lower ANSN than the one in the message
+ * Delete all destinations that have a lower ANSN.
  *
  * @param tc the entry to delete edges from
- * @param msg the message to fetch the ANSN from
+ * @param ansn the advertised neighbor set sequence number
  * @return 1 if any destinations were deleted 0 if not
  */
-int
-olsr_tc_delete_mprs(struct tc_entry *tc, struct tc_message *msg)
+static int
+olsr_delete_outdated_tc_edges(struct tc_entry *tc, olsr_u16_t ansn)
 {
   struct tc_edge_entry *tc_edge;
   int retval = 0;
@@ -412,7 +413,7 @@ olsr_tc_delete_mprs(struct tc_entry *tc, struct tc_message *msg)
 #endif
 
   OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
-    if (SEQNO_GREATER_THAN(msg->ansn, tc_edge->T_seq)) {
+    if (SEQNO_GREATER_THAN(ansn, tc_edge->T_seq)) {
       /*
        * Do not delete the edge now, just mark the edge as down.
        * Downed edges will be ignored by the SPF computation.
@@ -455,93 +456,102 @@ olsr_etx_significant_change(float etx1, float etx2)
 }
 
 /**
- * Update the destinations registered on an entry.
- * Creates new dest-entries if not registered.
- * Bases update on a receivied TC message
+ * Update an edge registered on an entry.
+ * Creates new edge-entries if not registered.
+ * Bases update on a received TC message
  *
  * @param entry the TC entry to check
- * @msg the TC message to update by
+ * @pkt the TC edge entry in the packet
  * @return 1 if entries are added 0 if not
  */
-int
-olsr_tc_update_mprs(struct tc_entry *tc, struct tc_message *msg)
+static int
+olsr_tc_update_edge(struct tc_entry *tc, unsigned int vtime_s, olsr_u16_t ansn,
+                    olsr_u8_t type, const unsigned char **curr)
 {
-  struct tc_mpr_addr *mprs;
   struct tc_edge_entry *tc_edge;
+  double link_quality, neigh_link_quality;
+  union olsr_ip_addr neighbor;
   int edge_change;
 
-#if 0
-  OLSR_PRINTF(1, "TC: update MPRS\n");
-#endif
-
   edge_change = 0;
 
-  mprs = msg->multipoint_relay_selector_address;
-  
-  /* Add all the MPRs */
+  /*
+   * Fetch the per-edge data
+   * LQ messages also contain LQ data.
+   */
+  pkt_get_ipaddress(curr, &neighbor);
 
-  while (mprs) {
+  if (type == LQ_TC_MESSAGE) {
+    pkt_get_lq(curr, &link_quality);
+    pkt_get_lq(curr, &neigh_link_quality);
+    pkt_ignore_u16(curr);
+  } else {
+    link_quality = 1.0;
+    neigh_link_quality = 1.0;
+  }
 
-    /* First check if we know this edge */
-    tc_edge = olsr_lookup_tc_edge(tc, &mprs->address);
+  /* First check if we know this edge */
+  tc_edge = olsr_lookup_tc_edge(tc, &neighbor);
 
-    if(!tc_edge) {
+  if(!tc_edge) {
       
-      /*
-       * Yet unknown - create it.
-       */
-      olsr_add_tc_edge_entry(tc, &mprs->address, msg->ansn,
-                             (unsigned int )msg->vtime,
-                             mprs->link_quality, mprs->neigh_link_quality);
-      edge_change = 1;
+    /*
+     * Yet unknown - create it.
+     * Check if the address is allowed.
+     */
+    if (!olsr_validate_address(&neighbor)) {
+      return 0;
+    }
 
-    } else {
+    olsr_add_tc_edge_entry(tc, &neighbor, ansn, vtime_s,
+                           link_quality, neigh_link_quality);
+    edge_change = 1;
 
-      /*
-       * We know this edge - Update entry.
-       */
-      olsr_set_tc_edge_timer(tc_edge, msg->vtime*1000);
-      tc_edge->T_seq = msg->ansn;
+  } else {
 
-      /*
-       * Clear the (possibly set) down flag.
-       */
-      tc_edge->flags &= ~OLSR_TC_EDGE_DOWN;
+    /*
+     * We know this edge - Update entry.
+     */
+    olsr_set_tc_edge_timer(tc_edge, vtime_s*1000);
+    tc_edge->T_seq = ansn;
 
-      /*
-       * Determine if the etx change is meaningful enough
-       * in order to trigger a SPF calculation.
-       */
-      if (olsr_etx_significant_change(tc_edge->link_quality,
-                                      mprs->neigh_link_quality)) {
+    /*
+     * Clear the (possibly set) down flag.
+     */
+    tc_edge->flags &= ~OLSR_TC_EDGE_DOWN;
 
-        if (msg->hop_count <= olsr_cnf->lq_dlimit)
-          edge_change = 1;
-      }
-      tc_edge->link_quality = mprs->neigh_link_quality;
+    /*
+     * Determine if the etx change is meaningful enough
+     * in order to trigger a SPF calculation.
+     */
+    if (olsr_etx_significant_change(tc_edge->link_quality,
+                                    neigh_link_quality)) {
 
-      if (olsr_etx_significant_change(tc_edge->inverse_link_quality,
-                                      mprs->link_quality)) {
+      if (tc->msg_hops <= olsr_cnf->lq_dlimit)
+        edge_change = 1;
+    }
+    tc_edge->link_quality = neigh_link_quality;
 
-        if (msg->hop_count <= olsr_cnf->lq_dlimit)
-          edge_change = 1;
-      }
-      tc_edge->inverse_link_quality = mprs->link_quality;
+    if (olsr_etx_significant_change(tc_edge->inverse_link_quality,
+                                    link_quality)) {
 
-      /*
-       * Update the etx.
-       */
-      olsr_calc_tc_edge_entry_etx(tc_edge);
+      if (tc->msg_hops <= olsr_cnf->lq_dlimit)
+        edge_change = 1;
+    }
+    tc_edge->inverse_link_quality = link_quality;
+
+    /*
+     * Update the etx.
+     */
+    olsr_calc_tc_edge_entry_etx(tc_edge);
 
 #if 0
-      if (edge_change) {          
-        OLSR_PRINTF(1, "TC:   chg edge entry %s\n",
-                    olsr_tc_edge_to_string(tc_edge));
-      }
+    if (edge_change) {          
+      OLSR_PRINTF(1, "TC:   chg edge entry %s\n",
+                  olsr_tc_edge_to_string(tc_edge));
+    }
 #endif
 
-    }
-    mprs = mprs->next;
   }
 
   return edge_change;
@@ -637,6 +647,135 @@ float olsr_calc_tc_etx(const struct tc_edge_entry *tc_edge)
 }
 
 /*
+ * Process an incoming TC or TC_LQ message.
+ *
+ * If the message is interesting enough, update our edges for it,
+ * trigger SPF and finally flood it to all our 2way neighbors.
+ *
+ * The order for extracting data off the message does matter, 
+ * as every call to pkt_get increases the packet offset and
+ * hence the spot we are looking at.
+ */
+void
+olsr_input_tc(union olsr_message *msg, struct interface *input_if,
+              union olsr_ip_addr *from_addr)
+{
+#ifndef NODEBUG 
+  struct ipaddr_str buf;
+#endif
+  olsr_u16_t size, msg_seq, ansn;
+  olsr_u8_t type, ttl, msg_hops;
+  double vtime;
+  unsigned int vtime_s;
+  union olsr_ip_addr originator;
+  union olsr_ip_addr *main_addr;
+  const unsigned char *limit, *curr;
+  struct tc_entry *tc;
+
+  curr = (void *)msg;
+  if (!msg) {
+    return;
+  }
+
+  /* We are only interested in TC message types. */
+  pkt_get_u8(&curr, &type);
+  if ((type != LQ_TC_MESSAGE) && (type != TC_MESSAGE)) {
+    return;
+  }
+
+  pkt_get_double(&curr, &vtime);
+  vtime_s = (unsigned int)vtime;
+  pkt_get_u16(&curr, &size);
+
+  pkt_get_ipaddress(&curr, &originator);
+
+  /* Copy header values */
+  pkt_get_u8(&curr, &ttl);
+  pkt_get_u8(&curr, &msg_hops);
+  pkt_get_u16(&curr, &msg_seq);
+  pkt_get_u16(&curr, &ansn);
+  pkt_ignore_u16(&curr);
+
+  /*
+   * Check if we know this guy and if we already know what he has to say.
+   */
+  tc = olsr_lookup_tc_entry(&originator);
+  if (tc) {
+    if (!SEQNO_GREATER_THAN(msg_seq, tc->msg_seq)) {
+      return;
+    }
+  }
+
+  /* Check the sender address. */
+  if (!olsr_validate_address(&originator)) {
+    return;
+  }
+
+  /* Check the main address. */
+  main_addr = mid_lookup_main_addr(from_addr);
+  if (!main_addr) {
+    main_addr = from_addr;
+  }
+  if (!olsr_validate_address(main_addr)) {
+    return;
+  }
+
+  /*
+   * Generate an new tc_entry in the lsdb and store the sequence number.
+   */
+  if (!tc) {
+    tc = olsr_add_tc_entry(&originator);
+    tc->msg_seq = msg_seq;
+  }
+
+  OLSR_PRINTF(1, "Processing TC from %s, seq 0x%04x\n",
+              olsr_ip_to_string(&buf, &originator), ansn);
+
+  /*
+   * If the sender interface (NB: not originator) of this message
+   * is not in the symmetric 1-hop neighborhood of this node, the
+   * message MUST be discarded.
+   */
+  if (check_neighbor_link(from_addr) != SYM_LINK) {
+    OLSR_PRINTF(2, "Received TC from NON SYM neighbor %s\n",
+                olsr_ip_to_string(&buf, from_addr));
+    return;
+  }
+
+  /*
+   * Update the tc entry.
+   */
+  tc->msg_hops = msg_hops;
+  tc->msg_seq = msg_seq;
+
+  /*
+   * Now walk the edge advertisements contained in the packet.
+   * Play some efficiency games here, like checking first
+   * if the edge exists in order to avoid address validation.
+   */
+  limit = (void *)msg + size;
+  while (curr < limit) {
+    if (olsr_tc_update_edge(tc, vtime_s, ansn, type, &curr)) {
+      changes_topology = OLSR_TRUE;
+    }
+  }
+
+  /*
+   * Do the edge garbage collection at the end in order
+   * to avoid malloc() churn.
+   */
+  if (olsr_delete_outdated_tc_edges(tc, ansn)) {
+    changes_topology = OLSR_TRUE;
+  }
+
+  /*
+   * Last, flood the message to our other neighbors.
+   */
+  olsr_forward_message(msg, &originator, msg_seq, input_if, from_addr);
+  return;
+}
+
+/*
  * Local Variables:
  * c-basic-offset: 2
  * End:
index 15ef827..5f0a28d 100644 (file)
@@ -37,7 +37,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: tc_set.h,v 1.22 2007/11/08 22:47:41 bernd67 Exp $
+ * $Id: tc_set.h,v 1.23 2007/11/16 21:43:55 bernd67 Exp $
  */
 
 #ifndef _OLSR_TOP_SET
@@ -62,7 +62,7 @@ struct tc_edge_entry
   struct tc_edge_entry *edge_inv; /* shortcut, used during SPF calculation */
   struct tc_entry    *tc; /* backpointer to owning tc entry */
   clock_t            T_time; /* expiration timer, timer_node key */
-  olsr_u16_t         T_seq; /* sequence number */
+  olsr_u16_t         T_seq; /* sequence number of the advertised neighbor set */
   olsr_u16_t         flags; /* misc flags */
   float              etx; /* metric used for SPF calculation */
   float              link_quality;
@@ -85,6 +85,8 @@ struct tc_entry
   struct avl_tree    edge_tree; /* subtree for edges */
   struct link_entry *next_hop; /* SPF calculated link to the 1st hop neighbor */
   float              path_etx; /* SPF calculated distance, cand_tree_node key */
+  olsr_u16_t         msg_seq; /* sequence number of the tc message */
+  olsr_u8_t          msg_hops; /* hopcount as per the tc message */
   olsr_u8_t          hops; /* SPF calculated hopcount */
 };
 
@@ -119,11 +121,13 @@ extern struct tc_entry *tc_myself;
 
 void olsr_init_tc(void);
 void olsr_change_myself_tc(void);
-int olsr_tc_delete_mprs(struct tc_entry *, struct tc_message *);
-int olsr_tc_update_mprs(struct tc_entry *, struct tc_message *);
 void olsr_print_tc_table(void);
 void olsr_time_out_tc_set(void);
 
+/* tc msg input parser */
+void olsr_input_tc(union olsr_message *, struct interface *,
+                   union olsr_ip_addr *from);
+
 /* tc_entry manipulation */
 struct tc_entry *olsr_lookup_tc_entry(union olsr_ip_addr *);
 struct tc_entry *olsr_add_tc_entry(union olsr_ip_addr *);