quagga: remove babel

Ticket: CM-9274
Reviewed By: sharpd@cumulusnetworks.com
Testing Done:

<DETAILED DESCRIPTION (REPLACE)>
This commit is contained in:
Daniel Walton 2016-02-11 08:55:24 -08:00
parent b3556ea327
commit 41d9cc6a65
79 changed files with 43 additions and 9306 deletions

View file

@ -1,10 +1,10 @@
## Process this file with automake to produce Makefile.in.
SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ @BABELD@ \
SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ \
@ISISD@ @WATCHQUAGGA@ @VTYSH@ @OSPFCLIENT@ @DOC@ m4 @pkgsrcdir@ \
redhat @SOLARIS@ tests
DIST_SUBDIRS = lib zebra bgpd ripd ripngd ospfd ospf6d babeld \
DIST_SUBDIRS = lib zebra bgpd ripd ripngd ospfd ospf6d \
isisd watchquagga vtysh ospfclient doc m4 pkgsrc redhat tests \
solaris

7
babeld/.gitignore vendored
View file

@ -1,7 +0,0 @@
*
!*.c
!*.h
!LICENCE
!Makefile.am
!babeld.conf.sample
!.gitignore

View file

@ -1,36 +0,0 @@
Code in this directory is made available under the following licence:
---------------------------------------------------------------------------
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---------------------------------------------------------------------------
The code also makes calls to and links with the "libzebra" code of Quagga,
in the lib/ directory of this project, which is subject to the GPL licence
as given in the top-level COPYING file included with Quagga.
Contributors to the code in babeld/ are asked to make their work available
under the same MIT/X11 licence as given immediately above. Please indicate
your assent to this by updating this file and appending the appropriate
Copyright <year> <Author name>, <author contact details>
line to the existing copyright assertion lines in the MIT/X11 licence text
above in this file.

View file

@ -1,29 +0,0 @@
## Process this file with automake to produce Makefile.in.
INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600
AM_CFLAGS = $(PICFLAGS) $(WERROR)
AM_LDFLAGS = $(PILDFLAGS)
noinst_LIBRARIES = libbabel.a
sbin_PROGRAMS = babeld
libbabel_a_SOURCES = \
babel_zebra.c net.c kernel.c util.c source.c neighbour.c \
route.c xroute.c message.c resend.c babel_interface.c babeld.c \
babel_filter.c
noinst_HEADERS = \
babel_zebra.h net.h kernel.h util.h source.h neighbour.h \
route.h xroute.h message.h resend.h babel_interface.h babeld.h \
babel_filter.h babel_main.h
babeld_SOURCES = \
babel_main.c $(libbabel_a_SOURCES)
babeld_LDADD = ../lib/libzebra.la @LIBCAP@
examplesdir = $(exampledir)
dist_examples_DATA = babeld.conf.sample

View file

@ -1,124 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "babel_filter.h"
#include "vty.h"
#include "filter.h"
#include "log.h"
#include "plist.h"
#include "distribute.h"
#include "util.h"
int
babel_filter(int output, const unsigned char *prefix, unsigned short plen,
unsigned int ifindex)
{
struct interface *ifp = if_lookup_by_index(ifindex);
babel_interface_nfo *babel_ifp = ifp ? babel_get_if_nfo(ifp) : NULL;
struct prefix p;
struct distribute *dist;
struct access_list *alist;
struct prefix_list *plist;
int filter = output ? BABEL_FILTER_OUT : BABEL_FILTER_IN;
int distribute = output ? DISTRIBUTE_OUT : DISTRIBUTE_IN;
p.family = v4mapped(prefix) ? AF_INET : AF_INET6;
p.prefixlen = v4mapped(prefix) ? plen - 96 : plen;
if (p.family == AF_INET)
uchar_to_inaddr(&p.u.prefix4, prefix);
else
uchar_to_in6addr(&p.u.prefix6, prefix);
if (babel_ifp != NULL && babel_ifp->list[filter]) {
if (access_list_apply (babel_ifp->list[filter], &p)
== FILTER_DENY) {
debugf(BABEL_DEBUG_FILTER,
"%s/%d filtered by distribute in",
p.family == AF_INET ?
inet_ntoa(p.u.prefix4) :
inet6_ntoa (p.u.prefix6),
p.prefixlen);
return INFINITY;
}
}
if (babel_ifp != NULL && babel_ifp->prefix[filter]) {
if (prefix_list_apply (babel_ifp->prefix[filter], &p)
== PREFIX_DENY) {
debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in",
p.family == AF_INET ?
inet_ntoa(p.u.prefix4) :
inet6_ntoa (p.u.prefix6),
p.prefixlen);
return INFINITY;
}
}
/* All interface filter check. */
dist = distribute_lookup (NULL);
if (dist) {
if (dist->list[distribute]) {
alist = access_list_lookup (AFI_IP6, dist->list[distribute]);
if (alist) {
if (access_list_apply (alist, &p) == FILTER_DENY) {
debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in",
p.family == AF_INET ?
inet_ntoa(p.u.prefix4) :
inet6_ntoa (p.u.prefix6),
p.prefixlen);
return INFINITY;
}
}
}
if (dist->prefix[distribute]) {
plist = prefix_list_lookup (AFI_IP6, dist->prefix[distribute]);
if (plist) {
if (prefix_list_apply (plist, &p) == PREFIX_DENY) {
debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in",
p.family == AF_INET ?
inet_ntoa(p.u.prefix4) :
inet6_ntoa (p.u.prefix6),
p.prefixlen);
return INFINITY;
}
}
}
}
return 0;
}

View file

@ -1,49 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef BABELD_BABEL_FILTER_H
#define BABELD_BABEL_FILTER_H
#include <zebra.h>
#include "prefix.h"
#include "babel_interface.h"
int babel_filter(int output, const unsigned char *prefix, unsigned short plen,
unsigned int index);
#endif /* BABELD_BABEL_FILTER_H */

File diff suppressed because it is too large Load diff

View file

@ -1,152 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef BABEL_INTERFACE_H
#define BABEL_INTERFACE_H
#include <zebra.h>
#include "zclient.h"
#include "vty.h"
#define CONFIG_DEFAULT 0
#define CONFIG_NO 1
#define CONFIG_YES 2
/* babeld interface informations */
struct babel_interface {
unsigned short flags; /* see below */
unsigned short cost;
int channel;
struct timeval hello_timeout;
struct timeval update_timeout;
struct timeval flush_timeout;
struct timeval update_flush_timeout;
unsigned char *ipv4;
int buffered;
int bufsize;
char have_buffered_hello;
char have_buffered_id;
char have_buffered_nh;
char have_buffered_prefix;
unsigned char buffered_id[16];
unsigned char buffered_nh[4];
unsigned char buffered_prefix[16];
unsigned char *sendbuf;
struct buffered_update *buffered_updates;
int num_buffered_updates;
int update_bufsize;
time_t bucket_time;
unsigned int bucket;
time_t last_update_time;
unsigned short hello_seqno;
unsigned hello_interval;
unsigned update_interval;
/* For filter type slot. */
#define BABEL_FILTER_IN 0
#define BABEL_FILTER_OUT 1
#define BABEL_FILTER_MAX 2
struct access_list *list[BABEL_FILTER_MAX]; /* Access-list. */
struct prefix_list *prefix[BABEL_FILTER_MAX]; /* Prefix-list. */
};
typedef struct babel_interface babel_interface_nfo;
static inline babel_interface_nfo* babel_get_if_nfo(struct interface *ifp)
{
return ((babel_interface_nfo*) ifp->info);
}
/* babel_interface_nfo flags */
#define BABEL_IF_IS_UP (1 << 0)
#define BABEL_IF_WIRED (1 << 1)
#define BABEL_IF_SPLIT_HORIZON (1 << 2)
#define BABEL_IF_LQ (1 << 3)
#define BABEL_IF_FARAWAY (1 << 4)
/* Only INTERFERING can appear on the wire. */
#define BABEL_IF_CHANNEL_UNKNOWN 0
#define BABEL_IF_CHANNEL_INTERFERING 255
#define BABEL_IF_CHANNEL_NONINTERFERING -2
static inline int
if_up(struct interface *ifp)
{
return (if_is_operative(ifp) &&
ifp->connected != NULL &&
(babel_get_if_nfo(ifp)->flags & BABEL_IF_IS_UP));
}
/* types:
struct interface _ifp, struct listnode node */
#define FOR_ALL_INTERFACES(_ifp, _node) \
for(ALL_LIST_ELEMENTS_RO(iflist, _node, _ifp))
/* types:
struct interface *ifp, struct connected *_connected, struct listnode *node */
#define FOR_ALL_INTERFACES_ADDRESSES(ifp, _connected, _node) \
for(ALL_LIST_ELEMENTS_RO(ifp->connected, _node, _connected))
struct buffered_update {
unsigned char id[8];
unsigned char prefix[16];
unsigned char plen;
unsigned char pad[3];
};
/* init function */
void babel_if_init(void);
/* Callback functions for zebra client */
int babel_interface_up (int, struct zclient *, zebra_size_t, vrf_id_t);
int babel_interface_down (int, struct zclient *, zebra_size_t, vrf_id_t);
int babel_interface_add (int, struct zclient *, zebra_size_t, vrf_id_t);
int babel_interface_delete (int, struct zclient *, zebra_size_t, vrf_id_t);
int babel_interface_address_add (int, struct zclient *, zebra_size_t, vrf_id_t);
int babel_interface_address_delete (int, struct zclient *, zebra_size_t, vrf_id_t);
unsigned jitter(babel_interface_nfo *, int);
unsigned update_jitter(babel_interface_nfo *babel_ifp, int urgent);
/* return "true" if "address" is one of our ipv6 addresses */
int is_interface_ll_address(struct interface *ifp, const unsigned char *address);
/* Send retraction to all, and reset all interfaces statistics. */
void babel_interface_close_all(void);
extern int babel_enable_if_config_write (struct vty *);
#endif

View file

@ -1,533 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* include zebra library */
#include <zebra.h>
#include "getopt.h"
#include "if.h"
#include "log.h"
#include "thread.h"
#include "privs.h"
#include "sigevent.h"
#include "version.h"
#include "command.h"
#include "vty.h"
#include "memory.h"
#include "systemd.h"
#include "babel_main.h"
#include "babeld.h"
#include "util.h"
#include "kernel.h"
#include "babel_interface.h"
#include "neighbour.h"
#include "route.h"
#include "xroute.h"
#include "message.h"
#include "resend.h"
#include "babel_zebra.h"
static void babel_init (int argc, char **argv);
static char *babel_get_progname(char *argv_0);
static void babel_fail(void);
static void babel_init_random(void);
static void babel_replace_by_null(int fd);
static void babel_init_signals(void);
static void babel_exit_properly(void);
static void babel_save_state_file(void);
struct thread_master *master; /* quagga's threads handler */
struct timeval babel_now; /* current time */
unsigned char myid[8]; /* unique id (mac address of an interface) */
int debug = 0;
int resend_delay = -1;
static const char *pidfile = PATH_BABELD_PID;
const unsigned char zeroes[16] = {0};
const unsigned char ones[16] =
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static const char *state_file = DAEMON_VTY_DIR "/babel-state";
unsigned char protocol_group[16]; /* babel's link-local multicast address */
int protocol_port; /* babel's port */
int protocol_socket = -1; /* socket: communicate with others babeld */
static char babel_config_default[] = SYSCONFDIR BABEL_DEFAULT_CONFIG;
static char *babel_config_file = NULL;
static char *babel_vty_addr = NULL;
static int babel_vty_port = BABEL_VTY_PORT;
/* Babeld options. */
struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
{ "config_file", required_argument, NULL, 'f'},
{ "pid_file", required_argument, NULL, 'i'},
{ "socket", required_argument, NULL, 'z'},
{ "help", no_argument, NULL, 'h'},
{ "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'},
{ "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'},
{ "version", no_argument, NULL, 'v'},
{ 0 }
};
/* babeld privileges */
static zebra_capabilities_t _caps_p [] =
{
ZCAP_NET_RAW,
ZCAP_BIND
};
static struct zebra_privs_t babeld_privs =
{
#if defined(QUAGGA_USER)
.user = QUAGGA_USER,
#endif
#if defined QUAGGA_GROUP
.group = QUAGGA_GROUP,
#endif
#ifdef VTY_GROUP
.vty_group = VTY_GROUP,
#endif
.caps_p = _caps_p,
.cap_num_p = 2,
.cap_num_i = 0
};
int
main(int argc, char **argv)
{
struct thread thread;
/* and print banner too */
babel_init(argc, argv);
while (thread_fetch (master, &thread)) {
thread_call (&thread);
}
return 0;
}
static void
babel_usage (char *progname, int status)
{
if (status != 0)
fprintf (stderr, "Try `%s --help' for more information.\n", progname);
else
{
printf ("Usage : %s [OPTION...]\n\
Daemon which manages Babel routing protocol.\n\n\
-d, --daemon Runs in daemon mode\n\
-f, --config_file Set configuration file name\n\
-i, --pid_file Set process identifier file name\n\
-z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\
-u, --user User to run as\n\
-g, --group Group to run as\n\
-v, --version Print program version\n\
-h, --help Display this help and exit\n\
\n\
Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
}
exit (status);
}
/* make initialisations witch don't need infos about kernel(interfaces, etc.) */
static void
babel_init(int argc, char **argv)
{
int rc, opt;
int do_daemonise = 0;
char *progname = NULL;
/* Set umask before anything for security */
umask (0027);
progname = babel_get_progname(argv[0]);
/* set default log (lib/log.h) */
zlog_default = openzlog(progname, ZLOG_BABEL, 0,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
/* set log destination as stdout until the config file is read */
zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
babel_init_random();
/* set the Babel's default link-local multicast address and Babel's port */
parse_address("ff02:0:0:0:0:0:1:6", protocol_group, NULL);
protocol_port = 6696;
/* get options */
while(1) {
opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:v", longopts, 0);
if(opt < 0)
break;
switch(opt) {
case 0:
break;
case 'd':
do_daemonise = -1;
break;
case 'f':
babel_config_file = optarg;
break;
case 'i':
pidfile = optarg;
break;
case 'z':
zclient_serv_path_set (optarg);
break;
case 'A':
babel_vty_addr = optarg;
break;
case 'P':
babel_vty_port = atoi (optarg);
if (babel_vty_port <= 0 || babel_vty_port > 0xffff)
babel_vty_port = BABEL_VTY_PORT;
break;
case 'u':
babeld_privs.user = optarg;
break;
case 'g':
babeld_privs.group = optarg;
break;
case 'v':
print_version (progname);
exit (0);
break;
case 'h':
babel_usage (progname, 0);
break;
default:
babel_usage (progname, 1);
break;
}
}
/* create the threads handler */
master = thread_master_create ();
/* Library inits. */
zprivs_init (&babeld_privs);
babel_init_signals();
cmd_init (1);
vty_init (master);
memory_init ();
resend_delay = BABEL_DEFAULT_RESEND_DELAY;
babel_replace_by_null(STDIN_FILENO);
if (do_daemonise && daemonise() < 0) {
zlog_err("daemonise: %s", safe_strerror(errno));
exit (1);
}
/* write pid file */
if (pid_output(pidfile) < 0) {
zlog_err("error while writing pidfile");
exit (1);
};
systemd_send_started (master);
/* init some quagga's dependencies, and babeld's commands */
babeld_quagga_init();
/* init zebra client's structure and it's commands */
/* this replace kernel_setup && kernel_setup_socket */
babelz_zebra_init(master);
/* Get zebra configuration file. */
zlog_set_level (NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
vty_read_config (babel_config_file, babel_config_default);
/* Create VTY socket */
vty_serv_sock (babel_vty_addr, babel_vty_port, BABEL_VTYSH_PATH);
/* init buffer */
rc = resize_receive_buffer(1500);
if(rc < 0)
babel_fail();
schedule_neighbours_check(5000, 1);
zlog_notice ("BABELd %s starting: vty@%d", BABEL_VERSION, babel_vty_port);
}
/* return the progname (without path, example: "./x/progname" --> "progname") */
static char *
babel_get_progname(char *argv_0) {
char *p = strrchr (argv_0, '/');
return (p ? ++p : argv_0);
}
static void
babel_fail(void)
{
systemd_send_stopping ();
exit(1);
}
/* initialize random value, and set 'babel_now' by the way. */
static void
babel_init_random(void)
{
gettime(&babel_now);
int rc;
unsigned int seed;
rc = read_random_bytes(&seed, sizeof(seed));
if(rc < 0) {
zlog_err("read(random): %s", safe_strerror(errno));
seed = 42;
}
seed ^= (babel_now.tv_sec ^ babel_now.tv_usec);
srandom(seed);
}
/*
close fd, and replace it by "/dev/null"
exit if error
*/
static void
babel_replace_by_null(int fd)
{
int fd_null;
int rc;
fd_null = open("/dev/null", O_RDONLY);
if(fd_null < 0) {
zlog_err("open(null): %s", safe_strerror(errno));
exit(1);
}
rc = dup2(fd_null, fd);
if(rc < 0) {
zlog_err("dup2(null, 0): %s", safe_strerror(errno));
exit(1);
}
close(fd_null);
}
/*
Load the state file: check last babeld's running state, usefull in case of
"/etc/init.d/babeld restart"
*/
void
babel_load_state_file(void)
{
int fd;
int rc;
fd = open(state_file, O_RDONLY);
if(fd < 0 && errno != ENOENT)
zlog_err("open(babel-state: %s)", safe_strerror(errno));
rc = unlink(state_file);
if(fd >= 0 && rc < 0) {
zlog_err("unlink(babel-state): %s", safe_strerror(errno));
/* If we couldn't unlink it, it's probably stale. */
close(fd);
fd = -1;
}
if(fd >= 0) {
char buf[100];
char buf2[100];
int s;
long t;
rc = read(fd, buf, 99);
if(rc < 0) {
zlog_err("read(babel-state): %s", safe_strerror(errno));
} else {
buf[rc] = '\0';
rc = sscanf(buf, "%99s %d %ld\n", buf2, &s, &t);
if(rc == 3 && s >= 0 && s <= 0xFFFF) {
unsigned char sid[8];
rc = parse_eui64(buf2, sid);
if(rc < 0) {
zlog_err("Couldn't parse babel-state.");
} else {
struct timeval realnow;
debugf(BABEL_DEBUG_COMMON,
"Got %s %d %ld from babel-state.",
format_eui64(sid), s, t);
gettimeofday(&realnow, NULL);
if(memcmp(sid, myid, 8) == 0)
myseqno = seqno_plus(s, 1);
else
zlog_err("ID mismatch in babel-state. id=%s; old=%s",
format_eui64(myid),
format_eui64(sid));
}
} else {
zlog_err("Couldn't parse babel-state.");
}
}
close(fd);
fd = -1;
}
}
static void
babel_sigexit(void)
{
zlog_notice("Terminating on signal");
babel_exit_properly();
}
static void
babel_sigusr1 (void)
{
zlog_rotate (NULL);
}
static void
babel_init_signals(void)
{
static struct quagga_signal_t babel_signals[] =
{
{
.signal = SIGUSR1,
.handler = &babel_sigusr1,
},
{
.signal = SIGINT,
.handler = &babel_sigexit,
},
{
.signal = SIGTERM,
.handler = &babel_sigexit,
},
};
signal_init (master, array_size(babel_signals), babel_signals);
}
static void
babel_exit_properly(void)
{
debugf(BABEL_DEBUG_COMMON, "Exiting...");
usleep(roughly(10000));
gettime(&babel_now);
/* Uninstall and flush all routes. */
debugf(BABEL_DEBUG_COMMON, "Uninstall routes.");
flush_all_routes();
babel_interface_close_all();
babel_zebra_close_connexion();
babel_save_state_file();
debugf(BABEL_DEBUG_COMMON, "Remove pid file.");
if(pidfile)
unlink(pidfile);
debugf(BABEL_DEBUG_COMMON, "Done.");
systemd_send_stopping ();
exit(0);
}
static void
babel_save_state_file(void)
{
int fd;
int rc;
debugf(BABEL_DEBUG_COMMON, "Save state file.");
fd = open(state_file, O_WRONLY | O_TRUNC | O_CREAT, 0644);
if(fd < 0) {
zlog_err("creat(babel-state): %s", safe_strerror(errno));
unlink(state_file);
} else {
struct timeval realnow;
char buf[100];
gettimeofday(&realnow, NULL);
rc = snprintf(buf, 100, "%s %d %ld\n",
format_eui64(myid), (int)myseqno,
(long)realnow.tv_sec);
if(rc < 0 || rc >= 100) {
zlog_err("write(babel-state): overflow.");
unlink(state_file);
} else {
rc = write(fd, buf, rc);
if(rc < 0) {
zlog_err("write(babel-state): %s", safe_strerror(errno));
unlink(state_file);
}
fsync(fd);
}
close(fd);
}
}
void
show_babel_main_configuration (struct vty *vty)
{
vty_out(vty,
"pid file = %s%s"
"state file = %s%s"
"configuration file = %s%s"
"protocol informations:%s"
" multicast address = %s%s"
" port = %d%s"
"vty address = %s%s"
"vty port = %d%s"
"id = %s%s"
"allow_duplicates = %s%s"
"kernel_metric = %d%s",
pidfile, VTY_NEWLINE,
state_file, VTY_NEWLINE,
babel_config_file ? babel_config_file : babel_config_default,
VTY_NEWLINE,
VTY_NEWLINE,
format_address(protocol_group), VTY_NEWLINE,
protocol_port, VTY_NEWLINE,
babel_vty_addr ? babel_vty_addr : "None",
VTY_NEWLINE,
babel_vty_port, VTY_NEWLINE,
format_eui64(myid), VTY_NEWLINE,
format_bool(allow_duplicates), VTY_NEWLINE,
kernel_metric, VTY_NEWLINE);
}

View file

@ -1,57 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "vty.h"
extern struct timeval babel_now; /* current time */
extern struct thread_master *master; /* quagga's threads handler */
extern int debug;
extern int resend_delay;
extern unsigned char myid[8];
extern const unsigned char zeroes[16], ones[16];
extern int protocol_port;
extern unsigned char protocol_group[16];
extern int protocol_socket;
extern int kernel_socket;
extern int max_request_hopcount;
void babel_load_state_file(void);
void show_babel_main_configuration (struct vty *vty);

View file

@ -1,388 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* quagga's includes */
#include <zebra.h>
#include "command.h"
#include "zclient.h"
#include "stream.h"
/* babel's includes*/
#include "babel_zebra.h"
#include "babel_interface.h"
#include "xroute.h"
#include "util.h"
/* we must use a pointer because of zclient.c's functions (new, free). */
struct zclient *zclient;
static int zebra_config_write (struct vty *vty);
/* Debug types */
static struct {
int type;
int str_min_len;
const char *str;
} debug_type[] = {
{BABEL_DEBUG_COMMON, 1, "common"},
{BABEL_DEBUG_KERNEL, 1, "kernel"},
{BABEL_DEBUG_FILTER, 1, "filter"},
{BABEL_DEBUG_TIMEOUT, 1, "timeout"},
{BABEL_DEBUG_IF, 1, "interface"},
{BABEL_DEBUG_ROUTE, 1, "route"},
{BABEL_DEBUG_ALL, 1, "all"},
{0, 0, NULL}
};
/* Zebra node structure. */
struct cmd_node zebra_node =
{
ZEBRA_NODE,
"%s(config-router)# ",
1 /* vtysh? yes */
};
/* Zebra route add and delete treatment (ipv6). */
static int
babel_zebra_read_ipv6 (int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct stream *s;
struct zapi_ipv6 api;
unsigned long ifindex = -1;
struct in6_addr nexthop;
struct prefix_ipv6 prefix;
s = zclient->ibuf;
ifindex = 0;
memset (&nexthop, 0, sizeof (struct in6_addr));
memset (&api, 0, sizeof(struct zapi_ipv6));
memset (&prefix, 0, sizeof (struct prefix_ipv6));
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
/* IPv6 prefix. */
prefix.family = AF_INET6;
prefix.prefixlen = stream_getc (s);
stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
api.nexthop_num = stream_getc (s);
stream_get (&nexthop, s, sizeof(nexthop));
}
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
api.ifindex_num = stream_getc (s);
ifindex = stream_getl (s);
}
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
api.distance = stream_getc (s);
else
api.distance = 0;
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
api.metric = stream_getl (s);
else
api.metric = 0;
if (command == ZEBRA_IPV6_ROUTE_ADD)
babel_ipv6_route_add(&api, &prefix, ifindex, &nexthop);
else
babel_ipv6_route_delete(&api, &prefix, ifindex);
return 0;
}
static int
babel_zebra_read_ipv4 (int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct stream *s;
struct zapi_ipv4 api;
unsigned long ifindex = -1;
struct in_addr nexthop;
struct prefix_ipv4 prefix;
s = zclient->ibuf;
ifindex = 0;
memset (&nexthop, 0, sizeof (struct in_addr));
memset (&api, 0, sizeof(struct zapi_ipv4));
memset (&prefix, 0, sizeof (struct prefix_ipv4));
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
/* IPv6 prefix. */
prefix.family = AF_INET;
prefix.prefixlen = stream_getc (s);
stream_get (&prefix.prefix, s, PSIZE (prefix.prefixlen));
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
api.nexthop_num = stream_getc (s);
stream_get (&nexthop, s, sizeof(nexthop));
}
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
api.ifindex_num = stream_getc (s);
ifindex = stream_getl (s);
}
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
api.distance = stream_getc (s);
else
api.distance = 0;
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
api.metric = stream_getl (s);
else
api.metric = 0;
if (command == ZEBRA_IPV6_ROUTE_ADD) {
babel_ipv4_route_add(&api, &prefix, ifindex, &nexthop);
} else {
babel_ipv4_route_delete(&api, &prefix, ifindex);
}
return 0;
}
/* [Babel Command] */
DEFUN (babel_redistribute_type,
babel_redistribute_type_cmd,
"redistribute " QUAGGA_REDIST_STR_BABELD,
"Redistribute\n"
QUAGGA_REDIST_HELP_STR_BABELD)
{
int type;
afi_t afi;
afi = AFI_IP6;
type = proto_redistnum(afi, argv[0]);
if (type < 0)
{
afi = AFI_IP;
type = proto_redistnum(afi, argv[0]);
}
if (type < 0) {
vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT);
return CMD_SUCCESS;
}
/* [Babel Command] */
DEFUN (no_babel_redistribute_type,
no_babel_redistribute_type_cmd,
"no redistribute " QUAGGA_REDIST_STR_BABELD,
NO_STR
"Redistribute\n"
QUAGGA_REDIST_HELP_STR_BABELD)
{
int type;
afi_t afi;
afi = AFI_IP6;
type = proto_redistnum(afi, argv[0]);
if (type < 0)
{
afi = AFI_IP;
type = proto_redistnum(afi, argv[0]);
}
if (type < 0) {
vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT);
/* perhaps should we remove xroutes having the same type... */
return CMD_SUCCESS;
}
#ifndef NO_DEBUG
/* [Babel Command] */
DEFUN (debug_babel,
debug_babel_cmd,
"debug babel (common|kernel|filter|timeout|interface|route|all)",
"Enable debug messages for specific or all part.\n"
"Babel information\n"
"Common messages (default)\n"
"Kernel messages\n"
"Filter messages\n"
"Timeout messages\n"
"Interface messages\n"
"Route messages\n"
"All messages\n")
{
int i;
for(i = 0; debug_type[i].str != NULL; i++) {
if (strncmp (debug_type[i].str, argv[0],
debug_type[i].str_min_len) == 0) {
debug |= debug_type[i].type;
return CMD_SUCCESS;
}
}
vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
/* [Babel Command] */
DEFUN (no_debug_babel,
no_debug_babel_cmd,
"no debug babel (common|kernel|filter|timeout|interface|route|all)",
NO_STR
"Disable debug messages for specific or all part.\n"
"Babel information\n"
"Common messages (default)\n"
"Kernel messages\n"
"Filter messages\n"
"Timeout messages\n"
"Interface messages\n"
"Route messages\n"
"All messages\n")
{
int i;
for (i = 0; debug_type[i].str; i++) {
if (strncmp(debug_type[i].str, argv[0],
debug_type[i].str_min_len) == 0) {
debug &= ~debug_type[i].type;
return CMD_SUCCESS;
}
}
vty_out(vty, "Invalid type %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
#endif /* NO_DEBUG */
/* Output "debug" statement lines, if necessary. */
int
debug_babel_config_write (struct vty * vty)
{
#ifdef NO_DEBUG
return 0;
#else
int i, lines = 0;
if (debug == BABEL_DEBUG_ALL)
{
vty_out (vty, "debug babel all%s", VTY_NEWLINE);
lines++;
}
else
for (i = 0; debug_type[i].str != NULL; i++)
if
(
debug_type[i].type != BABEL_DEBUG_ALL
&& CHECK_FLAG (debug, debug_type[i].type)
)
{
vty_out (vty, "debug babel %s%s", debug_type[i].str, VTY_NEWLINE);
lines++;
}
if (lines)
{
vty_out (vty, "!%s", VTY_NEWLINE);
lines++;
}
return lines;
#endif /* NO_DEBUG */
}
void babelz_zebra_init (struct thread_master *master)
{
zclient = zclient_new(master);
zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
zclient->interface_add = babel_interface_add;
zclient->interface_delete = babel_interface_delete;
zclient->interface_up = babel_interface_up;
zclient->interface_down = babel_interface_down;
zclient->interface_address_add = babel_interface_address_add;
zclient->interface_address_delete = babel_interface_address_delete;
zclient->ipv4_route_add = babel_zebra_read_ipv4;
zclient->ipv4_route_delete = babel_zebra_read_ipv4;
zclient->ipv6_route_add = babel_zebra_read_ipv6;
zclient->ipv6_route_delete = babel_zebra_read_ipv6;
install_node (&zebra_node, zebra_config_write);
install_element(BABEL_NODE, &babel_redistribute_type_cmd);
install_element(BABEL_NODE, &no_babel_redistribute_type_cmd);
install_element(ENABLE_NODE, &debug_babel_cmd);
install_element(ENABLE_NODE, &no_debug_babel_cmd);
install_element(CONFIG_NODE, &debug_babel_cmd);
install_element(CONFIG_NODE, &no_debug_babel_cmd);
}
static int
zebra_config_write (struct vty *vty)
{
if (! zclient->enable)
{
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
return 1;
}
else if (! (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BABEL], VRF_DEFAULT) ||
vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_BABEL], VRF_DEFAULT)))
{
vty_out (vty, "router zebra%s", VTY_NEWLINE);
vty_out (vty, " no redistribute babel%s", VTY_NEWLINE);
return 1;
}
return 0;
}
void
babel_zebra_close_connexion(void)
{
zclient_stop(zclient);
}

View file

@ -1,50 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef BABEL_ZEBRA_H
#define BABEL_ZEBRA_H
#include "vty.h"
extern struct zclient *zclient;
void babelz_zebra_init(struct thread_master *);
void babel_zebra_close_connexion(void);
extern int debug_babel_config_write (struct vty *);
#endif

View file

@ -1,732 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <zebra.h>
#include "command.h"
#include "prefix.h"
#include "memory.h"
#include "memtypes.h"
#include "table.h"
#include "distribute.h"
#include "prefix.h"
#include "filter.h"
#include "plist.h"
#include "babel_main.h"
#include "babeld.h"
#include "util.h"
#include "net.h"
#include "kernel.h"
#include "babel_interface.h"
#include "neighbour.h"
#include "route.h"
#include "message.h"
#include "resend.h"
#include "babel_filter.h"
#include "babel_zebra.h"
#include "vrf.h"
static int babel_init_routing_process(struct thread *thread);
static void babel_get_myid(void);
static void babel_initial_noise(void);
static int babel_read_protocol (struct thread *thread);
static int babel_main_loop(struct thread *thread);
static void babel_set_timer(struct timeval *timeout);
static void babel_fill_with_next_timeout(struct timeval *tv);
/* Informations relative to the babel running daemon. */
static struct babel *babel_routing_process = NULL;
static unsigned char *receive_buffer = NULL;
static int receive_buffer_size = 0;
/* timeouts */
struct timeval check_neighbours_timeout;
static time_t expiry_time;
static time_t source_expiry_time;
/* Babel node structure. */
static struct cmd_node cmd_babel_node =
{
.node = BABEL_NODE,
.prompt = "%s(config-router)# ",
.vtysh = 1,
};
/* print current babel configuration on vty */
static int
babel_config_write (struct vty *vty)
{
int lines = 0;
int i;
afi_t afi;
/* list enabled debug modes */
lines += debug_babel_config_write (vty);
if (!babel_routing_process)
return lines;
vty_out (vty, "router babel%s", VTY_NEWLINE);
if (resend_delay != BABEL_DEFAULT_RESEND_DELAY)
{
vty_out (vty, " babel resend-delay %u%s", resend_delay, VTY_NEWLINE);
lines++;
}
/* list enabled interfaces */
lines = 1 + babel_enable_if_config_write (vty);
/* list redistributed protocols */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != zclient->redist_default &&
vrf_bitmap_check (zclient->redist[afi][i], VRF_DEFAULT) )
{
vty_out (vty, " redistribute %s%s", zebra_route_string (i), VTY_NEWLINE);
lines++;
}
return lines;
}
static int
babel_create_routing_process (void)
{
assert (babel_routing_process == NULL);
/* Allocaste Babel instance. */
babel_routing_process = XCALLOC (MTYPE_BABEL, sizeof (struct babel));
/* Initialize timeouts */
gettime(&babel_now);
expiry_time = babel_now.tv_sec + roughly(30);
source_expiry_time = babel_now.tv_sec + roughly(300);
/* Make socket for Babel protocol. */
protocol_socket = babel_socket(protocol_port);
if (protocol_socket < 0) {
zlog_err("Couldn't create link local socket: %s", safe_strerror(errno));
goto fail;
}
/* Threads. */
babel_routing_process->t_read =
thread_add_read(master, &babel_read_protocol, NULL, protocol_socket);
/* wait a little: zebra will announce interfaces, addresses, routes... */
babel_routing_process->t_update =
thread_add_timer_msec(master, &babel_init_routing_process, NULL, 200L);
return 0;
fail:
XFREE(MTYPE_BABEL, babel_routing_process);
babel_routing_process = NULL;
return -1;
}
/* thread reading entries form others babel daemons */
static int
babel_read_protocol (struct thread *thread)
{
int rc;
struct interface *ifp = NULL;
struct sockaddr_in6 sin6;
struct listnode *linklist_node = NULL;
assert(babel_routing_process != NULL);
assert(protocol_socket >= 0);
rc = babel_recv(protocol_socket,
receive_buffer, receive_buffer_size,
(struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0) {
if(errno != EAGAIN && errno != EINTR) {
zlog_err("recv: %s", safe_strerror(errno));
}
} else {
FOR_ALL_INTERFACES(ifp, linklist_node) {
if(!if_up(ifp))
continue;
if(ifp->ifindex == sin6.sin6_scope_id) {
parse_packet((unsigned char*)&sin6.sin6_addr, ifp,
receive_buffer, rc);
break;
}
}
}
/* re-add thread */
babel_routing_process->t_read =
thread_add_read(master, &babel_read_protocol, NULL, protocol_socket);
return 0;
}
/* Zebra will give some information, especially about interfaces. This function
must be call with a litte timeout wich may give zebra the time to do his job,
making these inits have sense. */
static int
babel_init_routing_process(struct thread *thread)
{
myseqno = (random() & 0xFFFF);
babel_get_myid();
babel_load_state_file();
debugf(BABEL_DEBUG_COMMON, "My ID is : %s.", format_eui64(myid));
babel_initial_noise();
babel_main_loop(thread);/* this function self-add to the t_update thread */
return 0;
}
/* fill "myid" with an unique id (only if myid != {0}). */
static void
babel_get_myid(void)
{
struct interface *ifp = NULL;
struct listnode *linklist_node = NULL;
int rc;
int i;
/* if we already have an id (from state file), we return. */
if (memcmp(myid, zeroes, 8) != 0) {
return;
}
FOR_ALL_INTERFACES(ifp, linklist_node) {
/* ifp->ifindex is not necessarily valid at this point */
int ifindex = if_nametoindex(ifp->name);
if(ifindex > 0) {
unsigned char eui[8];
rc = if_eui64(ifp->name, ifindex, eui);
if(rc < 0)
continue;
memcpy(myid, eui, 8);
return;
}
}
/* We failed to get a global EUI64 from the interfaces we were given.
Let's try to find an interface with a MAC address. */
for(i = 1; i < 256; i++) {
char buf[IF_NAMESIZE], *ifname;
unsigned char eui[8];
ifname = if_indextoname(i, buf);
if(ifname == NULL)
continue;
rc = if_eui64(ifname, i, eui);
if(rc < 0)
continue;
memcpy(myid, eui, 8);
return;
}
zlog_err("Warning: couldn't find router id -- using random value.");
rc = read_random_bytes(myid, 8);
if(rc < 0) {
zlog_err("read(random): %s (cannot assign an ID)",safe_strerror(errno));
exit(1);
}
/* Clear group and global bits */
myid[0] &= ~3;
}
/* Make some noise so that others notice us, and send retractions in
case we were restarted recently */
static void
babel_initial_noise(void)
{
struct interface *ifp = NULL;
struct listnode *linklist_node = NULL;
FOR_ALL_INTERFACES(ifp, linklist_node) {
if(!if_up(ifp))
continue;
/* Apply jitter before we send the first message. */
usleep(roughly(10000));
gettime(&babel_now);
send_hello(ifp);
send_wildcard_retraction(ifp);
}
FOR_ALL_INTERFACES(ifp, linklist_node) {
if(!if_up(ifp))
continue;
usleep(roughly(10000));
gettime(&babel_now);
send_hello(ifp);
send_wildcard_retraction(ifp);
send_self_update(ifp);
send_request(ifp, NULL, 0);
flushupdates(ifp);
flushbuf(ifp);
}
}
/* Delete all the added babel routes, make babeld only speak to zebra. */
static void
babel_clean_routing_process()
{
flush_all_routes();
babel_interface_close_all();
/* cancel threads */
if (babel_routing_process->t_read != NULL) {
thread_cancel(babel_routing_process->t_read);
}
if (babel_routing_process->t_update != NULL) {
thread_cancel(babel_routing_process->t_update);
}
XFREE(MTYPE_BABEL, babel_routing_process);
babel_routing_process = NULL;
}
/* Function used with timeout. */
static int
babel_main_loop(struct thread *thread)
{
struct timeval tv;
struct interface *ifp = NULL;
struct listnode *linklist_node = NULL;
while(1) {
gettime(&babel_now);
/* timeouts --------------------------------------------------------- */
/* get the next timeout */
babel_fill_with_next_timeout(&tv);
/* if there is no timeout, we must wait. */
if(timeval_compare(&tv, &babel_now) > 0) {
timeval_minus(&tv, &tv, &babel_now);
debugf(BABEL_DEBUG_TIMEOUT, "babel main loop : timeout: %ld msecs",
tv.tv_sec * 1000 + tv.tv_usec / 1000);
/* it happens often to have less than 1 ms, it's bad. */
timeval_add_msec(&tv, &tv, 300);
babel_set_timer(&tv);
return 0;
}
gettime(&babel_now);
/* update database -------------------------------------------------- */
if(timeval_compare(&check_neighbours_timeout, &babel_now) < 0) {
int msecs;
msecs = check_neighbours();
msecs = MAX(msecs, 10);
schedule_neighbours_check(msecs, 1);
}
if(babel_now.tv_sec >= expiry_time) {
expire_routes();
expire_resend();
expiry_time = babel_now.tv_sec + roughly(30);
}
if(babel_now.tv_sec >= source_expiry_time) {
expire_sources();
source_expiry_time = babel_now.tv_sec + roughly(300);
}
FOR_ALL_INTERFACES(ifp, linklist_node) {
babel_interface_nfo *babel_ifp = NULL;
if(!if_up(ifp))
continue;
babel_ifp = babel_get_if_nfo(ifp);
if(timeval_compare(&babel_now, &babel_ifp->hello_timeout) >= 0)
send_hello(ifp);
if(timeval_compare(&babel_now, &babel_ifp->update_timeout) >= 0)
send_update(ifp, 0, NULL, 0);
if(timeval_compare(&babel_now,
&babel_ifp->update_flush_timeout) >= 0)
flushupdates(ifp);
}
if(resend_time.tv_sec != 0) {
if(timeval_compare(&babel_now, &resend_time) >= 0)
do_resend();
}
if(unicast_flush_timeout.tv_sec != 0) {
if(timeval_compare(&babel_now, &unicast_flush_timeout) >= 0)
flush_unicast(1);
}
FOR_ALL_INTERFACES(ifp, linklist_node) {
babel_interface_nfo *babel_ifp = NULL;
if(!if_up(ifp))
continue;
babel_ifp = babel_get_if_nfo(ifp);
if(babel_ifp->flush_timeout.tv_sec != 0) {
if(timeval_compare(&babel_now, &babel_ifp->flush_timeout) >= 0)
flushbuf(ifp);
}
}
}
assert(0); /* this line should never be reach */
}
static void
printIfMin(struct timeval *tv, int cmd, const char *tag, const char *ifname)
{
static struct timeval curr_tv;
static char buffer[200];
static const char *curr_tag = NULL;
switch (cmd) {
case 0: /* reset timeval */
curr_tv = *tv;
if(ifname != NULL) {
snprintf(buffer, 200L, "interface: %s; %s", ifname, tag);
curr_tag = buffer;
} else {
curr_tag = tag;
}
break;
case 1: /* take the min */
if (tv->tv_sec == 0 && tv->tv_usec == 0) { /* if (tv == ∞) */
break;
}
if (tv->tv_sec < curr_tv.tv_sec ||(tv->tv_sec == curr_tv.tv_sec &&
tv->tv_usec < curr_tv.tv_usec)) {
curr_tv = *tv;
if(ifname != NULL) {
snprintf(buffer, 200L, "interface: %s; %s", ifname, tag);
curr_tag = buffer;
} else {
curr_tag = tag;
}
}
break;
case 2: /* print message */
debugf(BABEL_DEBUG_TIMEOUT, "next timeout due to: %s", curr_tag);
break;
default:
break;
}
}
static void
babel_fill_with_next_timeout(struct timeval *tv)
{
#if (defined NO_DEBUG)
#define printIfMin(a,b,c,d)
#else
#define printIfMin(a,b,c,d) \
if (UNLIKELY(debug & BABEL_DEBUG_TIMEOUT)) {printIfMin(a,b,c,d);}
struct interface *ifp = NULL;
struct listnode *linklist_node = NULL;
*tv = check_neighbours_timeout;
printIfMin(tv, 0, "check_neighbours_timeout", NULL);
timeval_min_sec(tv, expiry_time);
printIfMin(tv, 1, "expiry_time", NULL);
timeval_min_sec(tv, source_expiry_time);
printIfMin(tv, 1, "source_expiry_time", NULL);
timeval_min(tv, &resend_time);
printIfMin(tv, 1, "resend_time", NULL);
FOR_ALL_INTERFACES(ifp, linklist_node) {
babel_interface_nfo *babel_ifp = NULL;
if(!if_up(ifp))
continue;
babel_ifp = babel_get_if_nfo(ifp);
timeval_min(tv, &babel_ifp->flush_timeout);
printIfMin(tv, 1, "flush_timeout", ifp->name);
timeval_min(tv, &babel_ifp->hello_timeout);
printIfMin(tv, 1, "hello_timeout", ifp->name);
timeval_min(tv, &babel_ifp->update_timeout);
printIfMin(tv, 1, "update_timeout", ifp->name);
timeval_min(tv, &babel_ifp->update_flush_timeout);
printIfMin(tv, 1, "update_flush_timeout",ifp->name);
}
timeval_min(tv, &unicast_flush_timeout);
printIfMin(tv, 1, "unicast_flush_timeout", NULL);
printIfMin(tv, 2, NULL, NULL);
#undef printIfMin
#endif
}
/* set the t_update thread of the babel routing process to be launch in
'timeout' (approximate at the milisecond) */
static void
babel_set_timer(struct timeval *timeout)
{
long msecs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
if (babel_routing_process->t_update != NULL) {
thread_cancel(babel_routing_process->t_update);
}
babel_routing_process->t_update =
thread_add_timer_msec(master, &babel_main_loop, NULL, msecs);
}
/* Schedule a neighbours check after roughly 3/2 times msecs have elapsed. */
void
schedule_neighbours_check(int msecs, int override)
{
struct timeval timeout;
timeval_add_msec(&timeout, &babel_now, roughly(msecs * 3 / 2));
if(override)
check_neighbours_timeout = timeout;
else
timeval_min(&check_neighbours_timeout, &timeout);
}
int
resize_receive_buffer(int size)
{
if(size <= receive_buffer_size)
return 0;
if(receive_buffer == NULL) {
receive_buffer = malloc(size);
if(receive_buffer == NULL) {
zlog_err("malloc(receive_buffer): %s", safe_strerror(errno));
return -1;
}
receive_buffer_size = size;
} else {
unsigned char *new;
new = realloc(receive_buffer, size);
if(new == NULL) {
zlog_err("realloc(receive_buffer): %s", safe_strerror(errno));
return -1;
}
receive_buffer = new;
receive_buffer_size = size;
}
return 1;
}
static void
babel_distribute_update (struct distribute *dist)
{
struct interface *ifp;
babel_interface_nfo *babel_ifp;
struct access_list *alist;
struct prefix_list *plist;
if (! dist->ifname)
return;
ifp = if_lookup_by_name (dist->ifname);
if (ifp == NULL)
return;
babel_ifp = babel_get_if_nfo(ifp);
if (dist->list[DISTRIBUTE_IN]) {
alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_IN]);
if (alist)
babel_ifp->list[BABEL_FILTER_IN] = alist;
else
babel_ifp->list[BABEL_FILTER_IN] = NULL;
} else {
babel_ifp->list[BABEL_FILTER_IN] = NULL;
}
if (dist->list[DISTRIBUTE_OUT]) {
alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_OUT]);
if (alist)
babel_ifp->list[BABEL_FILTER_OUT] = alist;
else
babel_ifp->list[BABEL_FILTER_OUT] = NULL;
} else {
babel_ifp->list[BABEL_FILTER_OUT] = NULL;
}
if (dist->prefix[DISTRIBUTE_IN]) {
plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_IN]);
if (plist)
babel_ifp->prefix[BABEL_FILTER_IN] = plist;
else
babel_ifp->prefix[BABEL_FILTER_IN] = NULL;
} else {
babel_ifp->prefix[BABEL_FILTER_IN] = NULL;
}
if (dist->prefix[DISTRIBUTE_OUT]) {
plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_OUT]);
if (plist)
babel_ifp->prefix[BABEL_FILTER_OUT] = plist;
else
babel_ifp->prefix[BABEL_FILTER_OUT] = NULL;
} else {
babel_ifp->prefix[BABEL_FILTER_OUT] = NULL;
}
}
static void
babel_distribute_update_interface (struct interface *ifp)
{
struct distribute *dist;
dist = distribute_lookup (ifp->name);
if (dist)
babel_distribute_update (dist);
}
/* Update all interface's distribute list. */
static void
babel_distribute_update_all (struct prefix_list *notused)
{
struct interface *ifp;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
babel_distribute_update_interface (ifp);
}
static void
babel_distribute_update_all_wrapper (struct access_list *notused)
{
babel_distribute_update_all(NULL);
}
/* [Command] */
DEFUN (router_babel,
router_babel_cmd,
"router babel",
"Enable a routing process\n"
"Make Babel instance command\n"
"No attributes\n")
{
int ret;
vty->node = BABEL_NODE;
if (!babel_routing_process) {
ret = babel_create_routing_process ();
/* Notice to user we couldn't create Babel. */
if (ret < 0) {
zlog_warn ("can't create Babel");
return CMD_WARNING;
}
}
return CMD_SUCCESS;
}
/* [Command] */
DEFUN (no_router_babel,
no_router_babel_cmd,
"no router babel",
NO_STR
"Disable a routing process\n"
"Remove Babel instance command\n"
"No attributes\n")
{
if(babel_routing_process)
babel_clean_routing_process();
return CMD_SUCCESS;
}
/* [Babel Command] */
DEFUN (babel_set_resend_delay,
babel_set_resend_delay_cmd,
"babel resend-delay <20-655340>",
"Babel commands\n"
"Time before resending a message\n"
"Milliseconds\n")
{
int interval;
VTY_GET_INTEGER_RANGE("milliseconds", interval, argv[0], 20, 10 * 0xFFFE);
resend_delay = interval;
return CMD_SUCCESS;
}
void
babeld_quagga_init(void)
{
install_node(&cmd_babel_node, &babel_config_write);
install_element(CONFIG_NODE, &router_babel_cmd);
install_element(CONFIG_NODE, &no_router_babel_cmd);
install_default(BABEL_NODE);
install_element(BABEL_NODE, &babel_set_resend_delay_cmd);
babel_if_init();
/* Access list install. */
access_list_init ();
access_list_add_hook (babel_distribute_update_all_wrapper);
access_list_delete_hook (babel_distribute_update_all_wrapper);
/* Prefix list initialize.*/
prefix_list_init ();
prefix_list_add_hook (babel_distribute_update_all);
prefix_list_delete_hook (babel_distribute_update_all);
/* Distribute list install. */
distribute_list_init (BABEL_NODE);
distribute_list_add_hook (babel_distribute_update);
distribute_list_delete_hook (babel_distribute_update);
}
/* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */
int
input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen,
const unsigned char *neigh, unsigned int ifindex)
{
return babel_filter(0, prefix, plen, ifindex);
}
int
output_filter(const unsigned char *id, const unsigned char *prefix,
unsigned short plen, unsigned int ifindex)
{
return babel_filter(1, prefix, plen, ifindex);
}
/* There's no redistribute filter in Quagga -- the zebra daemon does its
own filtering. */
int
redistribute_filter(const unsigned char *prefix, unsigned short plen,
unsigned int ifindex, int proto)
{
return 0;
}

View file

@ -1,30 +0,0 @@
debug babel common
!debug babel kernel
!debug babel filter
!debug babel timeout
!debug babel interface
!debug babel route
!debug babel all
router babel
! network wlan0
! network eth0
! redistribute kernel
! no redistribute static
! The defaults are fine for a wireless interface
!interface wlan0
! A few optimisation tweaks are optional but recommended on a wired interface
! Disable link quality estimation, enable split horizon processing, and
! increase the hello and update intervals.
!interface eth0
! babel wired
! babel split-horizon
! babel hello-interval 12000
! babel update-interval 36000
! log file /var/log/quagga/babeld.log
log stdout

View file

@ -1,141 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef BABEL_BABELD_H
#define BABEL_BABELD_H
#include <zebra.h>
#include "vty.h"
#define INFINITY ((unsigned short)(~0))
#ifndef RTPROT_BABEL
#define RTPROT_BABEL 42
#endif
#define RTPROT_BABEL_LOCAL -2
#undef MAX
#undef MIN
#define MAX(x,y) ((x)<=(y)?(y):(x))
#define MIN(x,y) ((x)<=(y)?(x):(y))
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* nothing */
#elif defined(__GNUC__)
#define inline __inline
#if (__GNUC__ >= 3)
#define restrict __restrict
#else
#define restrict /**/
#endif
#else
#define inline /**/
#define restrict /**/
#endif
#if defined(__GNUC__) && (__GNUC__ >= 3)
#define ATTRIBUTE(x) __attribute__ (x)
#define LIKELY(_x) __builtin_expect(!!(_x), 1)
#define UNLIKELY(_x) __builtin_expect(!!(_x), 0)
#else
#define ATTRIBUTE(x) /**/
#define LIKELY(_x) !!(_x)
#define UNLIKELY(_x) !!(_x)
#endif
#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
#define COLD __attribute__ ((cold))
#else
#define COLD /**/
#endif
#ifndef IF_NAMESIZE
#include <sys/socket.h>
#include <net/if.h>
#endif
#ifdef HAVE_VALGRIND
#include <valgrind/memcheck.h>
#else
#ifndef VALGRIND_MAKE_MEM_UNDEFINED
#define VALGRIND_MAKE_MEM_UNDEFINED(a, b) do {} while(0)
#endif
#ifndef VALGRIND_CHECK_MEM_IS_DEFINED
#define VALGRIND_CHECK_MEM_IS_DEFINED(a, b) do {} while(0)
#endif
#endif
#define BABEL_VTY_PORT 2609
#define BABEL_DEFAULT_CONFIG "babeld.conf"
#define BABEL_VERSION "0.1 for quagga"
/* Values in milliseconds */
#define BABEL_DEFAULT_HELLO_INTERVAL 4000
#define BABEL_DEFAULT_UPDATE_INTERVAL 16000
#define BABEL_DEFAULT_RESEND_DELAY 2000
/* Babel socket. */
extern int protocol_socket;
/* Babel structure. */
struct babel
{
/* Babel threads. */
struct thread *t_read; /* on Babel protocol's socket */
struct thread *t_update; /* timers */
};
extern void babeld_quagga_init(void);
extern int input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen,
const unsigned char *neigh, unsigned int ifindex);
extern int output_filter(const unsigned char *id, const unsigned char *prefix,
unsigned short plen, unsigned int ifindex);
extern int redistribute_filter(const unsigned char *prefix, unsigned short plen,
unsigned int ifindex, int proto);
extern int resize_receive_buffer(int size);
extern void schedule_neighbours_check(int msecs, int override);
#endif /* BABEL_BABELD_H */

View file

@ -1,316 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright 2007, 2008 by Grégoire Henry, Julien Cristau and Juliusz Chroboczek
Copyright 2011, 2012 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/time.h>
#include <sys/param.h>
#include <time.h>
#include "babeld.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <zebra.h>
#include "prefix.h"
#include "zclient.h"
#include "kernel.h"
#include "privs.h"
#include "command.h"
#include "vty.h"
#include "memory.h"
#include "thread.h"
#include "util.h"
#include "babel_interface.h"
#include "babel_zebra.h"
static int
kernel_route_v4(int add, const unsigned char *pref, unsigned short plen,
const unsigned char *gate, int ifindex,
unsigned int metric);
static int
kernel_route_v6(int add, const unsigned char *pref, unsigned short plen,
const unsigned char *gate, int ifindex,
unsigned int metric);
int
kernel_interface_operational(struct interface *interface)
{
return if_is_operative(interface);
}
int
kernel_interface_mtu(struct interface *interface)
{
return MIN(interface->mtu, interface->mtu6);
}
int
kernel_interface_wireless(struct interface *interface)
{
return 0;
}
int
kernel_route(int operation, const unsigned char *pref, unsigned short plen,
const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric)
{
int rc;
int ipv4;
/* Check that the protocol family is consistent. */
if(plen >= 96 && v4mapped(pref)) {
if(!v4mapped(gate)) {
errno = EINVAL;
return -1;
}
ipv4 = 1;
} else {
if(v4mapped(gate)) {
errno = EINVAL;
return -1;
}
ipv4 = 0;
}
switch (operation) {
case ROUTE_ADD:
return ipv4 ?
kernel_route_v4(1, pref, plen, gate, ifindex, metric):
kernel_route_v6(1, pref, plen, gate, ifindex, metric);
break;
case ROUTE_FLUSH:
return ipv4 ?
kernel_route_v4(0, pref, plen, gate, ifindex, metric):
kernel_route_v6(0, pref, plen, gate, ifindex, metric);
break;
case ROUTE_MODIFY:
if(newmetric == metric && memcmp(newgate, gate, 16) == 0 &&
newifindex == ifindex)
return 0;
debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new.");
rc = ipv4 ?
kernel_route_v4(0, pref, plen, gate, ifindex, metric):
kernel_route_v6(0, pref, plen, gate, ifindex, metric);
if (rc < 0)
return -1;
rc = ipv4 ?
kernel_route_v4(1, pref, plen, newgate, newifindex, newmetric):
kernel_route_v6(1, pref, plen, newgate, newifindex, newmetric);
return rc;
break;
default:
zlog_err("this should never appens (false value - kernel_route)");
assert(0);
exit(1);
break;
}
}
static int
kernel_route_v4(int add,
const unsigned char *pref, unsigned short plen,
const unsigned char *gate, int ifindex, unsigned int metric)
{
struct zapi_ipv4 api; /* quagga's communication system */
struct prefix_ipv4 quagga_prefix; /* quagga's prefix */
struct in_addr babel_prefix_addr; /* babeld's prefix addr */
struct in_addr nexthop; /* next router to go */
struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */
/* convert to be understandable by quagga */
/* convert given addresses */
uchar_to_inaddr(&babel_prefix_addr, pref);
uchar_to_inaddr(&nexthop, gate);
/* make prefix structure */
memset (&quagga_prefix, 0, sizeof(quagga_prefix));
quagga_prefix.family = AF_INET;
IPV4_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr);
quagga_prefix.prefixlen = plen - 96; /* our plen is for v4mapped's addr */
apply_mask_ipv4(&quagga_prefix);
api.vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_BABEL;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
/* Unlike the native Linux and BSD interfaces, Quagga doesn't like
there to be both and IPv4 nexthop and an ifindex. Omit the
ifindex, and assume that the connected prefixes be set up
correctly. */
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
api.ifindex_num = 0;
if(metric >= KERNEL_INFINITY) {
api.flags = ZEBRA_FLAG_BLACKHOLE;
api.nexthop_num = 0;
} else {
api.nexthop_num = 1;
api.nexthop = &nexthop_pointer;
SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;
}
debugf(BABEL_DEBUG_ROUTE, "%s route (ipv4) to zebra",
add ? "adding" : "removing" );
return zapi_ipv4_route (add ? ZEBRA_IPV4_ROUTE_ADD :
ZEBRA_IPV4_ROUTE_DELETE,
zclient, &quagga_prefix, &api);
}
static int
kernel_route_v6(int add, const unsigned char *pref, unsigned short plen,
const unsigned char *gate, int ifindex, unsigned int metric)
{
unsigned int tmp_ifindex = ifindex; /* (for typing) */
struct zapi_ipv6 api; /* quagga's communication system */
struct prefix_ipv6 quagga_prefix; /* quagga's prefix */
struct in6_addr babel_prefix_addr; /* babeld's prefix addr */
struct in6_addr nexthop; /* next router to go */
struct in6_addr *nexthop_pointer = &nexthop;
/* convert to be understandable by quagga */
/* convert given addresses */
uchar_to_in6addr(&babel_prefix_addr, pref);
uchar_to_in6addr(&nexthop, gate);
/* make prefix structure */
memset (&quagga_prefix, 0, sizeof(quagga_prefix));
quagga_prefix.family = AF_INET6;
IPV6_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr);
quagga_prefix.prefixlen = plen;
apply_mask_ipv6(&quagga_prefix);
api.vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_BABEL;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
if(metric >= KERNEL_INFINITY) {
api.flags = ZEBRA_FLAG_BLACKHOLE;
api.nexthop_num = 0;
api.ifindex_num = 0;
} else {
api.nexthop_num = 1;
api.nexthop = &nexthop_pointer;
SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX);
api.ifindex_num = 1;
api.ifindex = &tmp_ifindex;
SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;
}
debugf(BABEL_DEBUG_ROUTE, "%s route (ipv6) to zebra",
add ? "adding" : "removing" );
return zapi_ipv6_route (add ? ZEBRA_IPV6_ROUTE_ADD :
ZEBRA_IPV6_ROUTE_DELETE,
zclient, &quagga_prefix, &api);
}
int
if_eui64(char *ifname, int ifindex, unsigned char *eui)
{
struct interface *ifp = if_lookup_by_index(ifindex);
if (ifp == NULL) {
return -1;
}
#ifdef HAVE_STRUCT_SOCKADDR_DL
u_char len = ifp->sdl.sdl_alen;
char *tmp = ifp->sdl.sdl_data + ifp->sdl.sdl_nlen;
#else
u_char len = (u_char) ifp->hw_addr_len;
char *tmp = (void*) ifp->hw_addr;
#endif
if (len == 8) {
memcpy(eui, tmp, 8);
eui[0] ^= 2;
} else if (len == 6) {
memcpy(eui, tmp, 3);
eui[3] = 0xFF;
eui[4] = 0xFE;
memcpy(eui+5, tmp+3, 3);
} else {
return -1;
}
return 0;
}
/* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
available, falls back to gettimeofday but enforces monotonicity. */
int
gettime(struct timeval *tv)
{
return quagga_gettime(QUAGGA_CLK_MONOTONIC, tv);
}
/* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
caller will deal with gracefully. */
int
read_random_bytes(void *buf, size_t len)
{
int fd;
int rc;
fd = open("/dev/urandom", O_RDONLY);
if(fd < 0) {
rc = -1;
} else {
rc = read(fd, buf, len);
if(rc < 0 || (unsigned) rc < len)
rc = -1;
close(fd);
}
return rc;
}

View file

@ -1,69 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <netinet/in.h>
#include "babel_main.h"
#include "if.h"
#define KERNEL_INFINITY 0xFFFF
struct kernel_route {
unsigned char prefix[16];
int plen;
int metric;
unsigned int ifindex;
int proto;
unsigned char gw[16];
};
#define ROUTE_FLUSH 0
#define ROUTE_ADD 1
#define ROUTE_MODIFY 2
extern int export_table, import_table;
int kernel_interface_operational(struct interface *interface);
int kernel_interface_mtu(struct interface *interface);
int kernel_interface_wireless(struct interface *interface);
int kernel_route(int operation, const unsigned char *dest, unsigned short plen,
const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric);
int if_eui64(char *ifname, int ifindex, unsigned char *eui);
int gettime(struct timeval *tv);
int read_random_bytes(void *buf, size_t len);

File diff suppressed because it is too large Load diff

View file

@ -1,111 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef BABEL_MESSAGE_H
#define BABEL_MESSAGE_H
#include "babel_interface.h"
#define MAX_BUFFERED_UPDATES 200
#define BUCKET_TOKENS_MAX 200
#define BUCKET_TOKENS_PER_SEC 40
#define MESSAGE_PAD1 0
#define MESSAGE_PADN 1
#define MESSAGE_ACK_REQ 2
#define MESSAGE_ACK 3
#define MESSAGE_HELLO 4
#define MESSAGE_IHU 5
#define MESSAGE_ROUTER_ID 6
#define MESSAGE_NH 7
#define MESSAGE_UPDATE 8
#define MESSAGE_REQUEST 9
#define MESSAGE_MH_REQUEST 10
extern unsigned short myseqno;
extern struct timeval seqno_time;
extern int broadcast_ihu;
extern int split_horizon;
extern unsigned char packet_header[4];
extern struct neighbour *unicast_neighbour;
extern struct timeval unicast_flush_timeout;
void parse_packet(const unsigned char *from, struct interface *ifp,
const unsigned char *packet, int packetlen);
void flushbuf(struct interface *ifp);
void flushupdates(struct interface *ifp);
void send_ack(struct neighbour *neigh, unsigned short nonce,
unsigned short interval);
void send_hello_noupdate(struct interface *ifp, unsigned interval);
void send_hello(struct interface *ifp);
void flush_unicast(int dofree);
void send_update(struct interface *ifp, int urgent,
const unsigned char *prefix, unsigned char plen);
void send_update_resend(struct interface *ifp,
const unsigned char *prefix, unsigned char plen);
void send_wildcard_retraction(struct interface *ifp);
void update_myseqno(void);
void send_self_update(struct interface *ifp);
void send_ihu(struct neighbour *neigh, struct interface *ifp);
void send_marginal_ihu(struct interface *ifp);
void send_request(struct interface *ifp,
const unsigned char *prefix, unsigned char plen);
void send_unicast_request(struct neighbour *neigh,
const unsigned char *prefix, unsigned char plen);
void send_multihop_request(struct interface *ifp,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id,
unsigned short hop_count);
void
send_unicast_multihop_request(struct neighbour *neigh,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id,
unsigned short hop_count);
void send_request_resend(struct neighbour *neigh,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned char *id);
void handle_request(struct neighbour *neigh, const unsigned char *prefix,
unsigned char plen, unsigned char hop_count,
unsigned short seqno, const unsigned char *id);
#endif

View file

@ -1,343 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <zebra.h>
#include "if.h"
#include "babel_main.h"
#include "babeld.h"
#include "util.h"
#include "babel_interface.h"
#include "neighbour.h"
#include "source.h"
#include "route.h"
#include "message.h"
#include "resend.h"
struct neighbour *neighs = NULL;
static struct neighbour *
find_neighbour_nocreate(const unsigned char *address, struct interface *ifp)
{
struct neighbour *neigh;
FOR_ALL_NEIGHBOURS(neigh) {
if(memcmp(address, neigh->address, 16) == 0 &&
neigh->ifp == ifp)
return neigh;
}
return NULL;
}
void
flush_neighbour(struct neighbour *neigh)
{
flush_neighbour_routes(neigh);
if(unicast_neighbour == neigh)
flush_unicast(1);
flush_resends(neigh);
if(neighs == neigh) {
neighs = neigh->next;
} else {
struct neighbour *previous = neighs;
while(previous->next != neigh)
previous = previous->next;
previous->next = neigh->next;
}
free(neigh);
}
struct neighbour *
find_neighbour(const unsigned char *address, struct interface *ifp)
{
struct neighbour *neigh;
const struct timeval zero = {0, 0};
neigh = find_neighbour_nocreate(address, ifp);
if(neigh)
return neigh;
debugf(BABEL_DEBUG_COMMON,"Creating neighbour %s on %s.",
format_address(address), ifp->name);
neigh = malloc(sizeof(struct neighbour));
if(neigh == NULL) {
zlog_err("malloc(neighbour): %s", safe_strerror(errno));
return NULL;
}
neigh->hello_seqno = -1;
memcpy(neigh->address, address, 16);
neigh->reach = 0;
neigh->txcost = INFINITY;
neigh->ihu_time = babel_now;
neigh->hello_time = zero;
neigh->hello_interval = 0;
neigh->ihu_interval = 0;
neigh->ifp = ifp;
neigh->next = neighs;
neighs = neigh;
send_hello(ifp);
return neigh;
}
/* Recompute a neighbour's rxcost. Return true if anything changed.
This does not call local_notify_neighbour, see update_neighbour_metric. */
int
update_neighbour(struct neighbour *neigh, int hello, int hello_interval)
{
int missed_hellos;
int rc = 0;
if(hello < 0) {
if(neigh->hello_interval <= 0)
return rc;
missed_hellos =
((int)timeval_minus_msec(&babel_now, &neigh->hello_time) -
neigh->hello_interval * 7) /
(neigh->hello_interval * 10);
if(missed_hellos <= 0)
return rc;
timeval_add_msec(&neigh->hello_time, &neigh->hello_time,
missed_hellos * neigh->hello_interval * 10);
} else {
if(neigh->hello_seqno >= 0 && neigh->reach > 0) {
missed_hellos = seqno_minus(hello, neigh->hello_seqno) - 1;
if(missed_hellos < -8) {
/* Probably a neighbour that rebooted and lost its seqno.
Reboot the universe. */
neigh->reach = 0;
missed_hellos = 0;
rc = 1;
} else if(missed_hellos < 0) {
if(hello_interval > neigh->hello_interval) {
/* This neighbour has increased its hello interval,
and we didn't notice. */
neigh->reach <<= -missed_hellos;
missed_hellos = 0;
} else {
/* Late hello. Probably due to the link layer buffering
packets during a link outage. Ignore it, but reset
the expected seqno. */
neigh->hello_seqno = hello;
hello = -1;
missed_hellos = 0;
}
rc = 1;
}
} else {
missed_hellos = 0;
}
neigh->hello_time = babel_now;
neigh->hello_interval = hello_interval;
}
if(missed_hellos > 0) {
neigh->reach >>= missed_hellos;
neigh->hello_seqno = seqno_plus(neigh->hello_seqno, missed_hellos);
missed_hellos = 0;
rc = 1;
}
if(hello >= 0) {
neigh->hello_seqno = hello;
neigh->reach >>= 1;
neigh->reach |= 0x8000;
if((neigh->reach & 0xFC00) != 0xFC00)
rc = 1;
}
/* Make sure to give neighbours some feedback early after association */
if((neigh->reach & 0xBF00) == 0x8000) {
/* A new neighbour */
send_hello(neigh->ifp);
} else {
/* Don't send hellos, in order to avoid a positive feedback loop. */
int a = (neigh->reach & 0xC000);
int b = (neigh->reach & 0x3000);
if((a == 0xC000 && b == 0) || (a == 0 && b == 0x3000)) {
/* Reachability is either 1100 or 0011 */
send_self_update(neigh->ifp);
}
}
if((neigh->reach & 0xFC00) == 0xC000) {
/* This is a newish neighbour, let's request a full route dump.
We ought to avoid this when the network is dense */
send_unicast_request(neigh, NULL, 0);
send_ihu(neigh, NULL);
}
return rc;
}
static int
reset_txcost(struct neighbour *neigh)
{
unsigned delay;
delay = timeval_minus_msec(&babel_now, &neigh->ihu_time);
if(neigh->ihu_interval > 0 && delay < neigh->ihu_interval * 10U * 3U)
return 0;
/* If we're losing a lot of packets, we probably lost an IHU too */
if(delay >= 180000 || (neigh->reach & 0xFFF0) == 0 ||
(neigh->ihu_interval > 0 &&
delay >= neigh->ihu_interval * 10U * 10U)) {
neigh->txcost = INFINITY;
neigh->ihu_time = babel_now;
return 1;
}
return 0;
}
unsigned
neighbour_txcost(struct neighbour *neigh)
{
return neigh->txcost;
}
unsigned
check_neighbours()
{
struct neighbour *neigh;
int changed, rc;
unsigned msecs = 50000;
debugf(BABEL_DEBUG_COMMON,"Checking neighbours.");
neigh = neighs;
while(neigh) {
changed = update_neighbour(neigh, -1, 0);
if(neigh->reach == 0 ||
neigh->hello_time.tv_sec > babel_now.tv_sec || /* clock stepped */
timeval_minus_msec(&babel_now, &neigh->hello_time) > 300000) {
struct neighbour *old = neigh;
neigh = neigh->next;
flush_neighbour(old);
continue;
}
rc = reset_txcost(neigh);
changed = changed || rc;
update_neighbour_metric(neigh, changed);
if(neigh->hello_interval > 0)
msecs = MIN(msecs, neigh->hello_interval * 10U);
if(neigh->ihu_interval > 0)
msecs = MIN(msecs, neigh->ihu_interval * 10U);
neigh = neigh->next;
}
return msecs;
}
unsigned
neighbour_rxcost(struct neighbour *neigh)
{
unsigned delay;
unsigned short reach = neigh->reach;
delay = timeval_minus_msec(&babel_now, &neigh->hello_time);
if((reach & 0xFFF0) == 0 || delay >= 180000) {
return INFINITY;
} else if(babel_get_if_nfo(neigh->ifp)->flags & BABEL_IF_LQ) {
int sreach =
((reach & 0x8000) >> 2) +
((reach & 0x4000) >> 1) +
(reach & 0x3FFF);
/* 0 <= sreach <= 0x7FFF */
int cost = (0x8000 * babel_get_if_nfo(neigh->ifp)->cost) / (sreach + 1);
/* cost >= interface->cost */
if(delay >= 40000)
cost = (cost * (delay - 20000) + 10000) / 20000;
return MIN(cost, INFINITY);
} else {
/* To lose one hello is a misfortune, to lose two is carelessness. */
if((reach & 0xC000) == 0xC000)
return babel_get_if_nfo(neigh->ifp)->cost;
else if((reach & 0xC000) == 0)
return INFINITY;
else if((reach & 0x2000))
return babel_get_if_nfo(neigh->ifp)->cost;
else
return INFINITY;
}
}
unsigned
neighbour_cost(struct neighbour *neigh)
{
unsigned a, b;
if(!if_up(neigh->ifp))
return INFINITY;
a = neighbour_txcost(neigh);
if(a >= INFINITY)
return INFINITY;
b = neighbour_rxcost(neigh);
if(b >= INFINITY)
return INFINITY;
if(!(babel_get_if_nfo(neigh->ifp)->flags & BABEL_IF_LQ)
|| (a < 256 && b < 256)) {
return a;
} else {
/* a = 256/alpha, b = 256/beta, where alpha and beta are the expected
probabilities of a packet getting through in the direct and reverse
directions. */
a = MAX(a, 256);
b = MAX(b, 256);
/* 1/(alpha * beta), which is just plain ETX. */
/* Since a and b are capped to 16 bits, overflow is impossible. */
return (a * b + 128) >> 8;
}
}

View file

@ -1,66 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
struct neighbour {
struct neighbour *next;
/* This is -1 when unknown, so don't make it unsigned */
int hello_seqno;
unsigned char address[16];
unsigned short reach;
unsigned short txcost;
struct timeval hello_time;
struct timeval ihu_time;
unsigned short hello_interval; /* in centiseconds */
unsigned short ihu_interval; /* in centiseconds */
struct interface *ifp;
};
extern struct neighbour *neighs;
#define FOR_ALL_NEIGHBOURS(_neigh) \
for(_neigh = neighs; _neigh; _neigh = _neigh->next)
int neighbour_valid(struct neighbour *neigh);
void flush_neighbour(struct neighbour *neigh);
struct neighbour *find_neighbour(const unsigned char *address,
struct interface *ifp);
int update_neighbour(struct neighbour *neigh, int hello, int hello_interval);
unsigned check_neighbours(void);
unsigned neighbour_txcost(struct neighbour *neigh);
unsigned neighbour_rxcost(struct neighbour *neigh);
unsigned neighbour_cost(struct neighbour *neigh);

View file

@ -1,239 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include "babeld.h"
#include "util.h"
#include "net.h"
int
babel_socket(int port)
{
struct sockaddr_in6 sin6;
int s, rc;
int saved_errno;
int one = 1, zero = 0;
const int ds = 0xc0; /* CS6 - Network Control */
s = socket(PF_INET6, SOCK_DGRAM, 0);
if(s < 0)
return -1;
rc = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
if(rc < 0)
goto fail;
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if(rc < 0)
goto fail;
rc = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
&zero, sizeof(zero));
if(rc < 0)
goto fail;
rc = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
&one, sizeof(one));
if(rc < 0)
goto fail;
rc = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&one, sizeof(one));
if(rc < 0)
goto fail;
#ifdef IPV6_TCLASS
rc = setsockopt(s, IPPROTO_IPV6, IPV6_TCLASS, &ds, sizeof(ds));
#else
rc = -1;
errno = ENOSYS;
#endif
if(rc < 0)
perror("Couldn't set traffic class");
rc = fcntl(s, F_GETFL, 0);
if(rc < 0)
goto fail;
rc = fcntl(s, F_SETFL, (rc | O_NONBLOCK));
if(rc < 0)
goto fail;
rc = fcntl(s, F_GETFD, 0);
if(rc < 0)
goto fail;
rc = fcntl(s, F_SETFD, rc | FD_CLOEXEC);
if(rc < 0)
goto fail;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(port);
rc = bind(s, (struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0)
goto fail;
return s;
fail:
saved_errno = errno;
close(s);
errno = saved_errno;
return -1;
}
int
babel_recv(int s, void *buf, int buflen, struct sockaddr *sin, int slen)
{
struct iovec iovec;
struct msghdr msg;
int rc;
memset(&msg, 0, sizeof(msg));
iovec.iov_base = buf;
iovec.iov_len = buflen;
msg.msg_name = sin;
msg.msg_namelen = slen;
msg.msg_iov = &iovec;
msg.msg_iovlen = 1;
rc = recvmsg(s, &msg, 0);
return rc;
}
int
babel_send(int s,
void *buf1, int buflen1, void *buf2, int buflen2,
struct sockaddr *sin, int slen)
{
struct iovec iovec[2];
struct msghdr msg;
int rc;
iovec[0].iov_base = buf1;
iovec[0].iov_len = buflen1;
iovec[1].iov_base = buf2;
iovec[1].iov_len = buflen2;
memset(&msg, 0, sizeof(msg));
msg.msg_name = (struct sockaddr*)sin;
msg.msg_namelen = slen;
msg.msg_iov = iovec;
msg.msg_iovlen = 2;
again:
rc = sendmsg(s, &msg, 0);
if(rc < 0) {
if(errno == EINTR)
goto again;
else if(errno == EAGAIN) {
int rc2;
rc2 = wait_for_fd(1, s, 5);
if(rc2 > 0)
goto again;
errno = EAGAIN;
}
}
return rc;
}
int
tcp_server_socket(int port, int local)
{
struct sockaddr_in6 sin6;
int s, rc, saved_errno;
int one = 1;
s = socket(PF_INET6, SOCK_STREAM, 0);
if(s < 0)
return -1;
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if(rc < 0)
goto fail;
rc = fcntl(s, F_GETFL, 0);
if(rc < 0)
goto fail;
rc = fcntl(s, F_SETFL, (rc | O_NONBLOCK));
if(rc < 0)
goto fail;
rc = fcntl(s, F_GETFD, 0);
if(rc < 0)
goto fail;
rc = fcntl(s, F_SETFD, rc | FD_CLOEXEC);
if(rc < 0)
goto fail;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(port);
if(local) {
rc = inet_pton(AF_INET6, "::1", &sin6.sin6_addr);
if(rc < 0)
goto fail;
}
rc = bind(s, (struct sockaddr*)&sin6, sizeof(sin6));
if(rc < 0)
goto fail;
rc = listen(s, 2);
if(rc < 0)
goto fail;
return s;
fail:
saved_errno = errno;
close(s);
errno = saved_errno;
return -1;
}

View file

@ -1,44 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
int babel_socket(int port);
int babel_recv(int s, void *buf, int buflen, struct sockaddr *sin, int slen);
int babel_send(int s,
void *buf1, int buflen1, void *buf2, int buflen2,
struct sockaddr *sin, int slen);
int tcp_server_socket(int port, int local);

View file

@ -1,330 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <zebra.h>
#include "if.h"
#include "babel_main.h"
#include "babeld.h"
#include "util.h"
#include "neighbour.h"
#include "resend.h"
#include "message.h"
#include "babel_interface.h"
struct timeval resend_time = {0, 0};
struct resend *to_resend = NULL;
static int
resend_match(struct resend *resend,
int kind, const unsigned char *prefix, unsigned char plen)
{
return (resend->kind == kind &&
resend->plen == plen && memcmp(resend->prefix, prefix, 16) == 0);
}
/* This is called by neigh.c when a neighbour is flushed */
void
flush_resends(struct neighbour *neigh)
{
/* Nothing for now */
}
static struct resend *
find_resend(int kind, const unsigned char *prefix, unsigned char plen,
struct resend **previous_return)
{
struct resend *current, *previous;
previous = NULL;
current = to_resend;
while(current) {
if(resend_match(current, kind, prefix, plen)) {
if(previous_return)
*previous_return = previous;
return current;
}
previous = current;
current = current->next;
}
return NULL;
}
struct resend *
find_request(const unsigned char *prefix, unsigned char plen,
struct resend **previous_return)
{
return find_resend(RESEND_REQUEST, prefix, plen, previous_return);
}
int
record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id,
struct interface *ifp, int delay)
{
struct resend *resend;
unsigned int ifindex = ifp ? ifp->ifindex : 0;
if((kind == RESEND_REQUEST &&
input_filter(NULL, prefix, plen, NULL, ifindex) >= INFINITY) ||
(kind == RESEND_UPDATE &&
output_filter(NULL, prefix, plen, ifindex) >= INFINITY))
return 0;
if(delay >= 0xFFFF)
delay = 0xFFFF;
resend = find_resend(kind, prefix, plen, NULL);
if(resend) {
if(resend->delay && delay)
resend->delay = MIN(resend->delay, delay);
else if(delay)
resend->delay = delay;
resend->time = babel_now;
resend->max = RESEND_MAX;
if(id && memcmp(resend->id, id, 8) == 0 &&
seqno_compare(resend->seqno, seqno) > 0) {
return 0;
}
if(id)
memcpy(resend->id, id, 8);
else
memset(resend->id, 0, 8);
resend->seqno = seqno;
if(resend->ifp != ifp)
resend->ifp = NULL;
} else {
resend = malloc(sizeof(struct resend));
if(resend == NULL)
return -1;
resend->kind = kind;
resend->max = RESEND_MAX;
resend->delay = delay;
memcpy(resend->prefix, prefix, 16);
resend->plen = plen;
resend->seqno = seqno;
if(id)
memcpy(resend->id, id, 8);
else
memset(resend->id, 0, 8);
resend->ifp = ifp;
resend->time = babel_now;
resend->next = to_resend;
to_resend = resend;
}
if(resend->delay) {
struct timeval timeout;
timeval_add_msec(&timeout, &resend->time, resend->delay);
timeval_min(&resend_time, &timeout);
}
return 1;
}
static int
resend_expired(struct resend *resend)
{
switch(resend->kind) {
case RESEND_REQUEST:
return timeval_minus_msec(&babel_now, &resend->time) >= REQUEST_TIMEOUT;
default:
return resend->max <= 0;
}
}
int
unsatisfied_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id)
{
struct resend *request;
request = find_request(prefix, plen, NULL);
if(request == NULL || resend_expired(request))
return 0;
if(memcmp(request->id, id, 8) != 0 ||
seqno_compare(request->seqno, seqno) <= 0)
return 1;
return 0;
}
/* Determine whether a given request should be forwarded. */
int
request_redundant(struct interface *ifp,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id)
{
struct resend *request;
request = find_request(prefix, plen, NULL);
if(request == NULL || resend_expired(request))
return 0;
if(memcmp(request->id, id, 8) == 0 &&
seqno_compare(request->seqno, seqno) > 0)
return 0;
if(request->ifp != NULL && request->ifp != ifp)
return 0;
if(request->max > 0)
/* Will be resent. */
return 1;
if(timeval_minus_msec(&babel_now, &request->time) <
(ifp ? MIN(babel_get_if_nfo(ifp)->hello_interval, 1000) : 1000))
/* Fairly recent. */
return 1;
return 0;
}
int
satisfy_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id,
struct interface *ifp)
{
struct resend *request, *previous;
request = find_request(prefix, plen, &previous);
if(request == NULL)
return 0;
if(ifp != NULL && request->ifp != ifp)
return 0;
if(memcmp(request->id, id, 8) != 0 ||
seqno_compare(request->seqno, seqno) <= 0) {
/* We cannot remove the request, as we may be walking the list right
now. Mark it as expired, so that expire_resend will remove it. */
request->max = 0;
request->time.tv_sec = 0;
recompute_resend_time();
return 1;
}
return 0;
}
void
expire_resend()
{
struct resend *current, *previous;
int recompute = 0;
previous = NULL;
current = to_resend;
while(current) {
if(resend_expired(current)) {
if(previous == NULL) {
to_resend = current->next;
free(current);
current = to_resend;
} else {
previous->next = current->next;
free(current);
current = previous->next;
}
recompute = 1;
} else {
previous = current;
current = current->next;
}
}
if(recompute)
recompute_resend_time();
}
void
recompute_resend_time()
{
struct resend *request;
struct timeval resend = {0, 0};
request = to_resend;
while(request) {
if(!resend_expired(request) && request->delay > 0 && request->max > 0) {
struct timeval timeout;
timeval_add_msec(&timeout, &request->time, request->delay);
timeval_min(&resend, &timeout);
}
request = request->next;
}
resend_time = resend;
}
void
do_resend()
{
struct resend *resend;
resend = to_resend;
while(resend) {
if(!resend_expired(resend) && resend->delay > 0 && resend->max > 0) {
struct timeval timeout;
timeval_add_msec(&timeout, &resend->time, resend->delay);
if(timeval_compare(&babel_now, &timeout) >= 0) {
switch(resend->kind) {
case RESEND_REQUEST:
send_multihop_request(resend->ifp,
resend->prefix, resend->plen,
resend->seqno, resend->id, 127);
break;
case RESEND_UPDATE:
send_update(resend->ifp, 1,
resend->prefix, resend->plen);
break;
default: abort();
}
resend->delay = MIN(0xFFFF, resend->delay * 2);
resend->max--;
}
}
resend = resend->next;
}
recompute_resend_time();
}

View file

@ -1,77 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#define REQUEST_TIMEOUT 65000
#define RESEND_MAX 3
#define RESEND_REQUEST 1
#define RESEND_UPDATE 2
struct resend {
unsigned char kind;
unsigned char max;
unsigned short delay;
struct timeval time;
unsigned char prefix[16];
unsigned char plen;
unsigned short seqno;
unsigned char id[8];
struct interface *ifp;
struct resend *next;
};
extern struct timeval resend_time;
struct resend *find_request(const unsigned char *prefix, unsigned char plen,
struct resend **previous_return);
void flush_resends(struct neighbour *neigh);
int record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id,
struct interface *ifp, int delay);
int unsatisfied_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id);
int request_redundant(struct interface *ifp,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id);
int satisfy_request(const unsigned char *prefix, unsigned char plen,
unsigned short seqno, const unsigned char *id,
struct interface *ifp);
void expire_resend(void);
void recompute_resend_time(void);
void do_resend(void);

File diff suppressed because it is too large Load diff

View file

@ -1,135 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef BABEL_ROUTE_H
#define BABEL_ROUTE_H
#include "babel_interface.h"
#include "source.h"
#define DIVERSITY_NONE 0
#define DIVERSITY_INTERFACE_1 1
#define DIVERSITY_CHANNEL_1 2
#define DIVERSITY_CHANNEL 3
#define DIVERSITY_HOPS 8
struct babel_route {
struct source *src;
unsigned short refmetric;
unsigned short cost;
unsigned short add_metric;
unsigned short seqno;
struct neighbour *neigh;
unsigned char nexthop[16];
time_t time;
unsigned short hold_time; /* in seconds */
short installed;
unsigned char channels[DIVERSITY_HOPS];
struct babel_route *next;
};
extern struct babel_route **routes;
extern int kernel_metric, allow_duplicates;
extern int diversity_kind, diversity_factor;
extern int keep_unfeasible;
static inline int
route_metric(const struct babel_route *route)
{
int m = (int)route->refmetric + route->cost + route->add_metric;
return MIN(m, INFINITY);
}
static inline int
route_metric_noninterfering(const struct babel_route *route)
{
int m =
(int)route->refmetric +
(diversity_factor * route->cost + 128) / 256 +
route->add_metric;
m = MAX(m, route->refmetric + 1);
return MIN(m, INFINITY);
}
struct babel_route *find_route(const unsigned char *prefix, unsigned char plen,
struct neighbour *neigh, const unsigned char *nexthop);
struct babel_route *find_installed_route(const unsigned char *prefix,
unsigned char plen);
int installed_routes_estimate(void);
void flush_route(struct babel_route *route);
void flush_all_routes(void);
void flush_neighbour_routes(struct neighbour *neigh);
void flush_interface_routes(struct interface *ifp, int v4only);
void for_all_routes(void (*f)(struct babel_route*, void*), void *closure);
void for_all_installed_routes(void (*f)(struct babel_route*, void*), void *closure);
void install_route(struct babel_route *route);
void uninstall_route(struct babel_route *route);
void switch_route(struct babel_route *old, struct babel_route *new);
int route_feasible(struct babel_route *route);
int route_old(struct babel_route *route);
int route_expired(struct babel_route *route);
int route_interferes(struct babel_route *route, struct interface *ifp);
int update_feasible(struct source *src,
unsigned short seqno, unsigned short refmetric);
struct babel_route *find_best_route(const unsigned char *prefix, unsigned char plen,
int feasible, struct neighbour *exclude);
struct babel_route *install_best_route(const unsigned char prefix[16],
unsigned char plen);
void update_neighbour_metric(struct neighbour *neigh, int change);
void update_interface_metric(struct interface *ifp);
void update_route_metric(struct babel_route *route);
struct babel_route *update_route(const unsigned char *id,
const unsigned char *prefix, unsigned char plen,
unsigned short seqno, unsigned short refmetric,
unsigned short interval, struct neighbour *neigh,
const unsigned char *nexthop,
const unsigned char *channels, int channels_len);
void retract_neighbour_routes(struct neighbour *neigh);
void send_unfeasible_request(struct neighbour *neigh, int force,
unsigned short seqno, unsigned short metric,
struct source *src);
void send_triggered_update(struct babel_route *route,
struct source *oldsrc, unsigned oldmetric);
void route_changed(struct babel_route *route,
struct source *oldsrc, unsigned short oldmetric);
void route_lost(struct source *src, unsigned oldmetric);
void expire_routes(void);
#endif

View file

@ -1,180 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "babel_main.h"
#include "babeld.h"
#include "util.h"
#include "source.h"
#include "babel_interface.h"
#include "route.h"
struct source *srcs = NULL;
struct source*
find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
int create, unsigned short seqno)
{
struct source *src;
for(src = srcs; src; src = src->next) {
/* This should really be a hash table. For now, check the
last byte first. */
if(src->id[7] != id[7])
continue;
if(memcmp(src->id, id, 8) != 0)
continue;
if(src->plen != plen)
continue;
if(memcmp(src->prefix, p, 16) == 0)
return src;
}
if(!create)
return NULL;
src = malloc(sizeof(struct source));
if(src == NULL) {
zlog_err("malloc(source): %s", safe_strerror(errno));
return NULL;
}
memcpy(src->id, id, 8);
memcpy(src->prefix, p, 16);
src->plen = plen;
src->seqno = seqno;
src->metric = INFINITY;
src->time = babel_now.tv_sec;
src->route_count = 0;
src->next = srcs;
srcs = src;
return src;
}
struct source *
retain_source(struct source *src)
{
assert(src->route_count < 0xffff);
src->route_count++;
return src;
}
void
release_source(struct source *src)
{
assert(src->route_count > 0);
src->route_count--;
}
int
flush_source(struct source *src)
{
if(src->route_count > 0)
/* The source is in use by a route. */
return 0;
if(srcs == src) {
srcs = src->next;
} else {
struct source *previous = srcs;
while(previous->next != src)
previous = previous->next;
previous->next = src->next;
}
free(src);
return 1;
}
void
update_source(struct source *src,
unsigned short seqno, unsigned short metric)
{
if(metric >= INFINITY)
return;
/* If a source is expired, pretend that it doesn't exist and update
it unconditionally. This makes ensures that old data will
eventually be overridden, and prevents us from getting stuck if
a router loses its sequence number. */
if(src->time < babel_now.tv_sec - SOURCE_GC_TIME ||
seqno_compare(src->seqno, seqno) < 0 ||
(src->seqno == seqno && src->metric > metric)) {
src->seqno = seqno;
src->metric = metric;
}
src->time = babel_now.tv_sec;
}
void
expire_sources()
{
struct source *src;
src = srcs;
while(src) {
if(src->time > babel_now.tv_sec)
/* clock stepped */
src->time = babel_now.tv_sec;
if(src->time < babel_now.tv_sec - SOURCE_GC_TIME) {
struct source *old = src;
src = src->next;
flush_source(old);
continue;
}
src = src->next;
}
}
void
check_sources_released(void)
{
struct source *src;
for(src = srcs; src; src = src->next) {
if(src->route_count != 0)
fprintf(stderr, "Warning: source %s %s has refcount %d.\n",
format_eui64(src->id),
format_prefix(src->prefix, src->plen),
(int)src->route_count);
}
}

View file

@ -1,67 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef BABEL_SOURCE_H
#define BABEL_SOURCE_H
#define SOURCE_GC_TIME 200
struct source {
struct source *next;
unsigned char id[8];
unsigned char prefix[16];
unsigned char plen;
unsigned short seqno;
unsigned short metric;
unsigned short route_count;
time_t time;
};
struct source *find_source(const unsigned char *id,
const unsigned char *p,
unsigned char plen,
int create, unsigned short seqno);
struct source *retain_source(struct source *src);
void release_source(struct source *src);
int flush_source(struct source *src);
void update_source(struct source *src,
unsigned short seqno, unsigned short metric);
void expire_sources(void);
void check_sources_released(void);
#endif

View file

@ -1,445 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "babel_main.h"
#include "babeld.h"
#include "util.h"
unsigned
roughly(unsigned value)
{
return value * 3 / 4 + random() % (value / 2);
}
/* d = s1 - s2 */
void
timeval_minus(struct timeval *d,
const struct timeval *s1, const struct timeval *s2)
{
if(s1->tv_usec >= s2->tv_usec) {
d->tv_usec = s1->tv_usec - s2->tv_usec;
d->tv_sec = s1->tv_sec - s2->tv_sec;
} else {
d->tv_usec = s1->tv_usec + 1000000 - s2->tv_usec;
d->tv_sec = s1->tv_sec - s2->tv_sec - 1;
}
}
unsigned
timeval_minus_msec(const struct timeval *s1, const struct timeval *s2)
{
if(s1->tv_sec < s2->tv_sec)
return 0;
/* Avoid overflow. */
if(s1->tv_sec - s2->tv_sec > 2000000)
return 2000000000;
if(s1->tv_sec > s2->tv_sec)
return
(unsigned)((unsigned)(s1->tv_sec - s2->tv_sec) * 1000 +
((int)s1->tv_usec - s2->tv_usec) / 1000);
if(s1->tv_usec <= s2->tv_usec)
return 0;
return (unsigned)(s1->tv_usec - s2->tv_usec) / 1000u;
}
/* d = s + msecs */
void
timeval_add_msec(struct timeval *d, const struct timeval *s, const int msecs)
{
int usecs;
d->tv_sec = s->tv_sec + msecs / 1000;
usecs = s->tv_usec + (msecs % 1000) * 1000;
if(usecs < 1000000) {
d->tv_usec = usecs;
} else {
d->tv_usec = usecs - 1000000;
d->tv_sec++;
}
}
void
set_timeout(struct timeval *timeout, int msecs)
{
timeval_add_msec(timeout, &babel_now, roughly(msecs));
}
/* returns <0 if "s1" < "s2", etc. */
int
timeval_compare(const struct timeval *s1, const struct timeval *s2)
{
if(s1->tv_sec < s2->tv_sec)
return -1;
else if(s1->tv_sec > s2->tv_sec)
return 1;
else if(s1->tv_usec < s2->tv_usec)
return -1;
else if(s1->tv_usec > s2->tv_usec)
return 1;
else
return 0;
}
/* set d at min(d, s) */
/* {0, 0} represents infinity */
void
timeval_min(struct timeval *d, const struct timeval *s)
{
if(s->tv_sec == 0)
return;
if(d->tv_sec == 0 || timeval_compare(d, s) > 0) {
*d = *s;
}
}
/* set d to min(d, x) with x in [secs, secs+1] */
void
timeval_min_sec(struct timeval *d, time_t secs)
{
if(d->tv_sec == 0 || d->tv_sec > secs) {
d->tv_sec = secs;
d->tv_usec = random() % 1000000;
}
}
/* parse a float value in second and return the corresponding mili-seconds.
For example:
parse_msec("12.342345") returns 12342 */
int
parse_msec(const char *string)
{
unsigned int in, fl;
int i, j;
in = fl = 0;
i = 0;
while(string[i] == ' ' || string[i] == '\t')
i++;
while(string[i] >= '0' && string[i] <= '9') {
in = in * 10 + string[i] - '0';
i++;
}
if(string[i] == '.') {
i++;
j = 0;
while(string[i] >= '0' && string[i] <= '9') {
fl = fl * 10 + string[i] - '0';
i++;
j++;
}
while(j > 3) {
fl /= 10;
j--;
}
while(j < 3) {
fl *= 10;
j++;
}
}
while(string[i] == ' ' || string[i] == '\t')
i++;
if(string[i] == '\0')
return in * 1000 + fl;
return -1;
}
int
in_prefix(const unsigned char *restrict address,
const unsigned char *restrict prefix, unsigned char plen)
{
unsigned char m;
if(plen > 128)
plen = 128;
if(memcmp(address, prefix, plen / 8) != 0)
return 0;
if(plen % 8 == 0)
return 1;
m = 0xFF << (8 - (plen % 8));
return ((address[plen / 8] & m) == (prefix[plen / 8] & m));
}
unsigned char *
mask_prefix(unsigned char *restrict ret,
const unsigned char *restrict prefix, unsigned char plen)
{
if(plen >= 128) {
memcpy(ret, prefix, 16);
return ret;
}
memset(ret, 0, 16);
memcpy(ret, prefix, plen / 8);
if(plen % 8 != 0)
ret[plen / 8] =
(prefix[plen / 8] & ((0xFF << (8 - (plen % 8))) & 0xFF));
return ret;
}
static const unsigned char v4prefix[16] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
static const unsigned char llprefix[16] =
{0xFE, 0x80};
const char *
format_address(const unsigned char *address)
{
static char buf[4][INET6_ADDRSTRLEN];
static int i = 0;
i = (i + 1) % 4;
if(v4mapped(address))
inet_ntop(AF_INET, address + 12, buf[i], INET6_ADDRSTRLEN);
else
inet_ntop(AF_INET6, address, buf[i], INET6_ADDRSTRLEN);
return buf[i];
}
const char *
format_prefix(const unsigned char *prefix, unsigned char plen)
{
static char buf[4][INET6_ADDRSTRLEN + 4];
static int i = 0;
int n;
i = (i + 1) % 4;
if(plen >= 96 && v4mapped(prefix)) {
inet_ntop(AF_INET, prefix + 12, buf[i], INET6_ADDRSTRLEN);
n = strlen(buf[i]);
snprintf(buf[i] + n, INET6_ADDRSTRLEN + 4 - n, "/%d", plen - 96);
} else {
inet_ntop(AF_INET6, prefix, buf[i], INET6_ADDRSTRLEN);
n = strlen(buf[i]);
snprintf(buf[i] + n, INET6_ADDRSTRLEN + 4 - n, "/%d", plen);
}
return buf[i];
}
const char *
format_eui64(const unsigned char *eui)
{
static char buf[4][28];
static int i = 0;
i = (i + 1) % 4;
snprintf(buf[i], 28, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
eui[0], eui[1], eui[2], eui[3],
eui[4], eui[5], eui[6], eui[7]);
return buf[i];
}
const char *format_bool(const int b) {
return b ? "true" : "false";
}
int
parse_address(const char *address, unsigned char *addr_r, int *af_r)
{
struct in_addr ina;
struct in6_addr ina6;
int rc;
rc = inet_pton(AF_INET, address, &ina);
if(rc > 0) {
memcpy(addr_r, v4prefix, 12);
memcpy(addr_r + 12, &ina, 4);
if(af_r) *af_r = AF_INET;
return 0;
}
rc = inet_pton(AF_INET6, address, &ina6);
if(rc > 0) {
memcpy(addr_r, &ina6, 16);
if(af_r) *af_r = AF_INET6;
return 0;
}
return -1;
}
int
parse_eui64(const char *eui, unsigned char *eui_r)
{
int n;
n = sscanf(eui, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
&eui_r[0], &eui_r[1], &eui_r[2], &eui_r[3],
&eui_r[4], &eui_r[5], &eui_r[6], &eui_r[7]);
if(n == 8)
return 0;
n = sscanf(eui, "%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx",
&eui_r[0], &eui_r[1], &eui_r[2], &eui_r[3],
&eui_r[4], &eui_r[5], &eui_r[6], &eui_r[7]);
if(n == 8)
return 0;
n = sscanf(eui, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
&eui_r[0], &eui_r[1], &eui_r[2],
&eui_r[5], &eui_r[6], &eui_r[7]);
if(n == 6) {
eui_r[3] = 0xFF;
eui_r[4] = 0xFE;
return 0;
}
return -1;
}
int
wait_for_fd(int direction, int fd, int msecs)
{
fd_set fds;
int rc;
struct timeval tv;
tv.tv_sec = msecs / 1000;
tv.tv_usec = (msecs % 1000) * 1000;
FD_ZERO(&fds);
FD_SET(fd, &fds);
if(direction)
rc = select(fd + 1, NULL, &fds, NULL, &tv);
else
rc = select(fd + 1, &fds, NULL, NULL, &tv);
return rc;
}
int
martian_prefix(const unsigned char *prefix, int plen)
{
return
(plen >= 8 && prefix[0] == 0xFF) ||
(plen >= 10 && prefix[0] == 0xFE && (prefix[1] & 0xC0) == 0x80) ||
(plen >= 128 && memcmp(prefix, zeroes, 15) == 0 &&
(prefix[15] == 0 || prefix[15] == 1)) ||
(plen >= 96 && v4mapped(prefix) &&
((plen >= 104 && (prefix[12] == 127 || prefix[12] == 0)) ||
(plen >= 100 && (prefix[12] & 0xE0) == 0xE0)));
}
int
linklocal(const unsigned char *address)
{
return memcmp(address, llprefix, 8) == 0;
}
int
v4mapped(const unsigned char *address)
{
return memcmp(address, v4prefix, 12) == 0;
}
void
v4tov6(unsigned char *dst, const unsigned char *src)
{
memcpy(dst, v4prefix, 12);
memcpy(dst + 12, src, 4);
}
void
inaddr_to_uchar(unsigned char *dest, const struct in_addr *src)
{
memcpy(dest, v4prefix, 12);
memcpy(dest + 12, src, 4);
assert(v4mapped(dest));
}
void
uchar_to_inaddr(struct in_addr *dest, const unsigned char *src)
{
assert(v4mapped(src));
memcpy(dest, src + 12, 4);
}
void
in6addr_to_uchar(unsigned char *dest, const struct in6_addr *src)
{
memcpy(dest, src, 16);
}
void
uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src)
{
memcpy(dest, src, 16);
}
int
daemonise()
{
int rc;
fflush(stdout);
fflush(stderr);
rc = fork();
if(rc < 0)
return -1;
if(rc > 0)
exit(0);
rc = setsid();
if(rc < 0)
return -1;
return 1;
}

View file

@ -1,165 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "babeld.h"
#include "babel_main.h"
#include "log.h"
#if defined(i386) || defined(__mc68020__) || defined(__x86_64__)
#define DO_NTOHS(_d, _s) do{ _d = ntohs(*(const unsigned short*)(_s)); }while(0)
#define DO_NTOHL(_d, _s) do{ _d = ntohl(*(const unsigned*)(_s)); } while(0)
#define DO_HTONS(_d, _s) do{ *(unsigned short*)(_d) = htons(_s); } while(0)
#define DO_HTONL(_d, _s) do{ *(unsigned*)(_d) = htonl(_s); } while(0)
/* Some versions of gcc seem to be buggy, and ignore the packed attribute.
Disable this code until the issue is clarified. */
/* #elif defined __GNUC__*/
#elif 0
struct __us { unsigned short x __attribute__((packed)); };
#define DO_NTOHS(_d, _s) \
do { _d = ntohs(((const struct __us*)(_s))->x); } while(0)
#define DO_HTONS(_d, _s) \
do { ((struct __us*)(_d))->x = htons(_s); } while(0)
#else
#define DO_NTOHS(_d, _s) \
do { short _dd; \
memcpy(&(_dd), (_s), 2); \
_d = ntohs(_dd); } while(0)
#define DO_HTONS(_d, _s) \
do { unsigned short _dd; \
_dd = htons(_s); \
memcpy((_d), &(_dd), 2); } while(0)
#endif
static inline int
seqno_compare(unsigned short s1, unsigned short s2)
{
if(s1 == s2)
return 0;
else
return ((s2 - s1) & 0x8000) ? 1 : -1;
}
static inline short
seqno_minus(unsigned short s1, unsigned short s2)
{
return (short)((s1 - s2) & 0xFFFF);
}
static inline unsigned short
seqno_plus(unsigned short s, int plus)
{
return ((s + plus) & 0xFFFF);
}
unsigned roughly(unsigned value);
void timeval_minus(struct timeval *d,
const struct timeval *s1, const struct timeval *s2);
unsigned timeval_minus_msec(const struct timeval *s1, const struct timeval *s2)
ATTRIBUTE ((pure));
void timeval_add_msec(struct timeval *d,
const struct timeval *s, const int msecs);
void set_timeout (struct timeval *timeout, int msecs);
int timeval_compare(const struct timeval *s1, const struct timeval *s2)
ATTRIBUTE ((pure));
void timeval_min(struct timeval *d, const struct timeval *s);
void timeval_min_sec(struct timeval *d, time_t secs);
int parse_msec(const char *string) ATTRIBUTE ((pure));
int in_prefix(const unsigned char *restrict address,
const unsigned char *restrict prefix, unsigned char plen)
ATTRIBUTE ((pure));
unsigned char *mask_prefix(unsigned char *restrict ret,
const unsigned char *restrict prefix,
unsigned char plen);
const char *format_address(const unsigned char *address);
const char *format_prefix(const unsigned char *address, unsigned char prefix);
const char *format_eui64(const unsigned char *eui);
const char *format_bool(const int b);
int parse_address(const char *address, unsigned char *addr_r, int *af_r);
int parse_eui64(const char *eui, unsigned char *eui_r);
int wait_for_fd(int direction, int fd, int msecs);
int martian_prefix(const unsigned char *prefix, int plen) ATTRIBUTE ((pure));
int linklocal(const unsigned char *address) ATTRIBUTE ((pure));
int v4mapped(const unsigned char *address) ATTRIBUTE ((pure));
void v4tov6(unsigned char *dst, const unsigned char *src);
void inaddr_to_uchar(unsigned char *dest, const struct in_addr *src);
void uchar_to_inaddr(struct in_addr *dest, const unsigned char *src);
void in6addr_to_uchar(unsigned char *dest, const struct in6_addr *src);
void uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src);
int daemonise(void);
/* If debugging is disabled, we want to avoid calling format_address
for every omitted debugging message. So debug is a macro. But
vararg macros are not portable. */
#if defined NO_DEBUG
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define debugf(...) do {} while(0)
#elif defined __GNUC__
#define debugf(_args...) do {} while(0)
#else
static inline void debugf(int level, const char *format, ...) { return; }
#endif
#else /* NO_DEBUG */
/* some levels */
#define BABEL_DEBUG_COMMON (1 << 0)
#define BABEL_DEBUG_KERNEL (1 << 1)
#define BABEL_DEBUG_FILTER (1 << 2)
#define BABEL_DEBUG_TIMEOUT (1 << 3)
#define BABEL_DEBUG_IF (1 << 4)
#define BABEL_DEBUG_ROUTE (1 << 5)
#define BABEL_DEBUG_ALL (0xFFFF)
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define debugf(level, ...) \
do { \
if(UNLIKELY(debug & level)) zlog_debug(__VA_ARGS__); \
} while(0)
#elif defined __GNUC__
#define debugf(level, _args...) \
do { \
if(UNLIKELY(debug & level)) zlog_debug(_args); \
} while(0)
#else
static inline void debugf(int level, const char *format, ...) { return; }
#endif
#endif /* NO_DEBUG */

View file

@ -1,237 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <zebra.h>
#include "if.h"
#include "log.h"
#include "babeld.h"
#include "kernel.h"
#include "neighbour.h"
#include "message.h"
#include "route.h"
#include "xroute.h"
#include "util.h"
#include "babel_interface.h"
static int xroute_add_new_route(unsigned char prefix[16], unsigned char plen,
unsigned short metric, unsigned int ifindex,
int proto, int send_updates);
static struct xroute *xroutes;
static int numxroutes = 0, maxxroutes = 0;
/* Add redistributed route to Babel table. */
int
babel_ipv4_route_add (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix,
unsigned int ifindex, struct in_addr *nexthop)
{
unsigned char uchar_prefix[16];
inaddr_to_uchar(uchar_prefix, &prefix->prefix);
debugf(BABEL_DEBUG_ROUTE, "Adding new ipv4 route comming from Zebra.");
xroute_add_new_route(uchar_prefix, prefix->prefixlen + 96,
api->metric, ifindex, 0, 1);
return 0;
}
/* Remove redistributed route from Babel table. */
int
babel_ipv4_route_delete (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix,
unsigned int ifindex)
{
unsigned char uchar_prefix[16];
struct xroute *xroute = NULL;
inaddr_to_uchar(uchar_prefix, &prefix->prefix);
xroute = find_xroute(uchar_prefix, prefix->prefixlen + 96);
if (xroute != NULL) {
debugf(BABEL_DEBUG_ROUTE, "Removing ipv4 route (from zebra).");
flush_xroute(xroute);
}
return 0;
}
/* Add redistributed route to Babel table. */
int
babel_ipv6_route_add (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix,
unsigned int ifindex, struct in6_addr *nexthop)
{
unsigned char uchar_prefix[16];
in6addr_to_uchar(uchar_prefix, &prefix->prefix);
debugf(BABEL_DEBUG_ROUTE, "Adding new route comming from Zebra.");
xroute_add_new_route(uchar_prefix, prefix->prefixlen, api->metric, ifindex,
0, 1);
return 0;
}
/* Remove redistributed route from Babel table. */
int
babel_ipv6_route_delete (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix,
unsigned int ifindex)
{
unsigned char uchar_prefix[16];
struct xroute *xroute = NULL;
in6addr_to_uchar(uchar_prefix, &prefix->prefix);
xroute = find_xroute(uchar_prefix, prefix->prefixlen);
if (xroute != NULL) {
debugf(BABEL_DEBUG_ROUTE, "Removing route (from zebra).");
flush_xroute(xroute);
}
return 0;
}
struct xroute *
find_xroute(const unsigned char *prefix, unsigned char plen)
{
int i;
for(i = 0; i < numxroutes; i++) {
if(xroutes[i].plen == plen &&
memcmp(xroutes[i].prefix, prefix, 16) == 0)
return &xroutes[i];
}
return NULL;
}
void
flush_xroute(struct xroute *xroute)
{
int i;
i = xroute - xroutes;
assert(i >= 0 && i < numxroutes);
if(i != numxroutes - 1)
memcpy(xroutes + i, xroutes + numxroutes - 1, sizeof(struct xroute));
numxroutes--;
VALGRIND_MAKE_MEM_UNDEFINED(xroutes + numxroutes, sizeof(struct xroute));
if(numxroutes == 0) {
free(xroutes);
xroutes = NULL;
maxxroutes = 0;
} else if(maxxroutes > 8 && numxroutes < maxxroutes / 4) {
struct xroute *new_xroutes;
int n = maxxroutes / 2;
new_xroutes = realloc(xroutes, n * sizeof(struct xroute));
if(new_xroutes == NULL)
return;
xroutes = new_xroutes;
maxxroutes = n;
}
}
static int
add_xroute(unsigned char prefix[16], unsigned char plen,
unsigned short metric, unsigned int ifindex, int proto)
{
struct xroute *xroute = find_xroute(prefix, plen);
if(xroute) {
if(xroute->metric <= metric)
return 0;
xroute->metric = metric;
return 1;
}
if(numxroutes >= maxxroutes) {
struct xroute *new_xroutes;
int n = maxxroutes < 1 ? 8 : 2 * maxxroutes;
new_xroutes = xroutes == NULL ?
malloc(n * sizeof(struct xroute)) :
realloc(xroutes, n * sizeof(struct xroute));
if(new_xroutes == NULL)
return -1;
maxxroutes = n;
xroutes = new_xroutes;
}
memcpy(xroutes[numxroutes].prefix, prefix, 16);
xroutes[numxroutes].plen = plen;
xroutes[numxroutes].metric = metric;
xroutes[numxroutes].ifindex = ifindex;
xroutes[numxroutes].proto = proto;
numxroutes++;
return 1;
}
/* Returns an overestimate of the number of xroutes. */
int
xroutes_estimate()
{
return numxroutes;
}
void
for_all_xroutes(void (*f)(struct xroute*, void*), void *closure)
{
int i;
for(i = 0; i < numxroutes; i++)
(*f)(&xroutes[i], closure);
}
/* add an xroute, verifying some conditions; return 0 if there is no changes */
static int
xroute_add_new_route(unsigned char prefix[16], unsigned char plen,
unsigned short metric, unsigned int ifindex,
int proto, int send_updates)
{
int rc;
if(martian_prefix(prefix, plen))
return 0;
metric = redistribute_filter(prefix, plen, ifindex, proto);
if(metric < INFINITY) {
rc = add_xroute(prefix, plen, metric, ifindex, proto);
if(rc > 0) {
struct babel_route *route;
route = find_installed_route(prefix, plen);
if(route) {
if(allow_duplicates < 0 ||
metric < allow_duplicates)
uninstall_route(route);
}
if(send_updates)
send_update(NULL, 0, prefix, plen);
return 1;
}
}
return 0;
}

View file

@ -1,59 +0,0 @@
/*
* This file is free software: you may copy, redistribute and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
struct xroute {
unsigned char prefix[16];
unsigned char plen;
unsigned short metric;
unsigned int ifindex;
int proto;
};
struct xroute *find_xroute(const unsigned char *prefix, unsigned char plen);
void flush_xroute(struct xroute *xroute);
int babel_ipv4_route_add (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix,
unsigned int ifindex, struct in_addr *nexthop);
int babel_ipv4_route_delete (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix,
unsigned int ifindex);
int babel_ipv6_route_add (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix,
unsigned int ifindex, struct in6_addr *nexthop);
int babel_ipv6_route_delete (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix,
unsigned int ifindex);
int xroutes_estimate(void);
void for_all_xroutes(void (*f)(struct xroute*, void*), void *closure);

View file

@ -4,7 +4,7 @@
# builds some git commit of Quagga in some different configurations
# usage: buildtest.sh [commit [configurations...]]
basecfg="--prefix=/usr --enable-user=quagga --enable-group=quagga --enable-vty-group=quagga --enable-configfile-mask=0660 --enable-logfile-mask=0640 --enable-vtysh --sysconfdir=/etc/quagga --enable-exampledir=/etc/quagga/samples --localstatedir=/var/run/quagga --libdir=/usr/lib64/quagga --enable-ipv6 --enable-ripngd --enable-ospf6d --enable-rtadv --disable-static --enable-isisd --enable-multipath=0 --enable-babeld --enable-werror"
basecfg="--prefix=/usr --enable-user=quagga --enable-group=quagga --enable-vty-group=quagga --enable-configfile-mask=0660 --enable-logfile-mask=0640 --enable-vtysh --sysconfdir=/etc/quagga --enable-exampledir=/etc/quagga/samples --localstatedir=/var/run/quagga --libdir=/usr/lib64/quagga --enable-ipv6 --enable-ripngd --enable-ospf6d --enable-rtadv --disable-static --enable-isisd --enable-multipath=0 --enable-werror"
configs_base="gcc|$basecfg"
@ -12,7 +12,6 @@ configs_nov6="gcc|$basecfg"
configs_nov6="${configs_nov6/enable-ipv6/disable-ipv6}"
configs_nov6="${configs_nov6/enable-ospf6d/disable-ospf6d}"
configs_nov6="${configs_nov6/enable-ripngd/disable-ripngd}"
configs_nov6="${configs_nov6/enable-babeld/disable-babeld}"
configs_ext="gcc|$basecfg --enable-opaque-lsa --enable-ospf-te --enable-ospfclient --enable-isis-topology"
configs_snmp="gcc|$basecfg --enable-opaque-lsa --enable-ospf-te --enable-ospfclient --enable-isis-topology --enable-snmp"

View file

@ -232,8 +232,6 @@ AC_ARG_ENABLE(ospfd,
[ --disable-ospfd do not build ospfd])
AC_ARG_ENABLE(ospf6d,
[ --disable-ospf6d do not build ospf6d])
AC_ARG_ENABLE(babeld,
[ --disable-babeld do not build babeld])
AC_ARG_ENABLE(watchquagga,
[ --disable-watchquagga do not build watchquagga])
AC_ARG_ENABLE(isisd,
@ -1335,13 +1333,6 @@ else
fi
AM_CONDITIONAL(OSPFD, test "x$OSPFD" = "xospfd")
if test "${enable_babeld}" = "no";then
BABELD=""
else
BABELD="babeld"
fi
AM_CONDITIONAL(BABELD, test "x$BABELD" = "xbabeld")
if test "${enable_watchquagga}" = "no";then
WATCHQUAGGA=""
else
@ -1403,7 +1394,6 @@ AC_SUBST(RIPD)
AC_SUBST(RIPNGD)
AC_SUBST(OSPFD)
AC_SUBST(OSPF6D)
AC_SUBST(BABELD)
AC_SUBST(WATCHQUAGGA)
AC_SUBST(ISISD)
AC_SUBST(SOLARIS)
@ -1704,7 +1694,6 @@ AC_DEFINE_UNQUOTED(PATH_RIPNGD_PID, "$quagga_statedir/ripngd.pid",ripngd PID)
AC_DEFINE_UNQUOTED(PATH_BGPD_PID, "$quagga_statedir/bgpd.pid",bgpd PID)
AC_DEFINE_UNQUOTED(PATH_OSPFD_PID, "$quagga_statedir/ospfd.pid",ospfd PID)
AC_DEFINE_UNQUOTED(PATH_OSPF6D_PID, "$quagga_statedir/ospf6d.pid",ospf6d PID)
AC_DEFINE_UNQUOTED(PATH_BABELD_PID, "$quagga_statedir/babeld.pid",babeld PID)
AC_DEFINE_UNQUOTED(PATH_ISISD_PID, "$quagga_statedir/isisd.pid",isisd PID)
AC_DEFINE_UNQUOTED(PATH_WATCHQUAGGA_PID, "$quagga_statedir/watchquagga.pid",watchquagga PID)
AC_DEFINE_UNQUOTED(ZEBRA_SERV_PATH, "$quagga_statedir/zserv.api",zebra api socket)
@ -1714,7 +1703,6 @@ AC_DEFINE_UNQUOTED(RIPNG_VTYSH_PATH, "$quagga_statedir/ripngd.vty",ripng vty soc
AC_DEFINE_UNQUOTED(BGP_VTYSH_PATH, "$quagga_statedir/bgpd.vty",bgpd vty socket)
AC_DEFINE_UNQUOTED(OSPF_VTYSH_PATH, "$quagga_statedir/ospfd.vty",ospfd vty socket)
AC_DEFINE_UNQUOTED(OSPF6_VTYSH_PATH, "$quagga_statedir/ospf6d.vty",ospf6d vty socket)
AC_DEFINE_UNQUOTED(BABEL_VTYSH_PATH, "$quagga_statedir/babeld.vty",babeld vty socket)
AC_DEFINE_UNQUOTED(ISIS_VTYSH_PATH, "$quagga_statedir/isisd.vty",isisd vty socket)
AC_DEFINE_UNQUOTED(DAEMON_VTY_DIR, "$quagga_statedir",daemon vty directory)
@ -1739,7 +1727,7 @@ AC_MSG_RESULT($ac_cv_htonl_works)
AC_CONFIG_FILES([Makefile lib/Makefile zebra/Makefile ripd/Makefile
ripngd/Makefile bgpd/Makefile ospfd/Makefile watchquagga/Makefile
ospf6d/Makefile isisd/Makefile babeld/Makefile vtysh/Makefile
ospf6d/Makefile isisd/Makefile vtysh/Makefile
doc/Makefile ospfclient/Makefile tests/Makefile m4/Makefile
tests/bgpd.tests/Makefile
tests/libzebra.tests/Makefile

View file

@ -11,7 +11,6 @@ ospf6d_options=" --daemon -A ::1"
ripd_options=" --daemon -A 127.0.0.1"
ripngd_options=" --daemon -A ::1"
isisd_options=" --daemon -A 127.0.0.1"
babeld_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script.
watchquagga_enable=yes
watchquagga_options=(-adz -r /usr/sbin/servicebBquaggabBrestartbB%s -s /usr/sbin/servicebBquaggabBstartbB%s -k /usr/sbin/servicebBquaggabBstopbB%s -b bB -t 30)

View file

@ -108,9 +108,3 @@ See message #4525 from 2005-05-09 in the quagga-users mailing list.
Check /etc/pam.d/quagga, it probably denies access to your user. The passwords
configured in /etc/quagga/Quagga.conf are only for telnet access.
* Where is the babeld.8 manpage?
================================
It conflicted with the one from the babeld package and was therefore be
renamed to quagga-babeld.8.

20
debian/babeld.service vendored
View file

@ -1,20 +0,0 @@
[Unit]
Description=Babel routing daemon
After=syslog.target networking.service zebra.service
OnFailure=heartbeat-failed@%n.service
[Service]
Nice=-5
Type=notify
EnvironmentFile=/etc/default/quagga
StartLimitInterval=3m
StartLimitBurst=3
TimeoutSec=1m
WatchdogSec=60s
RestartSec=5
Restart=on-abnormal
LimitNOFILE=1024
ExecStart=/usr/lib/quagga/babeld $BABEL_OPTIONS
ExecStartPost=/usr/bin/vtysh -b -n
[Install]
WantedBy=network.target

108
debian/my/babeld.8 vendored
View file

@ -1,108 +0,0 @@
.TH babeld 8 "05 May 2012" "Quagga BABEL daemon" "Version 0.99.21"
.SH NAME
babeld \- a BABEL ad-hoc network routing engine for use with Quagga routing software.
.SH SYNOPSIS
.B babeld
[
.B \-f
.I config-file
] [
.B \-i
.I pid-file
] [
.B \-P
.I vty-port-number
] [
.B \-A
.I vty-address
] [
.B \-u
.I user
] [
.B \-g
.I group
]
.SH DESCRIPTION
.B babeld
is a routing component that works with the
.B Quagga
routing engine.
.SH OPTIONS
Options available for the
.B babeld
command:
.SH OPTIONS
.TP
\fB\-d\fR, \fB\-\-daemon\fR
Runs in daemon mode, forking and exiting from tty.
.TP
\fB\-f\fR, \fB\-\-config-file \fR\fIconfig-file\fR
Specifies the config file to use for startup. If not specified this
option will likely default to \fB\fI/usr/local/etc/babeld.conf\fR.
.TP
\fB\-g\fR, \fB\-\-group \fR\fIgroup\fR
Specify the group to run as. Default is \fIquagga\fR.
.TP
\fB\-h\fR, \fB\-\-help\fR
A brief message.
.TP
\fB\-i\fR, \fB\-\-pid_file \fR\fIpid-file\fR
When babeld starts its process identifier is written to
\fB\fIpid-file\fR. The init system uses the recorded PID to stop or
restart babeld. The likely default is \fB\fI/var/run/babeld.pid\fR.
.TP
\fB\-P\fR, \fB\-\-vty_port \fR\fIport-number\fR
Specify the port that the babeld VTY will listen on. This defaults to
2602, as specified in \fB\fI/etc/services\fR.
.TP
\fB\-A\fR, \fB\-\-vty_addr \fR\fIvty-address\fR
Specify the address that the babeld VTY will listen on. Default is all
interfaces.
.TP
\fB\-u\fR, \fB\-\-user \fR\fIuser\fR
Specify the user to run as. Default is \fIquagga\fR.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH FILES
.TP
.BI /usr/local/sbin/babeld
The default location of the
.B babeld
binary.
.TP
.BI /usr/local/etc/babeld.conf
The default location of the
.B babeld
config file.
.TP
.BI $(PWD)/babeld.log
If the
.B babeld
process is config'd to output logs to a file, then you will find this
file in the directory where you started \fBbabeld\fR.
.SH WARNING
This man page is intended to be a quick reference for command line
options. The definitive document is the Info file \fBQuagga\fR.
.SH DIAGNOSTICS
The babeld process may log to standard output, to a VTY, to a log
file, or through syslog to the system logs. \fBbabeld\fR supports many
debugging options, see the Info file, or the source for details.
.SH "SEE ALSO"
.BR bgpd (8),
.BR ripngd (8),
.BR ospfd (8),
.BR ospf6d (8),
.BR isisd (8),
.BR zebra (8),
.BR vtysh (1)
.SH BUGS
.B babeld
eats bugs for breakfast. If you have food for the maintainers try
.BI http://bugzilla.quagga.net
.SH AUTHORS
See
.BI http://www.zebra.org
and
.BI http://www.quagga.net
or the Info file for an accurate list of authors.

View file

@ -4,9 +4,6 @@
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* babeld vty socket */
#define BABEL_VTYSH_PATH "/var/run/quagga/babeld.vty"
/* bgpd vty socket */
#define BGP_VTYSH_PATH "/var/run/quagga/bgpd.vty"
@ -652,9 +649,6 @@
/* Have openpam_ttyconv */
#define PAM_CONV_FUNC misc_conv
/* babeld PID */
#define PATH_BABELD_PID "/var/run/quagga/babeld.pid"
/* bgpd PID */
#define PATH_BGPD_PID "/var/run/quagga/bgpd.pid"

1
debian/my/daemons vendored
View file

@ -28,4 +28,3 @@ ospf6d=no
ripd=no
ripngd=no
isisd=no
babeld=no

View file

@ -11,7 +11,6 @@ ospf6d_options=" --daemon -A ::1"
ripd_options=" --daemon -A 127.0.0.1"
ripngd_options=" --daemon -A ::1"
isisd_options=" --daemon -A 127.0.0.1"
babeld_options=" --daemon -A 127.0.0.1"
#
# Please note that watchquagga_options is an array and not a string so that
# quotes can be used.

View file

@ -7,4 +7,3 @@ OSPF6D_OPTIONS="-A ::1"
RIPD_OPTIONS="-A 127.0.0.1"
RIPNGD_OPTIONS="-A ::1"
ISISD_OPTIONS="-A 127.0.0.1"
BABELD_OPTIONS="-A 127.0.0.1"

View file

@ -13,7 +13,6 @@ usr/share/man/man8/ripd.8
usr/share/man/man8/ripngd.8
usr/share/man/man8/zebra.8
usr/share/man/man8/isisd.8
usr/share/man/man8/quagga-babeld.8
usr/share/man/man8/watchquagga.8
usr/share/snmp/mibs/
cumulus/etc/* etc/

View file

@ -7,7 +7,7 @@
create 640 quagga quaggavty
postrotate
for i in zebra bgpd ripd ospfd ripngd ospf6d isisd babeld; do
for i in zebra bgpd ripd ospfd ripngd ospf6d isisd; do
if [ -e /var/run/quagga/$i.pid ] ; then
kill -USR1 `cat /var/run/quagga/$i.pid`
fi

View file

@ -9,7 +9,6 @@ RemainAfterExit=yes
TimeoutSec=2m30s
TimeoutStopSec=1m
ExecStartPre=-/bin/systemctl start zebra.service
ExecStartPre=-/bin/systemctl start babeld.service
ExecStartPre=-/bin/systemctl start bgpd.service
ExecStartPre=-/bin/systemctl start isisd.service
ExecStartPre=-/bin/systemctl start ospfd.service
@ -21,7 +20,6 @@ ExecStartPost=-/usr/bin/vtysh -b -n
ExecStart=/bin/true
ExecStop=/bin/true
#
ExecStopPost=-/bin/systemctl stop babeld.service
ExecStopPost=-/bin/systemctl stop bgpd.service
ExecStopPost=-/bin/systemctl stop isisd.service
ExecStopPost=-/bin/systemctl stop ospfd.service

5
debian/rules vendored
View file

@ -107,15 +107,11 @@ override_dh_auto_install:
# installing the Quagga specific SNMP MIB
install -D -m 644 ./zebra/GNOME-PRODUCT-ZEBRA-MIB debian/tmp/usr/share/snmp/mibs/GNOME-PRODUCT-ZEBRA-MIB
# installing custom man page
cp debian/my/babeld.8 debian/tmp/usr/share/man/man8/quagga-babeld.8
# cleaning .la files
sed -i "/dependency_libs/ s/'.*'/''/" debian/tmp/usr/lib/*.la
override_dh_systemd_start:
dh_systemd_start quagga.service
dh_systemd_start babeld.service
dh_systemd_start bgpd.service
dh_systemd_start isisd.service
dh_systemd_start ospfd.service
@ -126,7 +122,6 @@ override_dh_systemd_start:
override_dh_systemd_enable:
dh_systemd_enable --no-enable quagga.service
dh_systemd_enable --no-enable babeld.service
dh_systemd_enable --no-enable bgpd.service
dh_systemd_enable --no-enable isisd.service
dh_systemd_enable --no-enable ospfd.service

View file

@ -6,7 +6,7 @@ set -e
# modify config file to enable all daemons and copy config files
CONFIG_FILE=/etc/quagga/daemons
DAEMONS=("zebra" "bgpd" "ospfd" "ospf6d" "ripd" "ripngd" "isisd" "babeld")
DAEMONS=("zebra" "bgpd" "ospfd" "ospf6d" "ripd" "ripngd" "isisd")
for daemon in "${DAEMONS[@]}"
do

View file

@ -46,7 +46,7 @@ info_TEXINFOS = quagga.texi
quagga.pdf: $(info_TEXINFOS) $(figures_pdf) $(quagga_TEXINFOS)
$(TEXI2PDF) -o "$@" $<
quagga_TEXINFOS = appendix.texi babeld.texi basic.texi bgpd.texi filter.texi \
quagga_TEXINFOS = appendix.texi basic.texi bgpd.texi filter.texi \
install.texi ipv6.texi kernel.texi main.texi ospf6d.texi ospfd.texi \
overview.texi protocol.texi ripd.texi ripngd.texi routemap.texi \
snmp.texi vtysh.texi routeserver.texi defines.texi $(figures_png) \

View file

@ -1,118 +0,0 @@
@c -*-texinfo-*-
@c This is part of the Quagga Manual.
@c @value{COPYRIGHT_STR}
@c See file quagga.texi for copying conditions.
@node Babel
@chapter Babel
Babel is an interior gateway protocol that is suitable both for wired
networks and for wireless mesh networks. Babel has been described as
``RIP on speed'' --- it is based on the same principles as RIP, but
includes a number of refinements that make it react much faster to
topology changes without ever counting to infinity, and allow it to
perform reliable link quality estimation on wireless links. Babel is
a double-stack routing protocol, meaning that a single Babel instance
is able to perform routing for both IPv4 and IPv6.
Quagga implements Babel as described in RFC6126.
@menu
* Configuring babeld::
* Babel configuration::
* Babel redistribution::
* Show Babel information::
* Babel debugging commands::
@end menu
@node Configuring babeld, Babel configuration, Babel, Babel
@section Configuring babeld
The @command{babeld} daemon can be invoked with any of the common
options (@pxref{Common Invocation Options}).
The @command{zebra} daemon must be running before @command{babeld} is
invoked. Also, if @command{zebra} is restarted then @command{babeld}
must be too.
Configuration of @command{babeld} is done in its configuration file
@file{babeld.conf}.
@node Babel configuration, Babel redistribution, Configuring babeld, Babel
@section Babel configuration
@deffn Command {router babel} {}
@deffnx Command {no router babel} {}
Enable or disable Babel routing.
@end deffn
@deffn {Babel Command} {network @var{ifname}} {}
@deffnx {Babel Command} {no network @var{ifname}} {}
Enable or disable Babel on the given interface.
@end deffn
@deffn {Interface Command} {babel wired} {}
@deffnx {Interface Command} {babel wireless} {}
Specifies whether this interface is wireless, which disables a number
of optimisations that are only correct on wired interfaces.
Specifying @code{wireless} (the default) is always correct, but may
cause slower convergence and extra routing traffic.
@end deffn
@deffn {Interface Command} {babel split-horizon}
@deffnx {Interface Command} {no babel split-horizon}
Specifies whether to perform split-horizon on the interface.
Specifying @code{no babel split-horizon} (the default) is always
correct, while @code{babel split-horizon} is an optimisation that
should only be used on symmetric and transitive (wired) networks.
@end deffn
@deffn {Interface Command} {babel hello-interval <20-655340>}
Specifies the time in milliseconds between two scheduled hellos. On
wired links, Babel notices a link failure within two hello intervals;
on wireless links, the link quality value is reestimated at every
hello interval. The default is 4000@dmn{ms}.
@end deffn
@deffn {Interface Command} {babel update-interval <20-655340>}
Specifies the time in milliseconds between two scheduled updates.
Since Babel makes extensive use of triggered updates, this can be set
to fairly high values on links with little packet loss. The default
is 20000@dmn{ms}.
@end deffn
@deffn {Babel Command} {babel resend-delay <20-655340>}
Specifies the time in milliseconds after which an ``important''
request or update will be resent. The default is 2000@dmn{ms}. You
probably don't want to tweak this value.
@end deffn
@node Babel redistribution, Show Babel information, Babel configuration, Babel
@section Babel redistribution
@deffn {Babel command} {redistribute @var{kind}}
@deffnx {Babel command} {no redistribute @var{kind}}
Specify which kind of routes should be redistributed into Babel.
@end deffn
@node Show Babel information, Babel debugging commands, Babel redistribution, Babel
@section Show Babel information
@deffn {Command} {show babel database} {}
@deffnx {Command} {show babel interface} {}
@deffnx {Command} {show babel neighbour} {}
@deffnx {Command} {show babel parameters} {}
These commands dump various parts of @command{babeld}'s internal
state. They are mostly useful for troubleshooting.
@end deffn
@node Babel debugging commands, , Show Babel information, Babel
@section Babel debugging commands
@deffn {Babel Command} {debug babel @var{kind}} {}
@deffnx {Babel Command} {no debug babel @var{kind}} {}
Enable or disable debugging messages of a given kind. @var{kind} can
be one of @samp{common}, @samp{kernel}, @samp{filter}, @samp{timeout},
@samp{interface}, @samp{route} or @samp{all}. Note that if you have
compiled with the NO_DEBUG flag, then these commands aren't available.
@end deffn

View file

@ -2,7 +2,7 @@
@chapter IPv6 Support
Quagga fully supports IPv6 routing. As described so far, Quagga supports
RIPng, OSPFv3, Babel and BGP-4+. You can give IPv6 addresses to an interface
RIPng, OSPFv3, and BGP-4+. You can give IPv6 addresses to an interface
and configure static IPv6 routing information. Quagga IPv6 also provides
automatic address configuration via a feature called @code{address
auto configuration}. To do it, the router must send router advertisement

View file

@ -86,7 +86,6 @@ for @value{PACKAGE_STRING}. @uref{http://www.quagga.net,,Quagga} is a fork of
* RIPng::
* OSPFv2::
* OSPFv3::
* Babel::
* BGP::
* Configuring Quagga as a Route Server::
* VTY shell::
@ -111,7 +110,6 @@ for @value{PACKAGE_STRING}. @uref{http://www.quagga.net,,Quagga} is a fork of
@include ripngd.texi
@include ospfd.texi
@include ospf6d.texi
@include babeld.texi
@include bgpd.texi
@include routeserver.texi
@include vtysh.texi

View file

@ -2935,7 +2935,6 @@ DEFUN (config_exit,
case BGP_NODE:
case RIP_NODE:
case RIPNG_NODE:
case BABEL_NODE:
case OSPF_NODE:
case OSPF6_NODE:
case ISIS_NODE:
@ -2986,7 +2985,6 @@ DEFUN (config_end,
case ZEBRA_NODE:
case RIP_NODE:
case RIPNG_NODE:
case BABEL_NODE:
case BGP_NODE:
case BGP_VPNV4_NODE:
case BGP_IPV4_NODE:

View file

@ -80,7 +80,6 @@ enum node_type
TABLE_NODE, /* rtm_table selection node. */
RIP_NODE, /* RIP protocol mode node. */
RIPNG_NODE, /* RIPng protocol mode node. */
BABEL_NODE, /* Babel protocol mode node. */
BGP_NODE, /* BGP protocol mode which includes BGP4+ */
BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */
BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */

View file

@ -775,10 +775,9 @@ distribute_list_init (int node)
install_element (node, &no_distribute_list_prefix_all_cmd);
install_element (node, &distribute_list_prefix_cmd);
install_element (node, &no_distribute_list_prefix_cmd);
} else if (node == RIPNG_NODE || node == BABEL_NODE) {
} else if (node == RIPNG_NODE) {
/* WARNING: two identical commands installed do a crash, so be worry with
aliases. For this reason, and because all these commands are aliases, Babel
is not set with RIP. */
* aliases */
install_element (node, &ipv6_distribute_list_all_cmd);
install_element (node, &no_ipv6_distribute_list_all_cmd);
install_element (node, &ipv6_distribute_list_cmd);

View file

@ -48,7 +48,6 @@ const char *zlog_proto_names[] =
"BGP",
"OSPF",
"RIPNG",
"BABEL",
"OSPF6",
"ISIS",
"MASC",
@ -963,8 +962,6 @@ proto_redistnum(int afi, const char *s)
else if (strncmp (s, "bg", 2) == 0)
return ZEBRA_ROUTE_BGP;
else if (strncmp (s, "ba", 2) == 0)
return ZEBRA_ROUTE_BABEL;
else if (strncmp (s, "t", 1) == 0)
return ZEBRA_ROUTE_TABLE;
}
if (afi == AFI_IP6)
@ -984,8 +981,6 @@ proto_redistnum(int afi, const char *s)
else if (strncmp (s, "bg", 2) == 0)
return ZEBRA_ROUTE_BGP;
else if (strncmp (s, "ba", 2) == 0)
return ZEBRA_ROUTE_BABEL;
else if (strncmp (s, "t", 1) == 0)
return ZEBRA_ROUTE_TABLE;
}
return -1;

View file

@ -50,7 +50,6 @@ typedef enum
ZLOG_BGP,
ZLOG_OSPF,
ZLOG_RIPNG,
ZLOG_BABEL,
ZLOG_OSPF6,
ZLOG_ISIS,
ZLOG_MASC

View file

@ -199,13 +199,6 @@ struct memory_list memory_list_ripng[] =
{ -1, NULL }
};
struct memory_list memory_list_babel[] =
{
{ MTYPE_BABEL, "Babel structure" },
{ MTYPE_BABEL_IF, "Babel interface" },
{ -1, NULL }
};
struct memory_list memory_list_ospf[] =
{
{ MTYPE_OSPF_TOP, "OSPF top" },

View file

@ -58,7 +58,6 @@ ZEBRA_ROUTE_BGP, bgp, bgpd, 'B', 1, 1, "BGP"
# possible).
ZEBRA_ROUTE_HSLS, hsls, hslsd, 'H', 0, 0, "HSLS"
ZEBRA_ROUTE_OLSR, olsr, olsrd, 'o', 0, 0, "OLSR"
ZEBRA_ROUTE_BABEL, babel, babeld, 'A', 1, 1, "Babel"
ZEBRA_ROUTE_TABLE, table, zebra, 'T', 1, 1, "Table"
## help strings
@ -74,5 +73,4 @@ 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_BABEL, "Babel routing protocol (Babel)"
ZEBRA_ROUTE_TABLE, "Non-main Kernel Routing Table"

View file

@ -45,7 +45,6 @@ typedef enum
{
RMAP_RIP,
RMAP_RIPNG,
RMAP_BABEL,
RMAP_OSPF,
RMAP_OSPF6,
RMAP_BGP,

View file

@ -701,7 +701,6 @@ vty_end_config (struct vty *vty)
case ZEBRA_NODE:
case RIP_NODE:
case RIPNG_NODE:
case BABEL_NODE:
case BGP_NODE:
case BGP_VPNV4_NODE:
case BGP_IPV4_NODE:
@ -1110,7 +1109,6 @@ vty_stop_input (struct vty *vty)
case ZEBRA_NODE:
case RIP_NODE:
case RIPNG_NODE:
case BABEL_NODE:
case BGP_NODE:
case RMAP_NODE:
case OSPF_NODE:

View file

@ -1,5 +1,5 @@
EXTRA_DIST = babeld.init babeld.service bgpd.init bgpd.service isisd.init \
EXTRA_DIST = bgpd.init bgpd.service isisd.init \
isisd.service ospf6d.init ospf6d.service ospfd.init ospfd.service \
quagga.logrotate quagga.pam quagga.pam.stack quagga.spec \
quagga.sysconfig ripd.init ripd.service ripngd.init ripngd.service \

View file

@ -1,72 +0,0 @@
#!/bin/bash
# chkconfig: - 16 84
# config: /etc/quagga/babeld.conf
### BEGIN INIT INFO
# Provides: babeld
# Short-Description: Babel routing engine
# Description: Babel routing engine for use with Zebra
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
# Get network config
. /etc/sysconfig/network
# quagga command line options
. /etc/sysconfig/quagga
RETVAL=0
PROG="babeld"
cmd=babeld
LOCK_FILE=/var/lock/subsys/babeld
CONF_FILE=/etc/quagga/babeld.conf
case "$1" in
start)
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1
# The process must be configured first.
[ -f $CONF_FILE ] || exit 6
if [ `id -u` -ne 0 ]; then
echo $"Insufficient privilege" 1>&2
exit 4
fi
echo -n $"Starting $PROG: "
daemon $cmd -d $BABELD_OPTS -f $CONF_FILE
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $LOCK_FILE
echo
;;
stop)
echo -n $"Shutting down $PROG: "
killproc $cmd
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
echo
;;
restart|reload|force-reload)
$0 stop
$0 start
RETVAL=$?
;;
condrestart|try-restart)
if [ -f $LOCK_FILE ]; then
$0 stop
$0 start
fi
RETVAL=$?
;;
status)
status $cmd
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
exit 2
esac
exit $RETVAL

View file

@ -1,14 +0,0 @@
[Unit]
Description=Babel routing daemon
BindTo=zebra.service
After=syslog.target network.target zebra.service
ConditionPathExists=/etc/quagga/babeld.conf
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/quagga
ExecStart=/usr/sbin/babeld -d $BABELD_OPTS -f /etc/quagga/babeld.conf
Restart=on-abort
[Install]
WantedBy=network.target

View file

@ -6,14 +6,6 @@
endscript
}
/var/log/quagga/babeld.log {
notifempty
missingok
postrotate
/bin/kill -USR1 `cat /var/run/quagga/babeld.pid 2> /dev/null` 2> /dev/null || true
endscript
}
/var/log/quagga/bgpd.log {
notifempty
missingok

View file

@ -68,7 +68,7 @@
%define daemon_list zebra ripd ospfd bgpd
%if %{with_ipv6}
%define daemonv6_list ripngd babeld ospf6d
%define daemonv6_list ripngd ospf6d
%else
%define daemonv6_list ""
%endif
@ -406,7 +406,6 @@ rm -rf $RPM_BUILD_ROOT
%if %{with_ipv6}
%{_sbindir}/ripngd
%{_sbindir}/ospf6d
%{_sbindir}/babeld
%endif
%if %{with_isisd}
%{_sbindir}/isisd

View file

@ -1,7 +1,6 @@
#
# Default: Bind all daemon vtys to the loopback(s) only
#
BABELD_OPTS="-A 127.0.0.1"
BGPD_OPTS="-A 127.0.0.1"
ISISD_OPTS="-A ::1"
OSPF6D_OPTS="-A ::1"

View file

@ -218,7 +218,6 @@ static struct {
{ZEBRA_ROUTE_STATIC, 1, "static"},
{ZEBRA_ROUTE_OSPF, 1, "ospf"},
{ZEBRA_ROUTE_BGP, 2, "bgp"},
{ZEBRA_ROUTE_BABEL, 2, "babel"},
{0, 0, NULL}
};

View file

@ -216,7 +216,6 @@ static struct {
{ZEBRA_ROUTE_STATIC, 1, "static"},
{ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
{ZEBRA_ROUTE_BGP, 2, "bgp"},
{ZEBRA_ROUTE_BABEL, 2, "babel"},
{0, 0, NULL}
};

View file

@ -133,12 +133,6 @@ static struct cmd_node ospf6_node =
"%s(config-ospf6)# "
};
static struct cmd_node babel_node =
{
BABEL_NODE,
"%s(config-babel)# "
};
static struct cmd_node keychain_node =
{
KEYCHAIN_NODE,
@ -217,7 +211,6 @@ test_init(void)
install_node (&ospf_node, NULL);
install_node (&ripng_node, NULL);
install_node (&ospf6_node, NULL);
install_node (&babel_node, NULL);
install_node (&keychain_node, NULL);
install_node (&keychain_key_node, NULL);
install_node (&isis_node, NULL);

View file

@ -299,14 +299,14 @@ complete 'no neighbor VARIABLE maximum-prefix'@22: rv==7
'maximum-prefix'
describe 'no neighbor VARIABLE maximum-prefix'@22: rv==0
'maximum-prefix' 'Maximum number of prefix accept from this peer'
execute relaxed 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
execute strict 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
execute relaxed 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
execute strict 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'isis', '0', '2', 'VARIABLE'
complete 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==7
'2'
describe 'redistribute isis route-map VARIABLE metric 0 metric-type 2'@23: rv==0
'2' 'Set OSPF External Type 2 metrics'
execute relaxed 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
execute strict 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
execute relaxed 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
execute strict 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'rip', '0', '1', 'VARIABLE'
complete 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==7
'1'
describe 'redistribute rip metric 0 route-map VARIABLE metric-type 1'@23: rv==0
@ -910,14 +910,14 @@ execute strict 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0, 'sh
complete 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==2
describe 'show ipv6 bgp community wARIBLE VARIABLE 8ARIABLE'@4: rv==0
'AA:NN' 'community number'
execute relaxed 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp|babel)': 'bgp'
execute strict 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp|babel)': 'bgp'
execute relaxed 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp)': 'bgp'
execute strict 'redistribute bgp'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp)': 'bgp'
complete 'redistribute bgp'@14: rv==7
'bgp'
describe 'redistribute bgp'@14: rv==0
'bgp' 'Border Gateway Protocol (BGP)'
execute relaxed 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp|babel)': 'bgp'
execute strict 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp|babel)': 'bgp'
execute relaxed 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp)': 'bgp'
execute strict 'redistribute bgp'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp)': 'bgp'
complete 'redistribute bgp'@15: rv==7
'bgp'
describe 'redistribute bgp'@15: rv==0
@ -928,24 +928,24 @@ complete 'redistribute bgp'@16: rv==7
'bgp'
describe 'redistribute bgp'@16: rv==0
'bgp' 'Border Gateway Protocol (BGP)'
execute relaxed 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
execute strict 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
execute relaxed 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
execute strict 'redistribute bgp'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', '(null)'
complete 'redistribute bgp'@23: rv==7
'bgp'
describe 'redistribute bgp'@23: rv==0
'bgp' 'Border Gateway Protocol (BGP)'
execute relaxed 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp|babel)': 'bgp'
execute strict 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp|babel)': 'bgp'
execute relaxed 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp)': 'bgp'
execute strict 'redistribute bgp'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp)': 'bgp'
complete 'redistribute bgp'@24: rv==7
'bgp'
describe 'redistribute bgp'@24: rv==0
'bgp' 'Border Gateway Protocol (BGP)'
execute relaxed 'redistribute bgp m 10'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp|babel) metric <0-16>': 'bgp', '10'
execute relaxed 'redistribute bgp m 10'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) metric <0-16>': 'bgp', '10'
execute strict 'redistribute bgp m 10'@14: rv==2
complete 'redistribute bgp m 10'@14: rv==2
describe 'redistribute bgp m 10'@14: rv==0
'<0-16>' 'Metric value'
execute relaxed 'redistribute bgp m 10'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp|babel) metric <0-16>': 'bgp', '10'
execute relaxed 'redistribute bgp m 10'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) metric <0-16>': 'bgp', '10'
execute strict 'redistribute bgp m 10'@15: rv==2
complete 'redistribute bgp m 10'@15: rv==2
describe 'redistribute bgp m 10'@15: rv==0
@ -954,29 +954,29 @@ execute relaxed 'redistribute bgp m 10'@23: rv==3
execute strict 'redistribute bgp m 10'@23: rv==2
complete 'redistribute bgp m 10'@23: rv==3
describe 'redistribute bgp m 10'@23: rv==3
execute relaxed 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
execute strict 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
execute relaxed 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
execute strict 'redistribute bgp metric 10 metric-type 1'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '10', '1', '(null)'
complete 'redistribute bgp metric 10 metric-type 1'@23: rv==7
'1'
describe 'redistribute bgp metric 10 metric-type 1'@23: rv==0
'1' 'Set OSPF External Type 1 metrics'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp|babel) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp|babel) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0, 'redistribute (kernel|connected|static|ospf|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
complete 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==2
describe 'redistribute bgp route-map RMAP_REDIST_BGP'@14: rv==0
'WORD' 'Pointer to route-map entries'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp|babel) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp|babel) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0, 'redistribute (kernel|connected|static|ospf6|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
complete 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==2
describe 'redistribute bgp route-map RMAP_REDIST_BGP'@15: rv==0
'WORD' 'Pointer to route-map entries'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp|babel) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0, 'redistribute (kernel|connected|static|rip|isis|bgp) {metric <0-16777214>|metric-type (1|2)|route-map WORD}': 'bgp', '(null)', '(null)', 'RMAP_REDIST_BGP'
complete 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==2
describe 'redistribute bgp route-map RMAP_REDIST_BGP'@23: rv==0
'WORD' 'Pointer to route-map entries'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp|babel) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp|babel) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute relaxed 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
execute strict 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0, 'redistribute (kernel|connected|static|ripng|isis|bgp) route-map WORD': 'bgp', 'RMAP_REDIST_BGP'
complete 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==2
describe 'redistribute bgp route-map RMAP_REDIST_BGP'@24: rv==0
'WORD' 'Route map name'

View file

@ -24,7 +24,6 @@ EXTRA_DIST = extract.pl
vtysh_cmd_FILES = $(top_srcdir)/bgpd/*.c $(top_srcdir)/isisd/*.c \
$(top_srcdir)/ospfd/*.c $(top_srcdir)/ospf6d/*.c \
$(top_srcdir)/ripd/*.c $(top_srcdir)/ripngd/*.c \
$(top_srcdir)/babeld/*.c \
$(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \
$(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \
$(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \

View file

@ -40,7 +40,6 @@ $ignore{'"router ripng"'} = "ignore";
$ignore{'"router ospf"'} = "ignore";
$ignore{'"router ospf <1-65535>"'} = "ignore";
$ignore{'"router ospf6"'} = "ignore";
$ignore{'"router babel"'} = "ignore";
$ignore{'"router bgp"'} = "ignore";
$ignore{'"router bgp " "<1-4294967295>"'} = "ignore";
$ignore{'"router bgp " "<1-4294967295>" " (view|vrf) WORD"'} = "ignore";

View file

@ -66,7 +66,6 @@ struct vtysh_client vtysh_client[] =
{ .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH, .next = NULL},
};
/*
@ -988,12 +987,6 @@ static struct cmd_node ospf6_node =
"%s(config-ospf6)# "
};
static struct cmd_node babel_node =
{
BABEL_NODE,
"%s(config-babel)# "
};
static struct cmd_node keychain_node =
{
KEYCHAIN_NODE,
@ -1221,17 +1214,6 @@ DEFUNSH (VTYSH_OSPF6D,
return CMD_SUCCESS;
}
DEFUNSH (VTYSH_BABELD,
router_babel,
router_babel_cmd,
"router babel",
ROUTER_STR
"Babel")
{
vty->node = BABEL_NODE;
return CMD_SUCCESS;
}
DEFUNSH (VTYSH_ISISD,
router_isis,
router_isis_cmd,
@ -1321,7 +1303,6 @@ vtysh_exit (struct vty *vty)
case RIPNG_NODE:
case OSPF_NODE:
case OSPF6_NODE:
case BABEL_NODE:
case ISIS_NODE:
case MASC_NODE:
case RMAP_NODE:
@ -2058,7 +2039,7 @@ DEFUN (vtysh_write_terminal,
DEFUN (vtysh_write_terminal_daemon,
vtysh_write_terminal_daemon_cmd,
"write terminal (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|babeld)",
"write terminal (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd)",
"Write running configuration to memory, network, or terminal\n"
"Write to terminal\n"
"For the zebra daemon\n"
@ -2067,8 +2048,7 @@ DEFUN (vtysh_write_terminal_daemon,
"For the ospf daemon\n"
"For the ospfv6 daemon\n"
"For the bgp daemon\n"
"For the isis daemon\n"
"For the babel daemon\n")
"For the isis daemon\n")
{
unsigned int i;
int ret = CMD_SUCCESS;
@ -2255,7 +2235,7 @@ ALIAS (vtysh_write_terminal,
ALIAS (vtysh_write_terminal_daemon,
vtysh_show_running_config_daemon_cmd,
"show running-config (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|babeld)",
"show running-config (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd)",
SHOW_STR
"Current operating configuration\n"
"For the zebra daemon\n"
@ -2264,8 +2244,7 @@ ALIAS (vtysh_write_terminal_daemon,
"For the ospf daemon\n"
"For the ospfv6 daemon\n"
"For the bgp daemon\n"
"For the isis daemon\n"
"For the babel daemon\n")
"For the isis daemon\n")
DEFUN (vtysh_terminal_length,
vtysh_terminal_length_cmd,
@ -2757,7 +2736,6 @@ vtysh_init_vty (void)
install_node (&ripng_node, NULL);
install_node (&ospf6_node, NULL);
/* #endif */
install_node (&babel_node, NULL);
install_node (&keychain_node, NULL);
install_node (&keychain_key_node, NULL);
install_node (&isis_node, NULL);
@ -2780,7 +2758,6 @@ vtysh_init_vty (void)
vtysh_install_default (OSPF_NODE);
vtysh_install_default (RIPNG_NODE);
vtysh_install_default (OSPF6_NODE);
vtysh_install_default (BABEL_NODE);
vtysh_install_default (ISIS_NODE);
vtysh_install_default (KEYCHAIN_NODE);
vtysh_install_default (KEYCHAIN_KEY_NODE);
@ -2835,7 +2812,6 @@ vtysh_init_vty (void)
install_element (RIPNG_NODE, &vtysh_end_all_cmd);
install_element (OSPF_NODE, &vtysh_end_all_cmd);
install_element (OSPF6_NODE, &vtysh_end_all_cmd);
install_element (BABEL_NODE, &vtysh_end_all_cmd);
install_element (BGP_NODE, &vtysh_end_all_cmd);
install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
@ -2867,7 +2843,6 @@ vtysh_init_vty (void)
#ifdef HAVE_IPV6
install_element (CONFIG_NODE, &router_ospf6_cmd);
#endif
install_element (CONFIG_NODE, &router_babel_cmd);
install_element (CONFIG_NODE, &router_isis_cmd);
install_element (CONFIG_NODE, &router_bgp_cmd);
install_element (CONFIG_NODE, &router_bgp_asn_cmd);

View file

@ -29,10 +29,9 @@
#define VTYSH_OSPF6D 0x10
#define VTYSH_BGPD 0x20
#define VTYSH_ISISD 0x40
#define VTYSH_BABELD 0x80
#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_BABELD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_BABELD
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_BABELD
#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD
#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD
#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD
#define VTYSH_VRF VTYSH_ZEBRA
/* vtysh local configuration file. */

View file

@ -210,8 +210,6 @@ vtysh_config_parse_line (const char *line)
config = config_get (OSPF_NODE, line);
else if (strncmp (line, "router ospf6", strlen ("router ospf6")) == 0)
config = config_get (OSPF6_NODE, line);
else if (strncmp (line, "router babel", strlen ("router babel")) == 0)
config = config_get (BABEL_NODE, line);
else if (strncmp (line, "router bgp", strlen ("router bgp")) == 0)
config = config_get (BGP_NODE, line);
else if (strncmp (line, "router isis", strlen ("router isis")) == 0)

View file

@ -116,7 +116,6 @@ struct zebra_info
{ "static", ZEBRA_ROUTE_STATIC },
{ "rip", ZEBRA_ROUTE_RIP },
{ "ripng", ZEBRA_ROUTE_RIPNG },
{ "babel", ZEBRA_ROUTE_BABEL },
{ "ospf", ZEBRA_ROUTE_OSPF },
{ "ospf6", ZEBRA_ROUTE_OSPF6 },
{ "bgp", ZEBRA_ROUTE_BGP },

View file

@ -76,7 +76,6 @@ static const struct
[ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110},
[ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115},
[ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */},
[ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 95},
/* no entry/default: 150 */
};
@ -1697,7 +1696,6 @@ static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
[ZEBRA_ROUTE_ISIS] = 2,
[ZEBRA_ROUTE_BGP] = 3,
[ZEBRA_ROUTE_HSLS] = 4,
[ZEBRA_ROUTE_BABEL] = 2,
[ZEBRA_ROUTE_TABLE] = 1,
};

View file

@ -1777,7 +1777,6 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
#define ONE_WEEK_SECOND 60*60*24*7
if (rib->type == ZEBRA_ROUTE_RIP
|| rib->type == ZEBRA_ROUTE_OSPF
|| rib->type == ZEBRA_ROUTE_BABEL
|| rib->type == ZEBRA_ROUTE_ISIS
|| rib->type == ZEBRA_ROUTE_TABLE
|| rib->type == ZEBRA_ROUTE_BGP)
@ -1989,7 +1988,6 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
if (rib->type == ZEBRA_ROUTE_RIP
|| rib->type == ZEBRA_ROUTE_OSPF
|| rib->type == ZEBRA_ROUTE_BABEL
|| rib->type == ZEBRA_ROUTE_ISIS
|| rib->type == ZEBRA_ROUTE_TABLE
|| rib->type == ZEBRA_ROUTE_BGP)
@ -4323,7 +4321,6 @@ vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
#define ONE_WEEK_SECOND 60*60*24*7
if (rib->type == ZEBRA_ROUTE_RIPNG
|| rib->type == ZEBRA_ROUTE_OSPF6
|| rib->type == ZEBRA_ROUTE_BABEL
|| rib->type == ZEBRA_ROUTE_ISIS
|| rib->type == ZEBRA_ROUTE_BGP)
{
@ -4451,7 +4448,6 @@ vty_show_ipv6_route (struct vty *vty, struct route_node *rn,
if (rib->type == ZEBRA_ROUTE_RIPNG
|| rib->type == ZEBRA_ROUTE_OSPF6
|| rib->type == ZEBRA_ROUTE_BABEL
|| rib->type == ZEBRA_ROUTE_ISIS
|| rib->type == ZEBRA_ROUTE_BGP)
{