add tc fragmentation support again
authorHenning Rogge <hrogge@googlemail.com>
Sat, 8 Aug 2009 20:55:21 +0000 (22:55 +0200)
committerHenning Rogge <hrogge@googlemail.com>
Sat, 8 Aug 2009 20:55:21 +0000 (22:55 +0200)
move tc/hna/mid generation to global timer

src/hna_set.c
src/interfaces.c
src/interfaces.h
src/main.c
src/mid_set.c
src/tc_set.c
src/unix/ifnet.c

index fe12f23..961126a 100644 (file)
@@ -339,15 +339,15 @@ olsr_input_hna(union olsr_message *msg, struct interface *in_if __attribute__ ((
 }
 
 void
 }
 
 void
-generate_hna(void *p) {
-  struct interface *ifp = p;
+generate_hna(void *p __attribute__ ((unused))) {
+  struct interface *ifp;
   struct ip_prefix_entry *h;
   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
   uint8_t *curr = msg_buffer;
   uint8_t *length_field, *last;
   bool sendHNA = false;
 
   struct ip_prefix_entry *h;
   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
   uint8_t *curr = msg_buffer;
   uint8_t *length_field, *last;
   bool sendHNA = false;
 
-  OLSR_INFO(LOG_PACKET_CREATION, "Building HNA on %s\n-------------------\n", ifp->int_name);
+  OLSR_INFO(LOG_PACKET_CREATION, "Building HNA\n-------------------\n");
 
   pkt_put_u8(&curr, HNA_MESSAGE);
   pkt_put_reltime(&curr, olsr_cnf->hna_params.validity_time);
 
   pkt_put_u8(&curr, HNA_MESSAGE);
   pkt_put_reltime(&curr, olsr_cnf->hna_params.validity_time);
@@ -377,11 +377,13 @@ generate_hna(void *p) {
 
   pkt_put_u16(&length_field, curr - msg_buffer);
 
 
   pkt_put_u16(&length_field, curr - msg_buffer);
 
-  if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
-    net_output(ifp);
-    set_buffer_timer(ifp);
-  }
-  net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
+  OLSR_FOR_ALL_INTERFACES(ifp) {
+    if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
+      net_output(ifp);
+      set_buffer_timer(ifp);
+    }
+    net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
+  } OLSR_FOR_ALL_INTERFACES_END(ifp)
 }
 
 /*
 }
 
 /*
index bf85125..05cd772 100644 (file)
@@ -261,12 +261,6 @@ remove_interface(struct interface **pinterf)
    */
   olsr_stop_timer(ifp->hello_gen_timer);
   ifp->hello_gen_timer = NULL;
    */
   olsr_stop_timer(ifp->hello_gen_timer);
   ifp->hello_gen_timer = NULL;
-  olsr_stop_timer(ifp->tc_gen_timer);
-  ifp->tc_gen_timer = NULL;
-  olsr_stop_timer(ifp->mid_gen_timer);
-  ifp->mid_gen_timer = NULL;
-  olsr_stop_timer(ifp->hna_gen_timer);
-  ifp->hna_gen_timer = NULL;
 
   /*
    * Stop interface pacing.
 
   /*
    * Stop interface pacing.
index d2ba117..ea18147 100644 (file)
@@ -146,9 +146,6 @@ struct interface {
 
   /* Periodic message generation timers */
   struct timer_entry *hello_gen_timer;
 
   /* Periodic message generation timers */
   struct timer_entry *hello_gen_timer;
-  struct timer_entry *hna_gen_timer;
-  struct timer_entry *mid_gen_timer;
-  struct timer_entry *tc_gen_timer;
 
   /* Message build related  */
   struct timer_entry *buffer_hold_timer;        /* Timer for message batching */
 
   /* Message build related  */
   struct timer_entry *buffer_hold_timer;        /* Timer for message batching */
index 7002dc3..3f3017c 100644 (file)
@@ -98,6 +98,10 @@ static char copyright_string[] __attribute__ ((unused)) =
 static char pulsedata[] = "\\|/-";
 static uint8_t pulse_state = 0;
 
 static char pulsedata[] = "\\|/-";
 static uint8_t pulse_state = 0;
 
+static struct timer_entry *hna_gen_timer;
+static struct timer_entry *mid_gen_timer;
+static struct timer_entry *tc_gen_timer;
+
 static void
 generate_stdout_pulse(void *foo __attribute__ ((unused)))
 {
 static void
 generate_stdout_pulse(void *foo __attribute__ ((unused)))
 {
@@ -391,10 +395,24 @@ main(int argc, char *argv[])
 
   link_changes = false;
 
 
   link_changes = false;
 
+  tc_gen_timer =
+    olsr_start_timer(olsr_cnf->tc_params.emission_interval,
+                     TC_JITTER, OLSR_TIMER_PERIODIC, &olsr_output_lq_tc, NULL, tc_gen_timer_cookie);
+  mid_gen_timer =
+    olsr_start_timer(olsr_cnf->mid_params.emission_interval,
+                     MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, NULL, mid_gen_timer_cookie);
+  hna_gen_timer =
+    olsr_start_timer(olsr_cnf->hna_params.emission_interval,
+                     HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, NULL, hna_gen_timer_cookie);
+
   /* Starting scheduler */
   app_state = STATE_RUNNING;
   olsr_scheduler();
 
   /* Starting scheduler */
   app_state = STATE_RUNNING;
   olsr_scheduler();
 
+  olsr_stop_timer(tc_gen_timer);
+  olsr_stop_timer(mid_gen_timer);
+  olsr_stop_timer(hna_gen_timer);
+
   exitcode = olsr_cnf->exit_value;
   switch (app_state) {
   case STATE_INIT:
   exitcode = olsr_cnf->exit_value;
   switch (app_state) {
   case STATE_INIT:
index adb693f..0476f90 100644 (file)
@@ -530,14 +530,14 @@ olsr_input_mid(union olsr_message *msg, struct interface *input_if __attribute__
 }
 
 void
 }
 
 void
-generate_mid(void *p) {
-  struct interface *ifp = p, *allif;
+generate_mid(void *p  __attribute__ ((unused))) {
+  struct interface *ifp, *allif;
   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
   uint8_t *curr = msg_buffer;
   uint8_t *length_field, *last;
   bool sendMID = false;
 
   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
   uint8_t *curr = msg_buffer;
   uint8_t *length_field, *last;
   bool sendMID = false;
 
-  OLSR_INFO(LOG_PACKET_CREATION, "Building MID on %s\n-------------------\n", ifp->int_name);
+  OLSR_INFO(LOG_PACKET_CREATION, "Building MID\n-------------------\n");
 
   pkt_put_u8(&curr, MID_MESSAGE);
   pkt_put_reltime(&curr, olsr_cnf->mid_params.validity_time);
 
   pkt_put_u8(&curr, MID_MESSAGE);
   pkt_put_reltime(&curr, olsr_cnf->mid_params.validity_time);
@@ -569,11 +569,13 @@ generate_mid(void *p) {
 
   pkt_put_u16(&length_field, curr - msg_buffer);
 
 
   pkt_put_u16(&length_field, curr - msg_buffer);
 
-  if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
-    net_output(ifp);
-    set_buffer_timer(ifp);
-  }
-  net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
+  OLSR_FOR_ALL_INTERFACES(ifp) {
+    if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
+      net_output(ifp);
+      set_buffer_timer(ifp);
+    }
+    net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
+  } OLSR_FOR_ALL_INTERFACES_END(ifp)
 }
 /*
  * Local Variables:
 }
 /*
  * Local Variables:
index c00ab05..88209ca 100644 (file)
@@ -62,6 +62,7 @@ struct olsr_cookie_info *spf_backoff_timer_cookie = NULL;
 struct olsr_cookie_info *tc_mem_cookie = NULL;
 
 static uint32_t relevantTcCount = 0;
 struct olsr_cookie_info *tc_mem_cookie = NULL;
 
 static uint32_t relevantTcCount = 0;
+static int ttl_index = 0;
 
 static void olsr_cleanup_tc_entry(struct tc_entry *tc);
 
 
 static void olsr_cleanup_tc_entry(struct tc_entry *tc);
 
@@ -952,7 +953,6 @@ olsr_delete_all_tc_entries(void) {
   }OLSR_FOR_ALL_TC_ENTRIES_END(tc)
 }
 
   }OLSR_FOR_ALL_TC_ENTRIES_END(tc)
 }
 
-#if 0
 static uint8_t
 calculate_border_flag(void *lower_border, void *higher_border)
 {
 static uint8_t
 calculate_border_flag(void *lower_border, void *higher_border)
 {
@@ -981,21 +981,20 @@ calculate_border_flag(void *lower_border, void *higher_border)
   bitpos += 8 * (olsr_cnf->ipsize - part - 1);
   return bitpos + 1;
 }
   bitpos += 8 * (olsr_cnf->ipsize - part - 1);
   return bitpos + 1;
 }
-#endif
 
 
-void
-olsr_output_lq_tc(void *ctx)
+static bool
+olsr_output_lq_tc_internal(void *ctx  __attribute__ ((unused)), union olsr_ip_addr *nextIp, bool skip)
 {
   static int ttl_list[] = { 2, 8, 2, 16, 2, 8, 2, MAX_TTL };
 {
   static int ttl_list[] = { 2, 8, 2, 16, 2, 8, 2, MAX_TTL };
-  struct interface *ifp = ctx;
+  struct interface *ifp;
   struct nbr_entry *nbr;
   struct link_entry *link;
   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
   uint8_t *curr = msg_buffer;
   struct nbr_entry *nbr;
   struct link_entry *link;
   uint8_t msg_buffer[MAXMESSAGESIZE - OLSR_HEADERSIZE];
   uint8_t *curr = msg_buffer;
-  uint8_t *length_field, *last;
-  bool sendTC = false;
+  uint8_t *length_field, *border_flags, *last;
+  bool sendTC = false, nextFragment = false;
 
 
-  OLSR_INFO(LOG_PACKET_CREATION, "Building TC on %s\n-------------------\n", ifp->int_name);
+  OLSR_INFO(LOG_PACKET_CREATION, "Building TC\n-------------------\n");
 
   pkt_put_u8(&curr, olsr_get_TC_MessageId());
   pkt_put_reltime(&curr, olsr_cnf->tc_params.validity_time);
 
   pkt_put_u8(&curr, olsr_get_TC_MessageId());
   pkt_put_reltime(&curr, olsr_cnf->tc_params.validity_time);
@@ -1006,24 +1005,55 @@ olsr_output_lq_tc(void *ctx)
   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
 
   if (olsr_cnf->lq_fish > 0) {
   pkt_put_ipaddress(&curr, &olsr_cnf->router_id);
 
   if (olsr_cnf->lq_fish > 0) {
-    pkt_put_u8(&curr, ttl_list[ifp->ttl_index]);
-    OLSR_DEBUG(LOG_PACKET_CREATION, "Creating LQ TC with TTL %d.\n", ttl_list[ifp->ttl_index]);
+    /* handle fisheye */
+    pkt_put_u8(&curr, ttl_list[ttl_index]);
+    OLSR_DEBUG(LOG_PACKET_CREATION, "Creating LQ TC with TTL %d.\n", ttl_list[ttl_index]);
 
 
-    ifp->ttl_index++;
-    ifp->ttl_index %= ARRAYSIZE(ttl_list);
+    ttl_index++;
+    ttl_index %= ARRAYSIZE(ttl_list);
   }
   else {
   }
   else {
-    pkt_put_u8(&curr, 255);
+    /* normal TTL */
+    pkt_put_u8(&curr, MAX_TTL);
   }
   }
+
+  /* hopcount */
   pkt_put_u8(&curr, 0);
   pkt_put_u8(&curr, 0);
-  pkt_put_u16(&curr, get_msg_seqno());
 
 
+  pkt_put_u16(&curr, get_msg_seqno());
   pkt_put_u16(&curr, get_local_ansn_number(false));
   pkt_put_u16(&curr, get_local_ansn_number(false));
-  pkt_put_u16(&curr, 0xffff); /* TODO: border flags and fragmentation */
+
+  /* border flags */
+  border_flags = curr;
+  pkt_put_u16(&curr, 0xffff);
 
   last = msg_buffer + sizeof(msg_buffer) - olsr_cnf->ipsize - olsr_sizeof_TCLQ();
 
   OLSR_FOR_ALL_NBR_ENTRIES(nbr) {
 
   last = msg_buffer + sizeof(msg_buffer) - olsr_cnf->ipsize - olsr_sizeof_TCLQ();
 
   OLSR_FOR_ALL_NBR_ENTRIES(nbr) {
+    /* allow fragmentation */
+    if (skip) {
+      struct nbr_entry *prevNbr;
+      if (olsr_ipcmp(&nbr->nbr_addr, nextIp) != 0) {
+        continue;
+      }
+      skip = false;
+
+      /* rewrite lower border flag */
+      prevNbr = nbr_node_to_nbr(nbr->nbr_node.prev);
+      *border_flags = calculate_border_flag(&prevNbr->nbr_addr, &nbr->nbr_addr);
+    }
+
+    /* too long ? */
+    if (curr > last) {
+      /* rewrite upper border flag */
+      struct nbr_entry *prevNbr = nbr_node_to_nbr(nbr->nbr_node.prev);
+
+      *(border_flags+1) = calculate_border_flag(&prevNbr->nbr_addr, &nbr->nbr_addr);
+      *nextIp = nbr->nbr_addr;
+      nextFragment = true;
+      break;
+    }
+
     /*
      * TC redundancy 2
      *
     /*
      * TC redundancy 2
      *
@@ -1069,17 +1099,31 @@ olsr_output_lq_tc(void *ctx)
     sendTC = true;
   } OLSR_FOR_ALL_NBR_ENTRIES_END(nbr)
 
     sendTC = true;
   } OLSR_FOR_ALL_NBR_ENTRIES_END(nbr)
 
-  if (!sendTC) {
-    return;
+  if (!sendTC && skip) {
+    OLSR_DEBUG(LOG_TC, "Nothing to send for this TC...\n");
+    return false;
   }
 
   pkt_put_u16(&length_field, curr - msg_buffer);
 
   }
 
   pkt_put_u16(&length_field, curr - msg_buffer);
 
-  if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
-    net_output(ifp);
-    set_buffer_timer(ifp);
-  }
-  net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
+  OLSR_FOR_ALL_INTERFACES(ifp) {
+    if (net_outbuffer_bytes_left(ifp) < curr - msg_buffer) {
+      net_output(ifp);
+      set_buffer_timer(ifp);
+    }
+    net_outbuffer_push(ifp, msg_buffer, curr - msg_buffer);
+  } OLSR_FOR_ALL_INTERFACES_END(ifp)
+  return nextFragment;
+}
+
+void
+olsr_output_lq_tc(void *ctx) {
+  union olsr_ip_addr next;
+  bool skip = false;
+
+  memset(&next, 0, sizeof(next));
+
+  while ((skip = olsr_output_lq_tc_internal(ctx, &next, skip)));
 }
 
 /*
 }
 
 /*
index e518d86..b7088ce 100644 (file)
@@ -593,16 +593,6 @@ chk_if_up(struct olsr_if_config *iface)
   ifp->hello_gen_timer =
     olsr_start_timer(iface->cnf->hello_params.emission_interval,
                      HELLO_JITTER, OLSR_TIMER_PERIODIC, &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
   ifp->hello_gen_timer =
     olsr_start_timer(iface->cnf->hello_params.emission_interval,
                      HELLO_JITTER, OLSR_TIMER_PERIODIC, &olsr_output_lq_hello, ifp, hello_gen_timer_cookie);
-  ifp->tc_gen_timer =
-    olsr_start_timer(olsr_cnf->tc_params.emission_interval,
-                     TC_JITTER, OLSR_TIMER_PERIODIC, &olsr_output_lq_tc, ifp, tc_gen_timer_cookie);
-  ifp->mid_gen_timer =
-    olsr_start_timer(olsr_cnf->mid_params.emission_interval,
-                     MID_JITTER, OLSR_TIMER_PERIODIC, &generate_mid, ifp, mid_gen_timer_cookie);
-  ifp->hna_gen_timer =
-    olsr_start_timer(olsr_cnf->hna_params.emission_interval,
-                     HNA_JITTER, OLSR_TIMER_PERIODIC, &generate_hna, ifp, hna_gen_timer_cookie);
-
   ifp->hello_interval = iface->cnf->hello_params.emission_interval;
   ifp->hello_validity = iface->cnf->hello_params.validity_time;
 
   ifp->hello_interval = iface->cnf->hello_params.emission_interval;
   ifp->hello_validity = iface->cnf->hello_params.validity_time;