summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2009-09-16 01:52:42 +0200
committerDenis Ovsienko <infrastation@yandex.ru>2011-12-13 19:13:17 +0400
commite0ca5fde7be5b5ce90dae78c2477e8245aecb8e9 (patch)
tree0e0b32ddbed4a84a3b2de9dd7217165cb81f52fa /lib
parentebf08631cad8a420fc6bfb7c45af5496dc11023e (diff)
lib: put route_types.txt to real use
this replaces most occurences of routing protocol lists by preprocessor defines from route_types.h. the latter is autogenerated from route_types.txt by a perl script (previously awk). adding a routing protocol now is mostly a matter of changing route_types.txt and log.c. Conflicts: lib/route_types.awk
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am6
-rw-r--r--lib/log.c69
-rw-r--r--lib/route_types.awk185
-rwxr-xr-xlib/route_types.pl199
-rw-r--r--lib/route_types.txt10
-rw-r--r--lib/zebra.h19
6 files changed, 259 insertions, 229 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 315e919b..890cc5ca 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -29,10 +29,10 @@ pkginclude_HEADERS = \
privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \
workqueue.h route_types.h
-EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.awk route_types.txt
+EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.pl route_types.txt
memtypes.h: $(srcdir)/memtypes.c $(srcdir)/memtypes.awk
($(GAWK) -f $(srcdir)/memtypes.awk $(srcdir)/memtypes.c > $@)
-route_types.h: $(srcdir)/route_types.txt $(srcdir)/route_types.awk
- ($(GAWK) -f $(srcdir)/route_types.awk $(srcdir)/route_types.txt > $@)
+route_types.h: $(srcdir)/route_types.txt $(srcdir)/route_types.pl
+ @PERL@ $(srcdir)/route_types.pl < $(srcdir)/route_types.txt > $@
diff --git a/lib/log.c b/lib/log.c
index 4afe9229..7edc5c4c 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -20,6 +20,8 @@
* 02111-1307, USA.
*/
+#define QUAGGA_DEFINE_DESC_TABLE
+
#include <zebra.h>
#include "log.h"
@@ -817,29 +819,6 @@ safe_strerror(int errnum)
return (s != NULL) ? s : "Unknown error";
}
-struct zebra_desc_table
-{
- unsigned int type;
- const char *string;
- char chr;
-};
-
-#define DESC_ENTRY(T,S,C) [(T)] = { (T), (S), (C) }
-static const struct zebra_desc_table route_types[] = {
- DESC_ENTRY (ZEBRA_ROUTE_SYSTEM, "system", 'X' ),
- DESC_ENTRY (ZEBRA_ROUTE_KERNEL, "kernel", 'K' ),
- DESC_ENTRY (ZEBRA_ROUTE_CONNECT, "connected", 'C' ),
- DESC_ENTRY (ZEBRA_ROUTE_STATIC, "static", 'S' ),
- DESC_ENTRY (ZEBRA_ROUTE_RIP, "rip", 'R' ),
- DESC_ENTRY (ZEBRA_ROUTE_RIPNG, "ripng", 'R' ),
- DESC_ENTRY (ZEBRA_ROUTE_OSPF, "ospf", 'O' ),
- DESC_ENTRY (ZEBRA_ROUTE_OSPF6, "ospf6", 'O' ),
- DESC_ENTRY (ZEBRA_ROUTE_ISIS, "isis", 'I' ),
- DESC_ENTRY (ZEBRA_ROUTE_BGP, "bgp", 'B' ),
- DESC_ENTRY (ZEBRA_ROUTE_HSLS, "hsls", 'H' ),
-};
-#undef DESC_ENTRY
-
#define DESC_ENTRY(T) [(T)] = { (T), (#T), '\0' }
static const struct zebra_desc_table command_types[] = {
DESC_ENTRY (ZEBRA_INTERFACE_ADD),
@@ -929,4 +908,48 @@ proto_name2num(const char *s)
return route_types[i].type;
return -1;
}
+
#undef RTSIZE
+
+int
+proto_redistnum(int afi, const char *s)
+{
+ if (! s)
+ return -1;
+
+ if (afi == AFI_IP)
+ {
+ if (strncmp (s, "k", 1) == 0)
+ return ZEBRA_ROUTE_KERNEL;
+ else if (strncmp (s, "c", 1) == 0)
+ return ZEBRA_ROUTE_CONNECT;
+ else if (strncmp (s, "s", 1) == 0)
+ return ZEBRA_ROUTE_STATIC;
+ else if (strncmp (s, "r", 1) == 0)
+ return ZEBRA_ROUTE_RIP;
+ else if (strncmp (s, "o", 1) == 0)
+ return ZEBRA_ROUTE_OSPF;
+ else if (strncmp (s, "i", 1) == 0)
+ return ZEBRA_ROUTE_ISIS;
+ else if (strncmp (s, "b", 1) == 0)
+ return ZEBRA_ROUTE_BGP;
+ }
+ if (afi == AFI_IP6)
+ {
+ if (strncmp (s, "k", 1) == 0)
+ return ZEBRA_ROUTE_KERNEL;
+ else if (strncmp (s, "c", 1) == 0)
+ return ZEBRA_ROUTE_CONNECT;
+ else if (strncmp (s, "s", 1) == 0)
+ return ZEBRA_ROUTE_STATIC;
+ else if (strncmp (s, "r", 1) == 0)
+ return ZEBRA_ROUTE_RIPNG;
+ else if (strncmp (s, "o", 1) == 0)
+ return ZEBRA_ROUTE_OSPF6;
+ else if (strncmp (s, "i", 1) == 0)
+ return ZEBRA_ROUTE_ISIS;
+ else if (strncmp (s, "b", 1) == 0)
+ return ZEBRA_ROUTE_BGP;
+ }
+ return -1;
+}
diff --git a/lib/route_types.awk b/lib/route_types.awk
deleted file mode 100644
index 6cfd5377..00000000
--- a/lib/route_types.awk
+++ /dev/null
@@ -1,185 +0,0 @@
-# Scan a file of route-type definitions (see eg route_types.txt) and
-# generate a corresponding header file with:
-#
-# - enum of Zserv route-types
-# - redistribute strings for the various Quagga daemons
-#
-# See route_types.txt for the format.
-#
-#
-
-BEGIN {
- FS="[,]";
-
- # globals
- exitret = 0;
- tcount = 0;
-
- # formats for output
- ## the define format
- redist_def_fmt = "#define QUAGGA_REDIST_STR_%s \\\n";
- ## DEFUN/vty route-type argument
- redist_str_fmt = "\"(%s)\"\n";
- redist_help_def_fmt = "#define QUAGGA_REDIST_HELP_STR_%s";
- redist_help_str_fmt = " \\\n \"%s\\n\"";
-
- # header
- header = "/* Auto-generated from route_types.txt by " ARGV[0] ". */\n";
- header = header "/* Do not edit! */\n";
- header = header "\n#ifndef _QUAGGA_ROUTE_TYPES_H\n";
- header = header "#define _QUAGGA_ROUTE_TYPES_H\n";
- footer = "#endif /* _QUAGGA_ROUTE_TYPES_H */\n";
- printf ("%s\n", header);
-}
-
-# Chomp comment lines
-($0 ~ /^#/) {
- next;
-}
-
-# get rid of the commas, leading/trailling whitespace and
-# quotes
-{
- for (i = 1; i <= NF; i++) {
- #print "before:" $i;
- $i = gensub(/^[[:blank:]]*(.*)[,]*.*/, "\\1", "g",$i);
- $i = gensub(/^["](.*)["]$/, "\\1", "g", $i);
- #print "after :" $i;
- }
-}
-
-# 7 field format:
-# type cname daemon C 4 6 short help
-(NF >= 7) {
- #print "7", $1, $0;
-
- if ($1 in types) {
- print "error: attempt to redefine", $1;
- exitret = 1;
- exit exitret;
- }
-
- typesbynum[tcount] = $1;
- types[$1,"num"] = tcount++;
- types[$1,"cname"] = $2;
- types[$1,"daemon"] = $3;
- types[$1,"C"] = $4;
- types[$1,"4"] = strtonum($5);
- types[$1,"6"] = strtonum($6);
- types[$1,"shelp"] = $7;
-
- #print "num :", types[$1,"num"]
- #print "cname :", types[$1,"cname"]
- #print "daemon:", types[$1,"daemon"];
- #print "char :", types[$1,"C"];
-};
-
-# 2 field: type "long description"
-(NF == 2) {
- #print "2", $1, $2;
-
- if (!(($1 SUBSEP "num") in types)) {
- print "error: type", $1, "must be defined before help str";
- exitret = 2;
- exit exitret;
- }
-
- types[$1,"lhelp"] = $2;
-}
-
-END {
- if (exitret)
- exit exitret;
-
- # The enums
- # not yet...
- #printf("enum\n{\n");
- #for (i = 0; i < tcount; i++) {
- # type = typesbynum[i];
- # if (type != "" && types[type,"num"] == i)
- # printf (" %s,\n", type);
- #}
- #printf (" ZEBRA_ROUTE_MAX,\n};\n\n");
-
- # the redistribute defines
- for (i = 0; i < tcount; i++) {
- type = typesbynum[i];
-
- # must be a type, and must cross-check against recorded type
- if (type == "" || types[type,"num"] != i)
- continue;
-
- # ignore route types that can't be redistributed
- if (!(types[type,"4"] || types[type,"6"]))
- continue;
-
- # must have a daemon name
- if (!((type SUBSEP "daemon") in types))
- continue;
- if (!(daemon = types[type,"daemon"]))
- continue;
-
- # might have done this daemon already?
- if (daemon in seen_daemons)
- continue;
-
- cname = types[type,"cname"];
- all = all "|" cname;
- rstr = "";
- hstr = "";
-
- # add it to the others
- for (j = 0; j < tcount; j++) {
- # ignore self
- if (i == j)
- continue;
-
- type2 = typesbynum[j];
-
- # type2 must be valid, and self-check.
- if (type2 == "" || types[type2,"num"] != j)
- continue;
-
- # ignore different route types for the same daemon
- # (eg system/kernel/connected)
- if (types[type2,"daemon"] == daemon)
- continue;
-
- if ((types[type2,"4"] && types[type,"4"]) \
- || (types[type2,"6"] && types[type,"6"])) {
-
- if (rstr == "")
- rstr = types[type2,"cname"];
- else
- rstr = rstr "|" types[type2,"cname"];
-
- if ((type2 SUBSEP "lhelp") in types)
- hstr2 = types[type2,"lhelp"];
- else if ((type2 SUBSEP "shelp") in types)
- hstr2 = types[type2,"shelp"];
- else
- hstr2 = types[type2,"cname"];
-
- hstr = hstr sprintf(redist_help_str_fmt, hstr2);
- }
- }
-
- # dont double-process daemons.
- seen_daemons[daemon] = 1;
-
- printf("/* %s */\n", daemon);
- printf(redist_def_fmt, toupper(daemon));
- printf(redist_str_fmt, rstr);
- printf(redist_help_def_fmt, toupper(daemon));
- printf("%s", hstr);
- printf("\n\n");
- }
-
- #printf("#define QUAGGA_REDIST_STR_ALL %s\n",all);
-
-# for (i = 0; i < lcount; i++) {
-# if (mlists[i] != "")
-# printf (mlistformat "\n", mlists[i]);
-# }
- printf (footer);
-}
diff --git a/lib/route_types.pl b/lib/route_types.pl
new file mode 100755
index 00000000..e1595afc
--- /dev/null
+++ b/lib/route_types.pl
@@ -0,0 +1,199 @@
+#!/usr/bin/perl
+##
+## Scan a file of route-type definitions (see eg route_types.txt) and
+## generate a corresponding header file with:
+##
+## - enum of Zserv route-types
+## - redistribute strings for the various Quagga daemons
+##
+## See route_types.txt for the format.
+##
+##
+## Copyright (C) 2009 David Lamparter.
+## 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.
+##
+
+use strict;
+
+# input processing
+#
+my @protos;
+my %protodetail;
+
+my %daemons;
+
+while (<STDIN>) {
+ # skip comments and empty lines
+ next if (/^\s*(#|$)/);
+
+ # strip whitespace
+ chomp;
+ $_ =~ s/^\s*//;
+ $_ =~ s/\s*$//;
+
+ # match help strings
+ if (/^(ZEBRA_ROUTE_[^\s]+)\s*,\s*"(.*)"$/) {
+ $protodetail{$1}->{'longhelp'} = $2;
+ next;
+ }
+
+ $_ =~ s/\s*,\s*/,/g;
+
+ # else: 7-field line
+ my @f = split(/,/, $_);
+ unless (@f == 7) {
+ die "invalid input on route_types line $.\n";
+ }
+
+ my $proto = $f[0];
+ $f[3] = $1 if ($f[3] =~ /^'(.*)'$/);
+ $f[6] = $1 if ($f[6] =~ /^"(.*)"$/);
+
+ $protodetail{$proto} = {
+ "number" => scalar @protos,
+ "type" => $f[0],
+ "cname" => $f[1],
+ "daemon" => $f[2],
+ "char" => $f[3],
+ "ipv4" => int($f[4]),
+ "ipv6" => int($f[5]),
+ "shorthelp" => $f[6],
+ };
+ push @protos, $proto;
+ $daemons{$f[2]} = {
+ "ipv4" => int($f[4]),
+ "ipv6" => int($f[5])
+ } unless ($f[2] eq "NULL");
+}
+
+# output
+printf <<EOF, $ARGV[0];
+/* Auto-generated from route_types.txt by %s. */
+/* Do not edit! */
+
+#ifndef _QUAGGA_ROUTE_TYPES_H
+#define _QUAGGA_ROUTE_TYPES_H
+
+/* Zebra route's types. */
+EOF
+
+push @protos, "ZEBRA_ROUTE_MAX";
+my (@protosv4, @protosv6) = ((), ());
+for (my $c = 0; $c < @protos; $c++) {
+ my $p = $protos[$c];
+ printf "#define %-32s %d\n", $p, $c;
+ push @protosv4, $p if ($protodetail{$p}->{"ipv4"});
+ push @protosv6, $p if ($protodetail{$p}->{"ipv6"});
+}
+pop @protos;
+
+sub codelist {
+ my (@protos) = @_;
+ my (@lines) = ();
+ my $str = " \"Codes: ";
+ for my $p (@protos) {
+ my $s = sprintf("%s - %s, ",
+ $protodetail{$p}->{"char"},
+ $protodetail{$p}->{"shorthelp"});
+ if (length($str . $s) > 70) {
+ $str =~ s/ $//;
+ push @lines, $str . "%s\" \\\n";
+ $str = " \" ";
+ }
+ $str .= $s;
+ }
+ $str =~ s/ $//;
+ push @lines, $str . "%s\" \\\n";
+ push @lines, " \" > - selected route, * - FIB route%s%s\", \\\n";
+ my @nl = ();
+ for (my $c = 0; $c < @lines + 1; $c++) {
+ push @nl, "VTY_NEWLINE"
+ }
+ return join("", @lines) ." ". join(", ", @nl);
+}
+
+print "\n";
+printf "#define SHOW_ROUTE_V4_HEADER \\\n%s\n", codelist(@protosv4);
+printf "#define SHOW_ROUTE_V6_HEADER \\\n%s\n", codelist(@protosv6);
+print "\n";
+
+sub collect {
+ my ($daemon, $ipv4, $ipv6) = @_;
+ my (@names, @help) = ((), ());
+ for my $p (@protos) {
+ next if ($protodetail{$p}->{"daemon"} eq $daemon && $daemon ne "zebra");
+ next unless (($ipv4 && $protodetail{$p}->{"ipv4"})
+ || ($ipv6 && $protodetail{$p}->{"ipv6"}));
+ push @names, $protodetail{$p}->{"cname"};
+ push @help, " \"".$protodetail{$p}->{"longhelp"}."\\n\"";
+ }
+ return ("\"(" . join("|", @names) . ")\"", join(" \\\n", @help));
+}
+
+for my $daemon (sort keys %daemons) {
+ next unless ($daemons{$daemon}->{"ipv4"} || $daemons{$daemon}->{"ipv6"});
+ printf "/* %s */\n", $daemon;
+ if ($daemons{$daemon}->{"ipv4"} && $daemons{$daemon}->{"ipv6"}) {
+ my ($names, $help) = collect($daemon, 1, 1);
+ printf "#define QUAGGA_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
+ printf "#define QUAGGA_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
+ ($names, $help) = collect($daemon, 1, 0);
+ printf "#define QUAGGA_IP_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
+ printf "#define QUAGGA_IP_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
+ ($names, $help) = collect($daemon, 0, 1);
+ printf "#define QUAGGA_IP6_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
+ printf "#define QUAGGA_IP6_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
+ } else {
+ my ($names, $help) = collect($daemon,
+ $daemons{$daemon}->{"ipv4"}, $daemons{$daemon}->{"ipv6"});
+ printf "#define QUAGGA_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
+ printf "#define QUAGGA_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
+ }
+ print "\n";
+}
+
+print <<EOF;
+
+#ifdef QUAGGA_DEFINE_DESC_TABLE
+
+struct zebra_desc_table
+{
+ unsigned int type;
+ const char *string;
+ char chr;
+};
+
+#define DESC_ENTRY(T,S,C) [(T)] = { (T), (S), (C) }
+static const struct zebra_desc_table route_types[] = {
+EOF
+
+for (my $c = 0; $c < @protos; $c++) {
+ my $p = $protos[$c];
+ printf " DESC_ENTRY\t(%s\t \"%s\",\t'%s' ),\n",
+ $p.",", $protodetail{$p}->{"cname"}, $protodetail{$p}->{"char"};
+}
+
+print <<EOF;
+};
+#undef DESC_ENTRY
+
+#endif /* QUAGGA_DEFINE_DESC_TABLE */
+
+#endif /* _QUAGGA_ROUTE_TYPES_H */
+EOF
+
diff --git a/lib/route_types.txt b/lib/route_types.txt
index e99cacde..fde0bc8d 100644
--- a/lib/route_types.txt
+++ b/lib/route_types.txt
@@ -42,13 +42,13 @@
## type cname daemon C 4 6 short help
ZEBRA_ROUTE_SYSTEM, system, NULL, 'X', 0, 0, "Reserved"
-ZEBRA_ROUTE_KERNEL, kernel, zebra, 'K', 1, 1, NULL
-ZEBRA_ROUTE_CONNECT, connected, zebra, 'C', 1, 1, NULL
-ZEBRA_ROUTE_STATIC, static, zebra, 'S', 1, 1, NULL
+ZEBRA_ROUTE_KERNEL, kernel, zebra, 'K', 1, 1, "kernel route"
+ZEBRA_ROUTE_CONNECT, connected, zebra, 'C', 1, 1, "connected"
+ZEBRA_ROUTE_STATIC, static, zebra, 'S', 1, 1, "static"
ZEBRA_ROUTE_RIP, rip, ripd, 'R', 1, 0, "RIP"
ZEBRA_ROUTE_RIPNG, ripng, ripngd, 'R', 0, 1, "RIPng"
ZEBRA_ROUTE_OSPF, ospf, ospfd, 'O', 1, 0, "OSPF"
-ZEBRA_ROUTE_OSPF6, ospf6, ospf6d, 'O', 0, 1, "OSPF"
+ZEBRA_ROUTE_OSPF6, ospf6, ospf6d, 'O', 0, 1, "OSPFv6"
ZEBRA_ROUTE_ISIS, isis, isisd, 'I', 1, 1, "IS-IS"
ZEBRA_ROUTE_BGP, bgp, bgpd, 'B', 1, 1, "BGP"
# HSLS and OLSR both are AFI independent (so: 1, 1), however
@@ -57,7 +57,7 @@ ZEBRA_ROUTE_BGP, bgp, bgpd, 'B', 1, 1, "BGP"
# to 'switch on' redist support (direct numeric entry remaining
# possible).
ZEBRA_ROUTE_HSLS, hsls, hslsd, 'H', 0, 0, "HSLS"
-ZEBRA_ROUTE_OLSR, olsr, oslrd, 'o', 0, 0, "OLSR"
+ZEBRA_ROUTE_OLSR, olsr, olsrd, 'o', 0, 0, "OLSR"
## help strings
ZEBRA_ROUTE_SYSTEM, "Reserved route type, for internal use only"
diff --git a/lib/zebra.h b/lib/zebra.h
index c4c69d3d..4b4c7c00 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -425,19 +425,8 @@ struct in_pktinfo
*/
#define ZEBRA_HEADER_MARKER 255
-/* 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_MAX 11
+/* Zebra route's types are defined in route_types.h */
+#include "route_types.h"
/* Note: whenever a new route-type or zserv-command is added the
* corresponding {command,route}_types[] table in lib/log.c MUST be
@@ -451,6 +440,10 @@ extern char zebra_route_char(unsigned int route_type);
* e.g. ZEBRA_INTERFACE_ADD -> "ZEBRA_INTERFACE_ADD" */
/* Map a protocol name to its number. e.g. ZEBRA_ROUTE_BGP->9*/
extern int proto_name2num(const char *s);
+/* Map redistribute X argument to protocol number.
+ * unlike proto_name2num, this accepts shorthands and takes
+ * an AFI value to restrict input */
+extern int proto_redistnum(int afi, const char *s);
extern const char *zserv_command_string (unsigned int command);