--- /dev/null
+--- a/lib/quagga/src/common.h
++++ b/lib/quagga/src/common.h
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -21,7 +21,7 @@
+
+ /* Zebra route types */
+ #define ZEBRA_ROUTE_OLSR 11
+-#define ZEBRA_ROUTE_MAX 13
++#define ZEBRA_ROUTE_MAX 14
+
+ struct zebra {
+ unsigned char status;
+--- a/lib/quagga/src/packet.c
++++ b/lib/quagga/src/packet.c
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -28,24 +28,43 @@ unsigned char
+ {
+ int count;
+ uint8_t len;
+- uint16_t size;
++ uint16_t size, safi;
+ uint32_t ind, metric;
+ unsigned char *cmdopt, *t;
+
+ cmdopt = olsr_malloc(ZEBRA_MAX_PACKET_SIZ, "QUAGGA: New route packet");
+
+ t = &cmdopt[2];
+- if (zebra.version) {
+- *t++ = ZEBRA_HEADER_MARKER;
+- *t++ = zebra.version;
+- cmd = htons(cmd);
+- memcpy(t, &cmd, sizeof cmd);
+- t += sizeof cmd;
+- } else
++ switch (zebra.version) {
++ case 0:
+ *t++ = (unsigned char) cmd;
++ break;
++ case 1:
++ case 2:
++ *t++ = ZEBRA_HEADER_MARKER;
++ *t++ = zebra.version;
++ cmd = htons(cmd);
++ memcpy(t, &cmd, sizeof cmd);
++ t += sizeof cmd;
++ break;
++ default:
++ break;
++ }
+ *t++ = r->type;
+ *t++ = r->flags;
+ *t++ = r->message;
++ switch (zebra.version) {
++ case 0:
++ case 1:
++ break;
++ case 2:
++ safi = htons(r->safi);
++ memcpy(t, &safi, sizeof safi);
++ t += sizeof safi;
++ break;
++ default:
++ break;
++ }
+ *t++ = r->prefixlen;
+ len = (r->prefixlen + 7) / 8;
+ if (olsr_cnf->ip_version == AF_INET)
+@@ -97,14 +116,21 @@ unsigned char
+ data = olsr_malloc(ZEBRA_MAX_PACKET_SIZ , "QUAGGA: New redistribute packet");
+
+ pnt = &data[2];
+- if (zebra.version) {
+- *pnt++ = ZEBRA_HEADER_MARKER;
+- *pnt++ = zebra.version;
+- cmd = htons(cmd);
+- memcpy(pnt, &cmd, sizeof cmd);
+- pnt += sizeof cmd;
+- } else
++ switch (zebra.version) {
++ case 0:
+ *pnt++ = (unsigned char) cmd;
++ break;
++ case 1:
++ case 2:
++ *pnt++ = ZEBRA_HEADER_MARKER;
++ *pnt++ = zebra.version;
++ cmd = htons(cmd);
++ memcpy(pnt, &cmd, sizeof cmd);
++ pnt += sizeof cmd;
++ break;
++ default:
++ break;
++ }
+ *pnt++ = type;
+ size = htons(pnt - data);
+ memcpy(data, &size, sizeof size);
+--- a/lib/quagga/src/packet.h
++++ b/lib/quagga/src/packet.h
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -32,6 +32,7 @@
+ #define ZEBRA_IPV6_ROUTE_DELETE 10
+ #define ZEBRA_REDISTRIBUTE_ADD 11
+ #define ZEBRA_REDISTRIBUTE_DELETE 12
++#define ZEBRA_HELLO 23
+
+ /* Zebra nexthop flags */
+ #define ZEBRA_NEXTHOP_IFINDEX 1
+@@ -44,6 +45,9 @@
+ #define ZAPI_MESSAGE_DISTANCE 0x04
+ #define ZAPI_MESSAGE_METRIC 0x08
+
++/* Subsequent Address Family Identifier */
++#define SAFI_UNICAST 1
++
+ /* Zebra flags */
+ #define ZEBRA_FLAG_SELECTED 0x10
+
+@@ -51,6 +55,7 @@ struct zroute {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char message;
++ uint16_t safi;
+ unsigned char prefixlen;
+ union olsr_ip_addr prefix;
+ unsigned char nexthop_num;
+--- a/lib/quagga/src/parse.c
++++ b/lib/quagga/src/parse.c
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -52,7 +52,17 @@ static struct zroute
+ length = ntohs (length);
+
+ r = olsr_malloc(sizeof *r, "QUAGGA: New zebra route");
+- pnt = (zebra.version ? &opt[6] : &opt[3]);
++ switch (zebra.version) {
++ case 0:
++ pnt = &opt[3];
++ break;
++ case 1:
++ case 2:
++ pnt = &opt[6];
++ break;
++ default:
++ break;
++ }
+ r->type = *pnt++;
+ r->flags = *pnt++;
+ r->message = *pnt++;
+@@ -68,6 +78,7 @@ static struct zroute
+ switch (zebra.version) {
+ case 0:
+ case 1:
++ case 2:
+ if (r->message & ZAPI_MESSAGE_NEXTHOP) {
+ r->nexthop_num = *pnt++;
+ r->nexthop = olsr_malloc((sizeof *r->nexthop) * r->nexthop_num, "QUAGGA: New zebra route nexthop");
+@@ -137,13 +148,20 @@ zparse(void *foo __attribute__ ((unused)
+ length = ntohs (length);
+ if (!length) // something weired happened
+ olsr_exit("(QUAGGA) Zero message length!", EXIT_FAILURE);
+- if (zebra.version) {
+- if ((f[2] != ZEBRA_HEADER_MARKER) || (f[3] != zebra.version))
+- olsr_exit("(QUAGGA) Invalid zebra header received!", EXIT_FAILURE);
+- memcpy(&command, &f[4], sizeof command);
+- command = ntohs (command);
+- } else
++ switch (zebra.version) {
++ case 0:
+ command = f[2];
++ break;
++ case 1:
++ case 2:
++ if ((f[2] != ZEBRA_HEADER_MARKER) || (f[3] != zebra.version))
++ olsr_exit("(QUAGGA) Invalid zebra header received!", EXIT_FAILURE);
++ memcpy(&command, &f[4], sizeof command);
++ command = ntohs (command);
++ break;
++ default:
++ break;
++ }
+ if (olsr_cnf->ip_version == AF_INET) {
+ switch (command) {
+ case ZEBRA_IPV4_ROUTE_ADD:
+--- a/lib/quagga/src/plugin.c
++++ b/lib/quagga/src/plugin.c
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -50,7 +50,7 @@ zplugin_redistribute(const char *value,
+ {
+ const char *zroute_types[] = { "system", "kernel", "connect",
+ "static", "rip", "ripng", "ospf", "ospf6", "isis", "bgp",
+- "hsls", "olsr", "batman"
++ "hsls", "olsr", "batman", "babel"
+ };
+ unsigned int i;
+
+@@ -144,7 +144,7 @@ zplugin_version(const char *value, void
+
+ if (set_plugin_int(value, &version, addon))
+ return 1;
+- if (version < 0 || version > 1)
++ if (version < 0 || version > 2)
+ return 1;
+ zebra.version = version;
+
+--- a/lib/quagga/src/quagga.c
++++ b/lib/quagga/src/quagga.c
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2011 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -63,6 +63,7 @@ zebra_addroute(const struct rt_entry *r)
+ route.type = ZEBRA_ROUTE_OLSR;
+ route.flags = zebra.flags;
+ route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
++ route.safi = SAFI_UNICAST;
+ route.prefixlen = r->rt_dst.prefix_len;
+ if (olsr_cnf->ip_version == AF_INET)
+ route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
+@@ -112,6 +113,7 @@ zebra_delroute(const struct rt_entry *r)
+ route.type = ZEBRA_ROUTE_OLSR;
+ route.flags = zebra.flags;
+ route.message = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_METRIC;
++ route.safi = SAFI_UNICAST;
+ route.prefixlen = r->rt_dst.prefix_len;
+ if (olsr_cnf->ip_version == AF_INET)
+ route.prefix.v4.s_addr = r->rt_dst.prefix.v4.s_addr;
+@@ -164,6 +166,15 @@ zebra_redistribute(uint16_t cmd)
+
+ }
+
++void
++zebra_hello(uint16_t cmd)
++{
++
++ if (zclient_write(zpacket_redistribute(cmd, ZEBRA_ROUTE_OLSR)) < 0)
++ olsr_exit("(QUAGGA) Could not write hello packet!", EXIT_FAILURE);
++
++}
++
+ /*
+ * Local Variables:
+ * c-basic-offset: 2
+--- a/lib/quagga/src/client.c
++++ b/lib/quagga/src/client.c
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -95,6 +95,7 @@ zclient_reconnect(void)
+ if (!(zebra.status & STATUS_CONNECTED))
+ return; // try again next time
+
++ zebra_hello(ZEBRA_HELLO);
+ if (zebra.options & OPTION_EXPORT) {
+ OLSR_FOR_ALL_RT_ENTRIES(tmp) {
+ zebra_addroute(tmp);
+--- a/lib/quagga/README_QUAGGA
++++ b/lib/quagga/README_QUAGGA
+@@ -11,9 +11,9 @@ It allows olsrd to redistribute from var
+ as well as to export olsr-routes to quagga so that they can be
+ redistributed by the quagga-routing-daemons.
+
+-You also need a source distribution of quagga-0.98.6 or quagga-0.99.15.
++You also need a source distribution of quagga-0.98.6 or quagga-0.99.21.
+ The quagga source tree needs to be patched with quagga-0.98.6.diff or
+-quagga-0.99.15.diff, respectively, compiled and installed via
++quagga-0.99.21.diff, respectively, compiled and installed via
+ 'make install'.
+
+ ---------------------------------------------------------------------
+@@ -48,7 +48,10 @@ PlParam "Port" "<port>"
+
+ PlParam "Version" "<version>"
+ sets the version of packet format to communicate with zebra.
+- use "0" for Quagga 0.98.x and "1" for Quagga 0.99.x.
++ use:
++ "0" for Quagga 0.98.x
++ "1" for Quagga 0.99.17 up to 0.99.20.1
++ "2" for Quagga 0.99.21 and above
+ defaults to "0".
+
+ ---------------------------------------------------------------------
+@@ -65,9 +68,9 @@ LoadPlugin "olsrd_quagga.so.0.2.2"
+ PlParam "Distance" "125"
+ PlParam "LocalPref" "false"
+ PlParam "SockPath" "/var/run/zserv.api"
+- PlParam "Version" "1"
++ PlParam "Version" "2"
+ }
+
+
+ ---------------------------------------------------------------------
+-EOF / 10.03.2010
++EOF / 31.05.2012
+--- a/lib/quagga/src/quagga.h
++++ b/lib/quagga/src/quagga.h
+@@ -2,7 +2,7 @@
+ * OLSRd Quagga plugin
+ *
+ * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg <immo@chaostreff-dortmund.de>
+- * Copyright (C) 2007-2010 Vasilis Tsiligiannis <acinonyxs@yahoo.gr>
++ * Copyright (C) 2007-2012 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
+@@ -31,6 +31,7 @@ void zebra_fini(void);
+ int zebra_addroute(const struct rt_entry *);
+ int zebra_delroute(const struct rt_entry *);
+ void zebra_redistribute(uint16_t cmd);
++void zebra_hello(uint16_t cmd);
+
+ /*
+ * Local Variables: