diff -Nuar batman-0.3/Makefile batman-0.3-quagga/Makefile
--- batman-0.3/Makefile	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/Makefile	2008-05-06 16:23:26.000000000 +0300
@@ -48,8 +48,8 @@
 
 SRC_FILES=	"\(\.c\)\|\(\.h\)\|\(Makefile\)\|\(INSTALL\)\|\(LIESMICH\)\|\(README\)\|\(THANKS\)\|\(TRASH\)\|\(Doxyfile\)\|\(./posix\)\|\(./linux\)\|\(./bsd\)\|\(./man\)\|\(./doc\)"
 
-SRC_C=		batman.c originator.c schedule.c list-batman.c allocate.c bitarray.c hash.c profile.c ring_buffer.c $(OS_C)
-SRC_H=		batman.h originator.h schedule.h list-batman.h os.h allocate.h bitarray.h hash.h profile.h vis-types.h ring_buffer.h
+SRC_C=		batman.c originator.c schedule.c list-batman.c allocate.c bitarray.c hash.c profile.c ring_buffer.c quagga.c $(OS_C)
+SRC_H=		batman.h originator.h schedule.h list-batman.h os.h allocate.h bitarray.h hash.h profile.h vis-types.h ring_buffer.h quagga.h
 SRC_O=		$(SRC_C:.c=.o)
 
 PACKAGE_NAME=	batmand
diff -Nuar batman-0.3/batman.c batman-0.3-quagga/batman.c
--- batman-0.3/batman.c	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/batman.c	2008-05-06 16:23:26.000000000 +0300
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006 B.A.T.M.A.N. contributors:
  * Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann,
- * Felix Fietkau, Marek Lindner
+ * Felix Fietkau, Marek Lindner, Vasilis Tsiligiannis
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -124,7 +124,7 @@
 uint8_t num_words = (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE);
 uint8_t aggregation_enabled = 0;
 
-
+struct zebra zebra;
 
 void usage(void)
 {
@@ -143,6 +143,7 @@
 	fprintf( stderr, "       -r routing class\n" );
 	fprintf( stderr, "       -s visualization server\n" );
 	fprintf( stderr, "       -v print version\n" );
+	fprintf( stderr, "       -z quagga unix socket\n" );
 	fprintf( stderr, "       --policy-routing-script\n" );
 }
 
@@ -194,6 +195,8 @@
 	fprintf( stderr, "       -s visualization server\n" );
 	fprintf( stderr, "          default: none, allowed values: IP\n\n" );
 	fprintf( stderr, "       -v print version\n" );
+	fprintf( stderr, "       -z quagga unix socket\n" );
+	fprintf( stderr, "          default: none, allowed values: Socket Path\n\n" );
 	fprintf( stderr, "       --policy-routing-script send all routing table changes to the script\n" );
 	fprintf( stderr, "       --aggregation enable packet aggregation (experimental feature)\n" );
 }
@@ -230,7 +233,7 @@
 		netmask = ( uint32_t )orig_node->hna_buff[ ( hna_buff_count * 5 ) + 4 ];
 
 		if ( ( netmask > 0 ) && ( netmask < 33 ) )
-			add_del_route( hna, netmask, orig_node->router->addr, orig_node->router->if_incoming->addr.sin_addr.s_addr, orig_node->batman_if->if_index, orig_node->batman_if->dev, BATMAN_RT_TABLE_NETWORKS, 0, del );
+			add_del_route( hna, netmask, orig_node->router->addr, orig_node->router->if_incoming->addr.sin_addr.s_addr, orig_node->batman_if->if_index, orig_node->batman_if->dev, BATMAN_RT_TABLE_NETWORKS, 0, orig_node->metric, del );
 
 		hna_buff_count++;
 
@@ -379,6 +382,7 @@
 {
 	char orig_str[ADDR_STR_LEN], next_str[ADDR_STR_LEN];
 	prof_start( PROF_update_routes );
+	uint16_t metric;
 
 
 	debug_output( 4, "update_routes() \n" );
@@ -405,7 +409,7 @@
 			if ( orig_node->hna_buff_len > 0 )
 				add_del_hna( orig_node, 1 );
 
-			add_del_route( orig_node->orig, 32, orig_node->router->addr, 0, orig_node->batman_if->if_index, orig_node->batman_if->dev, BATMAN_RT_TABLE_HOSTS, 0, 1 );
+			add_del_route( orig_node->orig, 32, orig_node->router->addr, 0, orig_node->batman_if->if_index, orig_node->batman_if->dev, BATMAN_RT_TABLE_HOSTS, 0, orig_node->metric, 1 );
 
 		}
 
@@ -418,10 +422,12 @@
 				debug_output( 4, "Route changed\n" );
 			}
 
-			add_del_route( orig_node->orig, 32, neigh_node->addr, neigh_node->if_incoming->addr.sin_addr.s_addr, neigh_node->if_incoming->if_index, neigh_node->if_incoming->dev, BATMAN_RT_TABLE_HOSTS, 0, 0 );
+			metric = 255 - neigh_node->last_ttl;
+			add_del_route( orig_node->orig, 32, neigh_node->addr, neigh_node->if_incoming->addr.sin_addr.s_addr, neigh_node->if_incoming->if_index, neigh_node->if_incoming->dev, BATMAN_RT_TABLE_HOSTS, 0, metric, 0 );
 
 			orig_node->batman_if = neigh_node->if_incoming;
 			orig_node->router = neigh_node;
+			orig_node->metric = metric;
 
 			/* add new announced network(s) */
 			if ( ( hna_buff_len > 0 ) && ( hna_recv_buff != NULL ) ) {
@@ -932,10 +938,10 @@
 			num_hna++;
 
 			/* add throw routing entries for own hna */
-			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 0 );
-			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 0 );
-			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 0 );
-			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 0 );
+			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 0, 0 );
+			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 0, 0 );
+			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 0, 0 );
+			add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 0, 0 );
 
 		}
 
@@ -1246,10 +1252,10 @@
 								if (hna_node->del) {
 									debug_output(3, "Deleting HNA from announce network list: %s/%i\n", oldorig_str, hna_node->netmask );
 
-									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 1 );
-									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 1 );
-									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 1 );
-									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 1 );
+									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 0, 1 );
+									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 0, 1 );
+									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 0, 1 );
+									add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 0, 1 );
 
 									list_del(prev_list_head, hna_pos, &hna_list);
 
@@ -1275,10 +1281,10 @@
 								debug_output(3, "Adding HNA to announce network list: %s/%i\n", oldorig_str, hna_node->netmask );
 
 								/* add throw routing entries for own hna */
-								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 0 );
-								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 0 );
-								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 0 );
-								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 0 );
+								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 0, 0 );
+								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 0, 0 );
+								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 0, 0 );
+								add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 0, 0 );
 
 								/* add node */
 								hna_node_exist = debugMalloc( sizeof(struct hna_node), 105 );
@@ -1346,10 +1352,10 @@
 		hna_node = list_entry( list_pos, struct hna_node, list );
 
 		/* add throw routing entries for own hna */
-		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 1 );
-		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 1 );
-		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 1 );
-		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 1 );
+		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_NETWORKS, 1, 0, 1 );
+		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_HOSTS, 1, 0, 1 );
+		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 1, 0, 1 );
+		add_del_route( hna_node->addr, hna_node->netmask, 0, 0, 0, "unknown", BATMAN_RT_TABLE_TUNNEL, 1, 0, 1 );
 
 		debugFree( hna_node, 1103 );
 
diff -Nuar batman-0.3/batman.h batman-0.3-quagga/batman.h
--- batman-0.3/batman.h	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/batman.h	2008-05-06 16:23:26.000000000 +0300
@@ -1,6 +1,8 @@
 /*
  * Copyright (C) 2006 B.A.T.M.A.N. contributors:
- * Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann, Marek Lindner
+ * Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann, Marek Lindner,
+ * Vasilis Tsiligiannis
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
  * License as published by the Free Software Foundation.
@@ -36,6 +38,7 @@
 #include "profile.h"
 #include "vis-types.h"
 #include "ring_buffer.h"
+#include "quagga.h"
 
 
 
@@ -186,6 +189,8 @@
 extern uint8_t num_words;
 extern uint8_t aggregation_enabled;
 
+extern struct zebra zebra;
+
 struct bat_packet
 {
 	uint8_t  version;  /* batman version field */
@@ -215,6 +220,7 @@
 	int16_t  hna_buff_len;
 	uint16_t last_real_seqno;   /* last and best known squence number */
 	uint8_t last_ttl;         /* ttl of last received packet */
+	uint16_t metric;
 	struct list_head_first neigh_list;
 };
 
@@ -339,6 +345,12 @@
 	uint32_t ifindex;
 };
 
+struct zebra {
+	uint8_t enabled;
+	char *unix_path;
+	int32_t unix_sock;
+};
+
 int8_t batman(void);
 void usage(void);
 void verbose_usage(void);
diff -Nuar batman-0.3/bsd/route.c batman-0.3-quagga/bsd/route.c
--- batman-0.3/bsd/route.c	2008-05-05 23:47:24.000000000 +0300
+++ batman-0.3-quagga/bsd/route.c	2008-05-06 16:23:26.000000000 +0300
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006, 2007 BATMAN contributors:
- * Stefan Sperling <stsp@stsp.name>
+ * Stefan Sperling <stsp@stsp.name>, Vasilis Tsiligiannis
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -140,7 +140,7 @@
 }
 
 void add_del_route(uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src_ip,
-		int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, int8_t del)
+		int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, uint16_t metric, int8_t del)
 {
 	char dest_str[16], router_str[16];
 	struct rt_msg msg;
diff -Nuar batman-0.3/linux/route.c batman-0.3-quagga/linux/route.c
--- batman-0.3/linux/route.c	2008-05-05 23:47:24.000000000 +0300
+++ batman-0.3-quagga/linux/route.c	2008-05-06 16:23:26.000000000 +0300
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 BATMAN contributors:
- * Marek Lindner
+ * Marek Lindner, Vasilis Tsiligiannis, Antony Chazapis
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
  * License as published by the Free Software Foundation.
@@ -40,7 +40,7 @@
  *
  ***/
 
-void add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src_ip, int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, int8_t del ) {
+void add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src_ip, int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, uint16_t metric, int8_t del ) {
 
 	int netlink_sock, len;
 	uint32_t my_router;
@@ -62,10 +62,15 @@
 	inet_ntop( AF_INET, &src_ip, str3, sizeof (str3) );
 
 	if (policy_routing_script != NULL) {
-		dprintf(policy_routing_pipe, "ROUTE %s %s %s %i %s %s %i %s %i\n", (del ? "del" : "add"), (route_type == 1 ? "THROW" : (route_type == 2 ? "UNREACH" : "UNICAST")), str1, netmask, str2, str3, ifi, dev, rt_table);
+		dprintf(policy_routing_pipe, "ROUTE %s %s %s %i %s %s %i %s %i %i\n", (del ? "del" : "add"), (route_type == 1 ? "THROW" : (route_type == 2 ? "UNREACH" : "UNICAST")), str1, netmask, str2, str3, ifi, dev, rt_table, metric);
 		return;
 	}
 
+	if (zebra.enabled) {
+		/* Send the routes to zebra, but add them to the host as well. */
+		zebra_add_del_route(dest, netmask, router, src_ip, ifi, dev, rt_table, route_type, metric, del);
+	}
+
 	if ( router == dest ) {
 
 		if ( dest == 0 ) {
@@ -231,10 +236,14 @@
 	inet_ntop(AF_INET, &network, str1, sizeof (str1));
 
 	if (policy_routing_script != NULL) {
-		dprintf(policy_routing_pipe, "RULE %s %s %s %i %s %s %i %s %i\n", (del ? "del" : "add"), (rule_type == 1 ? "DST" : (rule_type == 2 ? "IIF" : "SRC")), str1, netmask, "unused", "unused", prio, iif, rt_table);
+		dprintf(policy_routing_pipe, "RULE %s %s %s %i %s %s %i %s %i %i\n", (del ? "del" : "add"), (rule_type == 1 ? "DST" : (rule_type == 2 ? "IIF" : "SRC")), str1, netmask, "unused", "unused", prio, iif, rt_table, 0);
 		return;
 	}
 
+	if (zebra.enabled) {
+		/* Don't use the host's routing tables. */
+		return;
+	}
 
 	memset( &nladdr, 0, sizeof(struct sockaddr_nl) );
 	memset( &req, 0, sizeof(req) );
@@ -464,7 +473,7 @@
 		netaddr = ( ((struct sockaddr_in *)&ifr_tmp.ifr_addr)->sin_addr.s_addr & addr );
 		netmask = bit_count( ((struct sockaddr_in *)&ifr_tmp.ifr_addr)->sin_addr.s_addr );
 
-		add_del_route( netaddr, netmask, 0, 0, 0, ifr->ifr_name, BATMAN_RT_TABLE_TUNNEL, 1, del );
+		add_del_route( netaddr, netmask, 0, 0, 0, ifr->ifr_name, BATMAN_RT_TABLE_TUNNEL, 1, 0, del );
 
 		if ( is_batman_if( ifr->ifr_name, &batman_if ) )
 			continue;
@@ -617,7 +626,7 @@
 		if ( is_rule )
 			add_del_rule( ( rule_type == 2 ? 0 : dest ), ( rule_type == 2 ? 0 : ( rule_type == 1 ? rtm->rtm_dst_len : rtm->rtm_src_len ) ), rtm->rtm_table, prio, ( rule_type == 2 ? dev : 0 ) , rule_type, 1 );
 		else
-			add_del_route( dest, rtm->rtm_dst_len, router, 0, ifi, "unknown", rtm->rtm_table, rtm->rtm_type, 1 );
+			add_del_route( dest, rtm->rtm_dst_len, router, 0, ifi, "unknown", rtm->rtm_table, rtm->rtm_type, 0, 1 );
 
 	}
 
diff -Nuar batman-0.3/originator.c batman-0.3-quagga/originator.c
--- batman-0.3/originator.c	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/originator.c	2008-05-06 16:23:26.000000000 +0300
@@ -1,5 +1,5 @@
 /* Copyright (C) 2006 B.A.T.M.A.N. contributors:
- * Simon Wunderlich, Marek Lindner
+ * Simon Wunderlich, Marek Lindner, Vasilis Tsiligiannis
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -118,6 +118,7 @@
 	orig_node->orig = addr;
 	orig_node->router = NULL;
 	orig_node->batman_if = NULL;
+	orig_node->metric = 255;
 
 	orig_node->bcast_own = debugMalloc( found_ifs * sizeof(TYPE_OF_WORD) * num_words, 404 );
 	memset( orig_node->bcast_own, 0, found_ifs * sizeof(TYPE_OF_WORD) * num_words );
@@ -367,7 +368,7 @@
 						if ( orig_node->hna_buff_len > 0 )
 							add_del_hna( orig_node, 1 );
 
-						add_del_route( orig_node->orig, 32, orig_node->router->addr, 0, orig_node->batman_if->if_index, orig_node->batman_if->dev, BATMAN_RT_TABLE_HOSTS, 0, 1 );
+						add_del_route( orig_node->orig, 32, orig_node->router->addr, 0, orig_node->batman_if->if_index, orig_node->batman_if->dev, BATMAN_RT_TABLE_HOSTS, 0, orig_node->metric, 1 );
 
 						/* if the neighbour is the route towards our gateway */
 						if ((curr_gateway != NULL) && (curr_gateway->orig_node == orig_node))
diff -Nuar batman-0.3/os.h batman-0.3-quagga/os.h
--- batman-0.3/os.h	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/os.h	2008-05-06 16:23:26.000000000 +0300
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 BATMAN contributors:
- * Thomas Lopatic, Marek Lindner
+ * Thomas Lopatic, Marek Lindner, Vasilis Tsiligiannis
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
  * License as published by the Free Software Foundation.
@@ -37,7 +37,7 @@
 void restore_and_exit( uint8_t is_sigsegv );
 
 /* route.c */
-void add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src_ip, int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, int8_t del );
+void add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src_ip, int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, uint16_t metric, int8_t del );
 void add_del_rule( uint32_t network, uint8_t netmask, int8_t rt_table, uint32_t prio, char *iif, int8_t dst_rule, int8_t del );
 int add_del_interface_rules( int8_t del );
 int flush_routes_rules( int8_t rt_table );
diff -Nuar batman-0.3/posix/init.c batman-0.3-quagga/posix/init.c
--- batman-0.3/posix/init.c	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/posix/init.c	2008-05-06 16:23:26.000000000 +0300
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 BATMAN contributors:
- * Thomas Lopatic, Marek Lindner
+ * Thomas Lopatic, Marek Lindner, Vasilis Tsiligiannis
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
  * License as published by the Free Software Foundation.
@@ -243,11 +243,12 @@
 		{0, 0, 0, 0}
 	};
 
+	memset(&zebra, 0, sizeof(zebra));
 	memset( &tmp_ip_holder, 0, sizeof (struct in_addr) );
 	stop = 0;
 	prog_name = argv[0];
 
-	while ( ( optchar = getopt_long( argc, argv, "a:A:bcd:hHio:g:p:r:s:vV", long_options, &option_index ) ) != -1 ) {
+	while ( ( optchar = getopt_long( argc, argv, "a:A:bcd:hHio:g:p:r:s:vVz:", long_options, &option_index ) ) != -1 ) {
 
 		switch ( optchar ) {
 
@@ -461,6 +462,15 @@
 				found_args++;
 				break;
 
+			case 'z':
+				errno = 0;
+
+				zebra.enabled++;
+				zebra.unix_path = optarg;
+
+				found_args += ((*((char*)( optarg - 1)) == optchar) ? 1 : 2);
+				break;
+
 			case 'h':
 			default:
 				usage();
@@ -517,6 +527,9 @@
 
 		}
 
+		if ( ( zebra.enabled != 0 ) && ( !zebra_init(zebra.unix_path) ) )
+			exit(EXIT_FAILURE);
+
 		if (policy_routing_script != NULL)
 			create_routing_pipe();
 
@@ -669,7 +682,7 @@
 		add_del_rule( 0, 0, BATMAN_RT_TABLE_NETWORKS, BATMAN_RT_PRIO_UNREACH - 1, 0, 1, 0 );
 
 		/* add unreachable routing table entry */
-		add_del_route( 0, 0, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 2, 0 );
+		add_del_route( 0, 0, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 2, 0, 0 );
 
 		if ( routing_class > 0 ) {
 
@@ -1245,7 +1258,7 @@
 		close( skfd );
 
 		if( !ioc.exists )
-			add_del_route( ioc.universal, 16, 0, 0, ioc.ifindex, ioc.dev_name, 254, 0, 0 );
+			add_del_route( ioc.universal, 16, 0, 0, ioc.ifindex, ioc.dev_name, 254, 0, 0, 0 );
 
 
 	}
diff -Nuar batman-0.3/posix/posix.c batman-0.3-quagga/posix/posix.c
--- batman-0.3/posix/posix.c	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/posix/posix.c	2008-05-06 16:23:26.000000000 +0300
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 BATMAN contributors:
- * Thomas Lopatic, Marek Lindner
+ * Thomas Lopatic, Marek Lindner, Vasilis Tsiligiannis
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
  * License as published by the Free Software Foundation.
@@ -423,7 +423,7 @@
 	add_del_rule( 0, 0, BATMAN_RT_TABLE_NETWORKS, BATMAN_RT_PRIO_UNREACH - 1, 0, 1, 1 );
 
 	/* delete unreachable routing table entry */
-	add_del_route( 0, 0, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 2, 1 );
+	add_del_route( 0, 0, 0, 0, 0, "unknown", BATMAN_RT_TABLE_UNREACH, 2, 0, 1 );
 
 	if ( ( routing_class != 0 ) && ( curr_gateway != NULL ) )
 		del_default_route();
@@ -447,6 +447,9 @@
 		waitpid(policy_routing_script_pid, NULL, 0);
 	}
 
+	if ( zebra.unix_sock > 0 )
+		close( zebra.unix_sock );
+
 }
 
 
