summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am14
-rw-r--r--lib/command.c6
-rw-r--r--lib/if.h6
-rw-r--r--lib/log.c81
-rw-r--r--lib/md5.c73
-rw-r--r--lib/md5.h3
-rw-r--r--lib/paths.c65
-rw-r--r--lib/paths.h34
-rw-r--r--lib/prefix.c54
-rw-r--r--lib/prefix.h2
-rw-r--r--lib/route_types.awk187
-rwxr-xr-xlib/route_types.pl199
-rw-r--r--lib/route_types.txt17
-rw-r--r--lib/sockunion.c34
-rw-r--r--lib/sockunion.h2
-rw-r--r--lib/stream.c26
-rw-r--r--lib/stream.h4
-rw-r--r--lib/thread.c134
-rw-r--r--lib/thread.h5
-rw-r--r--lib/vty.c1
-rw-r--r--lib/zclient.c3
-rw-r--r--lib/zclient.h3
-rw-r--r--lib/zebra.h19
23 files changed, 648 insertions, 324 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 723e5dd4..a080e5e0 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -85,9 +85,9 @@ static struct cmd_node config_node =
/* Default motd string. */
static const char *default_motd =
"\r\n\
-Hello, this is " QUAGGA_PROGNAME " (version " QUAGGA_VERSION ").\r\n\
-" QUAGGA_COPYRIGHT "\r\n\
-\r\n";
+This is " QUAGGA_PROGNAME " " QUAGGA_VERSION "\r\n\r\n\
+You're using the dn42 branch. Send bug reports to equinox@diac24.net\r\n\
+The 1.1.0 version number is for package management purposes only.\r\n";
static const struct facility_map {
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 0c2f655b..b1f53a01 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -22,6 +22,8 @@
* 02111-1307, USA.
*/
+#define QUAGGA_DEFINE_DESC_TABLE
+
#include <zebra.h>
#include "log.h"
@@ -759,7 +761,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;
@@ -815,29 +817,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),
@@ -927,4 +906,58 @@ 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, "os", 2) == 0)
+ return ZEBRA_ROUTE_OSPF;
+ else if (strncmp (s, "i", 1) == 0)
+ return ZEBRA_ROUTE_ISIS;
+ else if (strncmp (s, "bg", 2) == 0)
+ return ZEBRA_ROUTE_BGP;
+ else if (strncmp (s, "ol", 2) == 0)
+ return ZEBRA_ROUTE_OLSR;
+ else if (strncmp (s, "ba", 2) == 0)
+ return ZEBRA_ROUTE_BATMAN;
+ else if (strncmp (s, "d", 1) == 0)
+ return ZEBRA_ROUTE_DHCP;
+ }
+ 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, "os", 2) == 0)
+ return ZEBRA_ROUTE_OSPF6;
+ else if (strncmp (s, "i", 1) == 0)
+ return ZEBRA_ROUTE_ISIS;
+ else if (strncmp (s, "bg", 2) == 0)
+ return ZEBRA_ROUTE_BGP;
+ else if (strncmp (s, "ol", 2) == 0)
+ return ZEBRA_ROUTE_OLSR;
+ else if (strncmp (s, "ba", 2) == 0)
+ return ZEBRA_ROUTE_BATMAN;
+ }
+ return -1;
+}
diff --git a/lib/md5.c b/lib/md5.c
index 894de648..2fc36e17 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -298,3 +298,76 @@ static void md5_calc(const uint8_t *b64, md5_ctxt * ctxt)
ctxt->md5_stc += C;
ctxt->md5_std += D;
}
+
+/* From RFC 2104 */
+void
+hmac_md5(text, text_len, key, key_len, digest)
+unsigned char* text; /* pointer to data stream */
+int text_len; /* length of data stream */
+unsigned char* key; /* pointer to authentication key */
+int key_len; /* length of authentication key */
+caddr_t digest; /* caller digest to be filled in */
+
+{
+ MD5_CTX context;
+ unsigned char k_ipad[65]; /* inner padding -
+ * key XORd with ipad
+ */
+ unsigned char k_opad[65]; /* outer padding -
+ * key XORd with opad
+ */
+ unsigned char tk[16];
+ int i;
+ /* if key is longer than 64 bytes reset it to key=MD5(key) */
+ if (key_len > 64) {
+
+ MD5_CTX tctx;
+
+ MD5Init(&tctx);
+ MD5Update(&tctx, key, key_len);
+ MD5Final(tk, &tctx);
+
+ key = tk;
+ key_len = 16;
+ }
+
+ /*
+ * the HMAC_MD5 transform looks like:
+ *
+ * MD5(K XOR opad, MD5(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected
+ */
+
+ /* start out by storing key in pads */
+ bzero( k_ipad, sizeof k_ipad);
+ bzero( k_opad, sizeof k_opad);
+ bcopy( key, k_ipad, key_len);
+ bcopy( key, k_opad, key_len);
+
+ /* XOR key with ipad and opad values */
+ for (i=0; i<64; i++) {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+ /*
+ * perform inner MD5
+ */
+ MD5Init(&context); /* init context for 1st
+ * pass */
+ MD5Update(&context, k_ipad, 64); /* start with inner pad */
+ MD5Update(&context, text, text_len); /* then text of datagram */
+ MD5Final(digest, &context); /* finish up 1st pass */
+ /*
+ * perform outer MD5
+ */
+ MD5Init(&context); /* init context for 2nd
+ * pass */
+ MD5Update(&context, k_opad, 64); /* start with outer pad */
+ MD5Update(&context, digest, 16); /* then results of 1st
+ * hash */
+ MD5Final(digest, &context); /* finish up 2nd pass */
+}
diff --git a/lib/md5.h b/lib/md5.h
index 89b9a320..3ce83a63 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -82,4 +82,7 @@ do { \
md5_result((x), (y)); \
} while (0)
+/* From RFC 2104 */
+void hmac_md5(unsigned char* text, int text_len, unsigned char* key, int key_len, caddr_t digest);
+
#endif /* ! _LIBZEBRA_MD5_H_*/
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 c85e6594..f5de4bde 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -180,6 +180,46 @@ prefix_cmp (const struct prefix *p1, const struct prefix *p2)
return 0;
}
+/*
+ * Count the number of common bits in 2 prefixes. The prefix length is
+ * ignored for this function; the whole prefix is compared. If the prefix
+ * address families don't match, return -1; otherwise the return value is
+ * in range 0 ... maximum prefix length for the address family.
+ */
+int
+prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
+{
+ int pos, bit;
+ int length = 0;
+ u_char xor;
+
+ /* Set both prefix's head pointer. */
+ const u_char *pp1 = (const u_char *)&p1->u.prefix;
+ const u_char *pp2 = (const u_char *)&p2->u.prefix;
+
+ if (p1->family == AF_INET)
+ length = IPV4_MAX_BYTELEN;
+#ifdef HAVE_IPV6
+ if (p1->family == AF_INET6)
+ length = IPV6_MAX_BYTELEN;
+#endif
+ if (p1->family != p2->family || !length)
+ return -1;
+
+ for (pos = 0; pos < length; pos++)
+ if (pp1[pos] != pp2[pos])
+ break;
+ if (pos == length)
+ return pos * 8;
+
+ xor = pp1[pos] ^ pp2[pos];
+ for (bit = 0; bit < 8; bit++)
+ if (xor & (1 << (7 - bit)))
+ break;
+
+ return pos * 8 + bit;
+}
+
/* Return prefix family type string. */
const char *
prefix_family_str (const struct prefix *p)
@@ -569,6 +609,20 @@ sockunion2hostprefix (const union sockunion *su)
return NULL;
}
+void
+prefix2sockunion (const struct prefix *p, union sockunion *su)
+{
+ memset (su, 0, sizeof (*su));
+
+ su->sa.sa_family = p->family;
+ if (p->family == AF_INET)
+ su->sin.sin_addr = p->u.prefix4;
+#ifdef HAVE_IPV6
+ if (p->family == AF_INET6)
+ memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
+#endif /* HAVE_IPV6 */
+}
+
int
prefix_blen (const struct prefix *p)
{
diff --git a/lib/prefix.h b/lib/prefix.h
index a7598b7e..f6259dee 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -156,12 +156,14 @@ extern int prefix2str (const struct prefix *, char *, int);
extern int prefix_match (const struct prefix *, const struct prefix *);
extern int prefix_same (const struct prefix *, const struct prefix *);
extern int prefix_cmp (const struct prefix *, const struct prefix *);
+extern int prefix_common_bits (const struct prefix *, const struct prefix *);
extern void prefix_copy (struct prefix *dest, const struct prefix *src);
extern void apply_mask (struct prefix *);
extern struct prefix *sockunion2prefix (const union sockunion *dest,
const union sockunion *mask);
extern struct prefix *sockunion2hostprefix (const union sockunion *);
+extern void prefix2sockunion (const struct prefix *, union sockunion *);
extern struct prefix_ipv4 *prefix_ipv4_new (void);
extern void prefix_ipv4_free (struct prefix_ipv4 *);
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..8111fc56 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
@@ -56,8 +56,10 @@ ZEBRA_ROUTE_BGP, bgp, bgpd, 'B', 1, 1, "BGP"
# This at least makes it trivial for users of these protocols
# 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_HSLS, hsls, hslsd, 'h', 1, 1, "HSLS"
+ZEBRA_ROUTE_OLSR, olsr, olsrd, 'o', 1, 1, "OLSR"
+ZEBRA_ROUTE_BATMAN, batman, batman, 'b', 1, 1, "BATMAN"
+ZEBRA_ROUTE_DHCP, dhcp, dhcpc, 'D', 1, 0, "DHCP"
## help strings
ZEBRA_ROUTE_SYSTEM, "Reserved route type, for internal use only"
@@ -72,3 +74,6 @@ ZEBRA_ROUTE_ISIS, "Intermediate System to Intermediate System (IS-IS)"
ZEBRA_ROUTE_BGP, "Border Gateway Protocol (BGP)"
ZEBRA_ROUTE_HSLS, "Hazy-Sighted Link State Protocol (HSLS)"
ZEBRA_ROUTE_OLSR, "Optimised Link State Routing (OLSR)"
+ZEBRA_ROUTE_BATMAN, "Better Approach To Mobile Ad-hoc Networking (BATMAN)"
+ZEBRA_ROUTE_DHCP, "Dynamic Host Configuration Protocol (DHCP)"
+
diff --git a/lib/sockunion.c b/lib/sockunion.c
index 6a40f332..5de3bcfc 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -527,6 +527,40 @@ 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;
+}
+
+int
+sockopt_cork (int sock, int onoff)
+{
+#ifdef TCP_CORK
+ return setsockopt (sock, IPPROTO_TCP, TCP_CORK, &onoff, sizeof(onoff));
+#else
+ return 0;
+#endif
+}
+
/* 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..2e8ce2d0 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -99,9 +99,11 @@ 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);
+extern int sockopt_cork (int sock, int onoff);
extern int sockunion_socket (union sockunion *su);
extern const char *inet_sutop (union sockunion *su, char *str);
extern enum connect_result sockunion_connect (int fd, union sockunion *su,
diff --git a/lib/stream.c b/lib/stream.c
index 983330ff..bff74d7b 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -711,32 +711,6 @@ stream_read (struct stream *s, int fd, size_t size)
return nbytes;
}
-/* Read size from fd. */
-int
-stream_read_unblock (struct stream *s, int fd, size_t size)
-{
- int nbytes;
- int val;
-
- STREAM_VERIFY_SANE(s);
-
- if (STREAM_WRITEABLE (s) < size)
- {
- STREAM_BOUND_WARN (s, "put");
- return 0;
- }
-
- val = fcntl (fd, F_GETFL, 0);
- fcntl (fd, F_SETFL, val|O_NONBLOCK);
- nbytes = read (fd, s->data + s->endp, size);
- fcntl (fd, F_SETFL, val);
-
- if (nbytes > 0)
- s->endp += nbytes;
-
- return nbytes;
-}
-
ssize_t
stream_read_try(struct stream *s, int fd, size_t size)
{
diff --git a/lib/stream.h b/lib/stream.h
index 3e4ba7b4..486a3f93 100644
--- a/lib/stream.h
+++ b/lib/stream.h
@@ -181,10 +181,6 @@ extern u_int32_t stream_get_ipv4 (struct stream *);
Use stream_read_try instead. */
extern int stream_read (struct stream *, int, size_t);
-/* Deprecated: all file descriptors should already be non-blocking.
- Will be removed. Use stream_read_try instead. */
-extern int stream_read_unblock (struct stream *, int, size_t);
-
/* Read up to size bytes into the stream.
Return code:
>0: number of bytes read
diff --git a/lib/thread.c b/lib/thread.c
index e89af541..1e714417 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -20,8 +20,9 @@
*/
/* #define DEBUG */
-
+#include <errno.h>
#include <zebra.h>
+#include <sys/times.h>
#include "thread.h"
#include "memory.h"
@@ -31,8 +32,7 @@
#include "sigevent.h"
/* Recent absolute time of day */
-struct timeval recent_time;
-static struct timeval last_recent_time;
+static struct timeval recent_time;
/* Relative time, since startup */
static struct timeval relative_time;
static struct timeval relative_time_base;
@@ -94,54 +94,98 @@ timeval_elapsed (struct timeval a, struct timeval b)
}
#ifndef HAVE_CLOCK_MONOTONIC
+static unsigned long recent_clock_mark; /* Holds value of last call to times(2) */
+static unsigned long last_clock_mark;
+static unsigned long clocks_per_sec, msec_scale, usec_scale;
+
+static unsigned long quagga_times(void)
+{
+#if defined(GNU_LINUX)
+ unsigned long ret;
+
+ errno = 0;
+ ret = times(NULL); /* Linux can handle NULL */
+ /* Workaround broken syscall impl.
+ * A bugfix exists for the kernel, hopefully
+ * it will make it into 2.6.28
+ */
+ if (errno)
+ ret = (unsigned long) (-errno);
+ return ret;
+#else
+ struct tms dummy; /* Only return value is used */
+
+ return times(&dummy);
+#endif
+}
+
static void
quagga_gettimeofday_relative_adjust (void)
{
- struct timeval diff;
- if (timeval_cmp (recent_time, last_recent_time) < 0)
- {
- relative_time.tv_sec++;
- relative_time.tv_usec = 0;
- }
- else
- {
- diff = timeval_subtract (recent_time, last_recent_time);
- relative_time.tv_sec += diff.tv_sec;
- relative_time.tv_usec += diff.tv_usec;
- relative_time = timeval_adjust (relative_time);
- }
- last_recent_time = recent_time;
+ unsigned long diff;
+
+ diff = recent_clock_mark - last_clock_mark;
+ if (!diff)
+ return;
+ /* save mark for next calculation */
+ last_clock_mark = recent_clock_mark;
+
+ relative_time.tv_sec += diff / clocks_per_sec; /* convert to seconds */
+ relative_time.tv_usec += (diff % clocks_per_sec) * usec_scale; /* convert to useconds */
+ relative_time = timeval_adjust (relative_time);
}
#endif /* !HAVE_CLOCK_MONOTONIC */
+static int init_quagga_timers(void)
+{
+ int ret;
+
+ ret = gettimeofday (&recent_time, NULL);
+ relative_time_base = recent_time;
+#if !defined(HAVE_CLOCK_MONOTONIC)
+ clocks_per_sec = sysconf(_SC_CLK_TCK);
+ assert(clocks_per_sec != 0);
+
+ /* Precondition: 1000 % clocks_per_sec == 0 */
+ assert(1000 % clocks_per_sec == 0);
+ msec_scale = 1000 / clocks_per_sec;
+
+ /* Precondition: TIMER_SECOND_MICRO % clocks_per_sec == 0 */
+ assert(TIMER_SECOND_MICRO % clocks_per_sec == 0);
+ usec_scale = TIMER_SECOND_MICRO / clocks_per_sec;
+ recent_clock_mark = quagga_times();
+ last_clock_mark = recent_clock_mark;
+#endif
+ if (ret)
+ return ret;
+ timers_inited = 1;
+ return 0;
+}
+
/* gettimeofday wrapper, to keep recent_time updated */
static int
quagga_gettimeofday (struct timeval *tv)
{
int ret;
-
- assert (tv);
-
- if (!(ret = gettimeofday (&recent_time, NULL)))
- {
- /* init... */
- if (!timers_inited)
- {
- relative_time_base = last_recent_time = recent_time;
- timers_inited = 1;
- }
- /* avoid copy if user passed recent_time pointer.. */
- if (tv != &recent_time)
- *tv = recent_time;
- return 0;
- }
- return ret;
+
+ /* init... */
+ if (!timers_inited)
+ ret = init_quagga_timers();
+ else
+ ret = gettimeofday (&recent_time, NULL);
+ if (ret)
+ return ret;
+
+ /* avoid copy if user passed recent_time pointer.. */
+ if (tv != &recent_time)
+ *tv = recent_time;
+ return 0;
}
static int
quagga_get_relative (struct timeval *tv)
{
- int ret;
+ int ret = 0;
#ifdef HAVE_CLOCK_MONOTONIC
{
@@ -153,8 +197,12 @@ quagga_get_relative (struct timeval *tv)
}
}
#else /* !HAVE_CLOCK_MONOTONIC */
- if (!(ret = quagga_gettimeofday (&recent_time)))
- quagga_gettimeofday_relative_adjust();
+ /* init... */
+ if (!timers_inited)
+ ret = init_quagga_timers();
+
+ recent_clock_mark = quagga_times();
+ quagga_gettimeofday_relative_adjust();
#endif /* HAVE_CLOCK_MONOTONIC */
if (tv)
@@ -910,7 +958,6 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
struct thread *thread;
fd_set readfd;
fd_set writefd;
- fd_set exceptfd;
struct timeval timer_val;
struct timeval timer_val_bg;
struct timeval *timer_wait;
@@ -936,7 +983,6 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
/* Structure copy. */
readfd = m->readfd;
writefd = m->writefd;
- exceptfd = m->exceptfd;
/* Calculate select wait timer if nothing else to do */
quagga_get_relative (NULL);
@@ -947,7 +993,7 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
(!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
timer_wait = timer_wait_bg;
- num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
+ num = select (FD_SETSIZE, &readfd, &writefd, NULL, timer_wait);
/* Signals should get quick treatment */
if (num < 0)
@@ -1028,14 +1074,6 @@ thread_getrusage (RUSAGE_T *r)
getrusage(RUSAGE_SELF, &(r->cpu));
#endif
r->real = relative_time;
-
-#ifdef HAVE_CLOCK_MONOTONIC
- /* quagga_get_relative() only updates recent_time if gettimeofday
- * based, not when using CLOCK_MONOTONIC. As we export recent_time
- * and guarantee to update it before threads are run...
- */
- quagga_gettimeofday(&recent_time);
-#endif /* HAVE_CLOCK_MONOTONIC */
}
/* We check thread consumed time. If the system has getrusage, we'll
diff --git a/lib/thread.h b/lib/thread.h
index b52bc541..a6aed173 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -53,7 +53,6 @@ struct thread_master
struct thread_list background;
fd_set readfd;
fd_set writefd;
- fd_set exceptfd;
unsigned long alloc;
};
@@ -209,10 +208,6 @@ extern time_t quagga_time (time_t *);
extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
unsigned long *cpu_time_elapsed);
-/* Global variable containing a recent result from gettimeofday. This can
- be used instead of calling gettimeofday if a recent value is sufficient.
- This is guaranteed to be refreshed before a thread is called. */
-extern struct timeval recent_time;
/* Similar to recent_time, but a monotonically increasing time value */
extern struct timeval recent_relative_time (void);
#endif /* _ZEBRA_THREAD_H */
diff --git a/lib/vty.c b/lib/vty.c
index e4818eb6..9c58b50d 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1816,6 +1816,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 2dc84514..b580934c 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -429,19 +429,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
@@ -455,6 +444,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);