--- a/lib/quagga/Makefile +++ b/lib/quagga/Makefile @@ -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 --- /dev/null +++ b/lib/quagga/patches/quagga-0.98.6.diff @@ -0,0 +1,860 @@ +diff -Nur quagga-0.98.6/bgpd/bgp_vty.c quagga-0.98.6.patched/bgpd/bgp_vty.c +--- quagga-0.98.6/bgpd/bgp_vty.c 2006-03-30 18:12:25.000000000 +0200 ++++ quagga-0.98.6.patched/bgpd/bgp_vty.c 2007-12-30 14:18:22.000000000 +0200 +@@ -3,6 +3,9 @@ + + This file is part of GNU Zebra. + ++This file was modified from the original on 30/12/2007 ++by Vasilis Tsiligiannis ++ + 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 +@@ -7793,8 +7796,12 @@ + return ZEBRA_ROUTE_STATIC; + else if (strncmp (str, "r", 1) == 0) + return ZEBRA_ROUTE_RIP; +- else if (strncmp (str, "o", 1) == 0) ++ else if (strncmp (str, "ol", 2) == 0) ++ return ZEBRA_ROUTE_OLSR; ++ else if (strncmp (str, "os", 2) == 0) + return ZEBRA_ROUTE_OSPF; ++ else if (strncmp (str, "ba", 2) == 0) ++ return ZEBRA_ROUTE_BATMAN; + } + if (afi == AFI_IP6) + { +@@ -7806,21 +7813,28 @@ + return ZEBRA_ROUTE_STATIC; + else if (strncmp (str, "r", 1) == 0) + return ZEBRA_ROUTE_RIPNG; +- else if (strncmp (str, "o", 1) == 0) ++ else if (strncmp (str, "os", 2) == 0) + return ZEBRA_ROUTE_OSPF6; ++ else if (strncmp (str, "ol", 2) == 0) ++ return ZEBRA_ROUTE_OLSR; ++ else if (strncmp (str, "ba", 2) == 0) ++ return ZEBRA_ROUTE_BATMAN; + } + return 0; + } + + DEFUN (bgp_redistribute_ipv4, + bgp_redistribute_ipv4_cmd, +- "redistribute (connected|kernel|ospf|rip|static)", ++ "redistribute (connected|kernel|ospf|rip|static|olsr|batman)", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" +- "Static routes\n") ++ "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++ ) + { + int type; + +@@ -7835,13 +7849,15 @@ + + DEFUN (bgp_redistribute_ipv4_rmap, + bgp_redistribute_ipv4_rmap_cmd, +- "redistribute (connected|kernel|ospf|rip|static) route-map WORD", ++ "redistribute (connected|kernel|ospf|rip|static|olsr|batman) route-map WORD", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n") + { +@@ -7860,13 +7876,15 @@ + + DEFUN (bgp_redistribute_ipv4_metric, + bgp_redistribute_ipv4_metric_cmd, +- "redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295>", ++ "redistribute (connected|kernel|ospf|rip|static|olsr|batman) metric <0-4294967295>", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n") + { +@@ -7887,13 +7905,15 @@ + + DEFUN (bgp_redistribute_ipv4_rmap_metric, + bgp_redistribute_ipv4_rmap_metric_cmd, +- "redistribute (connected|kernel|ospf|rip|static) route-map WORD metric <0-4294967295>", ++ "redistribute (connected|kernel|ospf|rip|static|olsr|batman) route-map WORD metric <0-4294967295>", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" +@@ -7917,13 +7937,15 @@ + + DEFUN (bgp_redistribute_ipv4_metric_rmap, + bgp_redistribute_ipv4_metric_rmap_cmd, +- "redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295> route-map WORD", ++ "redistribute (connected|kernel|ospf|rip|static|olsr|batman) metric <0-4294967295> route-map WORD", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" +@@ -7947,14 +7969,17 @@ + + DEFUN (no_bgp_redistribute_ipv4, + no_bgp_redistribute_ipv4_cmd, +- "no redistribute (connected|kernel|ospf|rip|static)", ++ "no redistribute (connected|kernel|ospf|rip|static|olsr|batman)", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" +- "Static routes\n") ++ "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++ ) + { + int type; + +@@ -7970,7 +7995,7 @@ + + DEFUN (no_bgp_redistribute_ipv4_rmap, + no_bgp_redistribute_ipv4_rmap_cmd, +- "no redistribute (connected|kernel|ospf|rip|static) route-map WORD", ++ "no redistribute (connected|kernel|ospf|rip|static|olsr|batman) route-map WORD", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -7978,6 +8003,8 @@ + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n") + { +@@ -7996,7 +8023,7 @@ + + DEFUN (no_bgp_redistribute_ipv4_metric, + no_bgp_redistribute_ipv4_metric_cmd, +- "no redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295>", ++ "no redistribute (connected|kernel|ospf|rip|static|olsr|batman) metric <0-4294967295>", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -8004,6 +8031,8 @@ + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n") + { +@@ -8022,7 +8051,7 @@ + + DEFUN (no_bgp_redistribute_ipv4_rmap_metric, + no_bgp_redistribute_ipv4_rmap_metric_cmd, +- "no redistribute (connected|kernel|ospf|rip|static) route-map WORD metric <0-4294967295>", ++ "no redistribute (connected|kernel|ospf|rip|static|olsr|batman) route-map WORD metric <0-4294967295>", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -8030,6 +8059,8 @@ + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" +@@ -8051,7 +8082,7 @@ + + ALIAS (no_bgp_redistribute_ipv4_rmap_metric, + no_bgp_redistribute_ipv4_metric_rmap_cmd, +- "no redistribute (connected|kernel|ospf|rip|static) metric <0-4294967295> route-map WORD", ++ "no redistribute (connected|kernel|ospf|rip|static|olsr|batman) metric <0-4294967295> route-map WORD", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -8059,6 +8090,8 @@ + "Open Shurtest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" +@@ -8067,13 +8100,16 @@ + #ifdef HAVE_IPV6 + DEFUN (bgp_redistribute_ipv6, + bgp_redistribute_ipv6_cmd, +- "redistribute (connected|kernel|ospf6|ripng|static)", ++ "redistribute (connected|kernel|ospf6|ripng|static|olsr|batman)", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" +- "Static routes\n") ++ "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++ ) + { + int type; + +@@ -8089,13 +8125,15 @@ + + DEFUN (bgp_redistribute_ipv6_rmap, + bgp_redistribute_ipv6_rmap_cmd, +- "redistribute (connected|kernel|ospf6|ripng|static) route-map WORD", ++ "redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) route-map WORD", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n") + { +@@ -8114,13 +8152,15 @@ + + DEFUN (bgp_redistribute_ipv6_metric, + bgp_redistribute_ipv6_metric_cmd, +- "redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295>", ++ "redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) metric <0-4294967295>", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n") + { +@@ -8141,13 +8181,15 @@ + + DEFUN (bgp_redistribute_ipv6_rmap_metric, + bgp_redistribute_ipv6_rmap_metric_cmd, +- "redistribute (connected|kernel|ospf6|ripng|static) route-map WORD metric <0-4294967295>", ++ "redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) route-map WORD metric <0-4294967295>", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" +@@ -8171,13 +8213,15 @@ + + DEFUN (bgp_redistribute_ipv6_metric_rmap, + bgp_redistribute_ipv6_metric_rmap_cmd, +- "redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295> route-map WORD", ++ "redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) metric <0-4294967295> route-map WORD", + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" +@@ -8201,14 +8245,17 @@ + + DEFUN (no_bgp_redistribute_ipv6, + no_bgp_redistribute_ipv6_cmd, +- "no redistribute (connected|kernel|ospf6|ripng|static)", ++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr|batman)", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" + "Kernel routes\n" + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" +- "Static routes\n") ++ "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++ ) + { + int type; + +@@ -8224,7 +8271,7 @@ + + DEFUN (no_bgp_redistribute_ipv6_rmap, + no_bgp_redistribute_ipv6_rmap_cmd, +- "no redistribute (connected|kernel|ospf6|ripng|static) route-map WORD", ++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) route-map WORD", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -8232,6 +8279,8 @@ + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n") + { +@@ -8250,7 +8299,7 @@ + + DEFUN (no_bgp_redistribute_ipv6_metric, + no_bgp_redistribute_ipv6_metric_cmd, +- "no redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295>", ++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) metric <0-4294967295>", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -8258,6 +8307,8 @@ + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n") + { +@@ -8276,7 +8327,7 @@ + + DEFUN (no_bgp_redistribute_ipv6_rmap_metric, + no_bgp_redistribute_ipv6_rmap_metric_cmd, +- "no redistribute (connected|kernel|ospf6|ripng|static) route-map WORD metric <0-4294967295>", ++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) route-map WORD metric <0-4294967295>", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -8284,6 +8335,8 @@ + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n" + "Metric for redistributed routes\n" +@@ -8305,7 +8358,7 @@ + + ALIAS (no_bgp_redistribute_ipv6_rmap_metric, + no_bgp_redistribute_ipv6_metric_rmap_cmd, +- "no redistribute (connected|kernel|ospf6|ripng|static) metric <0-4294967295> route-map WORD", ++ "no redistribute (connected|kernel|ospf6|ripng|static|olsr|batman) metric <0-4294967295> route-map WORD", + NO_STR + "Redistribute information from another routing protocol\n" + "Connected\n" +@@ -8313,6 +8366,8 @@ + "Open Shurtest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" + "Static routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "Default metric\n" + "Route map reference\n" +@@ -8325,7 +8380,7 @@ + { + int i; + const char *str[] = { "system", "kernel", "connected", "static", "rip", +- "ripng", "ospf", "ospf6", "isis", "bgp"}; ++ "ripng", "ospf", "ospf6", "isis", "bgp", "hsls", "olsr", "batman"}; + + /* Unicast redistribution only. */ + if (safi != SAFI_UNICAST) +diff -Nur quagga-0.98.6/lib/zebra.h quagga-0.98.6.patched/lib/zebra.h +--- quagga-0.98.6/lib/zebra.h 2005-06-15 14:54:18.000000000 +0300 ++++ quagga-0.98.6.patched/lib/zebra.h 2007-12-30 14:18:22.000000000 +0200 +@@ -3,6 +3,9 @@ + + This file is part of GNU Zebra. + ++This file was modified from the original on 30/12/2007 ++by Vasilis Tsiligiannis ++ + 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 +@@ -378,7 +381,9 @@ + #define ZEBRA_ROUTE_ISIS 8 + #define ZEBRA_ROUTE_BGP 9 + #define ZEBRA_ROUTE_HSLS 10 +-#define ZEBRA_ROUTE_MAX 11 ++#define ZEBRA_ROUTE_OLSR 11 ++#define ZEBRA_ROUTE_BATMAN 12 ++#define ZEBRA_ROUTE_MAX 13 + + /* Zebra's family types. */ + #define ZEBRA_FAMILY_IPV4 1 +diff -Nur quagga-0.98.6/ospfd/ospf_vty.c quagga-0.98.6.patched/ospfd/ospf_vty.c +--- quagga-0.98.6/ospfd/ospf_vty.c 2006-03-30 17:41:20.000000000 +0200 ++++ quagga-0.98.6.patched/ospfd/ospf_vty.c 2007-12-30 14:18:22.000000000 +0200 +@@ -3,6 +3,9 @@ + * + * This file is part of GNU Zebra. + * ++ * This file was modified from the original on 30/12/2007 ++ * by Vasilis Tsiligiannis ++ * + * 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 +@@ -106,11 +109,15 @@ + *source = ZEBRA_ROUTE_STATIC; + else if (strncmp (str, "r", 1) == 0) + *source = ZEBRA_ROUTE_RIP; +- else if (strncmp (str, "b", 1) == 0) ++ else if (strncmp (str, "bg", 2) == 0) + *source = ZEBRA_ROUTE_BGP; ++ else if (strncmp (str, "ol", 2) == 0) ++ *source = ZEBRA_ROUTE_OLSR; ++ else if (strncmp (str, "ba", 2) == 0) ++ *source = ZEBRA_ROUTE_BATMAN; + else + return 0; +- ++ + return 1; + } + +@@ -5302,13 +5309,15 @@ + + DEFUN (ospf_redistribute_source_metric_type, + ospf_redistribute_source_metric_type_routemap_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> metric-type (1|2) route-map WORD", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric <0-16777214> metric-type (1|2) route-map WORD", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "OSPF default metric\n" + "OSPF exterior metric type for redistributed routes\n" +@@ -5346,13 +5355,15 @@ + + ALIAS (ospf_redistribute_source_metric_type, + ospf_redistribute_source_metric_type_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> metric-type (1|2)", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric <0-16777214> metric-type (1|2)", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "OSPF default metric\n" + "OSPF exterior metric type for redistributed routes\n" +@@ -5361,25 +5372,29 @@ + + ALIAS (ospf_redistribute_source_metric_type, + ospf_redistribute_source_metric_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214>", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric <0-16777214>", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "OSPF default metric\n") + + DEFUN (ospf_redistribute_source_type_metric, + ospf_redistribute_source_type_metric_routemap_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric <0-16777214> route-map WORD", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric-type (1|2) metric <0-16777214> route-map WORD", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "OSPF exterior metric type for redistributed routes\n" + "Set OSPF External Type 1 metrics\n" + "Set OSPF External Type 2 metrics\n" +@@ -5417,13 +5432,15 @@ + + ALIAS (ospf_redistribute_source_type_metric, + ospf_redistribute_source_type_metric_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) metric <0-16777214>", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric-type (1|2) metric <0-16777214>", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "OSPF exterior metric type for redistributed routes\n" + "Set OSPF External Type 1 metrics\n" + "Set OSPF External Type 2 metrics\n" +@@ -5432,7 +5449,7 @@ + + ALIAS (ospf_redistribute_source_type_metric, + ospf_redistribute_source_type_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2)", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric-type (1|2)", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" +@@ -5440,28 +5457,35 @@ + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" + "OSPF exterior metric type for redistributed routes\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Set OSPF External Type 1 metrics\n" + "Set OSPF External Type 2 metrics\n") + + ALIAS (ospf_redistribute_source_type_metric, + ospf_redistribute_source_cmd, +- "redistribute (kernel|connected|static|rip|bgp)", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman)", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" +- "Border Gateway Protocol (BGP)\n") ++ "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++ ) + + DEFUN (ospf_redistribute_source_metric_routemap, + ospf_redistribute_source_metric_routemap_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric <0-16777214> route-map WORD", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric <0-16777214> route-map WORD", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Metric for redistributed routes\n" + "OSPF default metric\n" + "Route map reference\n" +@@ -5490,13 +5514,15 @@ + + DEFUN (ospf_redistribute_source_type_routemap, + ospf_redistribute_source_type_routemap_cmd, +- "redistribute (kernel|connected|static|rip|bgp) metric-type (1|2) route-map WORD", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) metric-type (1|2) route-map WORD", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "OSPF exterior metric type for redistributed routes\n" + "Set OSPF External Type 1 metrics\n" + "Set OSPF External Type 2 metrics\n" +@@ -5526,13 +5552,15 @@ + + DEFUN (ospf_redistribute_source_routemap, + ospf_redistribute_source_routemap_cmd, +- "redistribute (kernel|connected|static|rip|bgp) route-map WORD", ++ "redistribute (kernel|connected|static|rip|bgp|olsr|batman) route-map WORD", + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" + "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Route map reference\n" + "Pointer to route-map entries\n") + { +@@ -5553,14 +5581,17 @@ + + DEFUN (no_ospf_redistribute_source, + no_ospf_redistribute_source_cmd, +- "no redistribute (kernel|connected|static|rip|bgp)", ++ "no redistribute (kernel|connected|static|rip|bgp|olsr|batman)", + NO_STR + "Redistribute information from another routing protocol\n" + "Kernel routes\n" + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" +- "Border Gateway Protocol (BGP)\n") ++ "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++ ) + { + struct ospf *ospf = vty->index; + int source; +@@ -5574,7 +5605,7 @@ + + DEFUN (ospf_distribute_list_out, + ospf_distribute_list_out_cmd, +- "distribute-list WORD out (kernel|connected|static|rip|bgp)", ++ "distribute-list WORD out (kernel|connected|static|rip|bgp|olsr|batman)", + "Filter networks in routing updates\n" + "Access-list name\n" + OUT_STR +@@ -5582,7 +5613,10 @@ + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" +- "Border Gateway Protocol (BGP)\n") ++ "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++) + { + struct ospf *ospf = vty->index; + int source; +@@ -5596,7 +5630,7 @@ + + DEFUN (no_ospf_distribute_list_out, + no_ospf_distribute_list_out_cmd, +- "no distribute-list WORD out (kernel|connected|static|rip|bgp)", ++ "no distribute-list WORD out (kernel|connected|static|rip|bgp|olsr|batman)", + NO_STR + "Filter networks in routing updates\n" + "Access-list name\n" +@@ -5605,7 +5639,10 @@ + "Connected\n" + "Static routes\n" + "Routing Information Protocol (RIP)\n" +- "Border Gateway Protocol (BGP)\n") ++ "Border Gateway Protocol (BGP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" ++) + { + struct ospf *ospf = vty->index; + int source; +@@ -7121,7 +7158,8 @@ + + + const char *distribute_str[] = { "system", "kernel", "connected", "static", +- "rip", "ripng", "ospf", "ospf6", "isis", "bgp"}; ++ "rip", "ripng", "ospf", "ospf6", "isis", "bgp", ++ "hsls","olsr","batman"}; + int + config_write_ospf_redistribute (struct vty *vty, struct ospf *ospf) + { +diff -Nur quagga-0.98.6/zebra/redistribute.c quagga-0.98.6.patched/zebra/redistribute.c +--- quagga-0.98.6/zebra/redistribute.c 2005-06-15 14:54:51.000000000 +0300 ++++ quagga-0.98.6.patched/zebra/redistribute.c 2007-12-30 14:18:22.000000000 +0200 +@@ -3,6 +3,9 @@ + * + * This file is part of GNU Zebra. + * ++ * This file was modified from the original on 30/12/2007 ++ * by Vasilis Tsiligiannis ++ * + * 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 +@@ -253,6 +256,8 @@ + case ZEBRA_ROUTE_OSPF: + case ZEBRA_ROUTE_OSPF6: + case ZEBRA_ROUTE_BGP: ++ case ZEBRA_ROUTE_OLSR: ++ case ZEBRA_ROUTE_BATMAN: + if (! client->redist[type]) + { + client->redist[type] = 1; +@@ -281,6 +286,8 @@ + case ZEBRA_ROUTE_OSPF: + case ZEBRA_ROUTE_OSPF6: + case ZEBRA_ROUTE_BGP: ++ case ZEBRA_ROUTE_OLSR: ++ case ZEBRA_ROUTE_BATMAN: + client->redist[type] = 0; + break; + default: +diff -Nur quagga-0.98.6/zebra/zebra_vty.c quagga-0.98.6.patched/zebra/zebra_vty.c +--- quagga-0.98.6/zebra/zebra_vty.c 2004-12-18 18:03:29.000000000 +0200 ++++ quagga-0.98.6.patched/zebra/zebra_vty.c 2007-12-30 14:25:48.000000000 +0200 +@@ -53,6 +53,10 @@ + return "isis"; + case ZEBRA_ROUTE_BGP: + return "bgp"; ++ case ZEBRA_ROUTE_OLSR: ++ return "olsr"; ++ case ZEBRA_ROUTE_BATMAN: ++ return "batman"; + default: + return "unknown"; + } +@@ -84,6 +88,12 @@ + return 'I'; + case ZEBRA_ROUTE_BGP: + return 'B'; ++ case ZEBRA_ROUTE_HSLS: ++ return 'H'; ++ case ZEBRA_ROUTE_OLSR: ++ return 'L'; ++ case ZEBRA_ROUTE_BATMAN: ++ return 'M'; + default: + return '?'; + } +@@ -755,8 +765,8 @@ + } + + #define SHOW_ROUTE_V4_HEADER "Codes: K - kernel route, C - connected, " \ +- "S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, " \ +- "> - selected route, * - FIB route%s%s" ++ "S - static, R - RIP, O - OSPF,%s I - ISIS, B - BGP, H - HSLS, " \ ++ "L - OLSR, M - BATMAN, > - selected route, * - FIB route%s%s" + + DEFUN (show_ip_route, + show_ip_route_cmd, +@@ -874,7 +884,7 @@ + + DEFUN (show_ip_route_protocol, + show_ip_route_protocol_cmd, +- "show ip route (bgp|connected|isis|kernel|ospf|rip|static)", ++ "show ip route (bgp|connected|isis|kernel|ospf|rip|olsr|batman|static)", + SHOW_STR + IP_STR + "IP routing table\n" +@@ -884,6 +894,8 @@ + "Kernel\n" + "Open Shortest Path First (OSPF)\n" + "Routing Information Protocol (RIP)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Static routes\n") + { + int type; +@@ -892,13 +904,13 @@ + struct rib *rib; + int first = 1; + +- if (strncmp (argv[0], "b", 1) == 0) ++ if (strncmp (argv[0], "bg", 2) == 0) + type = ZEBRA_ROUTE_BGP; + else if (strncmp (argv[0], "c", 1) == 0) + type = ZEBRA_ROUTE_CONNECT; + else if (strncmp (argv[0], "k", 1) ==0) + type = ZEBRA_ROUTE_KERNEL; +- else if (strncmp (argv[0], "o", 1) == 0) ++ else if (strncmp (argv[0], "os", 2) == 0) + type = ZEBRA_ROUTE_OSPF; + else if (strncmp (argv[0], "i", 1) == 0) + type = ZEBRA_ROUTE_ISIS; +@@ -906,6 +918,10 @@ + type = ZEBRA_ROUTE_RIP; + else if (strncmp (argv[0], "s", 1) == 0) + type = ZEBRA_ROUTE_STATIC; ++ else if (strncmp (argv[0], "ol", 2) == 0) ++ type = ZEBRA_ROUTE_OLSR; ++ else if (strncmp (argv[0], "ba", 2) == 0) ++ type = ZEBRA_ROUTE_BATMAN; + else + { + vty_out (vty, "Unknown route type%s", VTY_NEWLINE); +@@ -1732,7 +1748,7 @@ + + DEFUN (show_ipv6_route_protocol, + show_ipv6_route_protocol_cmd, +- "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|static)", ++ "show ipv6 route (bgp|connected|isis|kernel|ospf6|ripng|olsr|batman|static)", + SHOW_STR + IP_STR + "IP routing table\n" +@@ -1742,6 +1758,8 @@ + "Kernel\n" + "Open Shortest Path First (OSPFv3)\n" + "Routing Information Protocol (RIPng)\n" ++ "Optimized Link State Routing (OLSR)\n" ++ "Better Approach to Mobile Ad-Hoc Networking (BATMAN)\n" + "Static routes\n") + { + int type; +@@ -1750,13 +1768,13 @@ + struct rib *rib; + int first = 1; + +- if (strncmp (argv[0], "b", 1) == 0) ++ if (strncmp (argv[0], "bg", 2) == 0) + type = ZEBRA_ROUTE_BGP; + else if (strncmp (argv[0], "c", 1) == 0) + type = ZEBRA_ROUTE_CONNECT; + else if (strncmp (argv[0], "k", 1) ==0) + type = ZEBRA_ROUTE_KERNEL; +- else if (strncmp (argv[0], "o", 1) == 0) ++ else if (strncmp (argv[0], "os", 2) == 0) + type = ZEBRA_ROUTE_OSPF6; + else if (strncmp (argv[0], "i", 1) == 0) + type = ZEBRA_ROUTE_ISIS; +@@ -1764,7 +1782,11 @@ + type = ZEBRA_ROUTE_RIPNG; + else if (strncmp (argv[0], "s", 1) == 0) + type = ZEBRA_ROUTE_STATIC; +- else ++ else if (strncmp (argv[0], "ol", 2) == 0) ++ type = ZEBRA_ROUTE_OLSR; ++ else if (strncmp (argv[0], "ba", 2) == 0) ++ type = ZEBRA_ROUTE_BATMAN; ++ else + { + vty_out (vty, "Unknown route type%s", VTY_NEWLINE); + return CMD_WARNING; --- a/lib/quagga/README_QUAGGA +++ b/lib/quagga/README_QUAGGA @@ -1,20 +1,20 @@ --------------------------------------------------------------------- QUAGGA PLUGIN FOR OLSRD by Immo 'FaUl' Wehrenberg + +addittions by: Sven-Ola Tuecke + Vasilis Tsiligiannis --------------------------------------------------------------------- -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" "" May be used more then once PlParam "ExportRoutes" "" - 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" "" 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 --- a/lib/quagga/src/olsrd_plugin.c +++ b/lib/quagga/src/olsrd_plugin.c @@ -1,19 +1,22 @@ +/* + * OLSRd Quagga plugin + * + * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg + * Copyright (C) 2007-2008 Vasilis Tsiligiannis + * + * 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 + * ------------------------------------------------------------------------- */ -/*************************************************************************** - 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. * - * * - ***************************************************************************/ #include #include @@ -24,7 +27,6 @@ #include "scheduler.h" #include "defs.h" #include "quagga.h" -#include "kernel_routes.h" #include "net_olsr.h" #define PLUGIN_NAME "OLSRD quagga plugin" @@ -41,120 +43,94 @@ static set_plugin_parameter set_exportro static set_plugin_parameter set_distance; static set_plugin_parameter set_localpref; -static export_route_function orig_addroute_function; -static export_route_function orig_delroute_function; -int -olsrd_plugin_interface_version(void) -{ +int olsrd_plugin_interface_version (void) { return PLUGIN_INTERFACE_VERSION; } static const struct olsrd_plugin_parameters plugin_parameters[] = { - {.name = "redistribute",.set_plugin_parameter = &set_redistribute,}, - {.name = "ExportRoutes",.set_plugin_parameter = &set_exportroutes,}, - {.name = "Distance",.set_plugin_parameter = &set_distance,}, - {.name = "LocalPref",.set_plugin_parameter = &set_localpref,}, + { .name = "redistribute", .set_plugin_parameter = &set_redistribute, }, + { .name = "ExportRoutes", .set_plugin_parameter = &set_exportroutes, }, + { .name = "Distance", .set_plugin_parameter = &set_distance, }, + { .name = "LocalPref", .set_plugin_parameter = &set_localpref, }, }; -void -olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size) -{ +void olsrd_get_plugin_parameters (const struct olsrd_plugin_parameters **params, + int *size) { *params = plugin_parameters; - *size = sizeof plugin_parameters / sizeof *plugin_parameters; + *size = ARRAYSIZE(plugin_parameters); } -static int -set_redistribute(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) -{ - const char *zebra_route_types[] = { "system", "kernel", "connect", - "static", "rip", "ripng", "ospf", - "ospf6", "isis", "bgp", "hsls" - }; +static int set_redistribute (const char *value, + void *data __attribute__((unused)), + set_plugin_parameter_addon addon __attribute__((unused))) { + const char *zebra_route_types[] = {"system","kernel","connect", + "static","rip","ripng","ospf", + "ospf6","isis","bgp","hsls"}; 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))) -{ +static int set_exportroutes (const char *value, + void *data __attribute__((unused)), + set_plugin_parameter_addon addon __attribute__((unused))) { if (!strcmp(value, "only")) { - orig_addroute_function = NULL; - orig_delroute_function = NULL; - 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")) { - orig_addroute_function = olsr_addroute_function; - orig_delroute_function = olsr_delroute_function; - olsr_addroute_function = zebra_add_olsr_v4_route; - olsr_delroute_function = zebra_del_olsr_v4_route; + } + else if (!strcmp(value, "additional")) { + olsr_addroute_function = zebra_add_route; + olsr_delroute_function = zebra_del_route; zebra_export_routes(1); - } else - zebra_export_routes(0); + } + else zebra_export_routes(0); return 0; } -static int -set_distance(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) -{ +static int set_distance(const char *value, void *data __attribute__((unused)), + set_plugin_parameter_addon addon __attribute__((unused))) { int distance; - if (set_plugin_int(value, &distance, addon)) - return 1; - if (distance < 0 || distance > 255) - return 1; + if (set_plugin_int(value, &distance, addon)) return 1; + if (distance < 0 || distance > 255) return 1; zebra_olsr_distance(distance); return 0; } -static int -set_localpref(const char *value, void *data __attribute__ ((unused)), set_plugin_parameter_addon addon __attribute__ ((unused))) -{ +static int set_localpref(const char *value, void *data __attribute__((unused)), + set_plugin_parameter_addon addon __attribute__((unused))) { int b; - if (set_plugin_boolean(value, &b, addon)) - return 1; - if (b) - zebra_olsr_localpref(); + if (set_plugin_boolean(value, &b, addon)) return 1; + if (b) zebra_olsr_localpref(); return 0; } -int -olsrd_plugin_init(void) -{ - if (olsr_cnf->ip_version != AF_INET) { - fputs("see the source - ipv6 so far not supported\n", stderr); + +int olsrd_plugin_init(void) { + if(olsr_cnf->ip_version != AF_INET) { + fputs("see the source - ipv6 so far not supported\n" ,stderr); return 1; } - olsr_start_timer(1 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, &zebra_check, NULL, 0); + olsr_start_timer(1 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC, + &zebra_parse, NULL, 0); return 0; } -static void -my_init(void) -{ +static void my_init(void) { init_zebra(); } -static void -my_fini(void) -{ +static void my_fini(void) { zebra_cleanup(); } -/* - * Local Variables: - * c-basic-offset: 2 - * indent-tabs-mode: nil - * End: - */ --- a/lib/quagga/src/quagga/zassert.h +++ /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: - */ --- a/lib/quagga/src/quagga/zebra.h +++ /dev/null @@ -1,503 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_STROPTS_H -#include -#endif /* HAVE_STROPTS_H */ -#include -#ifdef HAVE_SYS_SELECT_H -#include -#endif /* HAVE_SYS_SELECT_H */ -#include -#include -#include -#include -#ifdef HAVE_SYS_SYSCTL_H -#include -#endif /* HAVE_SYS_SYSCTL_H */ -#include -#ifdef HAVE_SYS_CONF_H -#include -#endif /* HAVE_SYS_CONF_H */ -#ifdef HAVE_SYS_KSYM_H -#include -#endif /* HAVE_SYS_KSYM_H */ -#include -#include -#include -#include -#ifdef HAVE_RUSAGE -#include -#endif /* HAVE_RUSAGE */ -#ifdef HAVE_LIMITS_H -#include -#endif /* HAVE_LIMITS_H */ - -/* machine dependent includes */ -#ifdef SUNOS_5 -#include -#endif /* SUNOS_5 */ - -/* machine dependent includes */ -#ifdef HAVE_LINUX_VERSION_H -#include -#endif /* HAVE_LINUX_VERSION_H */ - -#ifdef HAVE_ASM_TYPES_H -#include -#endif /* HAVE_ASM_TYPES_H */ - -/* misc include group */ -#include -#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 -#include -#endif /* HAVE_LCAPS */ - -/* network include group */ - -#include - -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif /* HAVE_SYS_SOCKIO_H */ - -#ifdef HAVE_NETINET_IN_H -#include -#endif /* HAVE_NETINET_IN_H */ -#include -#include -#include - -#ifdef HAVE_NET_NETOPT_H -#include -#endif /* HAVE_NET_NETOPT_H */ - -#include - -#ifdef HAVE_NET_IF_DL_H -#include -#endif /* HAVE_NET_IF_DL_H */ - -#ifdef HAVE_NET_IF_VAR_H -#include -#endif /* HAVE_NET_IF_VAR_H */ - -#ifdef HAVE_NET_ROUTE_H -#include -#endif /* HAVE_NET_ROUTE_H */ - -#ifdef HAVE_NETLINK -#include -#include -#else -#define RT_TABLE_MAIN 0 -#endif /* HAVE_NETLINK */ - -#ifdef HAVE_NETDB_H -#include -#endif /* HAVE_NETDB_H */ - -#include -#include - -#ifdef HAVE_INET_ND_H -#include -#endif /* HAVE_INET_ND_H */ - -#ifdef HAVE_NETINET_IN_VAR_H -#include -#endif /* HAVE_NETINET_IN_VAR_H */ - -#ifdef HAVE_NETINET6_IN6_VAR_H -#include -#endif /* HAVE_NETINET6_IN6_VAR_H */ - -#ifdef HAVE_NETINET_IN6_VAR_H -#include -#endif /* HAVE_NETINET_IN6_VAR_H */ - -#ifdef HAVE_NETINET6_IN_H -#include -#endif /* HAVE_NETINET6_IN_H */ - -#ifdef HAVE_NETINET6_IP6_H -#include -#endif /* HAVE_NETINET6_IP6_H */ - -#ifdef HAVE_NETINET_ICMP6_H -#include -#endif /* HAVE_NETINET_ICMP6_H */ - -#ifdef HAVE_NETINET6_ND6_H -#include -#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 -#endif /* HAVE_LIBUTIL_H */ - -#ifdef HAVE_GLIBC_BACKTRACE -#include -#endif /* HAVE_GLIBC_BACKTRACE */ - -#ifdef BSDI_NRL - -#ifdef HAVE_NETINET6_IN6_H -#include -#endif /* HAVE_NETINET6_IN6_H */ - -#ifdef NRL -#include -#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 ; - 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(__FreeBSD_kernel__)\ - || (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: - */ --- a/lib/quagga/src/quagga.c +++ b/lib/quagga/src/quagga.c @@ -1,866 +1,555 @@ +/* + * OLSRd Quagga plugin + * + * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg + * Copyright (C) 2007-2008 Vasilis Tsiligiannis + * + * 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 + * + */ -/*************************************************************************** - 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. * - * * - ***************************************************************************/ +/* ------------------------------------------------------------------------- + * File : quagga.c + * Description : functions to interface to the zebra daemon + * ------------------------------------------------------------------------- */ -#ifdef MY_DEBUG -#include -#endif #define HAVE_SOCKLEN_T +#include "quagga.h" +#include "olsr.h" /* olsr_exit + olsr_malloc */ +#include "log.h" /* olsr_syslog */ + #include +#include +#include +#include +#include +#include #include #include #include -#include -#include - -#include "quagga.h" -#include "olsr.h" -#include "log.h" -#include "defs.h" -#include "routing_table.h" - +#include #ifdef USE_UNIX_DOMAIN_SOCKET #include -#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 - int sock; // Socket to zebra... + char status; // internal status + char options; // internal options + int sock; // Socket to zebra... 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 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 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"); - } -} +static void *my_realloc (void *, size_t, const char *); +static void zebra_connect (void); +static unsigned char *try_read (ssize_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); #endif +static void free_ipv4_route (struct zebra_route *); + -void * -my_realloc(void *buf, size_t s, const char *c) -{ - buf = realloc(buf, s); +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)); + OLSR_PRINTF (1, "(QUAGGA) OUT OF MEMORY: %s\n", strerror(errno)); olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %m\n"); olsr_exit(c, EXIT_FAILURE); } return buf; } -void -init_zebra(void) -{ + +void init_zebra (void) { zebra_connect(); - if (!(zebra.status & STATUS_CONNECTED)) - olsr_exit("(QUAGGA) AIIIII, could not connect to zebra! is zebra running?", EXIT_FAILURE); + if (!(zebra.status&STATUS_CONNECTED)) + olsr_exit ("(QUAGGA) AIIIII, could not connect to zebra! is zebra running?", + EXIT_FAILURE); } -void -zebra_cleanup(void) -{ + +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); - } - OLSR_FOR_ALL_RT_ENTRIES_END(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); } -static void -zebra_reconnect(void) -{ + +#if 0 +static void zebra_reconnect (void) { struct rt_entry *tmp; int i; zebra_connect(); - if (!(zebra.status & STATUS_CONNECTED)) - return; // try again next time + if (!(zebra.status & STATUS_CONNECTED)) return; // try again next time if (zebra.options & OPTION_EXPORT) { OLSR_FOR_ALL_RT_ENTRIES(tmp) { - zebra_add_olsr_v4_route(tmp); - } - OLSR_FOR_ALL_RT_ENTRIES_END(tmp); + zebra_add_route (tmp); + } OLSR_FOR_ALL_RT_ENTRIES_END(tmp); } for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - if (zebra.redistribute[i]) - zebra_redistribute(i + 1); + if (zebra.redistribute[i]) zebra_redistribute(i + 1); /* Zebra sends us all routes of type it knows after zebra_redistribute(type) */ } +#endif + /* Connect to the zebra-daemon, returns a socket */ -static void -zebra_connect(void) -{ +static void zebra_connect (void) { int ret; #ifndef USE_UNIX_DOMAIN_SOCKET struct sockaddr_in i; - if (close(zebra.sock) < 0) - olsr_exit("(QUAGGA) Could not close socket!", EXIT_FAILURE); + if (close (zebra.sock) < 0) olsr_exit ("(QUAGGA) Could not close socket!", EXIT_FAILURE); + - zebra.sock = socket(AF_INET, SOCK_STREAM, 0); + zebra.sock = socket (AF_INET,SOCK_STREAM, 0); #else struct sockaddr_un i; - if (close(zebra.sock) < 0) - olsr_exit("(QUAGGA) Could not close socket!", EXIT_FAILURE); + if (close (zebra.sock) < 0) olsr_exit ("(QUAGGA) Could not close socket!", EXIT_FAILURE); - zebra.sock = socket(AF_UNIX, SOCK_STREAM, 0); + zebra.sock = socket (AF_UNIX,SOCK_STREAM, 0); #endif - if (zebra.sock < 0) + if (zebra.sock <0 ) olsr_exit("(QUAGGA) Could not create socket!", EXIT_FAILURE); - memset(&i, 0, sizeof i); + memset (&i, 0, sizeof i); #ifndef USE_UNIX_DOMAIN_SOCKET i.sin_family = AF_INET; - i.sin_port = htons(ZEBRA_PORT); - i.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + i.sin_port = htons (ZEBRA_PORT); + i.sin_addr.s_addr = htonl (INADDR_LOOPBACK); #else i.sun_family = AF_UNIX; - strscpy(i.sun_path, ZEBRA_SOCKET, sizeof(i.sun_path)); + strcpy (i.sun_path, ZEBRA_SOCKET); #endif - ret = connect(zebra.sock, (struct sockaddr *)&i, sizeof i); - if (ret < 0) - zebra.status &= ~STATUS_CONNECTED; - else - zebra.status |= STATUS_CONNECTED; + ret = connect (zebra.sock, (struct sockaddr *)&i, sizeof i); + if (ret < 0) zebra.status &= ~STATUS_CONNECTED; + else zebra.status |= STATUS_CONNECTED; } + /* 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); + if (!(zebra.status & STATUS_CONNECTED)) return 0; - memcpy(p, &len, 2); + pnt = options; + memcpy (&len, pnt, 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); - - errno = 0; + len = ntohs(len); do { - ret = write(zebra.sock, p, length); + ret = write (zebra.sock, pnt, len); if (ret < 0) { - if (errno == EINTR) { - errno = 0; - continue; - } else { - olsr_printf(1, "(QUAGGA) Disconnected from zebra\n"); - zebra.status &= ~STATUS_CONNECTED; - free(pnt); - return -1; + if ((errno == EINTR) || (errno == EAGAIN)) { + errno = 0; + ret = 0; + continue; + } + else { + OLSR_PRINTF (1, "(QUAGGA) Disconnected from zebra\n"); + zebra.status &= ~STATUS_CONNECTED; + 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 = olsr_malloc (ZEBRA_MAX_PACKET_SIZ , "zebra add_v4_route"); - cmdopt = zebra_route_packet(r, &optlen); + 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; - retval = zebra_send_command(ZEBRA_IPV4_ROUTE_ADD, cmdopt, optlen); - free(cmdopt); - 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; } -/* deletes a route from the zebra-daemon */ -int -zebra_delete_v4_route(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_DELETE, cmdopt, optlen); - free(cmdopt); - - return retval; - -} /* 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); + data = try_read (&len); if (data) { f = data; do { - ret = zebra_parse_packet(f, len); - if (!ret) // something wired happened - olsr_exit("(QUAGGA) Zero message length??? ", EXIT_FAILURE); - f += ret; - } - while ((f - data) < len); - free(data); + memcpy (&length, f, sizeof length); + length = ntohs (length); + if (!length) // something wired happened + olsr_exit ("(QUAGGA) Zero message length??? ", EXIT_FAILURE); + 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); } } + // 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; - - *len = 0; - - sockstate = fcntl(zebra.sock, F_GETFL, 0); - fcntl(zebra.sock, F_SETFL, sockstate | O_NONBLOCK); +static unsigned char *try_read (ssize_t *size) { + unsigned char *buf; + ssize_t bytes, bufsize; + uint16_t length, offset; + int sockstatus; + + /* initialize variables */ + buf = NULL; + offset = 0; + *size = 0; + bufsize = 0; + + /* 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! - free(buf); + + /* read from socket */ + bytes = read (zebra.sock, buf + *size, bufsize - *size); + /* handle broken packet */ + if (!bytes) { + free (buf); return NULL; } - - if (ret < 0) { - if (errno != EAGAIN) { // oops - we got disconnected - olsr_printf(1, "(QUAGGA) Disconnected from zebra\n"); + /* 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; } - free(buf); + free (buf); 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; -} - -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))) -{ + *size += bytes; - //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); -static int -parse_interface_down(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused))) -{ + /* restore socket status */ + fcntl (zebra.sock, F_SETFL, sockstatus); - //todo - return 0; + return buf; } -static int -parse_interface_address_delete(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused))) -{ - //todo - return 0; -} /* 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) -{ - struct ipv4_route r; - int f; +static unsigned char *zebra_redistribute_packet (unsigned char cmd, unsigned char type) { + unsigned char *data, *pnt; + uint16_t size; - f = parse_ipv4_route(opt, len, &r); - if (f < 0) - return f; + data = olsr_malloc (ZEBRA_MAX_PACKET_SIZ , "zebra_redistribute_packet"); - 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); + pnt = &data[2]; + *pnt++ = cmd; + *pnt++ = type; + size = htons (pnt - data); + memcpy (data, &size, 2); + return data; } -static int -parse_ipv6_route_add(unsigned char *opt __attribute__ ((unused)), size_t len __attribute__ ((unused))) -{ - //todo - return 0; -} /* start redistribution FROM zebra */ -int -zebra_redistribute(unsigned char type) -{ - - if (type > ZEBRA_ROUTE_MAX) - return -1; - zebra.redistribute[type - 1] = 1; - - return zebra_send_command(ZEBRA_REDISTRIBUTE_ADD, &type, 1); - -} - -/* end redistribution FROM zebra */ -int -zebra_disable_redistribute(unsigned char type) -{ - - if (type > ZEBRA_ROUTE_MAX) - return -1; - zebra.redistribute[type - 1] = 0; +int zebra_redistribute (unsigned char type) { - return zebra_send_command(ZEBRA_REDISTRIBUTE_DELETE, &type, 1); + if (zebra_send_command(zebra_redistribute_packet (ZEBRA_REDISTRIBUTE_ADD, type)) < 0) + olsr_exit("(QUAGGA) could not send redistribute add command", EXIT_FAILURE); -} + if (type > ZEBRA_ROUTE_MAX-1) return -1; + zebra.redistribute[type] = 1; -int -add_hna4_route(struct ipv4_route r) -{ - union olsr_ip_addr net; - -#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) -{ - union olsr_ip_addr net; +/* end redistribution FROM zebra */ +int zebra_disable_redistribute (unsigned char type) { -#ifdef MY_DEBUG - dump_ipv4_route(r, "delete_hna4_route"); -#endif + if (zebra_send_command(zebra_redistribute_packet (ZEBRA_REDISTRIBUTE_DELETE, type)) < 0) + olsr_exit("(QUAGGA) could not send redistribute delete command", EXIT_FAILURE); - net.v4.s_addr = r.prefix; + if (type > ZEBRA_ROUTE_MAX-1) return -1; + zebra.redistribute[type] = 0; - 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 uint8_t masktoprefixlen (uint32_t mask) { - - uint8_t prefixlen = 0; - mask = htonl (mask); +static void free_ipv4_route (struct zebra_route *r) { - 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.index = NULL; - route.distance = 0; - 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_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.iif_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; - } else { - route.message |= ZAPI_MESSAGE_NEXTHOP; - 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.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) { + 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.iif_index; + } + else { + 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; } - 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.index = NULL; - route.distance = 0; - 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.iif_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; - } else { - route.message |= ZAPI_MESSAGE_NEXTHOP; - 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.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.iif_index; + } + else { + 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) { @@ -868,36 +557,23 @@ zebra_del_olsr_v4_route(const struct rt_ route.distance = zebra.distance; } - 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) -{ +void zebra_olsr_distance (unsigned char dist) { zebra.distance = dist; } -void -zebra_olsr_localpref(void) -{ +void zebra_olsr_localpref (void) { zebra.flags &= ZEBRA_FLAG_SELECTED; } -void -zebra_export_routes(unsigned char t) -{ +void zebra_export_routes (unsigned char t) { if (t) zebra.options |= OPTION_EXPORT; else zebra.options &= ~OPTION_EXPORT; } - -/* - * Local Variables: - * c-basic-offset: 2 - * indent-tabs-mode: nil - * End: - */ --- a/lib/quagga/src/quagga.h +++ b/lib/quagga/src/quagga.h @@ -1,77 +1,102 @@ +/* + * OLSRd Quagga plugin + * + * Copyright (C) 2006-2008 Immo 'FaUl' Wehrenberg + * Copyright (C) 2007-2008 Vasilis Tsiligiannis + * + * 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 + * ------------------------------------------------------------------------- */ -/*************************************************************************** - 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. * - * * - ***************************************************************************/ + +#include "routing_table.h" /* rt_entry */ +#include "olsr_types.h" /* olsr_ip_addr */ #include -#include #include -#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 -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; +/* 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 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); -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 *); -void zebra_olsr_localpref(void); -void zebra_olsr_distance(unsigned char); +void init_zebra (void); +void zebra_cleanup (void); +void zebra_parse (void*); +int zebra_redistribute (unsigned char); +int zebra_disable_redistribute (unsigned char); +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); - -/* - * Local Variables: - * c-basic-offset: 2 - * indent-tabs-mode: nil - * End: - */ --- a/lib/quagga/test/foo.c +++ /dev/null @@ -1,20 +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: - */ --- a/lib/quagga/test/foo.pl +++ /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 --- a/lib/quagga/test/quagga.try1.c +++ /dev/null @@ -1,728 +0,0 @@ - -/* - * (C) 2006 by Immo 'FaUl' Wehrenberg - * - * This code is covered by the GPLv2 - * - */ - -#include -#ifdef MY_DEBUG -#include -#endif -#include -#include -#include -#define HAVE_SOCKLEN_T -#include -#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); - -} - -static uint32_t -prefixlentomask(uint8_t prefix) -{ - uint32_t mask; - mask = prefix_to_netmask4(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: - */