diff -Nuar batman-0.3/posix/tunnel.c batman-0.3-quagga/posix/tunnel.c
--- batman-0.3/posix/tunnel.c	2008-05-05 23:47:25.000000000 +0300
+++ batman-0.3-quagga/posix/tunnel.c	2008-05-06 16:23:26.000000000 +0300
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 BATMAN contributors:
- * Marek Lindner
+ * Marek Lindner, Vasilis Tsiligiannis
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
  * License as published by the Free Software Foundation.
@@ -209,7 +209,7 @@
 
 
 	if (add_dev_tun(curr_gw_data->batman_if, my_tun_addr, tun_if, sizeof(tun_if), &tun_fd, &tun_ifi ) > 0)
-		add_del_route(0, 0, 0, my_tun_addr, tun_ifi, tun_if, BATMAN_RT_TABLE_TUNNEL, 0, 0);
+		add_del_route(0, 0, 0, my_tun_addr, tun_ifi, tun_if, BATMAN_RT_TABLE_TUNNEL, 0, 0, 0);
 	else
 		goto udp_out;
 
@@ -393,7 +393,7 @@
 	}
 
 	/* cleanup */
-	add_del_route(0, 0, 0, my_tun_addr, tun_ifi, tun_if, BATMAN_RT_TABLE_TUNNEL, 0, 1);
+	add_del_route(0, 0, 0, my_tun_addr, tun_ifi, tun_if, BATMAN_RT_TABLE_TUNNEL, 0, 0, 1);
 	del_dev_tun(tun_fd);
 
 udp_out:
@@ -582,7 +582,7 @@
 		return NULL;
 	}
 
-	add_del_route( *(uint32_t *)my_tun_ip, 16, 0, 0, tun_ifi, tun_dev, 254, 0, 0 );
+	add_del_route( *(uint32_t *)my_tun_ip, 16, 0, 0, tun_ifi, tun_dev, 254, 0, 0, 0 );
 
 
 	FD_ZERO(&wait_sockets);
@@ -760,7 +760,7 @@
 
 	/* delete tun device and routes on exit */
 	my_tun_ip[3] = 0;
-	add_del_route( *(uint32_t *)my_tun_ip, 16, 0, 0, tun_ifi, tun_dev, 254, 0, 1 );
+	add_del_route( *(uint32_t *)my_tun_ip, 16, 0, 0, tun_ifi, tun_dev, 254, 0, 0, 1 );
 
 	del_dev_tun( tun_fd );
 
diff -Nuar batman-0.3/quagga.c batman-0.3-quagga/quagga.c
--- batman-0.3/quagga.c	1970-01-01 02:00:00.000000000 +0200
+++ batman-0.3-quagga/quagga.c	2008-05-06 16:23:26.000000000 +0300
@@ -0,0 +1,223 @@
+/*
+ * API client for Quagga zebra daemon
+ *
+ * Copyright (C) 2007 BATMAN contributors:
+ * Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+ * based on olsrd_quagga plugin by Immo 'FaUl' Wehrenberg
+ * Modifications for batmand revision >= 1040
+ * by Antony Chazapis <chazapis@cslab.ece.ntua.gr>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <sys/un.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include "quagga.h"
+#include "allocate.h"
+#include "os.h"
+
+
+struct zebra_api
+{
+	unsigned char cmd;
+	unsigned char type;
+	unsigned char flags;
+	unsigned char message;
+	unsigned char prefixlen;
+	struct in_addr prefix;
+	unsigned char nexthop_num;
+	unsigned char ifindex_num;
+	struct in_addr *nexthop;
+	uint32_t *ifindex;
+	unsigned char distance;
+	uint32_t metric;
+};
+
+static int32_t zebra_connect (char *socket_path);
+static unsigned char *zebra_packet (char cmd, struct zebra_api *api);
+static int8_t zebra_send (unsigned char *data);
+
+
+int32_t
+zebra_connect (char *unix_path)
+{
+	int sock;
+	struct sockaddr_un sock_addr;
+
+	// zebra socket address
+	memset (&sock_addr, 0, sizeof (sock_addr));
+	sock_addr.sun_family = AF_UNIX;
+	strcpy (sock_addr.sun_path, unix_path);
+
+	// create socket  
+	if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
+		fprintf (stderr, "Error - (Quagga) could not create socket!");
+		return -1;
+	}
+
+	// connect to zebra unix socket
+	if (connect (sock, (struct sockaddr *) &sock_addr, sizeof sock_addr) < 0) {
+		fprintf (stderr, "Error - (Quagga) could not connect to zebra! Is zebra running?\n");
+		close (sock);
+		return -1;
+	}
+
+	return sock;
+}
+
+
+int8_t
+zebra_init (char *unix_path)
+{
+	zebra.unix_sock = zebra_connect (unix_path);
+	if (zebra.unix_sock < 0) return 0;
+	return 1;
+}
+
+
+void
+zebra_add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src_ip, int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, uint16_t metric, int8_t del )
+{
+	struct zebra_api api;
+	struct in_addr nexthop;
+	uint32_t ifindex;
+
+	// XXX Is src_ip needed?
+	// XXX Map UNREACH type to smth?
+ 
+	// only forward UNICAST routes
+	if (route_type != 0)
+		return;
+ 
+	// sanity checks
+	if (router == 0)
+		return;			/* Quagga BUG workaround: don't add routes with destination = gateway
+					   see http://lists.olsr.org/pipermail/olsr-users/2006-June/001726.html */
+
+	// prepare api
+	api.type = ZEBRA_ROUTE_BATMAN;
+	api.flags = 0;
+	api.message = ZAPI_MESSAGE_NEXTHOP | (del ? 0 : ZAPI_MESSAGE_METRIC);
+	api.prefixlen = netmask;
+	api.prefix.s_addr = dest;
+	if (router != 0 || api.prefixlen < 32) {
+		api.nexthop_num = 1;
+		api.ifindex_num = 0;
+	} else {
+		api.message |= ZAPI_MESSAGE_IFINDEX;
+		api.nexthop_num = 0;
+		api.ifindex_num = 1;
+	}
+	nexthop.s_addr = router;
+	api.nexthop = &nexthop;
+	ifindex = ifi;
+	api.ifindex = &ifindex;
+	api.distance = 0;
+	api.metric = metric;
+	api.metric = htonl (api.metric);
+
+	zebra_send (zebra_packet (del ? ZEBRA_IPV4_ROUTE_DELETE : ZEBRA_IPV4_ROUTE_ADD, &api));
+}
+
+
+unsigned char *
+zebra_packet (char cmd, struct zebra_api *api)
+{
+	unsigned char *data, *pnt;
+	uint16_t size;
+	uint8_t len, i;
+
+	data = debugMalloc (ZEBRA_MAX_PACKET_SIZ, 1601);
+
+	pnt = &data[2];	// reserve 2 bytes for packet size
+	*pnt++ = cmd;
+	*pnt++ = api->type;
+	*pnt++ = api->flags;
+	*pnt++ = api->message;
+	*pnt++ = api->prefixlen;
+	len = (api->prefixlen + 7) / 8;
+	memcpy (pnt, &api->prefix.s_addr, len);
+	pnt = pnt + len;
+	if ((api->message & ZAPI_MESSAGE_NEXTHOP) > 0) {
+		if ((api->flags & ZEBRA_FLAG_BLACKHOLE) > 0) {
+			*pnt++ = 1;
+			*pnt++ = ZEBRA_NEXTHOP_BLACKHOLE;
+		} else
+			*pnt++ = api->nexthop_num + api->ifindex_num;
+		for (i = 0; i < api->nexthop_num; i++) {
+			*pnt++ = ZEBRA_NEXTHOP_IPV4;
+			memcpy (pnt, &api->nexthop[i].s_addr, sizeof api->nexthop[i].s_addr);
+			pnt += sizeof api->nexthop[i].s_addr;
+		}
+		for (i = 0; i < api->ifindex_num; i++) {
+			*pnt++ = ZEBRA_NEXTHOP_IFINDEX;
+			memcpy (pnt, &api->ifindex[i], sizeof api->ifindex[i]);
+			pnt += sizeof api->ifindex[i];
+		}
+	}
+	if ((api->message & ZAPI_MESSAGE_DISTANCE) > 0)
+		*pnt++ = api->distance;
+	if ((api->message & ZAPI_MESSAGE_METRIC) > 0) {
+		memcpy (pnt, &api->metric, sizeof api->metric);
+		pnt += sizeof api->metric;
+	}
+	size = htons (pnt - data);
+	memcpy (data, &size, 2);
+
+	return data;
+}
+
+int8_t
+zebra_send (unsigned char *data)
+{
+
+	int ret;
+	int16_t size;
+	unsigned char *pnt;
+
+	pnt = data;
+	memcpy (&size, pnt, 2);
+	size = ntohs (size);
+
+	do {
+		ret = write (zebra.unix_sock, pnt, size);
+		if (ret < 0) {
+			if (errno == EINTR) {
+				errno = 0;
+				continue;
+			} else {
+				fprintf (stderr, "Error - (Quagga) disconnected from zebra\n");
+				debugFree (data, 1601);
+				restore_and_exit (0);
+
+				return ret;
+			}
+		}
+		pnt = pnt + ret;
+	} while ((size -= ret));
+	debugFree (data, 1601);
+
+	return 0;
+}
diff -Nuar batman-0.3/quagga.h batman-0.3-quagga/quagga.h
--- batman-0.3/quagga.h	1970-01-01 02:00:00.000000000 +0200
+++ batman-0.3-quagga/quagga.h	2008-05-06 16:23:26.000000000 +0300
@@ -0,0 +1,110 @@
+/*
+ * API client for Quagga zebra daemon header file
+ *
+ * Copyright (C) 2007 BATMAN contributors:
+ * Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
+ * based on olsrd_quagga plugin by Immo 'FaUl' Wehrenberg
+ * Modifications for batmand revision >= 1040
+ * by Antony Chazapis <chazapis@cslab.ece.ntua.gr>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+/* 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_BATMAN		 12
+#define ZEBRA_ROUTE_MAX                  13
+
+/* 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
+
+/* For input/output buffer to zebra. */
+#define ZEBRA_MAX_PACKET_SIZ          4096
+
+/* Zebra API message flag. */
+#define ZAPI_MESSAGE_NEXTHOP  0x01
+#define ZAPI_MESSAGE_IFINDEX  0x02
+#define ZAPI_MESSAGE_DISTANCE 0x04
+#define ZAPI_MESSAGE_METRIC   0x08
+
+
+int8_t zebra_init (char *socket_path);
+void zebra_add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t src_ip, int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, uint16_t metric, int8_t del );
