mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
quagga: remove babel
Ticket: CM-9274 Reviewed By: sharpd@cumulusnetworks.com Testing Done: <DETAILED DESCRIPTION (REPLACE)>
This commit is contained in:
parent
b3556ea327
commit
41d9cc6a65
|
@ -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
7
babeld/.gitignore
vendored
|
@ -1,7 +0,0 @@
|
|||
*
|
||||
!*.c
|
||||
!*.h
|
||||
!LICENCE
|
||||
!Makefile.am
|
||||
!babeld.conf.sample
|
||||
!.gitignore
|
|
@ -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.
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
|
@ -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
|
732
babeld/babeld.c
732
babeld/babeld.c
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
141
babeld/babeld.h
141
babeld/babeld.h
|
@ -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 */
|
316
babeld/kernel.c
316
babeld/kernel.c
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
1561
babeld/message.c
1561
babeld/message.c
File diff suppressed because it is too large
Load diff
111
babeld/message.h
111
babeld/message.h
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
239
babeld/net.c
239
babeld/net.c
|
@ -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;
|
||||
}
|
44
babeld/net.h
44
babeld/net.h
|
@ -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);
|
330
babeld/resend.c
330
babeld/resend.c
|
@ -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();
|
||||
}
|
|
@ -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);
|
1019
babeld/route.c
1019
babeld/route.c
File diff suppressed because it is too large
Load diff
135
babeld/route.h
135
babeld/route.h
|
@ -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
|
180
babeld/source.c
180
babeld/source.c
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
445
babeld/util.c
445
babeld/util.c
|
@ -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;
|
||||
}
|
165
babeld/util.h
165
babeld/util.h
|
@ -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 */
|
||||
|
237
babeld/xroute.c
237
babeld/xroute.c
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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"
|
||||
|
|
14
configure.ac
14
configure.ac
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
6
debian/README.Debian
vendored
6
debian/README.Debian
vendored
|
@ -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
20
debian/babeld.service
vendored
|
@ -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
108
debian/my/babeld.8
vendored
|
@ -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.
|
6
debian/my/config.h.reference
vendored
6
debian/my/config.h.reference
vendored
|
@ -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
1
debian/my/daemons
vendored
|
@ -28,4 +28,3 @@ ospf6d=no
|
|||
ripd=no
|
||||
ripngd=no
|
||||
isisd=no
|
||||
babeld=no
|
||||
|
|
1
debian/my/debian.conf
vendored
1
debian/my/debian.conf
vendored
|
@ -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.
|
||||
|
|
1
debian/quagga.default
vendored
1
debian/quagga.default
vendored
|
@ -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"
|
||||
|
|
1
debian/quagga.install
vendored
1
debian/quagga.install
vendored
|
@ -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/
|
||||
|
|
2
debian/quagga.logrotate
vendored
2
debian/quagga.logrotate
vendored
|
@ -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
|
||||
|
|
2
debian/quagga.service
vendored
2
debian/quagga.service
vendored
|
@ -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
5
debian/rules
vendored
|
@ -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
|
||||
|
|
2
debian/tests/daemons
vendored
2
debian/tests/daemons
vendored
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
118
doc/babeld.texi
118
doc/babeld.texi
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -50,7 +50,6 @@ typedef enum
|
|||
ZLOG_BGP,
|
||||
ZLOG_OSPF,
|
||||
ZLOG_RIPNG,
|
||||
ZLOG_BABEL,
|
||||
ZLOG_OSPF6,
|
||||
ZLOG_ISIS,
|
||||
ZLOG_MASC
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -45,7 +45,6 @@ typedef enum
|
|||
{
|
||||
RMAP_RIP,
|
||||
RMAP_RIPNG,
|
||||
RMAP_BABEL,
|
||||
RMAP_OSPF,
|
||||
RMAP_OSPF6,
|
||||
RMAP_BGP,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue