diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 14 | ||||
-rw-r--r-- | lib/command.c | 10 | ||||
-rw-r--r-- | lib/if.h | 6 | ||||
-rw-r--r-- | lib/log.c | 71 | ||||
-rw-r--r-- | lib/md5.c | 3 | ||||
-rw-r--r-- | lib/memory.h | 8 | ||||
-rw-r--r-- | lib/paths.c | 65 | ||||
-rw-r--r-- | lib/paths.h | 34 | ||||
-rw-r--r-- | lib/prefix.c | 2 | ||||
-rw-r--r-- | lib/prefix.h | 16 | ||||
-rw-r--r-- | lib/route_types.awk | 187 | ||||
-rwxr-xr-x | lib/route_types.pl | 199 | ||||
-rw-r--r-- | lib/route_types.txt | 10 | ||||
-rw-r--r-- | lib/sockunion.c | 24 | ||||
-rw-r--r-- | lib/sockunion.h | 1 | ||||
-rw-r--r-- | lib/table.c | 62 | ||||
-rw-r--r-- | lib/table.h | 12 | ||||
-rw-r--r-- | lib/vty.c | 7 | ||||
-rw-r--r-- | lib/zclient.c | 3 | ||||
-rw-r--r-- | lib/zclient.h | 3 | ||||
-rw-r--r-- | lib/zebra.h | 20 |
21 files changed, 451 insertions, 306 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 315e919b..1b4134dc 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in. INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib @SNMP_INCLUDES@ -DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" +DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" -DPATH_CONFIG=\"$(sysconfdir)\" lib_LTLIBRARIES = libzebra.la libzebra_la_LDFLAGS = -version-info 0:0:0 @@ -12,13 +12,13 @@ libzebra_la_SOURCES = \ sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \ filter.c routemap.c distribute.c stream.c str.c log.c plist.c \ zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c \ - sigevent.c pqueue.c jhash.c memtypes.c workqueue.c + sigevent.c pqueue.c jhash.c memtypes.c workqueue.c paths.c BUILT_SOURCES = memtypes.h route_types.h libzebra_la_DEPENDENCIES = @LIB_REGEX@ -libzebra_la_LIBADD = @LIB_REGEX@ +libzebra_la_LIBADD = @LIB_REGEX@ @LIBCAP@ pkginclude_HEADERS = \ buffer.h checksum.h command.h filter.h getopt.h hash.h \ @@ -27,12 +27,12 @@ pkginclude_HEADERS = \ str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \ plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \ privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \ - workqueue.h route_types.h + workqueue.h route_types.h paths.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/command.c b/lib/command.c index 19ae5743..c432b323 100644 --- a/lib/command.c +++ b/lib/command.c @@ -82,14 +82,14 @@ static struct cmd_node config_node = }; /* Default motd string. */ -const char *default_motd = +static const char *default_motd = "\r\n\ Hello, this is " QUAGGA_PROGNAME " (version " QUAGGA_VERSION ").\r\n\ " QUAGGA_COPYRIGHT "\r\n\ \r\n"; -static struct facility_map { +static const struct facility_map { int facility; const char *name; size_t match; @@ -122,7 +122,7 @@ static struct facility_map { static const char * facility_name(int facility) { - struct facility_map *fm; + const struct facility_map *fm; for (fm = syslog_facilities; fm->name; fm++) if (fm->facility == facility) @@ -133,7 +133,7 @@ facility_name(int facility) static int facility_match(const char *str) { - struct facility_map *fm; + const struct facility_map *fm; for (fm = syslog_facilities; fm->name; fm++) if (!strncmp(str,fm->name,fm->match)) @@ -506,7 +506,7 @@ install_element (enum node_type ntype, struct cmd_element *cmd) cmd->cmdsize = cmd_cmdsize (cmd->strvec); } -static unsigned char itoa64[] = +static const unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static void @@ -172,6 +172,12 @@ struct connected /* Label for Linux 2.2.X and upper. */ char *label; + + /* scope value, Linux only */ + unsigned scope; + + /* address preference, NetBSD >=4.0 with option IPSRCSEL, in_getifa(9) */ + int preference; }; /* Does the destination field contain a peer address? */ @@ -23,6 +23,8 @@ * 02111-1307, USA. */ +#define QUAGGA_DEFINE_DESC_TABLE + #include <zebra.h> #include "log.h" @@ -761,7 +763,7 @@ lookup (const struct message *mes, int key) { const struct message *pnt; - for (pnt = mes; pnt->key != 0; pnt++) + for (pnt = mes; pnt->str; pnt++) if (pnt->key == key) return pnt->str; @@ -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; +} @@ -232,7 +232,7 @@ static void md5_calc(const uint8_t *b64, md5_ctxt * ctxt) const uint32_t *X = (const uint32_t *)b64; #elif (BYTE_ORDER == BIG_ENDIAN) uint32_t X[16]; -#endif + if (BYTE_ORDER == BIG_ENDIAN) { /* 4 byte words */ @@ -255,6 +255,7 @@ static void md5_calc(const uint8_t *b64, md5_ctxt * ctxt) y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56]; y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60]; } +#endif ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2); ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4); diff --git a/lib/memory.h b/lib/memory.h index 42eb5cae..a7eddce4 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -46,7 +46,10 @@ extern struct mlist mlists[]; #define XREALLOC(mtype, ptr, size) \ mtype_zrealloc (__FILE__, __LINE__, (mtype), (ptr), (size)) #define XFREE(mtype, ptr) \ - mtype_zfree (__FILE__, __LINE__, (mtype), (ptr)) + do { \ + mtype_zfree (__FILE__, __LINE__, (mtype), (ptr)); \ + ptr = NULL; } \ + while (0) #define XSTRDUP(mtype, str) \ mtype_zstrdup (__FILE__, __LINE__, (mtype), (str)) #else @@ -69,8 +72,7 @@ extern char *zstrdup (int type, const char *str); extern void *mtype_zmalloc (const char *file, int line, int type, size_t size); -extern void *mtype_zcalloc (const char *file, int line, int type, - size_t num, size_t size); +extern void *mtype_zcalloc (const char *file, int line, int type, size_t size); extern void *mtype_zrealloc (const char *file, int line, int type, void *ptr, size_t size); diff --git a/lib/paths.c b/lib/paths.c new file mode 100644 index 00000000..5678b873 --- /dev/null +++ b/lib/paths.c @@ -0,0 +1,65 @@ +/* + * Path helper functions (for namespaces) + * 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. + */ + +#include <zebra.h> +#include <log.h> +#include <paths.h> + +static char *namespace = ""; + +void path_set_namespace(const char *ns) +{ + size_t len; + + if (*namespace) + free(namespace); + if (!ns || !*ns) { + namespace = ""; + return; + } + + len = strlen(ns); + namespace = malloc(len + 2); + if (!namespace) { /* ugh... */ + namespace = ""; + return; + }; + namespace[0] = '/'; + memcpy(namespace + 1, ns, len + 1); +} + +const char *path_state(const char *filename) +{ + static char buf[MAXPATHLEN]; + snprintf(buf, sizeof(buf), "%s%s/%s", + PATH_STATE, namespace, filename); + return buf; +} + +const char *path_config(const char *filename) +{ + static char buf[MAXPATHLEN]; + snprintf(buf, sizeof(buf), "%s%s/%s", + PATH_CONFIG, namespace, filename); + return buf; +} + diff --git a/lib/paths.h b/lib/paths.h new file mode 100644 index 00000000..1f697855 --- /dev/null +++ b/lib/paths.h @@ -0,0 +1,34 @@ +/* + * Path helper functions (for namespaces) + * 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. + */ + +#ifndef _ZEBRA_PATHS_H +#define _ZEBRA_PATHS_H + +extern void path_set_namespace(const char *ns); + +/* the following two functions return pointers to a _static_ buffer! + * if you need to keep a reference to the values, do a strdup + */ +extern const char *path_state(const char *filename); +extern const char *path_config(const char *filename); + +#endif /* _ZEBRA_PATHS_H */ diff --git a/lib/prefix.c b/lib/prefix.c index 2afaa09c..c85e6594 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -29,7 +29,7 @@ #include "log.h" /* Maskbit. */ -static u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, +static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; /* Number of bits in prefix type. */ diff --git a/lib/prefix.h b/lib/prefix.h index 9cfc1556..a7598b7e 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -127,6 +127,22 @@ struct prefix_rd /* Prefix's family member. */ #define PREFIX_FAMILY(p) ((p)->family) +/* Check bit of the prefix. */ +static inline unsigned int +prefix_bit (const u_char *prefix, const u_char prefixlen) +{ + unsigned int offset = prefixlen / 8; + unsigned int shift = 7 - (prefixlen % 8); + + return (prefix[offset] >> shift) & 1; +} + +static inline unsigned int +prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen) +{ + return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen); +} + /* Prototypes. */ extern int afi2family (int); extern int family2afi (int); diff --git a/lib/route_types.awk b/lib/route_types.awk deleted file mode 100644 index eb3d382a..00000000 --- a/lib/route_types.awk +++ /dev/null @@ -1,187 +0,0 @@ -# $Id$ -# -# 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/sockunion.c b/lib/sockunion.c index 6a40f332..d1f6d80b 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -527,6 +527,30 @@ sockopt_ttl (int family, int sock, int ttl) return 0; } +int +sockopt_v6only (int family, int sock) +{ + int ret, on = 1; + +#ifdef HAVE_IPV6 +#ifdef IPV6_V6ONLY + if (family == AF_INET6) + { + ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, + (void *) &on, sizeof (int)); + if (ret < 0) + { + zlog (NULL, LOG_WARNING, "can't set sockopt IPV6_V6ONLY " + "to socket %d", sock); + return -1; + } + return 0; + } +#endif /* IPV6_V6ONLY */ +#endif /* HAVE_IPV6 */ + return 0; +} + /* If same family and same prefix return 1. */ int sockunion_same (union sockunion *su1, union sockunion *su2) diff --git a/lib/sockunion.h b/lib/sockunion.h index 96b9a0d4..db145cf2 100644 --- a/lib/sockunion.h +++ b/lib/sockunion.h @@ -99,6 +99,7 @@ extern int sockunion_accept (int sock, union sockunion *); extern int sockunion_stream_socket (union sockunion *); extern int sockopt_reuseaddr (int); extern int sockopt_reuseport (int); +extern int sockopt_v6only (int family, int sock); extern int sockunion_bind (int sock, union sockunion *, unsigned short, union sockunion *); extern int sockopt_ttl (int family, int sock, int ttl); diff --git a/lib/table.c b/lib/table.c index 2ade71b8..04df3af5 100644 --- a/lib/table.c +++ b/lib/table.c @@ -125,7 +125,7 @@ route_table_free (struct route_table *rt) } /* Utility mask array. */ -static u_char maskbit[] = +static const u_char maskbit[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; @@ -165,37 +165,10 @@ route_common (struct prefix *n, struct prefix *p, struct prefix *new) } } -/* Macro version of check_bit (). */ -#define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1) - -/* Check bit of the prefix. */ -static int -check_bit (u_char *prefix, u_char prefixlen) -{ - int offset; - int shift; - u_char *p = (u_char *)prefix; - - assert (prefixlen <= 128); - - offset = prefixlen / 8; - shift = 7 - (prefixlen % 8); - - return (p[offset] >> shift & 1); -} - -/* Macro version of set_link (). */ -#define SET_LINK(X,Y) do { (X)->link[CHECK_BIT(&(Y)->p.u.prefix,(X)->p.prefixlen)] = (Y);\ - (Y)->parent = (X); } while (0) - static void set_link (struct route_node *node, struct route_node *new) { - int bit; - - bit = check_bit (&new->p.u.prefix, node->p.prefixlen); - - assert (bit == 0 || bit == 1); + unsigned int bit = prefix_bit (&new->p.u.prefix, node->p.prefixlen); node->link[bit] = new; new->parent = node; @@ -219,26 +192,9 @@ route_unlock_node (struct route_node *node) route_node_delete (node); } -/* Dump routing table. */ -static void __attribute__ ((unused)) -route_dump_node (struct route_table *t) -{ - struct route_node *node; - char buf[46]; - - for (node = route_top (t); node != NULL; node = route_next (node)) - { - printf ("[%d] %p %s/%d\n", - node->lock, - node->info, - inet_ntop (node->p.family, &node->p.u.prefix, buf, 46), - node->p.prefixlen); - } -} - /* Find matched prefix. */ struct route_node * -route_node_match (struct route_table *table, struct prefix *p) +route_node_match (const struct route_table *table, const struct prefix *p) { struct route_node *node; struct route_node *matched; @@ -253,7 +209,7 @@ route_node_match (struct route_table *table, struct prefix *p) { if (node->info) matched = node; - node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)]; + node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } /* If matched route found, return it. */ @@ -264,7 +220,8 @@ route_node_match (struct route_table *table, struct prefix *p) } struct route_node * -route_node_match_ipv4 (struct route_table *table, struct in_addr *addr) +route_node_match_ipv4 (const struct route_table *table, + const struct in_addr *addr) { struct prefix_ipv4 p; @@ -278,7 +235,8 @@ route_node_match_ipv4 (struct route_table *table, struct in_addr *addr) #ifdef HAVE_IPV6 struct route_node * -route_node_match_ipv6 (struct route_table *table, struct in6_addr *addr) +route_node_match_ipv6 (const struct route_table *table, + const struct in6_addr *addr) { struct prefix_ipv6 p; @@ -305,7 +263,7 @@ route_node_lookup (struct route_table *table, struct prefix *p) if (node->p.prefixlen == p->prefixlen && node->info) return route_lock_node (node); - node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)]; + node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } return NULL; @@ -330,7 +288,7 @@ route_node_get (struct route_table *table, struct prefix *p) return node; } match = node; - node = node->link[check_bit(&p->u.prefix, node->p.prefixlen)]; + node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } if (node == NULL) diff --git a/lib/table.h b/lib/table.h index 45ec6067..41d1fa70 100644 --- a/lib/table.h +++ b/lib/table.h @@ -66,13 +66,13 @@ extern struct route_node *route_node_get (struct route_table *, extern struct route_node *route_node_lookup (struct route_table *, struct prefix *); extern struct route_node *route_lock_node (struct route_node *node); -extern struct route_node *route_node_match (struct route_table *, - struct prefix *); -extern struct route_node *route_node_match_ipv4 (struct route_table *, - struct in_addr *); +extern struct route_node *route_node_match (const struct route_table *, + const struct prefix *); +extern struct route_node *route_node_match_ipv4 (const struct route_table *, + const struct in_addr *); #ifdef HAVE_IPV6 -extern struct route_node *route_node_match_ipv6 (struct route_table *, - struct in6_addr *); +extern struct route_node *route_node_match_ipv6 (const struct route_table *, + const struct in6_addr *); #endif /* HAVE_IPV6 */ #endif /* _ZEBRA_TABLE_H */ @@ -1694,6 +1694,7 @@ vty_accept (struct thread *thread) int accept_sock; struct prefix *p = NULL; struct access_list *acl = NULL; + char *bufp; accept_sock = THREAD_FD (thread); @@ -1766,6 +1767,11 @@ vty_accept (struct thread *thread) zlog (NULL, LOG_INFO, "can't set sockopt to vty_sock : %s", safe_strerror (errno)); + zlog (NULL, LOG_INFO, "Vty connection from %s", + (bufp = sockunion_su2str (&su))); + if (bufp) + XFREE (MTYPE_TMP, bufp); + vty = vty_create (vty_sock, &su); return 0; @@ -1812,6 +1818,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port) if (sock < 0) continue; + sockopt_v6only (ainfo->ai_family, sock); sockopt_reuseaddr (sock); sockopt_reuseport (sock); diff --git a/lib/zclient.c b/lib/zclient.c index d3d53227..0d531ce7 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -32,6 +32,7 @@ #include "zclient.h" #include "memory.h" #include "table.h" +#include "paths.h" /* Zebra client events. */ enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT}; @@ -317,7 +318,7 @@ zclient_start (struct zclient *zclient) #ifdef HAVE_TCP_ZEBRA zclient->sock = zclient_socket (); #else - zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH); + zclient->sock = zclient_socket_un (path_state (ZEBRA_SERV_NAME)); #endif /* HAVE_TCP_ZEBRA */ if (zclient->sock < 0) { diff --git a/lib/zclient.h b/lib/zclient.h index 21786ab8..6a63ffa4 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -28,6 +28,9 @@ /* For input/output buffer to zebra. */ #define ZEBRA_MAX_PACKET_SIZ 4096 +/* Name of the zebra API socket */ +#define ZEBRA_SERV_NAME "zserv.api" + /* Zebra header size. */ #define ZEBRA_HEADER_SIZE 6 diff --git a/lib/zebra.h b/lib/zebra.h index db247bd3..83f04294 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -431,20 +431,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_PIM 11 -#define ZEBRA_ROUTE_MAX 12 +/* 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 @@ -458,6 +446,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); |