Merge branch 'int-new' of gitlab.labs.nic.cz:labs/bird into int-new
This commit is contained in:
commit
5af7b59660
51 changed files with 4210 additions and 122 deletions
17
NEWS
17
NEWS
|
@ -1,3 +1,20 @@
|
||||||
|
Version 1.6.0 (2016-04-29)
|
||||||
|
o Major RIP protocol redesign
|
||||||
|
o New Babel routing protocol
|
||||||
|
o BGP multipath support
|
||||||
|
o KRT: Add support for plenty of kernel route metrics
|
||||||
|
o KRT: Allow more than 256 routing tables
|
||||||
|
o Static: Allow to specify attributes for static routes
|
||||||
|
o Static: Support for BFD controlled static routes
|
||||||
|
o FreeBSD: Setup password for BGP MD5 authentication
|
||||||
|
o IO: Remove socket number limit
|
||||||
|
o Plenty of bug fixes
|
||||||
|
|
||||||
|
Upgrade notes:
|
||||||
|
|
||||||
|
For RIP, most protocol options were moved to interface blocks.
|
||||||
|
|
||||||
|
|
||||||
Version 1.5.0 (2015-04-20)
|
Version 1.5.0 (2015-04-20)
|
||||||
o Major OSPF protocol redesign.
|
o Major OSPF protocol redesign.
|
||||||
o OSPFv2 multi-instance extension (RFC 6549).
|
o OSPFv2 multi-instance extension (RFC 6549).
|
||||||
|
|
|
@ -153,7 +153,7 @@ input_init(void)
|
||||||
|
|
||||||
// readline library does strange things when stdin is nonblocking.
|
// readline library does strange things when stdin is nonblocking.
|
||||||
// if (fcntl(0, F_SETFL, O_NONBLOCK) < 0)
|
// if (fcntl(0, F_SETFL, O_NONBLOCK) < 0)
|
||||||
// die("fcntl: %m");
|
// DIE("fcntl");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -109,7 +110,7 @@ more_begin(void)
|
||||||
tty.c_lflag &= (~ICANON);
|
tty.c_lflag &= (~ICANON);
|
||||||
|
|
||||||
if (tcsetattr (0, TCSANOW, &tty) < 0)
|
if (tcsetattr (0, TCSANOW, &tty) < 0)
|
||||||
die("tcsetattr: %m");
|
DIE("tcsetattr");
|
||||||
|
|
||||||
more_active = 1;
|
more_active = 1;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +121,7 @@ more_end(void)
|
||||||
more_active = 0;
|
more_active = 0;
|
||||||
|
|
||||||
if (tcsetattr (0, TCSANOW, &stored_tty) < 0)
|
if (tcsetattr (0, TCSANOW, &stored_tty) < 0)
|
||||||
die("tcsetattr: %m");
|
DIE("tcsetattr");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -137,7 +138,7 @@ input_init(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (tcgetattr(0, &stored_tty) < 0)
|
if (tcgetattr(0, &stored_tty) < 0)
|
||||||
die("tcgetattr: %m");
|
DIE("tcgetattr");
|
||||||
|
|
||||||
if (signal(SIGINT, sig_handler) == SIG_IGN)
|
if (signal(SIGINT, sig_handler) == SIG_IGN)
|
||||||
signal(SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#define SERVER_READ_BUF_LEN 4096
|
#define SERVER_READ_BUF_LEN 4096
|
||||||
|
|
||||||
static char *opt_list = "s:vr";
|
static char *opt_list = "s:vrl";
|
||||||
static int verbose, restricted, once;
|
static int verbose, restricted, once;
|
||||||
static char *init_cmd;
|
static char *init_cmd;
|
||||||
|
|
||||||
|
@ -59,13 +59,14 @@ int term_lns, term_cls;
|
||||||
static void
|
static void
|
||||||
usage(char *name)
|
usage(char *name)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-s <control-socket>] [-v] [-r]\n", name);
|
fprintf(stderr, "Usage: %s [-s <control-socket>] [-v] [-r] [-l]\n", name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_args(int argc, char **argv)
|
parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int server_changed = 0;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, opt_list)) >= 0)
|
while ((c = getopt(argc, argv, opt_list)) >= 0)
|
||||||
|
@ -73,6 +74,7 @@ parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
case 's':
|
case 's':
|
||||||
server_path = optarg;
|
server_path = optarg;
|
||||||
|
server_changed = 1;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
|
@ -80,6 +82,10 @@ parse_args(int argc, char **argv)
|
||||||
case 'r':
|
case 'r':
|
||||||
restricted = 1;
|
restricted = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (!server_changed)
|
||||||
|
server_path = xbasename(server_path);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
}
|
}
|
||||||
|
@ -242,7 +248,7 @@ server_connect(void)
|
||||||
|
|
||||||
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (server_fd < 0)
|
if (server_fd < 0)
|
||||||
die("Cannot create socket: %m");
|
DIE("Cannot create socket");
|
||||||
|
|
||||||
if (strlen(server_path) >= sizeof(sa.sun_path))
|
if (strlen(server_path) >= sizeof(sa.sun_path))
|
||||||
die("server_connect: path too long");
|
die("server_connect: path too long");
|
||||||
|
@ -251,9 +257,9 @@ server_connect(void)
|
||||||
sa.sun_family = AF_UNIX;
|
sa.sun_family = AF_UNIX;
|
||||||
strcpy(sa.sun_path, server_path);
|
strcpy(sa.sun_path, server_path);
|
||||||
if (connect(server_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) < 0)
|
if (connect(server_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) < 0)
|
||||||
die("Unable to connect to server control socket (%s): %m", server_path);
|
DIE("Unable to connect to server control socket (%s)", server_path);
|
||||||
if (fcntl(server_fd, F_SETFL, O_NONBLOCK) < 0)
|
if (fcntl(server_fd, F_SETFL, O_NONBLOCK) < 0)
|
||||||
die("fcntl: %m");
|
DIE("fcntl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,13 +309,13 @@ server_read(void)
|
||||||
redo:
|
redo:
|
||||||
c = read(server_fd, server_read_pos, server_read_buf + sizeof(server_read_buf) - server_read_pos);
|
c = read(server_fd, server_read_pos, server_read_buf + sizeof(server_read_buf) - server_read_pos);
|
||||||
if (!c)
|
if (!c)
|
||||||
die("Connection closed by server.");
|
die("Connection closed by server");
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
{
|
{
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
goto redo;
|
goto redo;
|
||||||
else
|
else
|
||||||
die("Server read error: %m");
|
DIE("Server read error");
|
||||||
}
|
}
|
||||||
|
|
||||||
start = server_read_buf;
|
start = server_read_buf;
|
||||||
|
@ -360,7 +366,7 @@ select_loop(void)
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
die("select: %m");
|
DIE("select");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(0, &select_fds))
|
if (FD_ISSET(0, &select_fds))
|
||||||
|
@ -393,7 +399,7 @@ wait_for_write(int fd)
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
die("select: %m");
|
DIE("select");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(server_fd, &set))
|
if (FD_ISSET(server_fd, &set))
|
||||||
|
@ -420,7 +426,7 @@ server_send(char *cmd)
|
||||||
else if (errno == EINTR)
|
else if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
die("Server write error: %m");
|
DIE("Server write error");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -430,19 +436,6 @@ server_send(char *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* XXXX
|
|
||||||
|
|
||||||
get_term_size();
|
|
||||||
|
|
||||||
if (tcgetattr(0, &tty_save) != 0)
|
|
||||||
{
|
|
||||||
perror("tcgetattr error");
|
|
||||||
return(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,3 +34,6 @@ char *cmd_expand(char *cmd);
|
||||||
/* client.c */
|
/* client.c */
|
||||||
|
|
||||||
void submit_command(char *cmd_raw);
|
void submit_command(char *cmd_raw);
|
||||||
|
|
||||||
|
/* die() with system error messages */
|
||||||
|
#define DIE(x, y...) die(x ": %s", ##y, strerror(errno))
|
||||||
|
|
|
@ -60,7 +60,7 @@ cmd_build_tree(void)
|
||||||
if (!new)
|
if (!new)
|
||||||
{
|
{
|
||||||
int size = sizeof(struct cmd_node) + c-d;
|
int size = sizeof(struct cmd_node) + c-d;
|
||||||
new = xmalloc(size);
|
new = malloc(size);
|
||||||
bzero(new, size);
|
bzero(new, size);
|
||||||
*old->plastson = new;
|
*old->plastson = new;
|
||||||
old->plastson = &new->sibling;
|
old->plastson = &new->sibling;
|
||||||
|
@ -314,7 +314,7 @@ cmd_expand(char *cmd)
|
||||||
puts("No such command. Press `?' for help.");
|
puts("No such command. Press `?' for help.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
b = xmalloc(strlen(n->cmd->command) + strlen(args) + 1);
|
b = malloc(strlen(n->cmd->command) + strlen(args) + 1);
|
||||||
sprintf(b, "%s%s", n->cmd->command, args);
|
sprintf(b, "%s%s", n->cmd->command, args);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,11 @@ vlog(const char *msg, va_list args)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
if (bvsnprintf(buf, sizeof(buf)-1, msg, args) < 0)
|
int n = vsnprintf(buf, sizeof(buf), msg, args);
|
||||||
bsprintf(buf + sizeof(buf) - 100, " ... <too long>");
|
if (n < 0)
|
||||||
|
snprintf(buf, sizeof(buf), "???");
|
||||||
|
if (n >= sizeof(buf))
|
||||||
|
snprintf(buf + sizeof(buf) - 100, 100, " ... <too long>");
|
||||||
fputs(buf, stderr);
|
fputs(buf, stderr);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -563,6 +563,7 @@ cf_lex_init_kh(void)
|
||||||
/**
|
/**
|
||||||
* cf_lex_init - initialize the lexer
|
* cf_lex_init - initialize the lexer
|
||||||
* @is_cli: true if we're going to parse CLI command, false for configuration
|
* @is_cli: true if we're going to parse CLI command, false for configuration
|
||||||
|
* @c: configuration structure
|
||||||
*
|
*
|
||||||
* cf_lex_init() initializes the lexical analyzer and prepares it for
|
* cf_lex_init() initializes the lexical analyzer and prepares it for
|
||||||
* parsing of a new input.
|
* parsing of a new input.
|
||||||
|
|
|
@ -167,7 +167,7 @@ fi
|
||||||
|
|
||||||
AC_SUBST(iproutedir)
|
AC_SUBST(iproutedir)
|
||||||
|
|
||||||
# all_protocols="$proto_bfd bgp ospf pipe radv rip static"
|
# all_protocols="$proto_bfd babel bgp ospf pipe radv rip static"
|
||||||
all_protocols="$proto_bfd ospf pipe radv rip static"
|
all_protocols="$proto_bfd ospf pipe radv rip static"
|
||||||
|
|
||||||
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
|
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
|
||||||
|
|
230
doc/bird.sgml
230
doc/bird.sgml
|
@ -171,6 +171,11 @@ BIRD executable by configuring out routing protocols you don't use, and
|
||||||
<tag>-f</tag>
|
<tag>-f</tag>
|
||||||
run bird in foreground.
|
run bird in foreground.
|
||||||
|
|
||||||
|
<tag>-l</tag>
|
||||||
|
look for a configuration file and a communication socket in the current
|
||||||
|
working directory instead of in default system locations. However, paths
|
||||||
|
specified by options <cf/-c/, <cf/-s/ have higher priority.
|
||||||
|
|
||||||
<tag>-R</tag>
|
<tag>-R</tag>
|
||||||
apply graceful restart recovery after start.
|
apply graceful restart recovery after start.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
@ -190,7 +195,7 @@ privileges (capabilities CAP_NET_*). Note that the control socket is created
|
||||||
before the privileges are dropped, but the config file is read after that. The
|
before the privileges are dropped, but the config file is read after that. The
|
||||||
privilege restriction is not implemented in BSD port of BIRD.
|
privilege restriction is not implemented in BSD port of BIRD.
|
||||||
|
|
||||||
<p>A nonprivileged user (as an argument to <cf/-u/ options) may be the user
|
<p>An unprivileged user (as an argument to <cf/-u/ options) may be the user
|
||||||
<cf/nobody/, but it is suggested to use a new dedicated user account (like
|
<cf/nobody/, but it is suggested to use a new dedicated user account (like
|
||||||
<cf/bird/). The similar considerations apply for the group option, but there is
|
<cf/bird/). The similar considerations apply for the group option, but there is
|
||||||
one more condition -- the users in the same group can use <file/birdc/ to
|
one more condition -- the users in the same group can use <file/birdc/ to
|
||||||
|
@ -283,7 +288,7 @@ extensive way.
|
||||||
a comment, whitespace characters are treated as a single space. If there's a
|
a comment, whitespace characters are treated as a single space. If there's a
|
||||||
variable number of options, they are grouped using the <cf/{ }/ brackets. Each
|
variable number of options, they are grouped using the <cf/{ }/ brackets. Each
|
||||||
option is terminated by a <cf/;/. Configuration is case sensitive. There are two
|
option is terminated by a <cf/;/. Configuration is case sensitive. There are two
|
||||||
ways how to name symbols (like protocol names, filter names, constats etc.). You
|
ways how to name symbols (like protocol names, filter names, constants etc.). You
|
||||||
can either use a simple string starting with a letter followed by any
|
can either use a simple string starting with a letter followed by any
|
||||||
combination of letters and numbers (e.g. "R123", "myfilter", "bgp5") or you can
|
combination of letters and numbers (e.g. "R123", "myfilter", "bgp5") or you can
|
||||||
enclose the name into apostrophes (<cf/'/) and than you can use any combination
|
enclose the name into apostrophes (<cf/'/) and than you can use any combination
|
||||||
|
@ -712,6 +717,10 @@ This argument can be omitted if there exists only a single instance.
|
||||||
Show router status, that is BIRD version, uptime and time from last
|
Show router status, that is BIRD version, uptime and time from last
|
||||||
reconfiguration.
|
reconfiguration.
|
||||||
|
|
||||||
|
<tag>show interfaces [summary]</tag>
|
||||||
|
Show the list of interfaces. For each interface, print its type, state,
|
||||||
|
MTU and addresses assigned.
|
||||||
|
|
||||||
<tag>show protocols [all]</tag>
|
<tag>show protocols [all]</tag>
|
||||||
Show list of protocol instances along with tables they are connected to
|
Show list of protocol instances along with tables they are connected to
|
||||||
and protocol status, possibly giving verbose information, if <cf/all/ is
|
and protocol status, possibly giving verbose information, if <cf/all/ is
|
||||||
|
@ -739,16 +748,18 @@ This argument can be omitted if there exists only a single instance.
|
||||||
Show contents of an OSPF LSA database. Options could be used to filter
|
Show contents of an OSPF LSA database. Options could be used to filter
|
||||||
entries.
|
entries.
|
||||||
|
|
||||||
|
<tag>show rip interfaces [<m/name/] ["<m/interface/"]</tag>
|
||||||
|
Show detailed information about RIP interfaces.
|
||||||
|
|
||||||
|
<tag>show rip neighbors [<m/name/] ["<m/interface/"]</tag>
|
||||||
|
Show a list of RIP neighbors and associated state.
|
||||||
|
|
||||||
<tag>show static [<m/name/]</tag>
|
<tag>show static [<m/name/]</tag>
|
||||||
Show detailed information about static routes.
|
Show detailed information about static routes.
|
||||||
|
|
||||||
<tag>show bfd sessions [<m/name/]</tag>
|
<tag>show bfd sessions [<m/name/]</tag>
|
||||||
Show information about BFD sessions.
|
Show information about BFD sessions.
|
||||||
|
|
||||||
<tag>show interfaces [summary]</tag>
|
|
||||||
Show the list of interfaces. For each interface, print its type, state,
|
|
||||||
MTU and addresses assigned.
|
|
||||||
|
|
||||||
<tag>show symbols [table|filter|function|protocol|template|roa|<m/symbol/]</tag>
|
<tag>show symbols [table|filter|function|protocol|template|roa|<m/symbol/]</tag>
|
||||||
Show the list of symbols defined in the configuration (names of
|
Show the list of symbols defined in the configuration (names of
|
||||||
protocols, routing tables etc.).
|
protocols, routing tables etc.).
|
||||||
|
@ -824,7 +835,7 @@ This argument can be omitted if there exists only a single instance.
|
||||||
configuration could be either confirmed using <cf/configure confirm/
|
configuration could be either confirmed using <cf/configure confirm/
|
||||||
command, or it will be reverted to the old one when the config timer
|
command, or it will be reverted to the old one when the config timer
|
||||||
expires. This is useful for cases when reconfiguration breaks current
|
expires. This is useful for cases when reconfiguration breaks current
|
||||||
routing and a router becames inaccessible for an administrator. The
|
routing and a router becomes inaccessible for an administrator. The
|
||||||
config timeout expiration is equivalent to <cf/configure undo/
|
config timeout expiration is equivalent to <cf/configure undo/
|
||||||
command. The timeout duration could be specified, default is 300 s.
|
command. The timeout duration could be specified, default is 300 s.
|
||||||
|
|
||||||
|
@ -1005,7 +1016,7 @@ foot).
|
||||||
of type <cf/string/, print such variables, use standard string
|
of type <cf/string/, print such variables, use standard string
|
||||||
comparison operations (e.g. <cf/=, !=, <, >, <=, >=/), but
|
comparison operations (e.g. <cf/=, !=, <, >, <=, >=/), but
|
||||||
you can't concatenate two strings. String literals are written as
|
you can't concatenate two strings. String literals are written as
|
||||||
<cf/"This is a string constant"/. Additionaly matching <cf/˜/
|
<cf/"This is a string constant"/. Additionally matching <cf/˜/
|
||||||
operator could be used to match a string value against a shell pattern
|
operator could be used to match a string value against a shell pattern
|
||||||
(represented also as a string).
|
(represented also as a string).
|
||||||
|
|
||||||
|
@ -1369,6 +1380,102 @@ corresponding protocol sections.
|
||||||
|
|
||||||
<chapt>Protocols
|
<chapt>Protocols
|
||||||
|
|
||||||
|
<sect>Babel
|
||||||
|
|
||||||
|
<sect1>Introduction
|
||||||
|
|
||||||
|
<p>The Babel protocol (RFC6126) is a loop-avoiding distance-vector routing
|
||||||
|
protocol that is robust and efficient both in ordinary wired networks and in
|
||||||
|
wireless mesh networks. Babel is conceptually very simple in its operation and
|
||||||
|
"just works" in its default configuration, though some configuration is possible
|
||||||
|
and in some cases desirable.
|
||||||
|
|
||||||
|
<p>While the Babel protocol is dual stack (i.e., can carry both IPv4 and IPv6
|
||||||
|
routes over the same IPv6 transport), BIRD presently implements only the IPv6
|
||||||
|
subset of the protocol. No Babel extensions are implemented, but the BIRD
|
||||||
|
implementation can coexist with implementations using the extensions (and will
|
||||||
|
just ignore extension messages).
|
||||||
|
|
||||||
|
<p>The Babel protocol implementation in BIRD is currently in alpha stage.
|
||||||
|
|
||||||
|
<sect1>Configuration
|
||||||
|
|
||||||
|
<p>Babel supports no global configuration options apart from those common to all
|
||||||
|
other protocols, but supports the following per-interface configuration options:
|
||||||
|
|
||||||
|
<code>
|
||||||
|
protocol babel [<name>] {
|
||||||
|
interface <interface pattern> {
|
||||||
|
type <wired|wireless>;
|
||||||
|
rxcost <number>;
|
||||||
|
hello interval <number>;
|
||||||
|
update interval <number>;
|
||||||
|
port <number>;
|
||||||
|
tx class|dscp <number>;
|
||||||
|
tx priority <number>;
|
||||||
|
rx buffer <number>;
|
||||||
|
tx length <number>;
|
||||||
|
check link <switch>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<descrip>
|
||||||
|
<tag>type wired|wireless </tag>
|
||||||
|
This option specifies the interface type: Wired or wireless. Wired
|
||||||
|
interfaces are considered more reliable, and so the default hello
|
||||||
|
interval is higher, and a neighbour is considered unreachable after only
|
||||||
|
a small number of "hello" packets are lost. On wireless interfaces,
|
||||||
|
hello packets are sent more often, and the ETX link quality estimation
|
||||||
|
technique is used to compute the metrics of routes discovered over this
|
||||||
|
interface. This technique will gradually degrade the metric of routes
|
||||||
|
when packets are lost rather than the more binary up/down mechanism of
|
||||||
|
wired type links. Default: <cf/wired/.
|
||||||
|
|
||||||
|
<tag>rxcost <m/num/</tag>
|
||||||
|
This specifies the RX cost of the interface. The route metrics will be
|
||||||
|
computed from this value with a mechanism determined by the interface
|
||||||
|
<cf/type/. Default: 96 for wired interfaces, 256 for wireless.
|
||||||
|
|
||||||
|
<tag>hello interval <m/num/</tag>
|
||||||
|
Interval at which periodic "hello" messages are sent on this interface,
|
||||||
|
in seconds. Default: 4 seconds.
|
||||||
|
|
||||||
|
<tag>update interval <m/num/</tag>
|
||||||
|
Interval at which periodic (full) updates are sent. Default: 4 times the
|
||||||
|
hello interval.
|
||||||
|
|
||||||
|
<tag>port <m/number/</tag>
|
||||||
|
This option selects an UDP port to operate on. The default is to operate
|
||||||
|
on port 6696 as specified in the Babel RFC.
|
||||||
|
|
||||||
|
<tag>tx class|dscp|priority <m/number/</tag>
|
||||||
|
These options specify the ToS/DiffServ/Traffic class/Priority of the
|
||||||
|
outgoing Babel packets. See <ref id="dsc-prio" name="tx class"> common
|
||||||
|
option for detailed description.
|
||||||
|
|
||||||
|
<tag>rx buffer <m/number/</tag>
|
||||||
|
This option specifies the size of buffers used for packet processing.
|
||||||
|
The buffer size should be bigger than maximal size of received packets.
|
||||||
|
The default value is the interface MTU, and the value will be clamped to a
|
||||||
|
minimum of 512 bytes + IP packet overhead.
|
||||||
|
|
||||||
|
<tag>tx length <m/number/</tag>
|
||||||
|
This option specifies the maximum length of generated Babel packets. To
|
||||||
|
avoid IP fragmentation, it should not exceed the interface MTU value.
|
||||||
|
The default value is the interface MTU value, and the value will be
|
||||||
|
clamped to a minimum of 512 bytes + IP packet overhead.
|
||||||
|
|
||||||
|
<tag>check link <m/switch/</tag>
|
||||||
|
If set, the hardware link state (as reported by OS) is taken into
|
||||||
|
consideration. When the link disappears (e.g. an ethernet cable is
|
||||||
|
unplugged), neighbors are immediately considered unreachable and all
|
||||||
|
routes received from them are withdrawn. It is possible that some
|
||||||
|
hardware drivers or platforms do not implement this feature. Default:
|
||||||
|
yes.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
|
||||||
<sect><label id="sect-bfd">BFD
|
<sect><label id="sect-bfd">BFD
|
||||||
|
|
||||||
<sect1>Introduction
|
<sect1>Introduction
|
||||||
|
@ -1472,7 +1579,7 @@ protocol bfd [<name>] {
|
||||||
|
|
||||||
The session is identified by the IP address of the neighbor, with
|
The session is identified by the IP address of the neighbor, with
|
||||||
optional specification of used interface and local IP. By default
|
optional specification of used interface and local IP. By default
|
||||||
the neighbor must be directly connected, unless the the session is
|
the neighbor must be directly connected, unless the session is
|
||||||
configured as multihop. Note that local IP must be specified for
|
configured as multihop. Note that local IP must be specified for
|
||||||
multihop sessions.
|
multihop sessions.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
@ -1515,7 +1622,7 @@ protocol bfd [<name>] {
|
||||||
Default: 5.
|
Default: 5.
|
||||||
|
|
||||||
<tag>passive <m/switch/</tag>
|
<tag>passive <m/switch/</tag>
|
||||||
Generally, both BFD session endpoinds try to establish the session by
|
Generally, both BFD session endpoints try to establish the session by
|
||||||
sending control packets to the other side. This option allows to enable
|
sending control packets to the other side. This option allows to enable
|
||||||
passive mode, which means that the router does not send BFD packets
|
passive mode, which means that the router does not send BFD packets
|
||||||
until it has received one from the other side. Default: disabled.
|
until it has received one from the other side. Default: disabled.
|
||||||
|
@ -1753,9 +1860,20 @@ using the following configuration parameters:
|
||||||
only. Default: disabled.
|
only. Default: disabled.
|
||||||
|
|
||||||
<tag>password <m/string/</tag>
|
<tag>password <m/string/</tag>
|
||||||
Use this password for MD5 authentication of BGP sessions. Default: no
|
Use this password for MD5 authentication of BGP sessions (RFC 2385).
|
||||||
authentication. Password has to be set by external utility
|
When used on BSD systems, see also <cf/setkey/ option below. Default:
|
||||||
(e.g. setkey(8)) on BSD systems.
|
no authentication.
|
||||||
|
|
||||||
|
<tag>setkey <m/switch/</tag>
|
||||||
|
On BSD systems, keys for TCP MD5 authentication are stored in the global
|
||||||
|
SA/SP database, which can be accessed by external utilities (e.g.
|
||||||
|
setkey(8)). BIRD configures security associations in the SA/SP database
|
||||||
|
automatically based on <cf/password/ options (see above), this option
|
||||||
|
allows to disable automatic updates by BIRD when manual configuration by
|
||||||
|
external utilities is preferred. Note that automatic SA/SP database
|
||||||
|
updates are currently implemented only for FreeBSD. Passwords have to be
|
||||||
|
set manually by an external utility on NetBSD and OpenBSD. Default:
|
||||||
|
enabled (ignored on non-FreeBSD).
|
||||||
|
|
||||||
<tag>passive <m/switch/</tag>
|
<tag>passive <m/switch/</tag>
|
||||||
Standard BGP behavior is both initiating outgoing connections and
|
Standard BGP behavior is both initiating outgoing connections and
|
||||||
|
@ -2150,7 +2268,7 @@ conditions, because a lower priority IGP route for the same network is not
|
||||||
exported to the kernel routing table. This is an issue on BSD systems only, as
|
exported to the kernel routing table. This is an issue on BSD systems only, as
|
||||||
on Linux systems BIRD cannot change non-BIRD route in the kernel routing table.
|
on Linux systems BIRD cannot change non-BIRD route in the kernel routing table.
|
||||||
|
|
||||||
<p>The only configurable thing about direct is what interfaces it watches:
|
<p>There are just few configuration options for the Direct protocol:
|
||||||
|
|
||||||
<p><descrip>
|
<p><descrip>
|
||||||
<tag>interface <m/pattern [, ...]/</tag>
|
<tag>interface <m/pattern [, ...]/</tag>
|
||||||
|
@ -2161,6 +2279,12 @@ on Linux systems BIRD cannot change non-BIRD route in the kernel routing table.
|
||||||
interfaces), just use this clause. See <ref id="dsc-iface" name="interface">
|
interfaces), just use this clause. See <ref id="dsc-iface" name="interface">
|
||||||
common option for detailed description. The Direct protocol uses
|
common option for detailed description. The Direct protocol uses
|
||||||
extended interface clauses.
|
extended interface clauses.
|
||||||
|
|
||||||
|
<tag>check link <m/switch/</tag>
|
||||||
|
If enabled, a hardware link state (reported by OS) is taken into
|
||||||
|
consideration. Routes for directly connected networks are generated only
|
||||||
|
if link up is reported and they are withdrawn when link disappears
|
||||||
|
(e.g., an ethernet cable is unplugged). Default value is no.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
<p>Direct device routes don't contain any specific attributes.
|
<p>Direct device routes don't contain any specific attributes.
|
||||||
|
@ -2634,7 +2758,7 @@ protocol ospf <name> {
|
||||||
<tag>dead <M>num</M></tag>
|
<tag>dead <M>num</M></tag>
|
||||||
When the router does not receive any messages from a neighbor in
|
When the router does not receive any messages from a neighbor in
|
||||||
<m/dead/ seconds, it will consider the neighbor down. If both directives
|
<m/dead/ seconds, it will consider the neighbor down. If both directives
|
||||||
<cf/dead count/ and <cf/dead/ are used, <cf/dead/ has precendence.
|
<cf/dead count/ and <cf/dead/ are used, <cf/dead/ has precedence.
|
||||||
|
|
||||||
<tag>secondary <M>switch</M></tag>
|
<tag>secondary <M>switch</M></tag>
|
||||||
On BSD systems, older versions of BIRD supported OSPFv2 only for the
|
On BSD systems, older versions of BIRD supported OSPFv2 only for the
|
||||||
|
@ -3365,6 +3489,11 @@ protocol rip [<name>] {
|
||||||
RIP, the option is not supported for RIPng, as no further versions are
|
RIP, the option is not supported for RIPng, as no further versions are
|
||||||
defined.
|
defined.
|
||||||
|
|
||||||
|
<tag>version only <m/switch/</tag>
|
||||||
|
Regardless of RIP version configured for the interface, BIRD accepts
|
||||||
|
incoming packets of any RIP version. This option restrict accepted
|
||||||
|
packets to the configured version. Default: no.
|
||||||
|
|
||||||
<tag>split horizon <m/switch/</tag>
|
<tag>split horizon <m/switch/</tag>
|
||||||
Split horizon is a scheme for preventing routing loops. When split
|
Split horizon is a scheme for preventing routing loops. When split
|
||||||
horizon is active, routes are not regularly propagated back to the
|
horizon is active, routes are not regularly propagated back to the
|
||||||
|
@ -3509,7 +3638,7 @@ default route to prevent routing loops).
|
||||||
packets to a neighboring router, multipath routes specifying several (possibly
|
packets to a neighboring router, multipath routes specifying several (possibly
|
||||||
weighted) neighboring routers, device routes specifying forwarding to hosts on a
|
weighted) neighboring routers, device routes specifying forwarding to hosts on a
|
||||||
directly connected network, recursive routes computing their nexthops by doing
|
directly connected network, recursive routes computing their nexthops by doing
|
||||||
route table lookups for a given IP and special routes (sink, blackhole etc.)
|
route table lookups for a given IP, and special routes (sink, blackhole etc.)
|
||||||
which specify a special action to be done instead of forwarding the packet.
|
which specify a special action to be done instead of forwarding the packet.
|
||||||
|
|
||||||
<p>When the particular destination is not available (the interface is down or
|
<p>When the particular destination is not available (the interface is down or
|
||||||
|
@ -3517,8 +3646,26 @@ the next hop of the route is not a neighbor at the moment), Static just
|
||||||
uninstalls the route from the table it is connected to and adds it again as soon
|
uninstalls the route from the table it is connected to and adds it again as soon
|
||||||
as the destination becomes adjacent again.
|
as the destination becomes adjacent again.
|
||||||
|
|
||||||
<p>The Static protocol does not have many configuration options. The definition
|
<p>There are three classes of definitions in Static protocol configuration --
|
||||||
of the protocol contains mainly a list of static routes:
|
global options, static route definitions, and per-route options. Usually, the
|
||||||
|
definition of the protocol contains mainly a list of static routes.
|
||||||
|
|
||||||
|
<p>Global options:
|
||||||
|
|
||||||
|
<descrip>
|
||||||
|
<tag>check link <m/switch/</tag>
|
||||||
|
If set, hardware link states of network interfaces are taken into
|
||||||
|
consideration. When link disappears (e.g. ethernet cable is unplugged),
|
||||||
|
static routes directing to that interface are removed. It is possible
|
||||||
|
that some hardware drivers or platforms do not implement this feature.
|
||||||
|
Default: off.
|
||||||
|
|
||||||
|
<tag>igp table <m/name/</tag>
|
||||||
|
Specifies a table that is used for route table lookups of recursive
|
||||||
|
routes. Default: the same table as the protocol is connected to.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
<p>Route definitions (each may also contain a block of per-route options):
|
||||||
|
|
||||||
<descrip>
|
<descrip>
|
||||||
<tag>route <m/prefix/ via <m/ip/</tag>
|
<tag>route <m/prefix/ via <m/ip/</tag>
|
||||||
|
@ -3526,7 +3673,7 @@ of the protocol contains mainly a list of static routes:
|
||||||
interface can be specified as a part of the address (e.g.,
|
interface can be specified as a part of the address (e.g.,
|
||||||
<cf/via fe80::1234%eth0/).
|
<cf/via fe80::1234%eth0/).
|
||||||
|
|
||||||
<tag>route <m/prefix/ multipath via <m/ip/ [weight <m/num/] [via ...]</tag>
|
<tag>route <m/prefix/ multipath via <m/ip/ [weight <m/num/] [bfd <m/switch/] [via ...]</tag>
|
||||||
Static multipath route. Contains several nexthops (gateways), possibly
|
Static multipath route. Contains several nexthops (gateways), possibly
|
||||||
with their weights.
|
with their weights.
|
||||||
|
|
||||||
|
@ -3542,17 +3689,33 @@ of the protocol contains mainly a list of static routes:
|
||||||
Special routes specifying to silently drop the packet, return it as
|
Special routes specifying to silently drop the packet, return it as
|
||||||
unreachable or return it as administratively prohibited. First two
|
unreachable or return it as administratively prohibited. First two
|
||||||
targets are also known as <cf/drop/ and <cf/reject/.
|
targets are also known as <cf/drop/ and <cf/reject/.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
<tag>check link <m/switch/</tag>
|
<p>Per-route options:
|
||||||
If set, hardware link states of network interfaces are taken into
|
|
||||||
consideration. When link disappears (e.g. ethernet cable is unplugged),
|
|
||||||
static routes directing to that interface are removed. It is possible
|
|
||||||
that some hardware drivers or platforms do not implement this feature.
|
|
||||||
Default: off.
|
|
||||||
|
|
||||||
<tag>igp table <m/name/</tag>
|
<descrip>
|
||||||
Specifies a table that is used for route table lookups of recursive
|
<tag>bfd <m/switch/</tag>
|
||||||
routes. Default: the same table as the protocol is connected to.
|
The Static protocol could use BFD protocol for next hop liveness
|
||||||
|
detection. If enabled, a BFD session to the route next hop is created
|
||||||
|
and the static route is BFD-controlled -- the static route is announced
|
||||||
|
only if the next hop liveness is confirmed by BFD. If the BFD session
|
||||||
|
fails, the static route is removed. Note that this is a bit different
|
||||||
|
compared to other protocols, which may use BFD as an advisory mechanism
|
||||||
|
for fast failure detection but ignores it if a BFD session is not even
|
||||||
|
established.
|
||||||
|
|
||||||
|
This option can be used for static routes with a direct next hop, or
|
||||||
|
also for for individual next hops in a static multipath route (see
|
||||||
|
above). Note that BFD protocol also has to be configured, see
|
||||||
|
<ref id="sect-bfd" name="BFD"> section for details. Default value is no.
|
||||||
|
|
||||||
|
<tag><m/filter expression/</tag>
|
||||||
|
This is a special option that allows filter expressions to be configured
|
||||||
|
on per-route basis. Can be used multiple times. These expressions are
|
||||||
|
evaluated when the route is originated, similarly to the import filter
|
||||||
|
of the static protocol. This is especially useful for configuring route
|
||||||
|
attributes, e.g., <cf/ospf_metric1 = 100;/ for a route that will be
|
||||||
|
exported to the OSPF protocol.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
<p>Static routes have no specific attributes.
|
<p>Static routes have no specific attributes.
|
||||||
|
@ -3562,13 +3725,22 @@ of the protocol contains mainly a list of static routes:
|
||||||
<p><code>
|
<p><code>
|
||||||
protocol static {
|
protocol static {
|
||||||
table testable; # Connect to a non-default routing table
|
table testable; # Connect to a non-default routing table
|
||||||
|
check link; # Advertise routes only if link is up
|
||||||
route 0.0.0.0/0 via 198.51.100.130; # Default route
|
route 0.0.0.0/0 via 198.51.100.130; # Default route
|
||||||
route 10.0.0.0/8 multipath # Multipath route
|
route 10.0.0.0/8 multipath # Multipath route
|
||||||
via 198.51.100.10 weight 2
|
via 198.51.100.10 weight 2
|
||||||
via 198.51.100.20
|
via 198.51.100.20 bfd # BFD-controlled next hop
|
||||||
via 192.0.2.1;
|
via 192.0.2.1;
|
||||||
route 203.0.113.0/24 unreachable; # Sink route
|
route 203.0.113.0/24 unreachable; # Sink route
|
||||||
route 10.2.0.0/24 via "arc0"; # Secondary network
|
route 10.2.0.0/24 via "arc0"; # Secondary network
|
||||||
|
route 192.168.10.0/24 via 198.51.100.100 {
|
||||||
|
ospf_metric1 = 20; # Set extended attribute
|
||||||
|
}
|
||||||
|
route 192.168.10.0/24 via 198.51.100.100 {
|
||||||
|
ospf_metric2 = 100; # Set extended attribute
|
||||||
|
ospf_tag = 2; # Set extended attribute
|
||||||
|
bfd; # BFD-controlled route
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,9 @@ Reply codes of BIRD command-line interface
|
||||||
1020 Show BFD sessions
|
1020 Show BFD sessions
|
||||||
1021 Show RIP interface
|
1021 Show RIP interface
|
||||||
1022 Show RIP neighbors
|
1022 Show RIP neighbors
|
||||||
|
1023 Show Babel interfaces
|
||||||
|
1024 Show Babel neighbors
|
||||||
|
1025 Show Babel entries
|
||||||
|
|
||||||
8000 Reply too long
|
8000 Reply too long
|
||||||
8001 Route not found
|
8001 Route not found
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
src := bitops.c checksum.c ip.c lists.c md5.c net.c patmatch.c printf.c sha1.c sha256.c sha512.c slists.c xmalloc.c
|
|
||||||
obj := $(src-o-files)
|
|
||||||
$(all-client)
|
|
||||||
|
|
||||||
src := bitops.c checksum.c event.c idm.c ip.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
|
src := bitops.c checksum.c event.c idm.c ip.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
|
||||||
obj := $(src-o-files)
|
obj := $(src-o-files)
|
||||||
$(all-daemon)
|
$(all-daemon)
|
||||||
|
|
|
@ -61,6 +61,7 @@ static inline int u64_cmp(u64 i1, u64 i2)
|
||||||
|
|
||||||
#define NORET __attribute__((noreturn))
|
#define NORET __attribute__((noreturn))
|
||||||
#define UNUSED __attribute__((unused))
|
#define UNUSED __attribute__((unused))
|
||||||
|
#define PACKED __attribute__((packed))
|
||||||
|
|
||||||
|
|
||||||
/* Microsecond time */
|
/* Microsecond time */
|
||||||
|
|
|
@ -25,5 +25,6 @@ u32 u32_log2(u32 v);
|
||||||
|
|
||||||
static inline u32 u32_hash(u32 v) { return v * 2902958171u; }
|
static inline u32 u32_hash(u32 v) { return v * 2902958171u; }
|
||||||
|
|
||||||
#endif
|
static inline u8 u32_popcount(u32 v) { return __builtin_popcount(v); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
1
lib/ip.h
1
lib/ip.h
|
@ -26,6 +26,7 @@
|
||||||
#define IP6_OSPF_ALL_ROUTERS ipa_build6(0xFF020000, 0, 0, 5)
|
#define IP6_OSPF_ALL_ROUTERS ipa_build6(0xFF020000, 0, 0, 5)
|
||||||
#define IP6_OSPF_DES_ROUTERS ipa_build6(0xFF020000, 0, 0, 6)
|
#define IP6_OSPF_DES_ROUTERS ipa_build6(0xFF020000, 0, 0, 6)
|
||||||
#define IP6_RIP_ROUTERS ipa_build6(0xFF020000, 0, 0, 9)
|
#define IP6_RIP_ROUTERS ipa_build6(0xFF020000, 0, 0, 9)
|
||||||
|
#define IP6_BABEL_ROUTERS ipa_build6(0xFF020000, 0, 0, 0x00010006)
|
||||||
|
|
||||||
#define IP4_NONE _MI4(0)
|
#define IP4_NONE _MI4(0)
|
||||||
#define IP6_NONE _MI6(0,0,0,0)
|
#define IP6_NONE _MI6(0,0,0,0)
|
||||||
|
|
23
lib/printf.c
23
lib/printf.c
|
@ -124,9 +124,10 @@ static char * number(char * str, long num, int base, int size, int precision,
|
||||||
* standard IP address width which depends on whether we use IPv4 or IPv6; |%I4|
|
* standard IP address width which depends on whether we use IPv4 or IPv6; |%I4|
|
||||||
* or |%I6| can be used for explicit ip4_addr / ip6_addr arguments, |%N| for
|
* or |%I6| can be used for explicit ip4_addr / ip6_addr arguments, |%N| for
|
||||||
* generic network addresses (net_addr *), |%R| for Router / Network ID (u32
|
* generic network addresses (net_addr *), |%R| for Router / Network ID (u32
|
||||||
* value printed as IPv4 address) and |%m| resp. |%M| for error messages (uses
|
* value printed as IPv4 address), |%lR| for 64bit Router / Network ID (u64
|
||||||
* strerror() to translate @errno code to message text). On the other hand, it
|
* value printed as eight :-separated octets) and |%m| resp. |%M| for error
|
||||||
* doesn't support floating point numbers.
|
* messages (uses strerror() to translate @errno code to message text). On the
|
||||||
|
* other hand, it doesn't support floating point numbers.
|
||||||
*
|
*
|
||||||
* Result: number of characters of the output string or -1 if
|
* Result: number of characters of the output string or -1 if
|
||||||
* the buffer space was insufficient.
|
* the buffer space was insufficient.
|
||||||
|
@ -137,6 +138,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
|
||||||
unsigned long num;
|
unsigned long num;
|
||||||
int i, base;
|
int i, base;
|
||||||
u32 x;
|
u32 x;
|
||||||
|
u64 X;
|
||||||
char *str, *start;
|
char *str, *start;
|
||||||
const char *s;
|
const char *s;
|
||||||
char ipbuf[NET_MAX_TEXT_LENGTH+1];
|
char ipbuf[NET_MAX_TEXT_LENGTH+1];
|
||||||
|
@ -338,8 +340,23 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
|
||||||
|
|
||||||
/* Router/Network ID - essentially IPv4 address in u32 value */
|
/* Router/Network ID - essentially IPv4 address in u32 value */
|
||||||
case 'R':
|
case 'R':
|
||||||
|
if (qualifier == 'l') {
|
||||||
|
X = va_arg(args, u64);
|
||||||
|
bsprintf(ipbuf, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
((X >> 56) & 0xff),
|
||||||
|
((X >> 48) & 0xff),
|
||||||
|
((X >> 40) & 0xff),
|
||||||
|
((X >> 32) & 0xff),
|
||||||
|
((X >> 24) & 0xff),
|
||||||
|
((X >> 16) & 0xff),
|
||||||
|
((X >> 8) & 0xff),
|
||||||
|
(X & 0xff));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
x = va_arg(args, u32);
|
x = va_arg(args, u32);
|
||||||
ip4_ntop(ip4_from_u32(x), ipbuf);
|
ip4_ntop(ip4_from_u32(x), ipbuf);
|
||||||
|
}
|
||||||
s = ipbuf;
|
s = ipbuf;
|
||||||
goto str;
|
goto str;
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ int sk_leave_group(sock *s, ip_addr maddr); /* Leave multicast group on sk iface
|
||||||
int sk_setup_broadcast(sock *s);
|
int sk_setup_broadcast(sock *s);
|
||||||
int sk_set_ttl(sock *s, int ttl); /* Set transmit TTL for given socket */
|
int sk_set_ttl(sock *s, int ttl); /* Set transmit TTL for given socket */
|
||||||
int sk_set_min_ttl(sock *s, int ttl); /* Set minimal accepted TTL for given socket */
|
int sk_set_min_ttl(sock *s, int ttl); /* Set minimal accepted TTL for given socket */
|
||||||
int sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd);
|
int sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd, int setkey);
|
||||||
int sk_set_ipv6_checksum(sock *s, int offset);
|
int sk_set_ipv6_checksum(sock *s, int offset);
|
||||||
int sk_set_icmp6_filter(sock *s, int p1, int p2);
|
int sk_set_icmp6_filter(sock *s, int p1, int p2);
|
||||||
void sk_log_error(sock *s, const char *p);
|
void sk_log_error(sock *s, const char *p);
|
||||||
|
|
|
@ -24,4 +24,12 @@ void buffer_puts(buffer *buf, const char *str);
|
||||||
|
|
||||||
int patmatch(const byte *pat, const byte *str);
|
int patmatch(const byte *pat, const byte *str);
|
||||||
|
|
||||||
|
static inline char *xbasename(const char *str)
|
||||||
|
{
|
||||||
|
char *s = strrchr(str, '/');
|
||||||
|
return s ? s+1 : (char *) str;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ROUTER_ID_64_LENGTH 23
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Summary: BIRD Internet Routing Daemon
|
Summary: BIRD Internet Routing Daemon
|
||||||
Name: bird
|
Name: bird
|
||||||
Version: 1.5.0
|
Version: 1.6.0
|
||||||
Release: 1
|
Release: 1
|
||||||
Copyright: GPL
|
Copyright: GPL
|
||||||
Group: Networking/Daemons
|
Group: Networking/Daemons
|
||||||
|
|
|
@ -357,6 +357,7 @@ dev_proto:
|
||||||
| dev_proto proto_item ';'
|
| dev_proto proto_item ';'
|
||||||
| dev_proto proto_channel ';'
|
| dev_proto proto_channel ';'
|
||||||
| dev_proto dev_iface_patt ';'
|
| dev_proto dev_iface_patt ';'
|
||||||
|
| dev_proto CHECK LINK bool ';' { DIRECT_CFG->check_link = $4; }
|
||||||
;
|
;
|
||||||
|
|
||||||
dev_iface_init:
|
dev_iface_init:
|
||||||
|
|
|
@ -340,7 +340,7 @@ neigh_if_link(struct iface *i)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* neigh_ifa_update: notify neighbor cache about interface address add or remove event
|
* neigh_ifa_update: notify neighbor cache about interface address add or remove event
|
||||||
* @ifa: interface address in question
|
* @a: interface address in question
|
||||||
*
|
*
|
||||||
* Tell the neighbor cache that an address was added or removed.
|
* Tell the neighbor cache that an address was added or removed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -148,6 +148,7 @@ void get_route_info(rte *e, byte *buf, ea_list *attrs)
|
||||||
* get_attr - get attribute information
|
* get_attr - get attribute information
|
||||||
* @a: an extended attribute
|
* @a: an extended attribute
|
||||||
* @buf: buffer to be filled with attribute information
|
* @buf: buffer to be filled with attribute information
|
||||||
|
* @buflen: a length of the @buf parameter
|
||||||
*
|
*
|
||||||
* The get_attr() hook is called by the core to obtain a user friendly
|
* The get_attr() hook is called by the core to obtain a user friendly
|
||||||
* representation of an extended route attribute. It can either leave
|
* representation of an extended route attribute. It can either leave
|
||||||
|
|
|
@ -1068,6 +1068,7 @@ graceful_restart_init(void)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* graceful_restart_done - finalize graceful restart
|
* graceful_restart_done - finalize graceful restart
|
||||||
|
* @t: unused
|
||||||
*
|
*
|
||||||
* When there are no locks on graceful restart, the functions finalizes the
|
* When there are no locks on graceful restart, the functions finalizes the
|
||||||
* graceful restart recovery. Protocols postponing route export until the end of
|
* graceful restart recovery. Protocols postponing route export until the end of
|
||||||
|
@ -1258,6 +1259,9 @@ protos_build(void)
|
||||||
proto_build(&proto_bfd);
|
proto_build(&proto_bfd);
|
||||||
bfd_init_all();
|
bfd_init_all();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_BABEL
|
||||||
|
proto_build(&proto_babel);
|
||||||
|
#endif
|
||||||
|
|
||||||
proto_pool = rp_new(&root_pool, "Protocols");
|
proto_pool = rp_new(&root_pool, "Protocols");
|
||||||
proto_shutdown_timer = tm_new(proto_pool);
|
proto_shutdown_timer = tm_new(proto_pool);
|
||||||
|
|
|
@ -81,7 +81,7 @@ void protos_dump_all(void);
|
||||||
|
|
||||||
extern struct protocol
|
extern struct protocol
|
||||||
proto_device, proto_radv, proto_rip, proto_static,
|
proto_device, proto_radv, proto_rip, proto_static,
|
||||||
proto_ospf, proto_pipe, proto_bgp, proto_bfd;
|
proto_ospf, proto_pipe, proto_bgp, proto_bfd, proto_babel;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routing Protocol Instance
|
* Routing Protocol Instance
|
||||||
|
|
11
nest/route.h
11
nest/route.h
|
@ -228,6 +228,12 @@ typedef struct rte {
|
||||||
struct {
|
struct {
|
||||||
u8 suppressed; /* Used for deterministic MED comparison */
|
u8 suppressed; /* Used for deterministic MED comparison */
|
||||||
} bgp;
|
} bgp;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BABEL
|
||||||
|
struct {
|
||||||
|
u16 metric; /* Babel metric */
|
||||||
|
u64 router_id; /* Babel router id */
|
||||||
|
} babel;
|
||||||
#endif
|
#endif
|
||||||
struct { /* Routes generated by krt sync (both temporary and inherited ones) */
|
struct { /* Routes generated by krt sync (both temporary and inherited ones) */
|
||||||
s8 src; /* Alleged route source (see krt.h) */
|
s8 src; /* Alleged route source (see krt.h) */
|
||||||
|
@ -377,6 +383,7 @@ typedef struct rta {
|
||||||
#define RTS_OSPF_EXT2 10 /* OSPF external route type 2 */
|
#define RTS_OSPF_EXT2 10 /* OSPF external route type 2 */
|
||||||
#define RTS_BGP 11 /* BGP route */
|
#define RTS_BGP 11 /* BGP route */
|
||||||
#define RTS_PIPE 12 /* Inter-table wormhole */
|
#define RTS_PIPE 12 /* Inter-table wormhole */
|
||||||
|
#define RTS_BABEL 13 /* Babel route */
|
||||||
|
|
||||||
#define RTC_UNICAST 0
|
#define RTC_UNICAST 0
|
||||||
#define RTC_BROADCAST 1
|
#define RTC_BROADCAST 1
|
||||||
|
@ -425,7 +432,8 @@ typedef struct eattr {
|
||||||
#define EAP_RIP 2 /* RIP */
|
#define EAP_RIP 2 /* RIP */
|
||||||
#define EAP_OSPF 3 /* OSPF */
|
#define EAP_OSPF 3 /* OSPF */
|
||||||
#define EAP_KRT 4 /* Kernel route attributes */
|
#define EAP_KRT 4 /* Kernel route attributes */
|
||||||
#define EAP_MAX 5
|
#define EAP_BABEL 5 /* Babel attributes */
|
||||||
|
#define EAP_MAX 6
|
||||||
|
|
||||||
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
||||||
#define EA_PROTO(ea) ((ea) >> 8)
|
#define EA_PROTO(ea) ((ea) >> 8)
|
||||||
|
@ -550,6 +558,7 @@ extern struct protocol *attr_class_to_protocol[EAP_MAX];
|
||||||
#define DEF_PREF_DIRECT 240 /* Directly connected */
|
#define DEF_PREF_DIRECT 240 /* Directly connected */
|
||||||
#define DEF_PREF_STATIC 200 /* Static route */
|
#define DEF_PREF_STATIC 200 /* Static route */
|
||||||
#define DEF_PREF_OSPF 150 /* OSPF intra-area, inter-area and type 1 external routes */
|
#define DEF_PREF_OSPF 150 /* OSPF intra-area, inter-area and type 1 external routes */
|
||||||
|
#define DEF_PREF_BABEL 130 /* Babel */
|
||||||
#define DEF_PREF_RIP 120 /* RIP */
|
#define DEF_PREF_RIP 120 /* RIP */
|
||||||
#define DEF_PREF_BGP 100 /* BGP */
|
#define DEF_PREF_BGP 100 /* BGP */
|
||||||
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
|
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
|
||||||
|
|
|
@ -353,7 +353,7 @@ ea_find(ea_list *e, unsigned id)
|
||||||
* for first occurrences of attributes with ID in specified interval from @id to
|
* for first occurrences of attributes with ID in specified interval from @id to
|
||||||
* (@id + @max - 1), returning pointers to found &eattr structures, storing its
|
* (@id + @max - 1), returning pointers to found &eattr structures, storing its
|
||||||
* walk state in @s for subsequent calls.
|
* walk state in @s for subsequent calls.
|
||||||
|
*
|
||||||
* The function ea_walk() is supposed to be called in a loop, with initially
|
* The function ea_walk() is supposed to be called in a loop, with initially
|
||||||
* zeroed walk state structure @s with filled the initial extended attribute
|
* zeroed walk state structure @s with filled the initial extended attribute
|
||||||
* list, returning one found attribute in each call or %NULL when no other
|
* list, returning one found attribute in each call or %NULL when no other
|
||||||
|
|
|
@ -68,6 +68,9 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
|
||||||
|
|
||||||
DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
|
DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
|
||||||
|
|
||||||
|
if (cf->check_link && !(ad->iface->flags & IF_LINK_UP))
|
||||||
|
return;
|
||||||
|
|
||||||
/* Use iface ID as local source ID */
|
/* Use iface ID as local source ID */
|
||||||
struct rte_src *src = rt_get_source(P, ad->iface->index);
|
struct rte_src *src = rt_get_source(P, ad->iface->index);
|
||||||
|
|
||||||
|
@ -87,6 +90,25 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dev_if_notify(struct proto *p, uint c, struct iface *iface)
|
||||||
|
{
|
||||||
|
struct rt_dev_config *cf = (void *) p->cf;
|
||||||
|
|
||||||
|
if (c & (IF_CHANGE_UP | IF_CHANGE_DOWN))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((c & IF_CHANGE_LINK) && cf->check_link)
|
||||||
|
{
|
||||||
|
uint ac = (iface->flags & IF_LINK_UP) ? IF_CHANGE_UP : IF_CHANGE_DOWN;
|
||||||
|
|
||||||
|
struct ifa *a;
|
||||||
|
WALK_LIST(a, iface->addrs)
|
||||||
|
dev_ifa_notify(p, ac, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct proto *
|
static struct proto *
|
||||||
dev_init(struct proto_config *CF)
|
dev_init(struct proto_config *CF)
|
||||||
{
|
{
|
||||||
|
@ -97,6 +119,7 @@ dev_init(struct proto_config *CF)
|
||||||
proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4));
|
proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4));
|
||||||
proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
|
proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
|
||||||
|
|
||||||
|
P->if_notify = dev_if_notify;
|
||||||
P->ifa_notify = dev_ifa_notify;
|
P->ifa_notify = dev_ifa_notify;
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
|
@ -109,7 +132,8 @@ dev_reconfigure(struct proto *P, struct proto_config *CF)
|
||||||
struct rt_dev_config *o = (void *) P->cf;
|
struct rt_dev_config *o = (void *) P->cf;
|
||||||
struct rt_dev_config *n = (void *) CF;
|
struct rt_dev_config *n = (void *) CF;
|
||||||
|
|
||||||
if (!iface_patts_equal(&o->iface_list, &n->iface_list, NULL))
|
if (!iface_patts_equal(&o->iface_list, &n->iface_list, NULL) ||
|
||||||
|
(o->check_link != n->check_link))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -131,6 +155,8 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src)
|
||||||
* old nodes cannot be modified (although they contain internal lists).
|
* old nodes cannot be modified (although they contain internal lists).
|
||||||
*/
|
*/
|
||||||
cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_patt));
|
cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_patt));
|
||||||
|
|
||||||
|
d->check_link = s->check_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct protocol proto_device = {
|
struct protocol proto_device = {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
struct rt_dev_config {
|
struct rt_dev_config {
|
||||||
struct proto_config c;
|
struct proto_config c;
|
||||||
list iface_list; /* list of struct iface_patt */
|
list iface_list; /* list of struct iface_patt */
|
||||||
|
int check_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rt_dev_proto {
|
struct rt_dev_proto {
|
||||||
|
|
|
@ -834,16 +834,20 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed
|
||||||
* @net: network in question
|
* @net: network in question
|
||||||
* @new: the new route to be announced
|
* @new: the new route to be announced
|
||||||
* @old: the previous route for the same network
|
* @old: the previous route for the same network
|
||||||
|
* @new_best: the new best route for the same network
|
||||||
|
* @old_best: the previous best route for the same network
|
||||||
|
* @before_old: The previous route before @old for the same network.
|
||||||
|
* If @before_old is NULL @old was the first.
|
||||||
*
|
*
|
||||||
* This function gets a routing table update and announces it
|
* This function gets a routing table update and announces it
|
||||||
* to all protocols that acccepts given type of route announcement
|
* to all protocols that acccepts given type of route announcement
|
||||||
* and are connected to the same table by their announcement hooks.
|
* and are connected to the same table by their announcement hooks.
|
||||||
*
|
*
|
||||||
* Route announcement of type RA_OPTIMAL si generated when optimal
|
* Route announcement of type %RA_OPTIMAL si generated when optimal
|
||||||
* route (in routing table @tab) changes. In that case @old stores the
|
* route (in routing table @tab) changes. In that case @old stores the
|
||||||
* old optimal route.
|
* old optimal route.
|
||||||
*
|
*
|
||||||
* Route announcement of type RA_ANY si generated when any route (in
|
* Route announcement of type %RA_ANY si generated when any route (in
|
||||||
* routing table @tab) changes In that case @old stores the old route
|
* routing table @tab) changes In that case @old stores the old route
|
||||||
* from the same protocol.
|
* from the same protocol.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
H Protocols
|
H Protocols
|
||||||
|
C babel
|
||||||
C bfd
|
C bfd
|
||||||
C bgp
|
C bgp
|
||||||
C ospf
|
C ospf
|
||||||
|
|
2
proto/babel/Doc
Normal file
2
proto/babel/Doc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
S babel.c
|
||||||
|
S packets.c
|
5
proto/babel/Makefile
Normal file
5
proto/babel/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
source=babel.c packets.c
|
||||||
|
root-rel=../../
|
||||||
|
dir-name=proto/babel
|
||||||
|
|
||||||
|
include ../../Rules
|
2055
proto/babel/babel.c
Normal file
2055
proto/babel/babel.c
Normal file
File diff suppressed because it is too large
Load diff
335
proto/babel/babel.h
Normal file
335
proto/babel/babel.h
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
/*
|
||||||
|
* BIRD -- The Babel protocol
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015--2016 Toke Hoiland-Jorgensen
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*
|
||||||
|
* This file contains the data structures used by Babel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BIRD_BABEL_H_
|
||||||
|
#define _BIRD_BABEL_H_
|
||||||
|
|
||||||
|
#include "nest/bird.h"
|
||||||
|
#include "nest/cli.h"
|
||||||
|
#include "nest/iface.h"
|
||||||
|
#include "nest/route.h"
|
||||||
|
#include "nest/protocol.h"
|
||||||
|
#include "nest/locks.h"
|
||||||
|
#include "lib/resource.h"
|
||||||
|
#include "lib/lists.h"
|
||||||
|
#include "lib/socket.h"
|
||||||
|
#include "lib/string.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
|
|
||||||
|
#ifndef IPV6
|
||||||
|
#error "The Babel protocol only speaks IPv6"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EA_BABEL_METRIC EA_CODE(EAP_BABEL, 0)
|
||||||
|
#define EA_BABEL_ROUTER_ID EA_CODE(EAP_BABEL, 1)
|
||||||
|
|
||||||
|
#define BABEL_MAGIC 42
|
||||||
|
#define BABEL_VERSION 2
|
||||||
|
#define BABEL_PORT 6696
|
||||||
|
#define BABEL_INFINITY 0xFFFF
|
||||||
|
|
||||||
|
|
||||||
|
#define BABEL_HELLO_INTERVAL_WIRED 4 /* Default hello intervals in seconds */
|
||||||
|
#define BABEL_HELLO_INTERVAL_WIRELESS 4
|
||||||
|
#define BABEL_UPDATE_INTERVAL_FACTOR 4
|
||||||
|
#define BABEL_IHU_INTERVAL_FACTOR 3
|
||||||
|
#define BABEL_IHU_EXPIRY_FACTOR(X) ((X)*3/2) /* 1.5 */
|
||||||
|
#define BABEL_HELLO_EXPIRY_FACTOR(X) ((X)*3/2) /* 1.5 */
|
||||||
|
#define BABEL_ROUTE_EXPIRY_FACTOR(X) ((X)*7/2) /* 3.5 */
|
||||||
|
#define BABEL_ROUTE_REFRESH_INTERVAL 2 /* Seconds before route expiry to send route request */
|
||||||
|
#define BABEL_HOLD_TIME 10 /* Expiry time for our own routes */
|
||||||
|
#define BABEL_RXCOST_WIRED 96
|
||||||
|
#define BABEL_RXCOST_WIRELESS 256
|
||||||
|
#define BABEL_INITIAL_HOP_COUNT 255
|
||||||
|
#define BABEL_MAX_SEND_INTERVAL 5
|
||||||
|
#define BABEL_TIME_UNITS 100 /* On-wire times are counted in centiseconds */
|
||||||
|
|
||||||
|
#define BABEL_SEQNO_REQUEST_EXPIRY 60
|
||||||
|
#define BABEL_GARBAGE_INTERVAL 300
|
||||||
|
|
||||||
|
#define BABEL_OVERHEAD (SIZE_OF_IP_HEADER+UDP_HEADER_LENGTH)
|
||||||
|
#define BABEL_MIN_MTU (512 + BABEL_OVERHEAD)
|
||||||
|
|
||||||
|
|
||||||
|
enum babel_tlv_type {
|
||||||
|
BABEL_TLV_PAD1 = 0,
|
||||||
|
BABEL_TLV_PADN = 1,
|
||||||
|
BABEL_TLV_ACK_REQ = 2,
|
||||||
|
BABEL_TLV_ACK = 3,
|
||||||
|
BABEL_TLV_HELLO = 4,
|
||||||
|
BABEL_TLV_IHU = 5,
|
||||||
|
BABEL_TLV_ROUTER_ID = 6,
|
||||||
|
BABEL_TLV_NEXT_HOP = 7,
|
||||||
|
BABEL_TLV_UPDATE = 8,
|
||||||
|
BABEL_TLV_ROUTE_REQUEST = 9,
|
||||||
|
BABEL_TLV_SEQNO_REQUEST = 10,
|
||||||
|
/* extensions - not implemented
|
||||||
|
BABEL_TLV_TS_PC = 11,
|
||||||
|
BABEL_TLV_HMAC = 12,
|
||||||
|
BABEL_TLV_SS_UPDATE = 13,
|
||||||
|
BABEL_TLV_SS_REQUEST = 14,
|
||||||
|
BABEL_TLV_SS_SEQNO_REQUEST = 15,
|
||||||
|
*/
|
||||||
|
BABEL_TLV_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum babel_iface_type {
|
||||||
|
/* In practice, UNDEF and WIRED give equivalent behaviour */
|
||||||
|
BABEL_IFACE_TYPE_UNDEF = 0,
|
||||||
|
BABEL_IFACE_TYPE_WIRED = 1,
|
||||||
|
BABEL_IFACE_TYPE_WIRELESS = 2,
|
||||||
|
BABEL_IFACE_TYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum babel_ae_type {
|
||||||
|
BABEL_AE_WILDCARD = 0,
|
||||||
|
BABEL_AE_IP4 = 1,
|
||||||
|
BABEL_AE_IP6 = 2,
|
||||||
|
BABEL_AE_IP6_LL = 3,
|
||||||
|
BABEL_AE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct babel_config {
|
||||||
|
struct proto_config c;
|
||||||
|
|
||||||
|
list iface_list; /* Patterns configured -- keep it first; see babel_reconfigure why */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_iface_config {
|
||||||
|
struct iface_patt i;
|
||||||
|
|
||||||
|
u16 rxcost;
|
||||||
|
u8 type;
|
||||||
|
u8 check_link;
|
||||||
|
int port;
|
||||||
|
u16 hello_interval;
|
||||||
|
u16 ihu_interval;
|
||||||
|
u16 update_interval;
|
||||||
|
|
||||||
|
u16 rx_buffer; /* RX buffer size, 0 for MTU */
|
||||||
|
u16 tx_length; /* TX packet length limit (including headers), 0 for MTU */
|
||||||
|
int tx_tos;
|
||||||
|
int tx_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_proto {
|
||||||
|
struct proto p;
|
||||||
|
timer *timer;
|
||||||
|
struct fib rtable;
|
||||||
|
list interfaces; /* Interfaces we really know about (struct babel_iface) */
|
||||||
|
u64 router_id;
|
||||||
|
u16 update_seqno; /* To be increased on request */
|
||||||
|
u8 triggered; /* For triggering global updates */
|
||||||
|
|
||||||
|
slab *route_slab;
|
||||||
|
slab *source_slab;
|
||||||
|
slab *msg_slab;
|
||||||
|
|
||||||
|
slab *seqno_slab;
|
||||||
|
list seqno_cache; /* Seqno requests in the cache (struct babel_seqno_request) */
|
||||||
|
|
||||||
|
struct tbf log_pkt_tbf; /* TBF for packet messages */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_iface {
|
||||||
|
node n;
|
||||||
|
|
||||||
|
struct babel_proto *proto;
|
||||||
|
struct iface *iface;
|
||||||
|
|
||||||
|
struct babel_iface_config *cf;
|
||||||
|
|
||||||
|
u8 up;
|
||||||
|
|
||||||
|
pool *pool;
|
||||||
|
char *ifname;
|
||||||
|
sock *sk;
|
||||||
|
ip_addr addr;
|
||||||
|
int tx_length;
|
||||||
|
list neigh_list; /* List of neighbors seen on this iface (struct babel_neighbor) */
|
||||||
|
list msg_queue;
|
||||||
|
|
||||||
|
u16 hello_seqno; /* To be increased on each hello */
|
||||||
|
|
||||||
|
bird_clock_t next_hello;
|
||||||
|
bird_clock_t next_regular;
|
||||||
|
bird_clock_t next_triggered;
|
||||||
|
bird_clock_t want_triggered;
|
||||||
|
|
||||||
|
timer *timer;
|
||||||
|
event *send_event;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_neighbor {
|
||||||
|
node n;
|
||||||
|
struct babel_iface *ifa;
|
||||||
|
|
||||||
|
ip_addr addr;
|
||||||
|
u16 txcost;
|
||||||
|
u8 hello_cnt;
|
||||||
|
u16 hello_map;
|
||||||
|
u16 next_hello_seqno;
|
||||||
|
/* expiry timers */
|
||||||
|
bird_clock_t hello_expiry;
|
||||||
|
bird_clock_t ihu_expiry;
|
||||||
|
|
||||||
|
list routes; /* Routes this neighbour has sent us (struct babel_route) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_source {
|
||||||
|
node n;
|
||||||
|
|
||||||
|
u64 router_id;
|
||||||
|
u16 seqno;
|
||||||
|
u16 metric;
|
||||||
|
bird_clock_t expires;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_route {
|
||||||
|
node n;
|
||||||
|
node neigh_route;
|
||||||
|
struct babel_entry *e;
|
||||||
|
struct babel_neighbor *neigh;
|
||||||
|
|
||||||
|
u16 seqno;
|
||||||
|
u16 advert_metric;
|
||||||
|
u16 metric;
|
||||||
|
u64 router_id;
|
||||||
|
ip_addr next_hop;
|
||||||
|
bird_clock_t refresh_time;
|
||||||
|
bird_clock_t expires;
|
||||||
|
u16 expiry_interval;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_entry {
|
||||||
|
struct fib_node n;
|
||||||
|
struct babel_proto *proto;
|
||||||
|
struct babel_route *selected_in;
|
||||||
|
struct babel_route *selected_out;
|
||||||
|
|
||||||
|
bird_clock_t updated;
|
||||||
|
|
||||||
|
list sources; /* Source entries for this prefix (struct babel_source). */
|
||||||
|
list routes; /* Routes for this prefix (struct babel_route) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Stores forwarded seqno requests for duplicate suppression. */
|
||||||
|
struct babel_seqno_request {
|
||||||
|
node n;
|
||||||
|
ip_addr prefix;
|
||||||
|
u8 plen;
|
||||||
|
u64 router_id;
|
||||||
|
u16 seqno;
|
||||||
|
bird_clock_t updated;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal TLV messages
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct babel_msg_ack_req {
|
||||||
|
u8 type;
|
||||||
|
u16 nonce;
|
||||||
|
u16 interval;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_ack {
|
||||||
|
u8 type;
|
||||||
|
u16 nonce;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_hello {
|
||||||
|
u8 type;
|
||||||
|
u16 seqno;
|
||||||
|
u16 interval;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_ihu {
|
||||||
|
u8 type;
|
||||||
|
u8 ae;
|
||||||
|
u16 rxcost;
|
||||||
|
u16 interval;
|
||||||
|
ip_addr addr;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_update {
|
||||||
|
u8 type;
|
||||||
|
u8 ae;
|
||||||
|
u8 plen;
|
||||||
|
u16 interval;
|
||||||
|
u16 seqno;
|
||||||
|
u16 metric;
|
||||||
|
ip_addr prefix;
|
||||||
|
u64 router_id;
|
||||||
|
ip_addr next_hop;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_route_request {
|
||||||
|
u8 type;
|
||||||
|
u8 full;
|
||||||
|
u8 plen;
|
||||||
|
ip_addr prefix;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_seqno_request {
|
||||||
|
u8 type;
|
||||||
|
u8 plen;
|
||||||
|
u16 seqno;
|
||||||
|
u8 hop_count;
|
||||||
|
u64 router_id;
|
||||||
|
ip_addr prefix;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
union babel_msg {
|
||||||
|
u8 type;
|
||||||
|
struct babel_msg_ack_req ack_req;
|
||||||
|
struct babel_msg_ack ack;
|
||||||
|
struct babel_msg_hello hello;
|
||||||
|
struct babel_msg_ihu ihu;
|
||||||
|
struct babel_msg_update update;
|
||||||
|
struct babel_msg_route_request route_request;
|
||||||
|
struct babel_msg_seqno_request seqno_request;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_node {
|
||||||
|
node n;
|
||||||
|
union babel_msg msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* babel.c */
|
||||||
|
void babel_handle_ack_req(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_ack(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_hello(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_ihu(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_router_id(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_update(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_route_request(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_seqno_request(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
|
||||||
|
void babel_show_interfaces(struct proto *P, char *iff);
|
||||||
|
void babel_show_neighbors(struct proto *P, char *iff);
|
||||||
|
void babel_show_entries(struct proto *P);
|
||||||
|
|
||||||
|
/* packets.c */
|
||||||
|
void babel_enqueue(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_send_unicast(union babel_msg *msg, struct babel_iface *ifa, ip_addr dest);
|
||||||
|
int babel_open_socket(struct babel_iface *ifa);
|
||||||
|
void babel_send_queue(void *arg);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
129
proto/babel/config.Y
Normal file
129
proto/babel/config.Y
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* BIRD -- Babel Configuration
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 Toke Hoiland-Jorgensen
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CF_HDR
|
||||||
|
|
||||||
|
#include "proto/babel/babel.h"
|
||||||
|
#include "nest/iface.h"
|
||||||
|
|
||||||
|
CF_DEFINES
|
||||||
|
|
||||||
|
#define BABEL_CFG ((struct babel_config *) this_proto)
|
||||||
|
#define BABEL_IFACE ((struct babel_iface_config *) this_ipatt)
|
||||||
|
|
||||||
|
CF_DECLS
|
||||||
|
|
||||||
|
CF_KEYWORDS(BABEL, METRIC, RXCOST, HELLO, UPDATE, INTERVAL, PORT, WIRED,
|
||||||
|
WIRELESS, RX, TX, BUFFER, LENGTH, CHECK, LINK, BABEL_METRIC)
|
||||||
|
|
||||||
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
CF_ADDTO(proto, babel_proto)
|
||||||
|
|
||||||
|
babel_proto_start: proto_start BABEL
|
||||||
|
{
|
||||||
|
this_proto = proto_config_new(&proto_babel, $1);
|
||||||
|
init_list(&BABEL_CFG->iface_list);
|
||||||
|
};
|
||||||
|
|
||||||
|
babel_proto_item:
|
||||||
|
proto_item
|
||||||
|
| INTERFACE babel_iface
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_proto_opts:
|
||||||
|
/* empty */
|
||||||
|
| babel_proto_opts babel_proto_item ';'
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_proto:
|
||||||
|
babel_proto_start proto_name '{' babel_proto_opts '}';
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface_start:
|
||||||
|
{
|
||||||
|
this_ipatt = cfg_allocz(sizeof(struct babel_iface_config));
|
||||||
|
add_tail(&BABEL_CFG->iface_list, NODE this_ipatt);
|
||||||
|
init_list(&this_ipatt->ipn_list);
|
||||||
|
BABEL_IFACE->port = BABEL_PORT;
|
||||||
|
BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRED;
|
||||||
|
BABEL_IFACE->tx_tos = IP_PREC_INTERNET_CONTROL;
|
||||||
|
BABEL_IFACE->tx_priority = sk_priority_control;
|
||||||
|
BABEL_IFACE->check_link = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface_finish:
|
||||||
|
{
|
||||||
|
if (BABEL_IFACE->type == BABEL_IFACE_TYPE_WIRELESS)
|
||||||
|
{
|
||||||
|
if (!BABEL_IFACE->hello_interval)
|
||||||
|
BABEL_IFACE->hello_interval = BABEL_HELLO_INTERVAL_WIRELESS;
|
||||||
|
if (!BABEL_IFACE->rxcost)
|
||||||
|
BABEL_IFACE->rxcost = BABEL_RXCOST_WIRELESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!BABEL_IFACE->hello_interval)
|
||||||
|
BABEL_IFACE->hello_interval = BABEL_HELLO_INTERVAL_WIRED;
|
||||||
|
if (!BABEL_IFACE->rxcost)
|
||||||
|
BABEL_IFACE->rxcost = BABEL_RXCOST_WIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BABEL_IFACE->update_interval)
|
||||||
|
BABEL_IFACE->update_interval = BABEL_IFACE->hello_interval*BABEL_UPDATE_INTERVAL_FACTOR;
|
||||||
|
BABEL_IFACE->ihu_interval = BABEL_IFACE->hello_interval*BABEL_IHU_INTERVAL_FACTOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface_item:
|
||||||
|
| PORT expr { BABEL_IFACE->port = $2; if (($2<1) || ($2>65535)) cf_error("Invalid port number"); }
|
||||||
|
| RXCOST expr { BABEL_IFACE->rxcost = $2; if (($2<1) || ($2>65535)) cf_error("Invalid rxcost"); }
|
||||||
|
| HELLO INTERVAL expr { BABEL_IFACE->hello_interval = $3; if (($3<1) || ($3>65535)) cf_error("Invalid hello interval"); }
|
||||||
|
| UPDATE INTERVAL expr { BABEL_IFACE->update_interval = $3; if (($3<1) || ($3>65535)) cf_error("Invalid hello interval"); }
|
||||||
|
| TYPE WIRED { BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRED; }
|
||||||
|
| TYPE WIRELESS { BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRELESS; }
|
||||||
|
| RX BUFFER expr { BABEL_IFACE->rx_buffer = $3; if (($3<256) || ($3>65535)) cf_error("RX buffer must be in range 256-65535"); }
|
||||||
|
| TX LENGTH expr { BABEL_IFACE->tx_length = $3; if (($3<256) || ($3>65535)) cf_error("TX length must be in range 256-65535"); }
|
||||||
|
| TX tos { BABEL_IFACE->tx_tos = $2; }
|
||||||
|
| TX PRIORITY expr { BABEL_IFACE->tx_priority = $3; }
|
||||||
|
| CHECK LINK bool { BABEL_IFACE->check_link = $3; }
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_iface_opts:
|
||||||
|
/* empty */
|
||||||
|
| babel_iface_opts babel_iface_item ';'
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_iface_opt_list:
|
||||||
|
/* empty */
|
||||||
|
| '{' babel_iface_opts '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface:
|
||||||
|
babel_iface_start iface_patt_list_nopx babel_iface_opt_list babel_iface_finish;
|
||||||
|
|
||||||
|
CF_ADDTO(dynamic_attr, BABEL_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_BABEL_METRIC); })
|
||||||
|
|
||||||
|
CF_CLI_HELP(SHOW BABEL, ..., [[Show information about Babel protocol]]);
|
||||||
|
|
||||||
|
CF_CLI(SHOW BABEL INTERFACES, optsym opttext, [<name>] [\"<interface>\"], [[Show information about Babel interfaces]])
|
||||||
|
{ babel_show_interfaces(proto_get_named($4, &proto_babel), $5); };
|
||||||
|
|
||||||
|
CF_CLI(SHOW BABEL NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about Babel neighbors]])
|
||||||
|
{ babel_show_neighbors(proto_get_named($4, &proto_babel), $5); };
|
||||||
|
|
||||||
|
CF_CLI(SHOW BABEL ENTRIES, optsym opttext, [<name>], [[Show information about Babel prefix entries]])
|
||||||
|
{ babel_show_entries(proto_get_named($4, &proto_babel)); };
|
||||||
|
|
||||||
|
CF_CODE
|
||||||
|
|
||||||
|
CF_END
|
1093
proto/babel/packets.c
Normal file
1093
proto/babel/packets.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -121,7 +121,8 @@ bgp_open(struct bgp_proto *p)
|
||||||
bgp_counter++;
|
bgp_counter++;
|
||||||
|
|
||||||
if (p->cf->password)
|
if (p->cf->password)
|
||||||
if (sk_set_md5_auth(bgp_listen_sk, p->cf->remote_ip, p->cf->iface, p->cf->password) < 0)
|
if (sk_set_md5_auth(bgp_listen_sk, p->cf->source_addr, p->cf->remote_ip,
|
||||||
|
p->cf->iface, p->cf->password, p->cf->setkey) < 0)
|
||||||
{
|
{
|
||||||
sk_log_error(bgp_listen_sk, p->p.name);
|
sk_log_error(bgp_listen_sk, p->p.name);
|
||||||
bgp_close(p, 0);
|
bgp_close(p, 0);
|
||||||
|
@ -191,7 +192,8 @@ bgp_close(struct bgp_proto *p, int apply_md5)
|
||||||
bgp_counter--;
|
bgp_counter--;
|
||||||
|
|
||||||
if (p->cf->password && apply_md5)
|
if (p->cf->password && apply_md5)
|
||||||
if (sk_set_md5_auth(bgp_listen_sk, p->cf->remote_ip, p->cf->iface, NULL) < 0)
|
if (sk_set_md5_auth(bgp_listen_sk, p->cf->source_addr, p->cf->remote_ip,
|
||||||
|
p->cf->iface, NULL, p->cf->setkey) < 0)
|
||||||
sk_log_error(bgp_listen_sk, p->p.name);
|
sk_log_error(bgp_listen_sk, p->p.name);
|
||||||
|
|
||||||
if (!bgp_counter)
|
if (!bgp_counter)
|
||||||
|
|
|
@ -51,6 +51,7 @@ struct bgp_config {
|
||||||
int add_path; /* Use ADD-PATH extension [draft] */
|
int add_path; /* Use ADD-PATH extension [draft] */
|
||||||
int allow_local_as; /* Allow that number of local ASNs in incoming AS_PATHs */
|
int allow_local_as; /* Allow that number of local ASNs in incoming AS_PATHs */
|
||||||
int gr_mode; /* Graceful restart mode (BGP_GR_*) */
|
int gr_mode; /* Graceful restart mode (BGP_GR_*) */
|
||||||
|
int setkey; /* Set MD5 password to system SA/SP database */
|
||||||
unsigned gr_time; /* Graceful restart timeout */
|
unsigned gr_time; /* Graceful restart timeout */
|
||||||
unsigned connect_delay_time; /* Minimum delay between connect attempts */
|
unsigned connect_delay_time; /* Minimum delay between connect attempts */
|
||||||
unsigned connect_retry_time; /* Timeout for connect attempts */
|
unsigned connect_retry_time; /* Timeout for connect attempts */
|
||||||
|
|
|
@ -27,7 +27,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
|
||||||
INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP,
|
INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP,
|
||||||
TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC,
|
TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC,
|
||||||
SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE,
|
SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE,
|
||||||
CHECK, LINK, PORT, EXTENDED, MESSAGES)
|
CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY)
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ bgp_proto_start: proto_start BGP {
|
||||||
BGP_CFG->default_local_pref = 100;
|
BGP_CFG->default_local_pref = 100;
|
||||||
BGP_CFG->gr_mode = BGP_GR_AWARE;
|
BGP_CFG->gr_mode = BGP_GR_AWARE;
|
||||||
BGP_CFG->gr_time = 120;
|
BGP_CFG->gr_time = 120;
|
||||||
|
BGP_CFG->setkey = 1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -112,6 +113,7 @@ bgp_proto:
|
||||||
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
|
||||||
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
|
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
|
||||||
| bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; }
|
| bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; }
|
||||||
|
| bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; }
|
||||||
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
|
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
|
||||||
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
|
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
|
||||||
| bgp_proto SECONDARY bool ';' { BGP_CFG->secondary = $3; }
|
| bgp_proto SECONDARY bool ';' { BGP_CFG->secondary = $3; }
|
||||||
|
|
|
@ -192,6 +192,7 @@ ospf_do_send_dbdes(struct ospf_proto *p, struct ospf_neighbor *n)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ospf_send_dbdes - transmit database description packet
|
* ospf_send_dbdes - transmit database description packet
|
||||||
|
* @p: OSPF protocol instance
|
||||||
* @n: neighbor
|
* @n: neighbor
|
||||||
*
|
*
|
||||||
* Sending of a database description packet is described in 10.8 of RFC 2328.
|
* Sending of a database description packet is described in 10.8 of RFC 2328.
|
||||||
|
|
|
@ -552,12 +552,13 @@ lsa_validate_prefix(struct ospf_lsa_header *lsa, struct ospf_lsa_prefix *body)
|
||||||
/**
|
/**
|
||||||
* lsa_validate - check whether given LSA is valid
|
* lsa_validate - check whether given LSA is valid
|
||||||
* @lsa: LSA header
|
* @lsa: LSA header
|
||||||
|
* @lsa_type: internal LSA type (%LSA_T_xxx)
|
||||||
|
* @ospf2: %true for OSPFv2, %false for OSPFv3
|
||||||
* @body: pointer to LSA body
|
* @body: pointer to LSA body
|
||||||
*
|
*
|
||||||
* Checks internal structure of given LSA body (minimal length,
|
* Checks internal structure of given LSA body (minimal length,
|
||||||
* consistency). Returns true if valid.
|
* consistency). Returns true if valid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
lsa_validate(struct ospf_lsa_header *lsa, u32 lsa_type, int ospf2, void *body)
|
lsa_validate(struct ospf_lsa_header *lsa, u32 lsa_type, int ospf2, void *body)
|
||||||
{
|
{
|
||||||
|
|
|
@ -207,7 +207,7 @@ drop:
|
||||||
/**
|
/**
|
||||||
* ospf_rx_hook
|
* ospf_rx_hook
|
||||||
* @sk: socket we received the packet.
|
* @sk: socket we received the packet.
|
||||||
* @size: size of the packet
|
* @len: length of the packet
|
||||||
*
|
*
|
||||||
* This is the entry point for messages from neighbors. Many checks (like
|
* This is the entry point for messages from neighbors. Many checks (like
|
||||||
* authentication, checksums, size) are done before the packet is passed to
|
* authentication, checksums, size) are done before the packet is passed to
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#undef CONFIG_BGP
|
#undef CONFIG_BGP
|
||||||
#undef CONFIG_OSPF
|
#undef CONFIG_OSPF
|
||||||
#undef CONFIG_PIPE
|
#undef CONFIG_PIPE
|
||||||
|
#undef CONFIG_BABEL
|
||||||
|
|
||||||
/* We use multithreading */
|
/* We use multithreading */
|
||||||
#undef USE_PTHREADS
|
#undef USE_PTHREADS
|
||||||
|
|
170
sysdep/bsd/setkey.h
Normal file
170
sysdep/bsd/setkey.h
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* BIRD -- Manipulation the IPsec SA/SP database using setkey(8) utility
|
||||||
|
*
|
||||||
|
* (c) 2016 CZ.NIC z.s.p.o.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/pfkeyv2.h>
|
||||||
|
#include <netipsec/ipsec.h>
|
||||||
|
|
||||||
|
#include "nest/bird.h"
|
||||||
|
#include "lib/unix.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a socket for manage the IPsec SA/SP database entries
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
setkey_open_socket(void)
|
||||||
|
{
|
||||||
|
int s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
|
||||||
|
if (s < 0)
|
||||||
|
{
|
||||||
|
log(L_ERR "SETKEY: socket: %m");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
setkey_send(struct sadb_msg *msg, uint len)
|
||||||
|
{
|
||||||
|
int s = setkey_open_socket();
|
||||||
|
if (s < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (msg->sadb_msg_type == SADB_ADD)
|
||||||
|
{
|
||||||
|
/* Delete possible current key in the IPsec SA/SP database */
|
||||||
|
msg->sadb_msg_type = SADB_DELETE;
|
||||||
|
send(s, msg, len, 0);
|
||||||
|
msg->sadb_msg_type = SADB_ADD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send(s, msg, len, 0) < 0)
|
||||||
|
{
|
||||||
|
log(L_ERR "SETKEY: send: %m");
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform setkey(8)-like operation for set the password for TCP MD5 Signature.
|
||||||
|
* Could be called with SABD_ADD or SADB_DELETE argument. Note that SADB_ADD
|
||||||
|
* argument is internally processed as a pair of SADB_ADD and SADB_DELETE
|
||||||
|
* operations to implement replace.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
setkey_md5(sockaddr *src, sockaddr *dst, char *passwd, uint type)
|
||||||
|
{
|
||||||
|
uint passwd_len = passwd ? strlen(passwd) : 0;
|
||||||
|
|
||||||
|
uint total =
|
||||||
|
sizeof(struct sadb_msg) +
|
||||||
|
sizeof(struct sadb_key) + PFKEY_ALIGN8(passwd_len) +
|
||||||
|
sizeof(struct sadb_sa) +
|
||||||
|
sizeof(struct sadb_x_sa2) +
|
||||||
|
sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa.sa_len) +
|
||||||
|
sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa.sa_len);
|
||||||
|
|
||||||
|
char *buf = alloca(total);
|
||||||
|
char *pos = buf;
|
||||||
|
uint len;
|
||||||
|
|
||||||
|
memset(buf, 0, total);
|
||||||
|
|
||||||
|
struct sadb_msg *msg = (void *) pos;
|
||||||
|
len = sizeof(struct sadb_msg);
|
||||||
|
msg->sadb_msg_version = PF_KEY_V2;
|
||||||
|
msg->sadb_msg_type = type;
|
||||||
|
msg->sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE;
|
||||||
|
msg->sadb_msg_len = 0; /* Fix it later */
|
||||||
|
msg->sadb_msg_pid = getpid();
|
||||||
|
pos += len;
|
||||||
|
|
||||||
|
/* Set authentication algorithm and password */
|
||||||
|
struct sadb_key *key = (void *) pos;
|
||||||
|
len = sizeof(struct sadb_key) + PFKEY_ALIGN8(passwd_len);
|
||||||
|
key->sadb_key_len = PFKEY_UNIT64(len);
|
||||||
|
key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
|
||||||
|
key->sadb_key_bits = passwd_len * 8;
|
||||||
|
memcpy(pos + sizeof(struct sadb_key), passwd, passwd_len);
|
||||||
|
pos += len;
|
||||||
|
|
||||||
|
struct sadb_sa *sa = (void *) pos;
|
||||||
|
len = sizeof(struct sadb_sa);
|
||||||
|
sa->sadb_sa_len = PFKEY_UNIT64(len);
|
||||||
|
sa->sadb_sa_exttype = SADB_EXT_SA;
|
||||||
|
sa->sadb_sa_spi = htonl((u32) TCP_SIG_SPI);
|
||||||
|
sa->sadb_sa_auth = SADB_X_AALG_TCP_MD5;
|
||||||
|
sa->sadb_sa_encrypt = SADB_EALG_NONE;
|
||||||
|
sa->sadb_sa_flags = SADB_X_EXT_CYCSEQ;
|
||||||
|
pos += len;
|
||||||
|
|
||||||
|
struct sadb_x_sa2 *sa2 = (void *) pos;
|
||||||
|
len = sizeof(struct sadb_x_sa2);
|
||||||
|
sa2->sadb_x_sa2_len = PFKEY_UNIT64(len);
|
||||||
|
sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
|
||||||
|
sa2->sadb_x_sa2_mode = IPSEC_MODE_ANY;
|
||||||
|
pos += len;
|
||||||
|
|
||||||
|
/* Set source address */
|
||||||
|
struct sadb_address *saddr = (void *) pos;
|
||||||
|
len = sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa.sa_len);
|
||||||
|
saddr->sadb_address_len = PFKEY_UNIT64(len);
|
||||||
|
saddr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
|
||||||
|
saddr->sadb_address_proto = IPSEC_ULPROTO_ANY;
|
||||||
|
saddr->sadb_address_prefixlen = MAX_PREFIX_LENGTH;
|
||||||
|
memcpy(pos + sizeof(struct sadb_address), &src->sa, src->sa.sa_len);
|
||||||
|
pos += len;
|
||||||
|
|
||||||
|
/* Set destination address */
|
||||||
|
struct sadb_address *daddr = (void *) pos;
|
||||||
|
len = sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa.sa_len);
|
||||||
|
daddr->sadb_address_len = PFKEY_UNIT64(len);
|
||||||
|
daddr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
||||||
|
daddr->sadb_address_proto = IPSEC_ULPROTO_ANY;
|
||||||
|
daddr->sadb_address_prefixlen = MAX_PREFIX_LENGTH;
|
||||||
|
memcpy(pos + sizeof(struct sadb_address), &dst->sa, dst->sa.sa_len);
|
||||||
|
pos += len;
|
||||||
|
|
||||||
|
len = pos - buf;
|
||||||
|
msg->sadb_msg_len = PFKEY_UNIT64(len);
|
||||||
|
|
||||||
|
return setkey_send(msg, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manipulation with the IPsec SA/SP database
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sk_set_md5_in_sasp_db(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd)
|
||||||
|
{
|
||||||
|
sockaddr src, dst;
|
||||||
|
sockaddr_fill(&src, s->af, local, ifa, 0);
|
||||||
|
sockaddr_fill(&dst, s->af, remote, ifa, 0);
|
||||||
|
|
||||||
|
if (passwd && *passwd)
|
||||||
|
{
|
||||||
|
int len = strlen(passwd);
|
||||||
|
if (len > TCP_KEYLEN_MAX)
|
||||||
|
ERR_MSG("The password for TCP MD5 Signature is too long");
|
||||||
|
|
||||||
|
if (setkey_md5(&src, &dst, passwd, SADB_ADD) < 0)
|
||||||
|
ERR_MSG("Cannot add TCP-MD5 password into the IPsec SA/SP database");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (setkey_md5(&src, &dst, NULL, SADB_DELETE) < 0)
|
||||||
|
ERR_MSG("Cannot delete TCP-MD5 password from the IPsec SA/SP database");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -189,30 +189,26 @@ sk_prepare_ip_header(sock *s, void *hdr, int dlen)
|
||||||
#ifndef TCP_KEYLEN_MAX
|
#ifndef TCP_KEYLEN_MAX
|
||||||
#define TCP_KEYLEN_MAX 80
|
#define TCP_KEYLEN_MAX 80
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TCP_SIG_SPI
|
#ifndef TCP_SIG_SPI
|
||||||
#define TCP_SIG_SPI 0x1000
|
#define TCP_SIG_SPI 0x1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
#if defined(__FreeBSD__)
|
||||||
* FIXME: Passwords has to be set by setkey(8) command. This is the same
|
#define USE_MD5SIG_SETKEY
|
||||||
* behaviour like Quagga. We need to add code for SA/SP entries
|
#include "lib/setkey.h"
|
||||||
* management.
|
#endif
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd)
|
sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd, int setkey UNUSED)
|
||||||
{
|
{
|
||||||
int enable = 0;
|
#ifdef USE_MD5SIG_SETKEY
|
||||||
|
if (setkey)
|
||||||
if (passwd && *passwd)
|
if (sk_set_md5_in_sasp_db(s, local, remote, ifa, passwd) < 0)
|
||||||
{
|
return -1;
|
||||||
int len = strlen(passwd);
|
#endif
|
||||||
enable = TCP_SIG_SPI;
|
|
||||||
|
|
||||||
if (len > TCP_KEYLEN_MAX)
|
|
||||||
ERR_MSG("MD5 password too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int enable = (passwd && *passwd) ? TCP_SIG_SPI : 0;
|
||||||
if (setsockopt(s->fd, IPPROTO_TCP, TCP_MD5SIG, &enable, sizeof(enable)) < 0)
|
if (setsockopt(s->fd, IPPROTO_TCP, TCP_MD5SIG, &enable, sizeof(enable)) < 0)
|
||||||
{
|
{
|
||||||
if (errno == ENOPROTOOPT)
|
if (errno == ENOPROTOOPT)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define _BIRD_CONFIG_H_
|
#define _BIRD_CONFIG_H_
|
||||||
|
|
||||||
/* BIRD version */
|
/* BIRD version */
|
||||||
#define BIRD_VERSION "1.5.0"
|
#define BIRD_VERSION "1.6.0"
|
||||||
|
|
||||||
/* Include parameters determined by configure script */
|
/* Include parameters determined by configure script */
|
||||||
#include "sysdep/autoconf.h"
|
#include "sysdep/autoconf.h"
|
||||||
|
|
|
@ -126,7 +126,12 @@ nl_get_reply(struct nl_sock *nl)
|
||||||
{
|
{
|
||||||
struct iovec iov = { nl->rx_buffer, NL_RX_SIZE };
|
struct iovec iov = { nl->rx_buffer, NL_RX_SIZE };
|
||||||
struct sockaddr_nl sa;
|
struct sockaddr_nl sa;
|
||||||
struct msghdr m = { (struct sockaddr *) &sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
|
struct msghdr m = {
|
||||||
|
.msg_name = &sa,
|
||||||
|
.msg_namelen = sizeof(sa),
|
||||||
|
.msg_iov = &iov,
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
};
|
||||||
int x = recvmsg(nl->fd, &m, 0);
|
int x = recvmsg(nl->fd, &m, 0);
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
die("nl_get_reply: %m");
|
die("nl_get_reply: %m");
|
||||||
|
@ -1343,7 +1348,12 @@ nl_async_hook(sock *sk, int size UNUSED)
|
||||||
{
|
{
|
||||||
struct iovec iov = { nl_async_rx_buffer, NL_RX_SIZE };
|
struct iovec iov = { nl_async_rx_buffer, NL_RX_SIZE };
|
||||||
struct sockaddr_nl sa;
|
struct sockaddr_nl sa;
|
||||||
struct msghdr m = { (struct sockaddr *) &sa, sizeof(sa), &iov, 1, NULL, 0, 0 };
|
struct msghdr m = {
|
||||||
|
.msg_name = &sa,
|
||||||
|
.msg_namelen = sizeof(sa),
|
||||||
|
.msg_iov = &iov,
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
};
|
||||||
struct nlmsghdr *h;
|
struct nlmsghdr *h;
|
||||||
int x;
|
int x;
|
||||||
uint len;
|
uint len;
|
||||||
|
|
|
@ -179,19 +179,19 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd)
|
sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, struct iface *ifa, char *passwd, int setkey UNUSED)
|
||||||
{
|
{
|
||||||
struct tcp_md5sig md5;
|
struct tcp_md5sig md5;
|
||||||
|
|
||||||
memset(&md5, 0, sizeof(md5));
|
memset(&md5, 0, sizeof(md5));
|
||||||
sockaddr_fill((sockaddr *) &md5.tcpm_addr, fam_to_af[s->fam], a, ifa, 0);
|
sockaddr_fill((sockaddr *) &md5.tcpm_addr, fam_to_af[s->fam], remote, ifa, 0);
|
||||||
|
|
||||||
if (passwd)
|
if (passwd)
|
||||||
{
|
{
|
||||||
int len = strlen(passwd);
|
int len = strlen(passwd);
|
||||||
|
|
||||||
if (len > TCP_MD5SIG_MAXKEYLEN)
|
if (len > TCP_MD5SIG_MAXKEYLEN)
|
||||||
ERR_MSG("MD5 password too long");
|
ERR_MSG("The password for TCP MD5 Signature is too long");
|
||||||
|
|
||||||
md5.tcpm_keylen = len;
|
md5.tcpm_keylen = len;
|
||||||
memcpy(&md5.tcpm_key, passwd, len);
|
memcpy(&md5.tcpm_key, passwd, len);
|
||||||
|
|
|
@ -448,6 +448,7 @@ tm_format_reltime(char *x, struct tm *tm, bird_clock_t delta)
|
||||||
/**
|
/**
|
||||||
* tm_format_datetime - convert date and time to textual representation
|
* tm_format_datetime - convert date and time to textual representation
|
||||||
* @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
|
* @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
|
||||||
|
* @fmt_spec: specification of resulting textual representation of the time
|
||||||
* @t: time
|
* @t: time
|
||||||
*
|
*
|
||||||
* This function formats the given relative time value @t to a textual
|
* This function formats the given relative time value @t to a textual
|
||||||
|
@ -952,23 +953,32 @@ sk_set_min_ttl(sock *s, int ttl)
|
||||||
/**
|
/**
|
||||||
* sk_set_md5_auth - add / remove MD5 security association for given socket
|
* sk_set_md5_auth - add / remove MD5 security association for given socket
|
||||||
* @s: socket
|
* @s: socket
|
||||||
* @a: IP address of the other side
|
* @local: IP address of local side
|
||||||
|
* @remote: IP address of remote side
|
||||||
* @ifa: Interface for link-local IP address
|
* @ifa: Interface for link-local IP address
|
||||||
* @passwd: password used for MD5 authentication
|
* @passwd: Password used for MD5 authentication
|
||||||
|
* @setkey: Update also system SA/SP database
|
||||||
*
|
*
|
||||||
* In TCP MD5 handling code in kernel, there is a set of pairs (address,
|
* In TCP MD5 handling code in kernel, there is a set of security associations
|
||||||
* password) used to choose password according to address of the other side.
|
* used for choosing password and other authentication parameters according to
|
||||||
* This function is useful for listening socket, for active sockets it is enough
|
* the local and remote address. This function is useful for listening socket,
|
||||||
* to set s->password field.
|
* for active sockets it may be enough to set s->password field.
|
||||||
*
|
*
|
||||||
* When called with passwd != NULL, the new pair is added,
|
* When called with passwd != NULL, the new pair is added,
|
||||||
* When called with passwd == NULL, the existing pair is removed.
|
* When called with passwd == NULL, the existing pair is removed.
|
||||||
*
|
*
|
||||||
|
* Note that while in Linux, the MD5 SAs are specific to socket, in BSD they are
|
||||||
|
* stored in global SA/SP database (but the behavior also must be enabled on
|
||||||
|
* per-socket basis). In case of multiple sockets to the same neighbor, the
|
||||||
|
* socket-specific state must be configured for each socket while global state
|
||||||
|
* just once per src-dst pair. The @setkey argument controls whether the global
|
||||||
|
* state (SA/SP database) is also updated.
|
||||||
|
*
|
||||||
* Result: 0 for success, -1 for an error.
|
* Result: 0 for success, -1 for an error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd)
|
sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd, int setkey)
|
||||||
{ DUMMY; }
|
{ DUMMY; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1436,7 +1446,7 @@ sk_open(sock *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->password)
|
if (s->password)
|
||||||
if (sk_set_md5_auth(s, s->daddr, s->iface, s->password) < 0)
|
if (sk_set_md5_auth(s, s->saddr, s->daddr, s->iface, s->password, 0) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
switch (s->type)
|
switch (s->type)
|
||||||
|
|
|
@ -89,6 +89,7 @@ static char *class_names[] = {
|
||||||
/**
|
/**
|
||||||
* log_commit - commit a log message
|
* log_commit - commit a log message
|
||||||
* @class: message class information (%L_DEBUG to %L_BUG, see |lib/birdlib.h|)
|
* @class: message class information (%L_DEBUG to %L_BUG, see |lib/birdlib.h|)
|
||||||
|
* @buf: message to write
|
||||||
*
|
*
|
||||||
* This function writes a message prepared in the log buffer to the
|
* This function writes a message prepared in the log buffer to the
|
||||||
* log file (as specified in the configuration). The log buffer is
|
* log file (as specified in the configuration). The log buffer is
|
||||||
|
|
|
@ -621,7 +621,7 @@ signal_init(void)
|
||||||
* Parsing of command-line arguments
|
* Parsing of command-line arguments
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *opt_list = "c:dD:ps:P:u:g:fR";
|
static char *opt_list = "c:dD:ps:P:u:g:flR";
|
||||||
static int parse_and_exit;
|
static int parse_and_exit;
|
||||||
char *bird_name;
|
char *bird_name;
|
||||||
static char *use_user;
|
static char *use_user;
|
||||||
|
@ -631,7 +631,7 @@ static int run_in_foreground = 0;
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-c <config-file>] [-d] [-D <debug-file>] [-p] [-s <control-socket>] [-P <pid-file>] [-u <user>] [-g <group>] [-f] [-R]\n", bird_name);
|
fprintf(stderr, "Usage: %s [-c <config-file>] [-d] [-D <debug-file>] [-p] [-s <control-socket>] [-P <pid-file>] [-u <user>] [-g <group>] [-f] [-l] [-R]\n", bird_name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,6 +698,8 @@ get_gid(const char *s)
|
||||||
static void
|
static void
|
||||||
parse_args(int argc, char **argv)
|
parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int config_changed = 0;
|
||||||
|
int socket_changed = 0;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
bird_name = get_bird_name(argv[0], "bird");
|
bird_name = get_bird_name(argv[0], "bird");
|
||||||
|
@ -716,6 +718,7 @@ parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
case 'c':
|
case 'c':
|
||||||
config_name = optarg;
|
config_name = optarg;
|
||||||
|
config_changed = 1;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
debug_flag |= 1;
|
debug_flag |= 1;
|
||||||
|
@ -729,6 +732,7 @@ parse_args(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
path_control_socket = optarg;
|
path_control_socket = optarg;
|
||||||
|
socket_changed = 1;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
pid_file = optarg;
|
pid_file = optarg;
|
||||||
|
@ -742,6 +746,12 @@ parse_args(int argc, char **argv)
|
||||||
case 'f':
|
case 'f':
|
||||||
run_in_foreground = 1;
|
run_in_foreground = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (!config_changed)
|
||||||
|
config_name = xbasename(config_name);
|
||||||
|
if (!socket_changed)
|
||||||
|
path_control_socket = xbasename(path_control_socket);
|
||||||
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
graceful_restart_recovery();
|
graceful_restart_recovery();
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue