Sync with git://git.acinonyx.ath.cx/olsrd-quagga.git
authorVasilis Tsiligiannis <b_tsiligiannis@silverton.gr>
Fri, 9 Jan 2009 23:59:38 +0000 (01:59 +0200)
committerVasilis Tsiligiannis <b_tsiligiannis@silverton.gr>
Fri, 9 Jan 2009 23:59:38 +0000 (01:59 +0200)
lib/quagga/Makefile
lib/quagga/README_QUAGGA
lib/quagga/src/olsrd_plugin.c
lib/quagga/src/quagga.c
lib/quagga/src/quagga.h
lib/quagga/src/quagga/zassert.h [deleted file]
lib/quagga/src/quagga/zebra.h [deleted file]
lib/quagga/test/foo.c [deleted file]
lib/quagga/test/foo.pl [deleted file]
lib/quagga/test/quagga.try1.c [deleted file]

index 916163f..1850acf 100644 (file)
@@ -40,21 +40,19 @@ OLSRD_PLUGIN =      true
 PLUGIN_NAME =  olsrd_quagga
 PLUGIN_VER =   0.2.2
 
-TOPDIR= ../..
+TOPDIR = ../..
 include $(TOPDIR)/Makefile.inc
 
-#CPPFLAGS +=-DMY_DEBUG 
 CFLAGS += -g
 CPPFLAGS +=-DUSE_UNIX_DOMAIN_SOCKET
 
-#uncomment the following line only if you are sure what you're doing, it will 
-#probably break things! 
-# CPPFLAGS +=-DZEBRA_HEADER_MARKER=255 
-
 ifeq ($(OS),win32)
+
 default_target install clean:
-       @echo "**** Quagga not supportet on Windows (so it would be pointless to build the Quagga Plugin)"
+       @echo "*** Quagga not supported on Windows (so it would be pointless to build the Quagga plugin)"
+
 else
+
 default_target: $(PLUGIN_FULLNAME)
 
 $(PLUGIN_FULLNAME): $(OBJS) version-script.txt
@@ -66,4 +64,5 @@ install:      $(PLUGIN_FULLNAME)
 
 clean:
                rm -f $(OBJS) $(SRCS:%.c=%.d) $(PLUGIN_FULLNAME)
+
 endif
index 4a93c6f..ebc137d 100644 (file)
@@ -1,20 +1,20 @@
 ---------------------------------------------------------------------
 QUAGGA PLUGIN FOR OLSRD
 by Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+
+addittions by: Sven-Ola Tuecke <sven-ola-aet-gmx.de>
+               Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
 ---------------------------------------------------------------------
 
-This is the Quagga Plugin for the OLSRD
-It allowes olsrd to redistribute from various quagga-protocols 
+This is the Quagga Plugin for OLSRd
+It allows olsrd to redistribute from various quagga-protocols 
 as well as to export olsr-routes to quagga so that they can be
 redistributed by the quagga-routing-daemons.
 
-Note Sven-Ola: You also need a source distribution of quagga-0.98.5
-or quagga-0.98.6 (that is the current stable). The quagga source tree 
-needs to be patched with quagga-0.98.6-olsr.diff, compiled and installed
-via 'make install'. Because many people will otherwise have compile
-probs, I've added 2 include files in lib/quagga/src/quagga. If you
-want to use another version of quagga, make sure to remove these
-before you compile the olsrd_quagga plugin.
+You also need a source distribution of quagga-0.98.5 or quagga-0.98.6
+(that is the current stable). The quagga source tree needs to be
+patched with quagga-0.98.6.diff, compiled and installed via
+'make install'.
 
 ---------------------------------------------------------------------
 PLUGIN PARAMETERS (PlParam)
@@ -27,22 +27,22 @@ PlParam "redistribute" "<protocol>"
        May be used more then once
 
 PlParam "ExportRoutes" "<only/both>"
-       exportes olsr-routes to quagga or to both, quagga and kernel
+       exports olsr-routes to quagga or to both, quagga and kernel
        no routes are exported to quagga (normal behaviour) if not set.
 
-PlParam "LocalPref" "true"
+PlParam "LocalPref" "<true/false>"
         sets the Zebra SELECTED-flag on the routes exported to zebra
        which means these routes are prefered in any case.
 
 PlParam "Distance" "0-255"
-        allowes to set the administrative distance to routes exported 
-       to Zebra.
+        allows to set the administrative distance to routes exported 
+       to zebra.
        
 ---------------------------------------------------------------------
 SAMPLE CONFIG
 ---------------------------------------------------------------------
 
-add in /etc/olsrd.conf:
+add in /usr/local/etc/olsrd.conf:
 
 LoadPlugin "olsrd_quagga.so.0.2.2"
 {
@@ -55,4 +55,4 @@ LoadPlugin "olsrd_quagga.so.0.2.2"
 
 
 ---------------------------------------------------------------------
-EOF / 8.5.2006
+EOF / 29.12.2008
index 1a19aba..c549701 100644 (file)
@@ -1,18 +1,21 @@
-/***************************************************************************
- projekt              : olsrd-quagga
- file                 : olsrd_plugin.c
- usage                : olsrd-plugin-handler-stuff
- copyright            : (C) 2006 by Immo 'FaUl' Wehrenberg
- e-mail               : immo@chaostreff-dortmund.de
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License version 2 as     *
- *   published by the Free Software Foundation.                            *
- *                                                                         *
- ***************************************************************************/
+/*
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+ * Copyright (C) 2007-2008 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or - at your option - under
+ * the terms of the GNU General Public Licence version 2 but can be
+ * linked to any BSD-Licenced Software with public available sourcecode
+ *
+ */
+
+/* -------------------------------------------------------------------------
+ * File               : olsrd_plugin.c
+ * Description        : functions to setup plugin
+ * ------------------------------------------------------------------------- */
 
 
 #include <stdio.h>
 
 #include "olsrd_plugin.h"
 #include "plugin_util.h"
-#include "olsr.h"
 #include "scheduler.h"
 #include "defs.h"
 #include "quagga.h"
-#include "kernel_routes.h"
 #include "net_olsr.h"
 
 #define PLUGIN_NAME    "OLSRD quagga plugin"
@@ -41,13 +42,7 @@ static set_plugin_parameter set_exportroutes;
 static set_plugin_parameter set_distance;
 static set_plugin_parameter set_localpref;
 
-#if 0
-/* these are never read */
-static export_route_function orig_addroute_function;
-static export_route_function orig_delroute_function;
-#endif
-
-static struct olsr_cookie_info *zebra_check_timer_cookie;
+static struct olsr_cookie_info *event_timer_cookie;
 
 int olsrd_plugin_interface_version (void) {
   return PLUGIN_INTERFACE_VERSION;
@@ -75,33 +70,24 @@ static int set_redistribute (const char *value,
   unsigned int i;
 
   for (i = 0; i < ARRAYSIZE(zebra_route_types); i++) {
-    if (!strcmp(value, zebra_route_types[i])) {
-      zebra_redistribute(i);
-      return 0;
-    }
+    if (!strcmp(value, zebra_route_types[i]))
+      if (zebra_redistribute (i)) return 1;
   }
-  return 1;
+
+  return 0;
 }
 
 static int set_exportroutes (const char *value,
                             void *data __attribute__((unused)),
                             set_plugin_parameter_addon addon __attribute__((unused))) {
   if (!strcmp(value, "only")) {
-#if 0
-    orig_addroute_function = NULL;
-    orig_delroute_function = NULL;
-#endif
-    olsr_addroute_function = zebra_add_olsr_v4_route;
-    olsr_delroute_function = zebra_del_olsr_v4_route;
+    olsr_addroute_function = zebra_add_route;
+    olsr_delroute_function = zebra_del_route;
     zebra_export_routes(1);
   }
   else if (!strcmp(value, "additional")) {
-#if 0
-    orig_addroute_function = olsr_addroute_function;
-    orig_delroute_function = olsr_delroute_function;
-#endif
-    olsr_addroute_function = zebra_add_olsr_v4_route;
-    olsr_delroute_function = zebra_del_olsr_v4_route;
+    olsr_addroute_function = zebra_add_route;
+    olsr_delroute_function = zebra_del_route;
     zebra_export_routes(1);
   }
   else zebra_export_routes(0);
@@ -134,10 +120,10 @@ int olsrd_plugin_init(void) {
     return 1;
   }
 
-  zebra_check_timer_cookie = olsr_alloc_cookie("Quagga: Zebra Check", OLSR_COOKIE_TYPE_TIMER);
+  event_timer_cookie = olsr_alloc_cookie("Quagga: Event", OLSR_COOKIE_TYPE_TIMER);
 
   olsr_start_timer(1 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
-                   &zebra_check, NULL, zebra_check_timer_cookie->ci_id);
+                   &zebra_parse, NULL, event_timer_cookie->ci_id);
 
   return 0;
 }
index e87bc31..65d1c46 100644 (file)
@@ -1,71 +1,49 @@
-/***************************************************************************
- projekt              : olsrd-quagga
- file                 : quagga.c
- usage                : communication with the zebra-daemon
- copyright            : (C) 2006 by Immo 'FaUl' Wehrenberg
- e-mail               : immo@chaostreff-dortmund.de
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License version 2 as     *
- *   published by the Free Software Foundation.                            *
- *                                                                         *
- ***************************************************************************/
-
-
-#ifdef MY_DEBUG
-#include <stdio.h>
-#endif
+/*
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+ * Copyright (C) 2007-2008 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or - at your option - under
+ * the terms of the GNU General Public Licence version 2 but can be
+ * linked to any BSD-Licenced Software with public available sourcecode
+ *
+ */
+
+/* -------------------------------------------------------------------------
+ * File               : quagga.c
+ * Description        : functions to interface to the zebra daemon
+ * ------------------------------------------------------------------------- */
+
 
 #define HAVE_SOCKLEN_T
 
+#include "quagga.h"
+#include "olsr.h" /* olsr_exit
+                     olsr_malloc */
+#include "log.h" /* olsr_syslog */
+#include "common/string.h" /* strscpy */
+#include "olsr_ip_prefix_list.h" /* ip_prefix_list_add
+                                    ip_prefix_list_remove */
+
 #include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "quagga.h"
-#include "olsr.h"
-#include "log.h"
-#include "defs.h"
-#include "routing_table.h"
-#include "common/string.h"
-#include "olsr_ip_prefix_list.h"
-
+#include <arpa/inet.h>
 #ifdef USE_UNIX_DOMAIN_SOCKET
 #include <sys/un.h>
-#define ZEBRA_SOCKET "/var/run/quagga/zserv.api"
 #endif
 
-#define ZEBRA_IPV4_ROUTE_ADD           7
-#define ZEBRA_IPV4_ROUTE_DELETE                8
-#define ZEBRA_REDISTRIBUTE_ADD         11
-#define ZEBRA_REDISTRIBUTE_DELETE      12
-#define ZEBRA_MESSAGE_MAX              23
-
-#define ZEBRA_ROUTE_OLSR               11
-#define ZEBRA_ROUTE_MAX                        12
-
-#define ZEBRA_FLAG_SELECTED            0x10
-
-#define ZEBRA_NEXTHOP_IPV4             3
-#define ZEBRA_NEXTHOP_IPV4_IFINDEX     4
-
-#define ZAPI_MESSAGE_NEXTHOP  0x01
-#define ZAPI_MESSAGE_IFINDEX  0x02
-#define ZAPI_MESSAGE_DISTANCE 0x04
-#define ZAPI_MESSAGE_METRIC   0x08
-
-#define BUFSIZE 1024
-
-#define STATUS_CONNECTED 1
-#define OPTION_EXPORT 1
 
+/* prototypes intern */
 static struct {
   char status; // internal status
   char options; // internal options
@@ -73,98 +51,23 @@ static struct {
   char redistribute[ZEBRA_ROUTE_MAX];
   char distance;
   char flags;
-  struct ipv4_route *v4_rt; // routes currently exportet to zebra
+  struct zebra_route *v4_rt; // routes currently exportet to zebra
 } zebra;
 
-
-/* prototypes intern */
+static void *my_realloc (void *, size_t, const char *);
+static void zebra_connect (void);
 static unsigned char *try_read (ssize_t *);
-static unsigned char* zebra_route_packet (struct ipv4_route r, ssize_t *);
-static int parse_interface_add (unsigned char *, size_t);
-static int parse_interface_delete (unsigned char *, size_t);
-static int parse_interface_up (unsigned char *, size_t);
-static int parse_interface_down (unsigned char *, size_t);
-static int parse_interface_address_add (unsigned char *, size_t);
-static int parse_interface_address_delete (unsigned char *, size_t);
-static int parse_ipv4_route (unsigned char *, size_t, struct ipv4_route *);
-static int ipv4_route_add (unsigned char *, size_t);
-static int ipv4_route_delete (unsigned char *, size_t);
-static int parse_ipv6_route_add (unsigned char*, size_t);
+static int zebra_send_command (unsigned char *);
+static unsigned char* zebra_route_packet (uint16_t, struct zebra_route *);
+static unsigned char *zebra_redistribute_packet (unsigned char, unsigned char);
+static struct zebra_route *zebra_parse_route (unsigned char *);
+#if 0
 static void zebra_reconnect (void);
-static void zebra_connect (void);
-
-static void free_ipv4_route (struct ipv4_route);
-/*
-static void update_olsr_zebra_routes (struct ipv4_route*, struct ipv4_route*);
-static struct ipv4_route *zebra_create_ipv4_route_table_entry (uint32_t,
-                                                              uint32_t,
-                                                              uint32_t);
-static struct ipv4_route *zebra_create_ipv4_route_table (void);
-static void zebra_free_ipv4_route_table (struct ipv4_route*);
-*/
-
-/*static uint8_t masktoprefixlen (uint32_t);*/
-
-
-#ifdef MY_DEBUG
-static void dump_ipv4_route (struct ipv4_route r, char *c) {
-  int i = 0, x = 0;
-
-  puts (c);
-  printf("type: %d\n", r.type);
-  puts("flags:");
-  printf("  Internal: %s\n",r.flags&ZEBRA_FLAG_INTERNAL?"yes":"no");
-  printf("  Selfroute %s\n",r.flags&ZEBRA_FLAG_SELFROUTE?"yes":"no");
-  printf("  Blackhole %s\n",r.flags&ZEBRA_FLAG_BLACKHOLE?"yes":"no");
-  printf("  IBGP: %s\n",r.flags&ZEBRA_FLAG_IBGP?"yes":"no");
-  printf("  Selected: %s\n",r.flags&ZEBRA_FLAG_SELECTED?"yes":"no");
-  printf("  Changed: %s\n",r.flags&ZEBRA_FLAG_CHANGED?"yes":"no");
-  printf("  static: %s\n",r.flags&ZEBRA_FLAG_STATIC?"yes":"no");
-  printf("  reject: %s\n",r.flags&ZEBRA_FLAG_REJECT?"yes":"no");
-  puts("message:");
-  printf("  nexthop: %s\n",r.message&ZAPI_MESSAGE_NEXTHOP?"yes":"no");
-  printf("  ifindex: %s\n",r.message&ZAPI_MESSAGE_IFINDEX?"yes":"no");
-  printf("  distance: %s\n",r.message&ZAPI_MESSAGE_DISTANCE?"yes":"no");
-  printf("  metric: %s\n",r.message&ZAPI_MESSAGE_METRIC?"yes":"no");
-  printf("Prefixlen: %d\n", r.prefixlen);
-  printf("Prefix: %d", (unsigned char)r.prefix);
-  c = (char*) &r.prefix;
-  while (++i < (r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0)))
-    printf(".%d",(unsigned char)*(c + i));
-  while (i++ < 4)
-    printf(".0");
-  puts("");
-  i=0;
-  if (r.message&ZAPI_MESSAGE_NEXTHOP) {
-    printf("nexthop-count: %d\n", r.nh_count);
-    while (i++ < r.nh_count) {
-      if (r.nexthops[i].type == ZEBRA_NEXTHOP_IPV4) {
-       c = (unsigned char*) &r.nexthops[i].payload.v4;
-       printf ("Nexthop %d: %d", i, (unsigned char) *c);
-       while (++x < 4) {
-         printf (".%d", (unsigned char) c[x]);
-       }
-       puts("");
-      }
-    }
-    i=0;
-  }
-  if (r.message&ZAPI_MESSAGE_IFINDEX) {
-
-    printf("index-number: %d\n", r.ind_num);
-    while (i++ < r.ind_num)
-      printf("Index: %d: %d\n", i, r.index[i]);
-    i=0;
-    if (r.message&ZAPI_MESSAGE_DISTANCE)
-      printf("Distance: %d\n",r.distance);
-    if (r.message&ZAPI_MESSAGE_METRIC)
-      printf("Metric: %d\n",r.metric);
-    puts("\n");
-  }
-}
 #endif
+static void free_ipv4_route (struct zebra_route *);
 
-void *my_realloc (void *buf, size_t s, const char *c) {
+
+static void *my_realloc (void *buf, size_t s, const char *c) {
   buf = realloc (buf, s);
   if (!buf) {
     OLSR_PRINTF (1, "(QUAGGA) OUT OF MEMORY: %s\n", strerror(errno));
@@ -174,6 +77,7 @@ void *my_realloc (void *buf, size_t s, const char *c) {
   return buf;
 }
 
+
 void init_zebra (void) {
   zebra_connect();
   if (!(zebra.status&STATUS_CONNECTED))
@@ -181,21 +85,23 @@ void init_zebra (void) {
               EXIT_FAILURE);
 }
 
+
 void zebra_cleanup (void) {
   int i;
   struct rt_entry *tmp;
 
   if (zebra.options & OPTION_EXPORT) {
     OLSR_FOR_ALL_RT_ENTRIES(tmp) {
-      zebra_del_olsr_v4_route(tmp);
+      zebra_del_route(tmp);
     } OLSR_FOR_ALL_RT_ENTRIES_END(tmp);
   }
 
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
-    if (zebra.redistribute[i]) zebra_disable_redistribute(i + 1);
+    if (zebra.redistribute[i]) zebra_disable_redistribute(i);
 }
 
 
+#if 0
 static void zebra_reconnect (void) {
   struct rt_entry *tmp;
   int i;
@@ -205,7 +111,7 @@ static void zebra_reconnect (void) {
 
   if (zebra.options & OPTION_EXPORT) {
     OLSR_FOR_ALL_RT_ENTRIES(tmp) {
-      zebra_add_olsr_v4_route (tmp);
+      zebra_add_route (tmp);
     } OLSR_FOR_ALL_RT_ENTRIES_END(tmp);
   }
 
@@ -214,7 +120,7 @@ static void zebra_reconnect (void) {
   /* Zebra sends us all routes of type it knows after
      zebra_redistribute(type) */
 }
-
+#endif
 
 
 /* Connect to the zebra-daemon, returns a socket */
@@ -257,181 +163,135 @@ static void zebra_connect (void) {
 /* Sends a command to zebra, command is
    the command defined in zebra.h, options is the packet-payload,
    optlen the length, of the payload */
-unsigned char zebra_send_command (unsigned char command,
-                                  unsigned char *options, int optlen) {
+static int zebra_send_command (unsigned char *options) {
 
-  char *p, *pnt;
+  unsigned char *pnt;
   uint16_t len;
   int ret;
 
-#ifdef ZEBRA_HEADER_MARKER
-  uint16_t cmd;
-  uint16_t length = optlen + 6; /* length of option + command + packet_length +
-                                  marker + zserv-version */
-#else
-  uint16_t length = optlen + 3;  // length of option + command + packet_length
-#endif
-
   if (!(zebra.status & STATUS_CONNECTED)) return 0;
 
-  p = olsr_malloc (length, "zebra_send_command");
-  pnt = p;
-
-  len = htons(length);
-
-  memcpy (p, &len, 2);
-
-#ifdef ZEBRA_HEADER_MARKER
-  p[2] = ZEBRA_HEADER_MARKER;
-  p[3] = ZSERV_VERSION;
-  cmd = htons (command);
-  memcpy (p + 4, &cmd, 2);
-#else
-  p[2] = command;
-#endif
-  memcpy (p + length-optlen, options, optlen);
+  pnt = options;
+  memcpy (&len, pnt, 2);
 
-  errno = 0;
+  len = ntohs(len);
 
   do {
-    ret = write (zebra.sock, p, length);
+    ret = write (zebra.sock, pnt, len);
     if (ret < 0) {
-      if (errno == EINTR) {
+      if ((errno == EINTR) || (errno == EAGAIN)) {
        errno = 0;
+        ret = 0;
        continue;
       }
       else {
        OLSR_PRINTF (1, "(QUAGGA) Disconnected from zebra\n");
        zebra.status &= ~STATUS_CONNECTED;
-       free (pnt);
+       free (options);
        return -1;
       }
     }
-    p = p+ret;
-  } while ((length -= ret));
-  free (pnt);
+    pnt = pnt+ret;
+  } while ((len -= ret));
+  free (options);
   return 0;
 }
 
 
 /* Creates a Route-Packet-Payload, needs address, netmask, nexthop,
    distance, and a pointer of an size_t */
-static unsigned char* zebra_route_packet (struct ipv4_route r,
-                                          ssize_t *optlen) {
+static unsigned char* zebra_route_packet (uint16_t cmd, struct zebra_route *r) {
 
   int count;
+  uint8_t len;
+  uint16_t size;
+  uint32_t ind, metric;
 
   unsigned char *cmdopt, *t;
-  *optlen = 4; // first: type, flags, message, prefixlen
-  *optlen += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0); // + prefix
-  if (r.message & ZAPI_MESSAGE_NEXTHOP) {
-    if (r.nexthops->type == ZEBRA_NEXTHOP_IPV4
-       || r.nexthops->type == ZEBRA_NEXTHOP_IPV4_IFINDEX){
-      *optlen += (sizeof r.nexthops->payload.v4
-                 + sizeof r.nexthops->type) * r.nh_count + 1;
-    }
-    else if (r.nexthops->type == 0)
-      *optlen += 5;
-  }
-  if (r.message & ZAPI_MESSAGE_IFINDEX)
-    *optlen += r.ind_num * sizeof *r.index + 1;
-  if (r.message & ZAPI_MESSAGE_DISTANCE)
-    (*optlen)++;
-  if (r.message & ZAPI_MESSAGE_METRIC)
-    *optlen += sizeof r.metric;
-
-  cmdopt = olsr_malloc (*optlen, "zebra add_v4_route");
-
-  t = cmdopt;
-  *t++ = r.type;
-  *t++ = r.flags;
-  *t++ = r.message;
-  *t++ = r.prefixlen;
-  for (count = 0; count < r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0); count++) {
-    *t++ = *((char*)&r.prefix + count); /* this is so sick!! */
-  }
-
-  if (r.message & ZAPI_MESSAGE_NEXTHOP) {
-    *t++ = r.nh_count;
-    *t++ = r.nexthops->type;
-    if (r.nexthops->type == ZEBRA_NEXTHOP_IPV4 ||
-       r.nexthops->type == ZEBRA_NEXTHOP_IPV4_IFINDEX) {
-      for (count = 0; count != r.nh_count; count++) {
-       memcpy (t, &r.nexthops[count].payload.v4,
-               sizeof r.nexthops->payload.v4);
-       t += sizeof r.nexthops->payload.v4;
-      }
-    }
-    else if (r.nexthops->type == 0) {
-      *t++ = 0;
-      *t++ = 0;
-      *t++ = 0;
-    }
-  }
-  if (r.message & ZAPI_MESSAGE_IFINDEX) {
-    *t++ = r.ind_num;
-    memcpy (t, r.index, sizeof *r.index * r.ind_num);
-    t += sizeof r.index * r.ind_num;
-  }
-  if (r.message & ZAPI_MESSAGE_DISTANCE)
-    *t++ = r.distance;
-  if (r.message & ZAPI_MESSAGE_METRIC) {
-    memcpy (t, &r.metric, sizeof r.metric);
-    t += sizeof r.metric;
-  }
-  return cmdopt;
-}
-
-
-/* adds a route to zebra-daemon */
-int zebra_add_v4_route (const struct ipv4_route r) {
-
-  unsigned char *cmdopt;
-  ssize_t optlen;
-  int retval;
-
-  cmdopt = zebra_route_packet (r, &optlen);
-
-  retval = zebra_send_command (ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);
-  free (cmdopt);
-  return retval;
-
-}
 
-/* deletes a route from the zebra-daemon */
-int zebra_delete_v4_route (struct ipv4_route r) {
+  cmdopt = olsr_malloc (ZEBRA_MAX_PACKET_SIZ , "zebra add_v4_route");
 
-  unsigned char *cmdopt;
-  ssize_t optlen;
-  int retval;
-
-  cmdopt = zebra_route_packet (r, &optlen);
-
-  retval = zebra_send_command (ZEBRA_IPV4_ROUTE_DELETE, cmdopt, optlen);
-  free (cmdopt);
+  t = &cmdopt[2];
+  *t++ = cmd;
+  *t++ = r->type;
+  *t++ = r->flags;
+  *t++ = r->message;
+  *t++ = r->prefixlen;
+  len = (r->prefixlen + 7) / 8;
+  memcpy (t, &r->prefix.v4.s_addr, len);
+  t = t + len;
 
-  return retval;
+  if (r->message & ZAPI_MESSAGE_NEXTHOP) {
+    *t++ = r->nexthop_num + r->ifindex_num;
+    
+      for (count = 0; count < r->nexthop_num; count++)
+       {
+         *t++ = ZEBRA_NEXTHOP_IPV4;
+         memcpy (t, &r->nexthop[count].v4.s_addr,
+                 sizeof r->nexthop[count].v4.s_addr);
+         t += sizeof r->nexthop[count].v4.s_addr;
+       }
+      for (count = 0; count < r->ifindex_num; count++)
+       {
+         *t++ = ZEBRA_NEXTHOP_IFINDEX;
+          ind = htonl(r->ifindex[count]);
+         memcpy (t, &ind, sizeof ind);
+         t += sizeof ind;
+       }
+    }
+  if ((r->message & ZAPI_MESSAGE_DISTANCE) > 0)
+    *t++ = r->distance;
+  if ((r->message & ZAPI_MESSAGE_METRIC) > 0)
+    {
+      metric = htonl (r->metric);
+      memcpy (t, &metric, sizeof metric);
+      t += sizeof metric;
+    }
+  size = htons (t - cmdopt);
+  memcpy (cmdopt, &size, 2);
 
+  return cmdopt;
 }
 
 
 /* Check wether there is data from zebra aviable */
-void zebra_check (void* foo __attribute__((unused))) {
+void zebra_parse (void* foo __attribute__((unused))) {
   unsigned char *data, *f;
-  ssize_t len, ret;
+  unsigned char command;
+  uint16_t length;
+  ssize_t len;
+  struct zebra_route *route;
 
   if (!(zebra.status & STATUS_CONNECTED)) {
-    zebra_reconnect();
+//    zebra_reconnect();
     return;
   }
   data = try_read (&len);
   if (data) {
     f = data;
     do {
-      ret = zebra_parse_packet (f, len);
-      if (!ret) // something wired happened
+      memcpy (&length, f, sizeof length);
+      length = ntohs (length);
+      if (!length) // something wired happened
        olsr_exit ("(QUAGGA) Zero message length??? ", EXIT_FAILURE);
-      f += ret;
+      command = f[2];
+      switch (command) {
+        case ZEBRA_IPV4_ROUTE_ADD:
+          route = zebra_parse_route(f);
+          ip_prefix_list_add(&olsr_cnf->hna_entries, &route->prefix, route->prefixlen);
+          free_ipv4_route (route);
+          free (route);
+          break;
+        case ZEBRA_IPV4_ROUTE_DELETE:
+          route = zebra_parse_route(f);
+          ip_prefix_list_remove(&olsr_cnf->hna_entries, &route->prefix, route->prefixlen);
+          free_ipv4_route (route);
+          free (route);
+          break;
+        default:
+          break;
+      }
+      f += length;
     } while ((f - data) < len);
     free (data);
   }
@@ -440,29 +300,37 @@ void zebra_check (void* foo __attribute__((unused))) {
 
 // tries to read a packet from zebra_socket
 // if there is something to read - make sure to read whole packages
-static unsigned char *try_read (ssize_t *len) {
-  unsigned char *buf = NULL;
-  ssize_t ret = 0, bsize = 0;
-  uint16_t length = 0, l = 0;
-  int sockstate;
+static unsigned char *try_read (ssize_t *size) {
+  unsigned char *buf;
+  ssize_t bytes, bufsize;
+  uint16_t length, offset;
+  int sockstatus;
 
-  *len = 0;
+  offset = *size = bufsize = 0;
 
-  sockstate = fcntl (zebra.sock, F_GETFL, 0);
-  fcntl (zebra.sock, F_SETFL, sockstate|O_NONBLOCK);
+  /* save socket status and set non-blocking for read */
+  sockstatus = fcntl (zebra.sock, F_GETFL);
+  fcntl (zebra.sock, F_SETFL, sockstatus|O_NONBLOCK);
 
+  /* read whole packages */
   do {
-    if (*len == bsize) {
-      bsize += BUFSIZE;
-      buf = my_realloc (buf, bsize, "Zebra try_read");
+
+  /* (re)allocate buffer */
+    if (*size == bufsize) {
+      bufsize += BUFSIZE;
+      buf = my_realloc (buf, bufsize, "Zebra try_read");
     }
-    ret = read (zebra.sock, buf + l, bsize - l);
-    if (!ret) { // nothing more to read, packet is broken, discard!
+
+  /* read from socket */
+    bytes = read (zebra.sock, buf + *size, bufsize - *size);
+  /* handle broken packet */
+    if (!bytes) {
       free (buf);
       return NULL;
     }
-
-    if (ret < 0) {
+  /* handle no data available */
+    if (bytes < 0) {
+  /* handle disconnect */
       if (errno != EAGAIN) { // oops - we got disconnected
         OLSR_PRINTF (1, "(QUAGGA) Disconnected from zebra\n");
         zebra.status &= ~STATUS_CONNECTED;
@@ -471,218 +339,118 @@ static unsigned char *try_read (ssize_t *len) {
       return NULL;
     }
 
-    *len += ret;
-    while ((*len - l) > length) {
-      l += length;
-      memcpy (&length, buf + l, 2);
-      length = ntohs (length);
-    }
-    if (((*len) - l) == length) break; // GOT FULL PACKAGE!!
-    if (*len < l) {
-      fcntl (zebra.sock, F_SETFL, sockstate);
-      continue;
-    }
-  } while (1);
-
-  fcntl (zebra.sock, F_SETFL, sockstate);
-  return buf;
-}
-
-
-/* Parse a packet recived from zebra */
-int zebra_parse_packet (unsigned char *packet, ssize_t maxlen) {
-
-  uint16_t command;
-  int skip;
-
-  /* Array of functions */
-  int (*foo[ZEBRA_MESSAGE_MAX]) (unsigned char *, size_t) = {
-    parse_interface_add,
-    parse_interface_delete,
-    parse_interface_address_add,
-    parse_interface_address_delete,
-    parse_interface_up,
-    parse_interface_down,
-    ipv4_route_add,
-    ipv4_route_delete,
-    parse_ipv6_route_add
-  };
-
-  uint16_t length;
-  int ret;
-
-#ifdef MY_DEBUG
-  puts ("DEBUG: zebra_parse_packet");
-#endif
-
-  memcpy (&length, packet, 2);
-  length = ntohs (length);
-
-  if (maxlen < length) {
-    OLSR_PRINTF (1, "(QUAGGA) maxlen = %lu, packet_length = %d\n", (unsigned long)maxlen, length);
-    olsr_exit ("(QUAGGA) programmer is an idiot", EXIT_FAILURE);
-  }
-
-#ifdef ZEBRA_HEADER_MARKER
-  if (packet[2] == 255) { // found header marker!!
-    //packet[3] == ZSERV_VERSION: FIXME: HANDLE THIS!
-    memcpy (&command, packet + 4, sizeof command); // two bytes command now!
-    command = ntohs (command) - 1;
-    skip = 6;
-  }
-#else
-  command = packet[2] - 1;
-  skip = 3;
-#endif
-
-  if (command < ZEBRA_MESSAGE_MAX && foo[command]) {
-    if (!(ret = foo[command] (packet + skip, length - skip)))
-      return length;
-    else OLSR_PRINTF (1, "(QUAGGA) Parse error: %d\n", ret);
-  }
-  else
-    OLSR_PRINTF (1, "(QUAGGA) Unknown packet type: %d\n", packet[2]);
-
-  OLSR_PRINTF (1, "(Quagga) RECIVED PACKET FROM ZEBRA THAT I CAN'T PARSE");
-
-  return length;
-}
-
-
-static int parse_interface_add (unsigned char *opt __attribute__((unused)), size_t len __attribute__((unused))) {
-  //todo
-  return 0;
-}
-
-
-static int parse_interface_delete (unsigned char *opt __attribute__((unused)), size_t len __attribute__((unused))) {
-  //todo
-  return 0;
-}
-
+    *size += bytes;
 
-static int parse_interface_address_add (unsigned char *opt __attribute__((unused)), size_t len __attribute__((unused))) {
-
-  //todo
-  return 0;
-}
-
-static int parse_interface_up (unsigned char *opt __attribute__((unused)), size_t len __attribute__((unused))) {
-
-  //todo
-  return 0;
-}
-
-static int parse_interface_down (unsigned char *opt __attribute__((unused)), size_t len __attribute__((unused))) {
-
-  //todo
-  return 0;
-}
+  /* detect zebra packet fragmentation */
+    do {
+      memcpy (&length, buf + offset, sizeof length);
+      length = ntohs (length);
+      offset += length;
+    } while (*size >= (ssize_t) (offset + sizeof length));
+  /* set blocking socket on fragmented packet */
+    if (*size != offset)
+      fcntl (zebra.sock, F_SETFL, sockstatus);
+  } while (*size != offset);
 
+  /* restore socket status */
+  fcntl (zebra.sock, F_SETFL, sockstatus);
 
-static int parse_interface_address_delete (unsigned char *opt __attribute__((unused)), size_t  len __attribute__((unused))) {
-  //todo
-  return 0;
+  return buf;
 }
 
 
 /* Parse an ipv4-route-packet recived from zebra
  */
-static int parse_ipv4_route (unsigned char *opt, size_t len, struct ipv4_route *r) {
+static struct zebra_route *zebra_parse_route (unsigned char *opt) {
+  
+  struct zebra_route *r;
   int c;
-
-  if (len < 4) return -1;
-
-  r->type = *opt++;
-  r->flags = *opt++;
-  r->message = *opt++;
-  r->prefixlen = *opt++;
-  len -= 4;
-  r->prefix = 0;
-
-  if ((int)len < r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0)) return -1;
-
-  memcpy (&r->prefix, opt, r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0));
-  opt += r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0);
+  size_t size;
+  uint16_t length;
+  unsigned char *pnt;
+      
+  memcpy (&length, opt, sizeof length);
+  length = ntohs (length);
+  
+  r = olsr_malloc (sizeof *r , "zebra_parse_route");
+  pnt = &opt[3];
+  r->type = *pnt++;
+  r->flags = *pnt++;
+  r->message = *pnt++;
+  r->prefixlen = *pnt++;
+  r->prefix.v4.s_addr = 0;
+
+  size = (r->prefixlen + 7) / 8;
+  memcpy (&r->prefix.v4.s_addr, pnt, size);
+  pnt += size;
 
   if (r->message & ZAPI_MESSAGE_NEXTHOP) {
-    if (len < 1) return -1;
-    r->nh_count = *opt++;
-    len--;
-    if (len < (sizeof (uint32_t) + 1) * r->nh_count) return -1;
-    r->nexthops = olsr_malloc ((sizeof r->nexthops->type +
-                               sizeof r->nexthops->payload) * r->nh_count,
-                              "quagga: parse_ipv4_route_add");
-    for (c = 0; c < r->nh_count; c++) {
-      r->nexthops[c].type = *opt++;
-      memcpy (&r->nexthops[c].payload.v4, opt, sizeof (uint32_t));
-      opt += sizeof (uint32_t);
-      len -= sizeof (uint32_t) + 1;
+    r->nexthop_num = *pnt++;
+    r->nexthop = olsr_malloc ((sizeof *r->nexthop) * r->nexthop_num,
+        "quagga: zebra_parse_route");
+    for (c = 0; c < r->nexthop_num; c++) {
+      memcpy (&r->nexthop[c].v4.s_addr, pnt, sizeof r->nexthop[c].v4.s_addr);
+      pnt += sizeof r->nexthop[c].v4.s_addr;
     }
   }
 
   if (r->message & ZAPI_MESSAGE_IFINDEX) {
-    if (len < 1) return -1;
-    r->ind_num = *opt++;
-    if (len < sizeof (uint32_t) * r->ind_num) return -1;
-    r->index = olsr_malloc (sizeof (uint32_t) * r->ind_num,
-                           "quagga: parse_ipv4_route_add");
-    memcpy (r->index, opt, r->ind_num * sizeof (uint32_t));
-    opt += sizeof (uint32_t) * r->ind_num;
-    len -= sizeof (uint32_t) * r->ind_num;
+    r->ifindex_num = *pnt++;
+    r->ifindex = olsr_malloc (sizeof (uint32_t) * r->ifindex_num,
+                            "quagga: zebra_parse_route");
+    for (c = 0; c < r->ifindex_num; c++) {
+      memcpy (&r->ifindex[c], pnt, sizeof r->ifindex[c]);
+      r->ifindex[c] = ntohl (r->ifindex[c]);
+      pnt += sizeof r->ifindex[c];
+    }
   }
 
   if (r->message & ZAPI_MESSAGE_DISTANCE) {
-    if (len < 1) return -1;
-    r->distance = *opt++;
-    len--;
+    r->distance = *pnt++;
   }
 
-  if (r->message & ZAPI_MESSAGE_METRIC) {
-    if (len < sizeof (uint32_t)) return -1;
-    memcpy (&r->metric, opt, sizeof (uint32_t));
-  }
+// Quagga v0.98.6 BUG workaround: metric is always sent by zebra
+// even without ZAPI_MESSAGE_METRIC message.
+//  if (r.message & ZAPI_MESSAGE_METRIC) {
+    memcpy (&r->metric, pnt, sizeof (uint32_t));
+    r->metric = ntohl (r->metric);
+      pnt += sizeof r->metric;
+//  }
+    
+    if (pnt - opt != length) { olsr_exit ("(QUAGGA) length does not match ??? ", EXIT_FAILURE);
+     }
 
-  return 0;
+  return r;
 }
 
 
-static int ipv4_route_add (unsigned char *opt, size_t len) {
+static unsigned char *zebra_redistribute_packet (unsigned char cmd, unsigned char type) {
+  unsigned char *data, *pnt;
+  uint16_t size;
 
-  struct ipv4_route r;
-  int f;
+  data = olsr_malloc (ZEBRA_MAX_PACKET_SIZ , "zebra_redistribute_packet");
 
-  f = parse_ipv4_route (opt, len, &r);
-  if (f < 0) return f;
+  pnt = &data[2];
+  *pnt++ = cmd;
+  *pnt++ = type;
+  size = htons (pnt - data);
+  memcpy (data, &size, 2);
 
-  return add_hna4_route (r);
-}
-
-static int ipv4_route_delete (unsigned char *opt, size_t len) {
-  struct ipv4_route r;
-  int f;
-
-  f = parse_ipv4_route (opt, len, &r);
-  if (f < 0) return f;
-
-  return delete_hna4_route (r);
-
-}
-
-static int parse_ipv6_route_add (unsigned char *opt __attribute__((unused)), size_t len __attribute__((unused))) {
-  //todo
-  return 0;
+  return data;
 }
 
 
 /* start redistribution FROM zebra */
 int zebra_redistribute (unsigned char type) {
 
-  if (type > ZEBRA_ROUTE_MAX) return -1;
-  zebra.redistribute[type - 1] = 1;
+      if (zebra_send_command(zebra_redistribute_packet (ZEBRA_REDISTRIBUTE_ADD, type)) < 0)
+        olsr_exit("(QUAGGA) could not send redistribute add command", EXIT_FAILURE);
 
-  return zebra_send_command (ZEBRA_REDISTRIBUTE_ADD, &type, 1);
+  if (type > ZEBRA_ROUTE_MAX-1) return -1;
+  zebra.redistribute[type] = 1;
 
+  return 0;
 
 }
 
@@ -690,162 +458,108 @@ int zebra_redistribute (unsigned char type) {
 /* end redistribution FROM zebra */
 int zebra_disable_redistribute (unsigned char type) {
 
-  if (type > ZEBRA_ROUTE_MAX) return -1;
-  zebra.redistribute[type - 1] = 0;
-
-  return zebra_send_command (ZEBRA_REDISTRIBUTE_DELETE, &type, 1);
-
-}
-
-int add_hna4_route (struct ipv4_route r) {
-  union olsr_ip_addr net;
+      if (zebra_send_command(zebra_redistribute_packet (ZEBRA_REDISTRIBUTE_DELETE, type)) < 0)
+        olsr_exit("(QUAGGA) could not send redistribute delete command", EXIT_FAILURE);
 
-#ifdef MY_DEBUG
-  dump_ipv4_route(r, "add_hna4_route");
-#endif
-
-  net.v4.s_addr = r.prefix;
-
-  ip_prefix_list_add(&olsr_cnf->hna_entries, &net, r.prefixlen);
-  free_ipv4_route(r);
-  return 0;
-}
-
-int delete_hna4_route (struct ipv4_route r) {
+  if (type > ZEBRA_ROUTE_MAX-1) return -1;
+  zebra.redistribute[type] = 0;
 
-  union olsr_ip_addr net;
-
-#ifdef MY_DEBUG
-  dump_ipv4_route(r, "delete_hna4_route");
-#endif
-
-  net.v4.s_addr = r.prefix;
-
-  ip_prefix_list_remove(&olsr_cnf->hna_entries, &net, r.prefixlen) ? 0 : -1;
-  free_ipv4_route(r);
   return 0;
 
 }
 
-static void free_ipv4_route (struct ipv4_route r) {
 
-  if(r.message&ZAPI_MESSAGE_IFINDEX && r.ind_num) free(r.index);
-  if(r.message&ZAPI_MESSAGE_NEXTHOP && r.nh_count) free(r.nexthops);
+static void free_ipv4_route (struct zebra_route *r) {
 
-}
-
-/*
-static uint8_t masktoprefixlen (uint32_t mask) {
-
-  uint8_t prefixlen = 0;
-
-  mask = htonl (mask);
-
-  if (mask) while (mask << ++prefixlen && prefixlen < 32);
-
-  return prefixlen;
+  if(r->ifindex_num) free(r->ifindex);
+  if(r->nexthop_num) free(r->nexthop);
 
 }
-*/
 
-int zebra_add_olsr_v4_route (const struct rt_entry *r) {
 
-  struct ipv4_route route;
+int zebra_add_route (const struct rt_entry *r) {
+
+  struct zebra_route route;
   int retval;
 
-  route.type = ZEBRA_ROUTE_OLSR; // OLSR
-  route.message = ZAPI_MESSAGE_METRIC;
+  route.type = ZEBRA_ROUTE_OLSR;
   route.flags = zebra.flags;
+  route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
   route.prefixlen = r->rt_dst.prefix_len;
-  route.prefix = r->rt_dst.prefix.v4.s_addr;
+  route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
+  route.ifindex_num = 0;
+  route.ifindex = NULL;
+  route.nexthop_num = 0;
+  route.nexthop = NULL;
+
   if (r->rt_best->rtp_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr &&
-      route.prefixlen == 32) {
-    route.message |= ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_NEXTHOP;
-    route.ind_num = 1;
-    route.index = olsr_malloc (sizeof *route.index,
-                              "zebra_add_olsr_v4_route");
-    *route.index = htonl(r->rt_best->rtp_nexthop.interface->if_index);
-    route.nexthops = olsr_malloc (sizeof route.nexthops->type +
-                                 sizeof route.nexthops->payload,
-                                 "zebra_add_olsr_v4_route");
-    route.nh_count = 1;
-    route.nexthops->type = 0;
+       route.prefixlen == 32) {
+    return 0;                  /* Quagga BUG workaround: don't add routes with destination = gateway
+                                  see http://lists.olsr.org/pipermail/olsr-users/2006-June/001726.html */
+    route.ifindex_num++;
+    route.ifindex = olsr_malloc (sizeof *route.ifindex,
+                              "zebra_add_route");
+    *route.ifindex = r->rt_best->rtp_nexthop.interface->if_index;
   }
   else {
-    route.message |= ZAPI_MESSAGE_NEXTHOP;
-    route.ind_num = 0;
-    route.index = NULL;
-    route.nh_count = 1;
-    route.nexthops = olsr_malloc (route.nh_count *
-                                 (sizeof route.nexthops->type +
-                                  sizeof route.nexthops->payload),
-                                  "zebra_add_olsr_v4_route");
-    route.nexthops->type = ZEBRA_NEXTHOP_IPV4;
-    route.nexthops->payload.v4 = r->rt_best->rtp_nexthop.gateway.v4.s_addr;
+    route.nexthop_num++;
+    route.nexthop = olsr_malloc (sizeof *route.nexthop, "zebra_add_route");
+    route.nexthop->v4.s_addr = r->rt_best->rtp_nexthop.gateway.v4.s_addr;
   }
 
   route.metric = r->rt_best->rtp_metric.hops;
-  route.metric = htonl(route.metric);
 
   if (zebra.distance) {
     route.message |= ZAPI_MESSAGE_DISTANCE;
     route.distance = zebra.distance;
-  } else {
-    route.distance = 0;
   }
 
-  retval = zebra_add_v4_route(route);
-  free_ipv4_route (route);
+  retval = zebra_send_command (zebra_route_packet (ZEBRA_IPV4_ROUTE_ADD, &route));
   return retval;
+
 }
 
-int zebra_del_olsr_v4_route (const struct rt_entry *r) {
+int zebra_del_route (const struct rt_entry *r) {
 
-  struct ipv4_route route;
+  struct zebra_route route;
   int retval;
-  route.type = ZEBRA_ROUTE_OLSR; // OLSR
-  route.message = ZAPI_MESSAGE_METRIC;
+
+  route.type = ZEBRA_ROUTE_OLSR;
   route.flags = zebra.flags;
+  route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
   route.prefixlen = r->rt_dst.prefix_len;
-  route.prefix = r->rt_dst.prefix.v4.s_addr;
-  if ((r->rt_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr &&
-       route.prefixlen == 32)){
-    route.message |= ZAPI_MESSAGE_IFINDEX;
-    route.ind_num = 1;
-    route.index = olsr_malloc (sizeof *route.index,
-                              "zebra_add_olsr_v4_route");
-    *route.index = htonl (r->rt_nexthop.interface->if_index);
-    route.nexthops = olsr_malloc (sizeof route.nexthops->type +
-                                 sizeof route.nexthops->payload,
-                                 "zebra_add_olsr_v4_route");
-    route.nh_count = 1;
-    route.nexthops->type = 0;
+  route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
+  route.ifindex_num = 0;
+  route.ifindex = NULL;
+  route.nexthop_num = 0;
+  route.nexthop = NULL;
+
+  if (r->rt_nexthop.gateway.v4.s_addr == r->rt_dst.prefix.v4.s_addr &&
+       route.prefixlen == 32){
+    return 0;                  /* Quagga BUG workaround: don't delete routes with destination = gateway
+                                  see http://lists.olsr.org/pipermail/olsr-users/2006-June/001726.html */
+    route.ifindex_num++;
+    route.ifindex = olsr_malloc (sizeof *route.ifindex,
+                              "zebra_del_route");
+    *route.ifindex = r->rt_nexthop.interface->if_index;
   }
   else {
-    route.message |= ZAPI_MESSAGE_NEXTHOP;
-    route.ind_num = 0;
-    route.index = NULL;
-    route.nh_count = 1;
-    route.nexthops = olsr_malloc (route.nh_count *
-                                 (sizeof route.nexthops->type +
-                                  sizeof route.nexthops->payload),
-                                 "zebra_add_olsr_v4_route");
-    route.nexthops->type = ZEBRA_NEXTHOP_IPV4;
-    route.nexthops->payload.v4 = r->rt_nexthop.gateway.v4.s_addr;
+    route.nexthop_num++;
+    route.nexthop = olsr_malloc (sizeof *route.nexthop, "zebra_del_route");
+    route.nexthop->v4.s_addr = r->rt_nexthop.gateway.v4.s_addr;
   }
+
   route.metric = 0;
 
   if (zebra.distance) {
     route.message |= ZAPI_MESSAGE_DISTANCE;
     route.distance = zebra.distance;
-  } else {
-    route.distance = 0;
   }
 
-  retval = zebra_delete_v4_route(route);
 
-  free_ipv4_route (route);
+  retval = zebra_send_command (zebra_route_packet (ZEBRA_IPV4_ROUTE_DELETE, &route));
   return retval;
+
 }
 
 void zebra_olsr_distance (unsigned char dist) {
index 780ec8c..c9a91d5 100644 (file)
-/***************************************************************************
- projekt              : olsrd-quagga
- file                 : quagga.h
- usage                : header for quagga.c
- copyright            : (C) 2006 by Immo 'FaUl' Wehrenberg
- e-mail               : immo@chaostreff-dortmund.de
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License version 2 as     *
- *   published by the Free Software Foundation.                            *
- *                                                                         *
- ***************************************************************************/
+/*
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+ * Copyright (C) 2007-2008 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation or - at your option - under
+ * the terms of the GNU General Public Licence version 2 but can be
+ * linked to any BSD-Licenced Software with public available sourcecode
+ *
+ */
+
+/* -------------------------------------------------------------------------
+ * File               : quagga.h
+ * Description        : header file for quagga.c
+ * ------------------------------------------------------------------------- */
+
+
+#include "routing_table.h" /* rt_entry */
+#include "olsr_types.h" /* olsr_ip_addr */
 
 #include <stdint.h>
-#include <stdio.h>
 #include <stdlib.h>
-#include "routing_table.h"
+
 #define HAVE_SOCKLEN_T
 
+/* Zebra port */
 #ifndef ZEBRA_PORT
 #define ZEBRA_PORT 2600
 #endif
 
+/* Zebra version */
 #ifdef ZEBRA_HEADER_MARKER
 #ifndef ZSERV_VERSION
 #define ZSERV_VERSION 1
 #endif
 #endif
 
+/* Zebra socket */
+#define ZEBRA_SOCKET "/var/run/quagga/zserv.api"
+
+/* Zebra packet size */
+#define ZEBRA_MAX_PACKET_SIZ          4096
+
+/* Zebra message types */
+#define ZEBRA_IPV4_ROUTE_ADD           7
+#define ZEBRA_IPV4_ROUTE_DELETE                8
+#define ZEBRA_REDISTRIBUTE_ADD         11
+#define ZEBRA_REDISTRIBUTE_DELETE      12
+#define ZEBRA_MESSAGE_MAX              23
+
+/* Zebra route types */
+#define ZEBRA_ROUTE_OLSR               11
+#define ZEBRA_ROUTE_MAX                        13
+
+/* Zebra flags */
+#define ZEBRA_FLAG_SELECTED            0x10
+
+/* Zebra nexthop flags */
+#define ZEBRA_NEXTHOP_IFINDEX          1
+#define ZEBRA_NEXTHOP_IPV4             3
+
+/* Zebra message flags */
+#define ZAPI_MESSAGE_NEXTHOP  0x01
+#define ZAPI_MESSAGE_IFINDEX  0x02
+#define ZAPI_MESSAGE_DISTANCE 0x04
+#define ZAPI_MESSAGE_METRIC   0x08
+
+/* Buffer size */
+#define BUFSIZE 1024
+
+/* Quagga plugin flags */
+#define STATUS_CONNECTED 1
+#define OPTION_EXPORT 1
+
 
-struct ipv4_route {
-  uint8_t type;
-  uint8_t flags;
-  uint8_t message;
-  uint8_t prefixlen;
-  uint32_t prefix;
-  uint8_t nh_count;
-  struct {
-    uint8_t type;
-    union {
-      uint32_t v4;
-    } payload;
-  } *nexthops;
-  uint8_t ind_num;
-  uint32_t *index;
+struct zebra_route {
+  unsigned char type;
+  unsigned char flags;
+  unsigned char message;
+  unsigned char prefixlen;
+  union olsr_ip_addr prefix;
+  unsigned char nexthop_num;
+  union olsr_ip_addr *nexthop;
+  unsigned char ifindex_num;
+  uint32_t *ifindex;
   uint32_t metric;
   uint8_t distance;
-  struct ipv4_route *next;
 };
 
 void init_zebra (void);
 void zebra_cleanup (void);
-unsigned char zebra_send_command (unsigned char, unsigned char *, int );
-int zebra_add_v4_route (const struct ipv4_route r);
-int zebra_delete_v4_route (const struct ipv4_route r);
-void zebra_check (void*);
-int zebra_parse_packet (unsigned char*, ssize_t);
+void zebra_parse (void*);
 int zebra_redistribute (unsigned char);
 int zebra_disable_redistribute (unsigned char);
-int add_hna4_route (struct ipv4_route);
-int delete_hna4_route (struct ipv4_route);
-void *my_realloc (void *, size_t, const char *);
-int zebra_add_olsr_v4_route (const struct rt_entry *);
-int zebra_del_olsr_v4_route (const struct rt_entry *);
+int zebra_add_route (const struct rt_entry *);
+int zebra_del_route (const struct rt_entry *);
 void zebra_olsr_localpref (void);
 void zebra_olsr_distance (unsigned char);
 void zebra_export_routes(unsigned char);
diff --git a/lib/quagga/src/quagga/zassert.h b/lib/quagga/src/quagga/zassert.h
deleted file mode 100644 (file)
index 65e8acc..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- */
-
-#ifndef _QUAGGA_ASSERT_H
-#define _QUAGGA_ASSERT_H
-
-extern void _zlog_assert_failed (const char *assertion, const char *file,
-                                unsigned int line, const char *function)
-                                __attribute__ ((noreturn));
-
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#define __ASSERT_FUNCTION    __func__
-#elif defined(__GNUC__)
-#define __ASSERT_FUNCTION    __FUNCTION__
-#else
-#define __ASSERT_FUNCTION    NULL
-#endif
-
-#define zassert(EX) ((void)((EX) ?  0 :        \
-                           (_zlog_assert_failed(#EX, __FILE__, __LINE__, \
-                                                __ASSERT_FUNCTION), 0)))
-
-#undef assert
-#define assert(EX) zassert(EX)
-
-#endif /* _QUAGGA_ASSERT_H */
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/lib/quagga/src/quagga/zebra.h b/lib/quagga/src/quagga/zebra.h
deleted file mode 100644 (file)
index 71e01f3..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/* Zebra common header.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Kunihiro Ishiguro
-
-This file is part of GNU Zebra.
-
-GNU Zebra is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-GNU Zebra is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Zebra; see the file COPYING.  If not, write to the Free
-Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
-
-#ifndef _ZEBRA_H
-#define _ZEBRA_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#ifdef SUNOS_5
-#define _XPG4_2
-#define __EXTENSIONS__
-typedef unsigned int    u_int32_t;
-typedef unsigned short  u_int16_t;
-typedef unsigned char   u_int8_t;
-#endif /* SUNOS_5 */
-
-#ifndef HAVE_SOCKLEN_T
-typedef int socklen_t;
-#endif /* HAVE_SOCKLEN_T */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <pwd.h>
-#include <grp.h>
-#ifdef HAVE_STROPTS_H
-#include <stropts.h>
-#endif /* HAVE_STROPTS_H */
-#include <sys/fcntl.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif /* HAVE_SYS_SELECT_H */
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#ifdef HAVE_SYS_SYSCTL_H
-#include <sys/sysctl.h>
-#endif /* HAVE_SYS_SYSCTL_H */
-#include <sys/ioctl.h>
-#ifdef HAVE_SYS_CONF_H
-#include <sys/conf.h>
-#endif /* HAVE_SYS_CONF_H */
-#ifdef HAVE_SYS_KSYM_H
-#include <sys/ksym.h>
-#endif /* HAVE_SYS_KSYM_H */
-#include <syslog.h>
-#include <time.h>
-#include <sys/uio.h>
-#include <sys/utsname.h>
-#ifdef HAVE_RUSAGE
-#include <sys/resource.h>
-#endif /* HAVE_RUSAGE */
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif /* HAVE_LIMITS_H */
-
-/* machine dependent includes */
-#ifdef SUNOS_5
-#include <strings.h>
-#endif /* SUNOS_5 */
-
-/* machine dependent includes */
-#ifdef HAVE_LINUX_VERSION_H
-#include <linux/version.h>
-#endif /* HAVE_LINUX_VERSION_H */
-
-#ifdef HAVE_ASM_TYPES_H
-#include <asm/types.h>
-#endif /* HAVE_ASM_TYPES_H */
-
-/* misc include group */
-#include <stdarg.h>
-#if !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
-/* Not C99; do we need to define va_copy? */
-#ifndef va_copy
-#ifdef __va_copy
-#define va_copy(DST,SRC) __va_copy(DST,SRC)
-#else
-/* Now we are desperate; this should work on many typical platforms.
-   But this is slightly dangerous, because the standard does not require
-   va_copy to be a macro. */
-#define va_copy(DST,SRC) memcpy(&(DST), &(SRC), sizeof(va_list))
-#warning "Not C99 and no va_copy macro available, falling back to memcpy"
-#endif /* __va_copy */
-#endif /* !va_copy */
-#endif /* !C99 */
-
-
-#ifdef HAVE_LCAPS
-#include <sys/capability.h>
-#include <sys/prctl.h>
-#endif /* HAVE_LCAPS */
-
-/* network include group */
-
-#include <sys/socket.h>
-
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif /* HAVE_SYS_SOCKIO_H */
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif /* HAVE_NETINET_IN_H */
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#ifdef HAVE_NET_NETOPT_H
-#include <net/netopt.h>
-#endif /* HAVE_NET_NETOPT_H */
-
-#include <net/if.h>
-
-#ifdef HAVE_NET_IF_DL_H
-#include <net/if_dl.h>
-#endif /* HAVE_NET_IF_DL_H */
-
-#ifdef HAVE_NET_IF_VAR_H
-#include <net/if_var.h>
-#endif /* HAVE_NET_IF_VAR_H */
-
-#ifdef HAVE_NET_ROUTE_H
-#include <net/route.h>
-#endif /* HAVE_NET_ROUTE_H */
-
-#ifdef HAVE_NETLINK
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#else
-#define RT_TABLE_MAIN          0
-#endif /* HAVE_NETLINK */
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif /* HAVE_NETDB_H */
-
-#include <arpa/inet.h>
-#include <arpa/telnet.h>
-
-#ifdef HAVE_INET_ND_H
-#include <inet/nd.h>
-#endif /* HAVE_INET_ND_H */
-
-#ifdef HAVE_NETINET_IN_VAR_H
-#include <netinet/in_var.h>
-#endif /* HAVE_NETINET_IN_VAR_H */
-
-#ifdef HAVE_NETINET6_IN6_VAR_H
-#include <netinet6/in6_var.h>
-#endif /* HAVE_NETINET6_IN6_VAR_H */
-
-#ifdef HAVE_NETINET_IN6_VAR_H
-#include <netinet/in6_var.h>
-#endif /* HAVE_NETINET_IN6_VAR_H */
-
-#ifdef HAVE_NETINET6_IN_H
-#include <netinet6/in.h>
-#endif /* HAVE_NETINET6_IN_H */
-
-
-#ifdef HAVE_NETINET6_IP6_H
-#include <netinet6/ip6.h>
-#endif /* HAVE_NETINET6_IP6_H */
-
-#ifdef HAVE_NETINET_ICMP6_H
-#include <netinet/icmp6.h>
-#endif /* HAVE_NETINET_ICMP6_H */
-
-#ifdef HAVE_NETINET6_ND6_H
-#include <netinet6/nd6.h>
-#endif /* HAVE_NETINET6_ND6_H */
-
-/* Some systems do not define UINT32_MAX */
-#ifndef UINT32_MAX
-#define UINT32_MAX 0xFFFFFFFFU
-#endif /* UINT32_MAX */
-
-#ifdef HAVE_LIBUTIL_H
-#include <libutil.h>
-#endif /* HAVE_LIBUTIL_H */
-
-#ifdef HAVE_GLIBC_BACKTRACE
-#include <execinfo.h>
-#endif /* HAVE_GLIBC_BACKTRACE */
-
-#ifdef BSDI_NRL
-
-#ifdef HAVE_NETINET6_IN6_H
-#include <netinet6/in6.h>
-#endif /* HAVE_NETINET6_IN6_H */
-
-#ifdef NRL
-#include <netinet6/in6.h>
-#endif /* NRL */
-
-#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
-
-#endif /* BSDI_NRL */
-
-/* Local includes: */
-#if !(defined(__GNUC__) || defined(VTYSH_EXTRACT_PL))
-#define __attribute__(x)
-#endif  /* !__GNUC__ || VTYSH_EXTRACT_PL */
-
-#include "zassert.h"
-
-
-#ifdef HAVE_BROKEN_CMSG_FIRSTHDR
-/* This bug is present in Solaris 8 and pre-patch Solaris 9 <sys/socket.h>;
-   please refer to http://bugzilla.quagga.net/show_bug.cgi?id=142 */
-
-/* Check that msg_controllen is large enough. */
-#define ZCMSG_FIRSTHDR(mhdr) \
-  (((size_t)((mhdr)->msg_controllen) >= sizeof(struct cmsghdr)) ? \
-   CMSG_FIRSTHDR(mhdr) : (struct cmsghdr *)NULL)
-
-#warning "CMSG_FIRSTHDR is broken on this platform, using a workaround"
-
-#else /* HAVE_BROKEN_CMSG_FIRSTHDR */
-#define ZCMSG_FIRSTHDR(M) CMSG_FIRSTHDR(M)
-#endif /* HAVE_BROKEN_CMSG_FIRSTHDR */
-
-
-
-/*
- * RFC 3542 defines several macros for using struct cmsghdr.
- * Here, we define those that are not present
- */
-
-/*
- * Internal defines, for use only in this file.
- * These are likely wrong on other than ILP32 machines, so warn.
- */
-#ifndef _CMSG_DATA_ALIGN
-#define _CMSG_DATA_ALIGN(n)           (((n) + 3) & ~3)
-#endif /* _CMSG_DATA_ALIGN */
-
-#ifndef _CMSG_HDR_ALIGN
-#define _CMSG_HDR_ALIGN(n)            (((n) + 3) & ~3)
-#endif /* _CMSG_HDR_ALIGN */
-
-/*
- * CMSG_SPACE and CMSG_LEN are required in RFC3542, but were new in that
- * version.
- */
-#ifndef CMSG_SPACE
-#define CMSG_SPACE(l)       (_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)) + \
-                              _CMSG_HDR_ALIGN(l))
-#warning "assuming 4-byte alignment for CMSG_SPACE"
-#endif  /* CMSG_SPACE */
-
-
-#ifndef CMSG_LEN
-#define CMSG_LEN(l)         (_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)) + (l))
-#warning "assuming 4-byte alignment for CMSG_LEN"
-#endif /* CMSG_LEN */
-
-
-/*  The definition of struct in_pktinfo is missing in old version of
-    GLIBC 2.1 (Redhat 6.1).  */
-#if defined (GNU_LINUX) && ! defined (HAVE_INPKTINFO)
-struct in_pktinfo
-{
-  int ipi_ifindex;
-  struct in_addr ipi_spec_dst;
-  struct in_addr ipi_addr;
-};
-#endif
-
-/*
- * OSPF Fragmentation / fragmented writes
- *
- * ospfd can support writing fragmented packets, for cases where
- * kernel will not fragment IP_HDRINCL and/or multicast destined
- * packets (ie TTBOMK all kernels, BSD, SunOS, Linux). However,
- * SunOS, probably BSD too, clobber the user supplied IP ID and IP
- * flags fields, hence user-space fragmentation will not work.
- * Only Linux is known to leave IP header unmolested.
- * Further, fragmentation really should be done the kernel, which already
- * supports it, and which avoids nasty IP ID state problems.
- *
- * Fragmentation of OSPF packets can be required on networks with router
- * with many many interfaces active in one area, or on networks with links
- * with low MTUs.
- */
-#ifdef GNU_LINUX
-#define WANT_OSPF_WRITE_FRAGMENT
-#endif
-
-/*
- * IP_HDRINCL / struct ip byte order
- *
- * Linux: network byte order
- * *BSD: network, except for length and offset. (cf Stevens)
- * SunOS: nominally as per BSD. but bug: network order on LE.
- * OpenBSD: network byte order, apart from older versions which are as per
- *          *BSD
- */
-#if defined(__NetBSD__) || defined(__FreeBSD__) \
-   || (defined(__OpenBSD__) && (OpenBSD < 200311)) \
-   || (defined(SUNOS_5) && defined(WORDS_BIGENDIAN))
-#define HAVE_IP_HDRINCL_BSD_ORDER
-#endif
-
-/* MAX / MIN are not commonly defined, but useful */
-#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef MIN
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-/* For old definition. */
-#ifndef IN6_ARE_ADDR_EQUAL
-#define IN6_ARE_ADDR_EQUAL IN6_IS_ADDR_EQUAL
-#endif /* IN6_ARE_ADDR_EQUAL */
-
-/* Zebra message types. */
-#define ZEBRA_INTERFACE_ADD                1
-#define ZEBRA_INTERFACE_DELETE             2
-#define ZEBRA_INTERFACE_ADDRESS_ADD        3
-#define ZEBRA_INTERFACE_ADDRESS_DELETE     4
-#define ZEBRA_INTERFACE_UP                 5
-#define ZEBRA_INTERFACE_DOWN               6
-#define ZEBRA_IPV4_ROUTE_ADD               7
-#define ZEBRA_IPV4_ROUTE_DELETE            8
-#define ZEBRA_IPV6_ROUTE_ADD               9
-#define ZEBRA_IPV6_ROUTE_DELETE           10
-#define ZEBRA_REDISTRIBUTE_ADD            11
-#define ZEBRA_REDISTRIBUTE_DELETE         12
-#define ZEBRA_REDISTRIBUTE_DEFAULT_ADD    13
-#define ZEBRA_REDISTRIBUTE_DEFAULT_DELETE 14
-#define ZEBRA_IPV4_NEXTHOP_LOOKUP         15
-#define ZEBRA_IPV6_NEXTHOP_LOOKUP         16
-#define ZEBRA_IPV4_IMPORT_LOOKUP          17
-#define ZEBRA_IPV6_IMPORT_LOOKUP          18
-#define ZEBRA_INTERFACE_RENAME            19
-#define ZEBRA_ROUTER_ID_ADD               20
-#define ZEBRA_ROUTER_ID_DELETE            21
-#define ZEBRA_ROUTER_ID_UPDATE            22
-#define ZEBRA_MESSAGE_MAX                 23
-
-/* Zebra route's types. */
-#define ZEBRA_ROUTE_SYSTEM               0
-#define ZEBRA_ROUTE_KERNEL               1
-#define ZEBRA_ROUTE_CONNECT              2
-#define ZEBRA_ROUTE_STATIC               3
-#define ZEBRA_ROUTE_RIP                  4
-#define ZEBRA_ROUTE_RIPNG                5
-#define ZEBRA_ROUTE_OSPF                 6
-#define ZEBRA_ROUTE_OSPF6                7
-#define ZEBRA_ROUTE_ISIS                 8
-#define ZEBRA_ROUTE_BGP                  9
-#define ZEBRA_ROUTE_HSLS                10
-#define ZEBRA_ROUTE_OLSR                11
-#define ZEBRA_ROUTE_MAX                  12
-
-/* Zebra's family types. */
-#define ZEBRA_FAMILY_IPV4                1
-#define ZEBRA_FAMILY_IPV6                2
-#define ZEBRA_FAMILY_MAX                 3
-
-/* Error codes of zebra. */
-#define ZEBRA_ERR_RTEXIST               -1
-#define ZEBRA_ERR_RTUNREACH             -2
-#define ZEBRA_ERR_EPERM                 -3
-#define ZEBRA_ERR_RTNOEXIST             -4
-
-/* Zebra message flags */
-#define ZEBRA_FLAG_INTERNAL           0x01
-#define ZEBRA_FLAG_SELFROUTE          0x02
-#define ZEBRA_FLAG_BLACKHOLE          0x04
-#define ZEBRA_FLAG_IBGP               0x08
-#define ZEBRA_FLAG_SELECTED           0x10
-#define ZEBRA_FLAG_CHANGED            0x20
-#define ZEBRA_FLAG_STATIC             0x40
-#define ZEBRA_FLAG_REJECT             0x80
-
-/* Zebra nexthop flags. */
-#define ZEBRA_NEXTHOP_IFINDEX            1
-#define ZEBRA_NEXTHOP_IFNAME             2
-#define ZEBRA_NEXTHOP_IPV4               3
-#define ZEBRA_NEXTHOP_IPV4_IFINDEX       4
-#define ZEBRA_NEXTHOP_IPV4_IFNAME        5
-#define ZEBRA_NEXTHOP_IPV6               6
-#define ZEBRA_NEXTHOP_IPV6_IFINDEX       7
-#define ZEBRA_NEXTHOP_IPV6_IFNAME        8
-#define ZEBRA_NEXTHOP_BLACKHOLE          9
-
-#ifndef INADDR_LOOPBACK
-#define        INADDR_LOOPBACK 0x7f000001      /* Internet address 127.0.0.1.  */
-#endif
-
-/* Address family numbers from RFC1700. */
-#define AFI_IP                    1
-#define AFI_IP6                   2
-#define AFI_MAX                   3
-
-/* Subsequent Address Family Identifier. */
-#define SAFI_UNICAST              1
-#define SAFI_MULTICAST            2
-#define SAFI_UNICAST_MULTICAST    3
-#define SAFI_MPLS_VPN             4
-#define SAFI_MAX                  5
-
-/* Filter direction.  */
-#define FILTER_IN                 0
-#define FILTER_OUT                1
-#define FILTER_MAX                2
-
-/* Default Administrative Distance of each protocol. */
-#define ZEBRA_KERNEL_DISTANCE_DEFAULT      0
-#define ZEBRA_CONNECT_DISTANCE_DEFAULT     0
-#define ZEBRA_STATIC_DISTANCE_DEFAULT      1
-#define ZEBRA_RIP_DISTANCE_DEFAULT       120
-#define ZEBRA_RIPNG_DISTANCE_DEFAULT     120
-#define ZEBRA_OSPF_DISTANCE_DEFAULT      110
-#define ZEBRA_OSPF6_DISTANCE_DEFAULT     110
-#define ZEBRA_ISIS_DISTANCE_DEFAULT      115
-#define ZEBRA_IBGP_DISTANCE_DEFAULT      200
-#define ZEBRA_EBGP_DISTANCE_DEFAULT       20
-
-/* Flag manipulation macros. */
-#define CHECK_FLAG(V,F)      ((V) & (F))
-#define SET_FLAG(V,F)        (V) = (V) | (F)
-#define UNSET_FLAG(V,F)      (V) = (V) & ~(F)
-
-/* AFI and SAFI type. */
-typedef u_int16_t afi_t;
-typedef u_int8_t safi_t;
-
-/* Zebra types. */
-typedef u_int16_t zebra_size_t;
-typedef u_int8_t zebra_command_t;
-
-/* FIFO -- first in first out structure and macros.  */
-struct fifo
-{
-  struct fifo *next;
-  struct fifo *prev;
-};
-
-#define FIFO_INIT(F)                                  \
-  do {                                                \
-    struct fifo *Xfifo = (struct fifo *)(F);          \
-    Xfifo->next = Xfifo->prev = Xfifo;                \
-  } while (0)
-
-#define FIFO_ADD(F,N)                                 \
-  do {                                                \
-    struct fifo *Xfifo = (struct fifo *)(F);          \
-    struct fifo *Xnode = (struct fifo *)(N);          \
-    Xnode->next = Xfifo;                              \
-    Xnode->prev = Xfifo->prev;                        \
-    Xfifo->prev = Xfifo->prev->next = Xnode;          \
-  } while (0)
-
-#define FIFO_DEL(N)                                   \
-  do {                                                \
-    struct fifo *Xnode = (struct fifo *)(N);          \
-    Xnode->prev->next = Xnode->next;                  \
-    Xnode->next->prev = Xnode->prev;                  \
-  } while (0)
-
-#define FIFO_HEAD(F)                                  \
-  ((((struct fifo *)(F))->next == (struct fifo *)(F)) \
-  ? NULL : (F)->next)
-
-#define FIFO_EMPTY(F)                                 \
-  (((struct fifo *)(F))->next == (struct fifo *)(F))
-
-#define FIFO_TOP(F)                                   \
-  (FIFO_EMPTY(F) ? NULL : ((struct fifo *)(F))->next)
-
-#endif /* _ZEBRA_H */
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/lib/quagga/test/foo.c b/lib/quagga/test/foo.c
deleted file mode 100644 (file)
index 31cf08c..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "quagga.h"
-
-int main (void) {
-
-  init_zebra();
-  zebra_redistribute (2);
-  //  zebra_redistribute (1);
-  while (!sleep (1)) zebra_check();
-  return 0;
-}
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/lib/quagga/test/foo.pl b/lib/quagga/test/foo.pl
deleted file mode 100755 (executable)
index 771e3b5..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/perl
-
-use IO::Socket;
-
-$command = 11; # 11 = redistribute_add , 13 = redistribute_default_add
-
-$proto = 2; # connected 
-
-$remote = IO::Socket::INET->new (Proto => "tcp",
-                                 PeerAddr => "127.0.0.1",
-                                 PeerPort => "2600",
-                                 );
-$remote->autoflush (1);
-#print $remote pack ("nc", 3, 13);
-print $remote pack ("nc",3,1);
-print $remote pack ("ncc", 4,$command,2);
-print $remote pack ("ncccccNcNcNN", 25, 7, 10, 16, 11, 25, 0xc0a80206, 0, 0, 1, 5, 1);
-print <$remote>;
-close $remote
diff --git a/lib/quagga/test/quagga.try1.c b/lib/quagga/test/quagga.try1.c
deleted file mode 100644 (file)
index 339eea5..0000000
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- *  (C) 2006 by Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
- *
- *  This code is covered by the GPLv2
- *
- */
-
-#include <stdint.h>
-#ifdef MY_DEBUG
-#include <stdio.h>
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#define HAVE_SOCKLEN_T
-#include <quagga/zebra.h>
-#include "quagga.h"
-
-#ifdef OLSR_PLUGIN
-#include "olsr.h"
-#include "log.h"
-#include "defs.h"
-#include "local_hna_set.h"
-#endif
-
-#define ZAPI_MESSAGE_NEXTHOP  0x01
-#define ZAPI_MESSAGE_IFINDEX  0x02
-#define ZAPI_MESSAGE_DISTANCE 0x04
-#define ZAPI_MESSAGE_METRIC   0x08
-
-
-#define STATUS_CONNECTED 1
-#define BUFSIZE 1024
-static char status = 0;
-
-static int zsock; // Socket to zebra...
-struct ipv4_route *quagga_routes = 0; // routes currently exportet to zebra
-
-
-/* prototypes ntern */
-static char *try_read (ssize_t *);
-static char* zebra_route_packet (struct ipv4_route r, ssize_t *);
-static int parse_interface_add (char *, size_t);
-static int parse_interface_delete (char *, size_t);
-static int parse_interface_up (char *, size_t);
-static int parse_interface_down (char *, size_t);
-static int parse_interface_address_add (char *, size_t);
-static int parse_interface_address_delete (char *, size_t);
-static int parse_ipv4_route (char *, size_t, struct ipv4_route *);
-static int ipv4_route_add (char *, size_t);
-static int ipv4_route_delete (char *, size_t);
-static int parse_ipv6_route_add (char*, size_t);
-static uint32_t prefixlentomask (uint8_t);
-static void free_ipv4_route (struct ipv4_route);
-static void update_olsr_zebra_routes (struct ipv4_route*, struct ipv4_route*);
-static struct ipv4_route *zebra_create_ipv4_route_table_entry (uint32_t,
-                                                              uint32_t,
-                                                              uint32_t);
-static struct ipv4_route *zebra_create_ipv4_route_table (void);
-static void zebra_free_ipv4_route_table (struct ipv4_route*);
-static uint8_t masktoprefixlen (uint32_t);
-
-
-
-#ifdef MY_DEBUG
-static void dump_ipv4_route (struct ipv4_route r, char *c) {
-  int i = 0, x = 0;
-
-  puts (c);
-  printf("type: %d\n", r.type);
-  puts("flags:");
-  printf("  Internal: %s\n",r.flags&ZEBRA_FLAG_INTERNAL?"yes":"no");
-  printf("  Selfroute %s\n",r.flags&ZEBRA_FLAG_SELFROUTE?"yes":"no");
-  printf("  Blackhole %s\n",r.flags&ZEBRA_FLAG_BLACKHOLE?"yes":"no");
-  printf("  IBGP: %s\n",r.flags&ZEBRA_FLAG_IBGP?"yes":"no");
-  printf("  Selected: %s\n",r.flags&ZEBRA_FLAG_SELECTED?"yes":"no");
-  printf("  Changed: %s\n",r.flags&ZEBRA_FLAG_CHANGED?"yes":"no");
-  printf("  static: %s\n",r.flags&ZEBRA_FLAG_STATIC?"yes":"no");
-  printf("  reject: %s\n",r.flags&ZEBRA_FLAG_REJECT?"yes":"no");
-  puts("message:");
-  printf("  nexthop: %s\n",r.message&ZAPI_MESSAGE_NEXTHOP?"yes":"no");
-  printf("  ifindex: %s\n",r.message&ZAPI_MESSAGE_IFINDEX?"yes":"no");
-  printf("  distance: %s\n",r.message&ZAPI_MESSAGE_DISTANCE?"yes":"no");
-  printf("  metric: %s\n",r.message&ZAPI_MESSAGE_METRIC?"yes":"no");
-  printf("Prefixlen: %d\n", r.prefixlen);
-  printf("Prefix: %d", (unsigned char)r.prefix);
-  c = (char*) &r.prefix;
-  while (++i < (r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0)))
-    printf(".%d",(unsigned char)*(c + i));
-  while (i++ < 4)
-    printf(".0");
-  puts("");
-  i=0;
-  if (r.message&ZAPI_MESSAGE_NEXTHOP) {
-
-    printf("nexthop-count: %d\n", r.nh_count);
-    while (i++ < r.nh_count) {
-      c = (unsigned char*) &r.nexthops[i];
-      printf ("Nexthop %d: %d", i, (unsigned char) *c);
-      while (++x < 4) {
-       printf (".%d", (unsigned char) c[x]);
-      }
-      puts("");
-    }
-    i=0;
-  }
-  if (r.message&ZAPI_MESSAGE_IFINDEX) {
-
-    printf("index-number: %d\n", r.ind_num);
-    while (i++ < r.ind_num)
-      printf("Index: %d: %d\n", i, r.index[i]);
-    i=0;
-    if (r.message&ZAPI_MESSAGE_DISTANCE)
-      printf("Distance: %d\n",r.distance);
-    if (r.message&ZAPI_MESSAGE_METRIC)
-      printf("Metric: %d\n",r.metric);
-    puts("\n");
-  }
-}
-#endif
-
-void *my_realloc (void *buf, size_t s, const char *c) {
-  buf = realloc (buf, s);
-  if (!buf) {
-#ifdef OLSR_PLUGIN
-    OLSR_PRINTF (1, "OUT OF MEMORY: %s\n", strerror(errno));
-    olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n");
-    olsr_exit(c, EXIT_FAILURE);
-#else
-    exit (EXIT_FAILURE);
-#endif
-  }
-  return buf;
-}
-
-
-#ifndef OLSR_PLUGIN
-void *olsr_malloc (size_t f, const char *c) {
-  void* v = malloc (f);
-  return v;
-}
-#endif
-
-/* Connect to the zebra-daemon, returns a socket */
-int init_zebra () {
-  struct sockaddr_in i;
-  int ret;
-
-  zsock = socket (AF_INET,SOCK_STREAM, 0);
-  if (zsock <0 ) // TODO: Could not create socket
-    return -1;
-  memset (&i, 0, sizeof i);
-  i.sin_family = AF_INET;
-  i.sin_port = htons (ZEBRA_PORT);
-  //  i.sin_len = sizeof i;
-  i.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
-  ret = connect (zsock, (struct sockaddr *)&i, sizeof i);
-  if  (ret < 0) {
-    close (zsock);
-    return -1;
-  }
-  status |= STATUS_CONNECTED;
-  return zsock;
-}
-
-
-/* Sends a command to zebra, command is
-   the command defined in zebra.h, options is the packet-payload,
-   optlen the length, of the payload */
-char zebra_send_command (unsigned char command, char * options, int optlen) {
-
-  char *p = olsr_malloc (optlen+3, "zebra send_command");
-  uint16_t length = optlen + 3;  // length of option + command + packet_length
-
-  int ret;
-
-  uint16_t len = htons(length);
-  memcpy (p, &len, 2);
-  p[2] = command;
-  memcpy (p + 3, options, optlen);
-
-  do {
-    ret = write (zsock, p, length);
-    if (ret < 0) {
-      if (errno == EINTR) continue;
-    }
-    else return -1;
-    p = p+ret;
-  } while ((length -= ret));
-
-  return 0;
-}
-
-
-/* Creates a Route-Packet-Payload, needs address, netmask, nexthop,
-   distance, and a pointer of an size_t */
-static char* zebra_route_packet (struct ipv4_route r, ssize_t *optlen) {
-
-  char *cmdopt, *t;
-  *optlen = 9; // first: type, flags, message, prefixlen, nexthop number, nexthop)
-  *optlen += r.prefixlen / 8 + (r.prefixlen % 8 ? 1 : 0);
-
-  cmdopt = olsr_malloc (*optlen, "zebra add_v4_route");
-  t = cmdopt;
-  *t++ = 10; // Type: olsr
-  *t++ = r.flags; // flags
-  *t++ = r.message; // message: contains nexthop
-  *t++ = r.prefixlen;
-  memcpy (t, &r.prefix, r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0));
-  *t += r.prefixlen/8 + (r.prefixlen % 8 ? 1 : 0);
-  *t++ = r.nh_count;
-  memcpy (t, r.nexthops, r.nh_count * sizeof *r.nexthops);
-  return cmdopt;
-}
-
-
-/* adds a route to zebra-daemon (needs socket from zebra,
-   address = prefix of the route
-   mask = netmask of the route
-   nexthop = nexthop of the route
-   distance = distance-value of the route
-*/
-int zebra_add_v4_route (struct ipv4_route r) {
-
-  char *cmdopt;
-  ssize_t optlen;
-
-  cmdopt = zebra_route_packet (r, &optlen);
-
-  puts ("DEBUG: zebra_route_packet returned");
-
-
-
-  return zebra_send_command (ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen);
-
-}
-
-/* deletes a route from the zebra-daemon (
-   needs socket from zebra,
-   address = prefix of the route
-   mask = netmask of the route
-   nexthop = nexthop of the route
-   distance = distance-value of the route
-*/
-int zebra_delete_v4_route (struct ipv4_route r) {
-
-  char *cmdopt;
-  ssize_t optlen;
-
-  cmdopt = zebra_route_packet (r, &optlen);
-
-  return zebra_send_command (ZEBRA_IPV4_ROUTE_DELETE, cmdopt, optlen);
-
-}
-
-
-/* Check wether there is data from zebra aviable */
-void zebra_check (void* foo) {
-  char *data, *f;
-  ssize_t len, ret;
-
-  if (!status & STATUS_CONNECTED) {
-  }
-  data = try_read (&len);
-  if (data) {
-    f = data;
-    do {
-      ret = zebra_parse_packet (f, len);
-      if (!ret) {//something wired happened
-       puts ("DEBUG: IIIIIIIIIIRGS");
-       exit (EXIT_FAILURE);
-      }
-      f += ret;
-    } while ((f - data) < len);
-    free (data);
-  }
-}
-
-
-// tries to read a packet from zebra_socket
-// if there is something to read - make sure to read whole packages
-static char *try_read (ssize_t *len) {
-  char *buf = NULL;
-  ssize_t ret = 0, bsize = 0;
-  uint16_t length = 0, l = 0;
-  int sockstate;
-
-  *len = 0;
-
-  sockstate = fcntl (zsock, F_GETFL, 0);
-  fcntl (zsock, F_SETFL, sockstate|O_NONBLOCK);
-
-  do {
-    if (*len == bsize) {
-      bsize += BUFSIZE;
-      buf = my_realloc (buf, bsize, "Zebra try_read");
-    }
-    ret = read (zsock, buf + l, bsize - l);
-    if (ret <= 0) {
-      if (errno == EAGAIN) {
-       errno = 0;
-      }
-      else {
-       // TODO: errorhandling
-       ;
-      }
-      free (buf);
-      return NULL;
-    }
-    *len += ret;
-
-    while ((*len - l) > length) {
-      //      printf ("DEBUG: *len -l > length - %d - %d > %d\n", *len, l, length);
-      l += length;
-      memcpy (&length, buf + l, 2);
-      length = ntohs (length);
-    }
-    //    printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);
-    if (((*len) - l) == length) break; // GOT FULL PACKAGE!!
-    if (*len < l) {
-      //      printf ("DEBUG: *len, l, length: %d,%d,%d\n", *len, l, length);
-      fcntl (zsock, F_SETFL, sockstate);
-      continue;
-    }
-  } while (1);
-
-  fcntl (zsock, F_SETFL, sockstate);
-  return buf;
-}
-
-
-/* Parse a packet recived from zebra */
-int zebra_parse_packet (char *packet, ssize_t maxlen) {
-
-  /* Array of functions */
-  int (*foo[ZEBRA_MESSAGE_MAX]) (char *, size_t) = {
-    parse_interface_add,
-    parse_interface_delete,
-    parse_interface_address_add,
-    parse_interface_address_delete,
-    parse_interface_up,
-    parse_interface_down,
-    ipv4_route_add,
-    ipv4_route_delete,
-    parse_ipv6_route_add
-  };
-
-  puts ("DEBUG: zebra_parse_packet");
-  uint16_t length;
-
-  int ret;
-  memcpy (&length, packet, 2);
-  length = ntohs (length);
-
-  if (maxlen < length) {
-    puts("Error: programmer is an idiot");
-    printf ("DEBUG: maxlen = %d, packet_length = %d\n", maxlen, length);
-    return maxlen;
-  }
-
-  if (packet[2] - 1 < ZEBRA_MESSAGE_MAX && foo[packet[2] - 1]) {
-    if (!(ret = foo[packet[2] - 1] (packet + 3, length - 3)))
-      return length;
-    else printf ("DEBUG: Parse error: %d\n", ret);
-  }
-  else
-    printf ("Unknown packet type: %d\n", packet[2]);
-
-  puts ("Quagga: RECIVED PACKET FROM ZEBRA THAT I CAN'T PARSE");
-
-  return length;
-}
-
-
-static int parse_interface_add (char *opt, size_t len) {
-  //todo
-  return 0;
-}
-
-
-static int parse_interface_delete (char *opt, size_t len) {
-  //todo
-  return 0;
-}
-
-
-static int parse_interface_address_add (char *opt, size_t len) {
-
-  //todo
-  return 0;
-}
-
-static int parse_interface_up (char *opt, size_t len) {
-
-  //todo
-  return 0;
-}
-
-static int parse_interface_down (char *opt, size_t len) {
-
-  //todo
-  return 0;
-}
-
-
-static int parse_interface_address_delete (char *opt, size_t  len) {
-  //todo
-  return 0;
-}
-
-
-/* Parse an ipv4-route-packet recived from zebra
- */
-static int parse_ipv4_route (char *opt, size_t len, struct ipv4_route *r) {
-  //  puts ("DEBUG: parse_ipv4_route");
-  if (len < 4) return -1;
-
-  r->type = *opt++;
-  r->flags = *opt++;
-  r->message = *opt++;
-  r->prefixlen = *opt++;
-  len -= 4;
-  r->prefix = 0;
-
-  if ((int)len < r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0)) return -1;
-
-  memcpy (&r->prefix, opt, r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0));
-  opt += r->prefixlen/8 + (r->prefixlen % 8 ? 1 : 0);
-
-  if (r->message & ZAPI_MESSAGE_NEXTHOP) {
-    if (len < 1) return -1;
-    r->nh_count = *opt++;
-    if (len < sizeof (uint32_t) * r->nh_count) return -1;
-    r->nexthops = olsr_malloc (sizeof (uint32_t) * r->nh_count,
-                              "quagga: parse_ipv4_route_add");
-    memcpy (r->nexthops, opt, sizeof (uint32_t) * r->nh_count);
-    opt += sizeof (uint32_t) * r->nh_count;
-    len -= sizeof (uint32_t) * r->nh_count + 1;
-  }
-
-  if (r->message & ZAPI_MESSAGE_IFINDEX) {
-    if (len < 1) return -2;
-    r->ind_num = *opt++;
-    if (len < sizeof (uint32_t) * r->ind_num) return -3;
-    r->index = olsr_malloc (sizeof (uint32_t) * r->ind_num,
-                           "quagga: parse_ipv4_route_add");
-    memcpy (r->index, opt, r->ind_num * sizeof (uint32_t));
-    opt += sizeof (uint32_t) * r->ind_num;
-    len -= sizeof (uint32_t) * r->ind_num;
-  }
-
-  if (r->message & ZAPI_MESSAGE_DISTANCE)
-    // todo
-    ;
-
-  if (r->message & ZAPI_MESSAGE_METRIC) {
-    if (len < sizeof (uint32_t)) return -4;
-    memcpy (&r->metric, opt, sizeof (uint32_t));
-  }
-
-  return 0;
-}
-
-
-static int ipv4_route_add (char *opt, size_t len) {
-
-  struct ipv4_route r;
-  int f;
-
-  //  puts ("DEBUG: ipv4_route_add");
-
-  f = parse_ipv4_route (opt, len, &r);
-  if (f < 0) {
-    printf ("parse-error: %d\n",f);
-    return f;
-  }
-
-  add_hna4_route (r);
-  return 0;
-}
-
-static int ipv4_route_delete (char *opt, size_t len) {
-  struct ipv4_route r;
-  int f;
-
-  f = parse_ipv4_route (opt, len, &r);
-  if (f < 0) return f;
-
-  return delete_hna4_route (r);
-  // OK, now delete that foo
-
-}
-
-static int parse_ipv6_route_add (char *opt, size_t len) {
-  //todo
-  return 0;
-}
-
-
-/* start redistribution FROM zebra */
-int zebra_redistribute (unsigned char type) {
-
-  return zebra_send_command (ZEBRA_REDISTRIBUTE_ADD, &type, 1);
-
-
-}
-
-
-/* end redistribution FROM zebra */
-int zebra_disable_redistribute (unsigned char type) {
-
-  return zebra_send_command (ZEBRA_REDISTRIBUTE_DELETE, &type, 1);
-
-}
-
-/* this is buggy. see prefix_to_netmask4() for a working version. */
-static uint32_t prefixlentomask (uint8_t prefix) {
-  uint32_t mask;
-  mask = 0xffffffff<<(32-prefix);
-  mask = ntohl(mask);
-  return mask;
-}
-
-int add_hna4_route (struct ipv4_route r) {
-  union olsr_ip_addr net, mask;
-
-#ifdef MY_DEBUG
-  dump_ipv4_route(r, "add_hna4_route");
-#endif
-
-  mask.v4 = prefixlentomask(r.prefixlen);
-  net.v4 = r.prefix;
-
-
-#ifdef OLSR_PLUGIN
-  add_local_hna4_entry(&net, &mask);
-#endif
-  free_ipv4_route(r);
-  return 0;
-}
-
-int delete_hna4_route (struct ipv4_route r) {
-
-  union olsr_ip_addr net, mask;
-
-#ifdef MY_DEBUG
-  dump_ipv4_route(r, "delete_hna4_route");
-#endif
-
-  mask.v4 = prefixlentomask(r.prefixlen);
-  net.v4 = r.prefix;
-
-#ifdef OLSR_PLUGIN
-  return remove_local_hna4_entry(&net, &mask) ? 0 : -1;
-#endif
-
-  free_ipv4_route(r);
-  return 0;
-
-}
-
-static void free_ipv4_route (struct ipv4_route r) {
-
-  if(r.message&ZAPI_MESSAGE_IFINDEX && r.ind_num) free(r.index);
-  if(r.message&ZAPI_MESSAGE_NEXTHOP && r.nh_count) free(r.nexthops);
-
-}
-
-void zebra_clear_routes(void) {
-
-  struct ipv4_route *t;
-
-  t = quagga_routes;
-  while (t) {
-    zebra_delete_v4_route(*t);
-    t=t->next;
-  }
-  zebra_free_ipv4_route_table(quagga_routes);
-
-  quagga_routes = NULL;
-}
-
-
-void zebra_update_hna (void* f) {
-
-  struct ipv4_route *a = zebra_create_ipv4_route_table();
-  update_olsr_zebra_routes(a, quagga_routes);
-  zebra_free_ipv4_route_table(quagga_routes);
-
-  quagga_routes = a;
-
-}
-
-static struct ipv4_route *zebra_create_ipv4_route_table (void) {
-
-  struct ipv4_route *r = 0, *t = 0 /* make compiler happy */;
-  int i;
-  struct hna_entry *e;
-  struct hna_net *n;
-
-  for (i = 0; i < HASHSIZE; i++) {
-    e = hna_set[i].next;
-    for(;e != &hna_set[i];e = e->next) {
-      n = e->networks.next;
-      for(;n != &e->networks; n = n->next) {
-       if (!r) {
-         r = zebra_create_ipv4_route_table_entry(n->A_network_addr.v4,
-                                                 n->A_netmask.v4,
-                                                 e->A_gateway_addr.v4);
-         t = r;
-       }
-       else {
-         t->next = zebra_create_ipv4_route_table_entry(n->A_network_addr.v4,
-                                                       n->A_netmask.v4,
-                                                       e->A_gateway_addr.v4);
-         t = t->next;
-       }
-      }
-    }
-  }
-
-  return r;
-
-}
-
-
-static struct ipv4_route *zebra_create_ipv4_route_table_entry (uint32_t addr,
-                                                              uint32_t mask,
-                                                              uint32_t gw) {
-
-  struct ipv4_route *r;
-
-
-  r = olsr_malloc (sizeof *r,"zebra_create_ipv4_route_table_entry");
-  memset (r, 0, sizeof *r);
-  r->prefix = addr;
-  r->prefixlen = masktoprefixlen (mask);
-  r->message |= ZAPI_MESSAGE_NEXTHOP;
-  r->nh_count = 1;
-  r->nexthops = olsr_malloc (sizeof (uint32_t), "zebra_create_ipv4_route_table_entry");
-  *r->nexthops = gw;
-  r->next = NULL;
-
-  return r;
-}
-
-static uint8_t masktoprefixlen (uint32_t mask) {
-
-
-  uint8_t prefixlen = 0;
-  while (mask & (1 << ++prefixlen && prefixlen < 32);
-  return prefixlen;
-
-}
-
-static void update_olsr_zebra_routes (struct ipv4_route *a,
-                                     struct ipv4_route *r) {
-
-  struct ipv4_route *t;
-
-  if (!r) {
-    puts("no quagga_routing_table aviable");
-    for (;a;a = a->next) {
-      dump_ipv4_route (*a, "adding this route");
-      //      zebra_add_v4_route(*r);
-    }
-    return;
-  }
-
-  while (a) {
-    for (t = r; t; t = t->next) {
-      if (a->prefix == t->prefix)
-       if (a->prefixlen == t->prefixlen)
-         if (*a->nexthops == *t->nexthops) {
-           goto foo;
-         }
-    }
-    dump_ipv4_route (*a, "adding this route");
-    //zebra_add_v4_route(*a);
-  foo:
-    a = a->next;
-  }
-
-  while (r) {
-    for (t = a; t; t = t->next) {
-      if (r->prefix == t->prefix)
-       if (r->prefixlen == t->prefixlen)
-         if (*r->nexthops == *t->nexthops) {
-           goto bar;
-         }
-    }
-    dump_ipv4_route (*r, "deleting this route");
-    //zebra_delete_v4_route(*r);
-  bar:
-    r = r->next;
-  }
-
-}
-
-
-static void zebra_free_ipv4_route_table (struct ipv4_route *r) {
-  struct ipv4_route *n;
-  if (!r) return;
-  while ((n = r->next)) {
-    if (r->message & ZAPI_MESSAGE_NEXTHOP) free (r->nexthops);
-    if (r->message & ZAPI_MESSAGE_IFINDEX) free (r->index);
-    free(r);
-    r = n;
-  }
-}
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */