summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am14
-rw-r--r--lib/command.c10
-rw-r--r--lib/if.h6
-rw-r--r--lib/log.c71
-rw-r--r--lib/md5.c3
-rw-r--r--lib/memory.h8
-rw-r--r--lib/paths.c65
-rw-r--r--lib/paths.h34
-rw-r--r--lib/prefix.c2
-rw-r--r--lib/prefix.h16
-rw-r--r--lib/route_types.awk187
-rwxr-xr-xlib/route_types.pl199
-rw-r--r--lib/route_types.txt10
-rw-r--r--lib/sockunion.c24
-rw-r--r--lib/sockunion.h1
-rw-r--r--lib/table.c62
-rw-r--r--lib/table.h12
-rw-r--r--lib/vty.c7
-rw-r--r--lib/zclient.c3
-rw-r--r--lib/zclient.h3
-rw-r--r--lib/zebra.h20
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
diff --git a/lib/if.h b/lib/if.h
index c99ab81b..1b29f470 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -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? */
diff --git a/lib/log.c b/lib/log.c
index b626170a..ea0571c5 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -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;
+}
diff --git a/lib/md5.c b/lib/md5.c
index f1bd0668..894de648 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -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 */
diff --git a/lib/vty.c b/lib/vty.c
index fd3377cf..cae22ae7 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -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);