Commit 54305181 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Merge branch 'new' into socket2

parents e7b76b97 afa9f66c
......@@ -5,6 +5,7 @@ Version 1.2.1 (2010-02-11)
o Adds router ID of advertising router as OSPF route attribute.
o 'show route' command indicates primary route and shows OSPF Router ID.
o Configurable date/time formats.
o Symbol names can be enclosed by '' and so include hyphen and start with number.
o Several minor bugfixes.
Version 1.2.0 (2010-01-05)
......
......@@ -25,8 +25,10 @@
#include "client/client.h"
#include "sysdep/unix/unix.h"
static char *opt_list = "s:v";
static char *opt_list = "s:vr";
static int verbose;
static char *init_cmd;
static int once;
static char *server_path = PATH_CONTROL_SOCKET;
static int server_fd;
......@@ -49,7 +51,7 @@ static int num_lines, skip_input, interactive;
static void
usage(void)
{
fprintf(stderr, "Usage: birdc [-s <control-socket>] [-v]\n");
fprintf(stderr, "Usage: birdc [-s <control-socket>] [-v] [-r]\n");
exit(1);
}
......@@ -67,11 +69,36 @@ parse_args(int argc, char **argv)
case 'v':
verbose++;
break;
case 'r':
init_cmd = "restrict";
break;
default:
usage();
}
/* If some arguments are not options, we take it as commands */
if (optind < argc)
usage();
{
char *tmp;
int i;
int len = 0;
if (init_cmd)
usage();
for (i = optind; i < argc; i++)
len += strlen(argv[i]) + 1;
tmp = init_cmd = malloc(len);
for (i = optind; i < argc; i++)
{
strcpy(tmp, argv[i]);
tmp += strlen(tmp);
*tmp++ = ' ';
}
once = 1;
}
}
/*** Input ***/
......@@ -267,11 +294,29 @@ update_state(void)
if (nstate == cstate)
return;
if (init_cmd)
{
/* First transition - client received hello from BIRD
and there is waiting initial command */
submit_server_command(init_cmd);
init_cmd = NULL;
return;
}
if (!init_cmd && once)
{
/* Initial command is finished and we want to exit */
cleanup();
exit(0);
}
if (nstate == STATE_PROMPT)
if (input_initialized)
input_reveal();
else
input_init();
{
if (input_initialized)
input_reveal();
else
input_init();
}
if (nstate != STATE_PROMPT)
input_hide();
......@@ -329,6 +374,8 @@ server_connect(void)
die("fcntl: %m");
}
#define PRINTF(LEN, PARGS...) do { if (!skip_input) len = printf(PARGS); } while(0)
static void
server_got_reply(char *x)
{
......@@ -336,15 +383,15 @@ server_got_reply(char *x)
int len = 0;
if (*x == '+') /* Async reply */
skip_input || (len = printf(">>> %s\n", x+1));
PRINTF(len, ">>> %s\n", x+1);
else if (x[0] == ' ') /* Continuation */
skip_input || (len = printf("%s%s\n", verbose ? " " : "", x+1));
PRINTF(len, "%s%s\n", verbose ? " " : "", x+1);
else if (strlen(x) > 4 &&
sscanf(x, "%d", &code) == 1 && code >= 0 && code < 10000 &&
(x[4] == ' ' || x[4] == '-'))
{
if (code)
skip_input || (len = printf("%s\n", verbose ? x : x+5));
PRINTF(len, "%s\n", verbose ? x : x+5);
if (x[4] == ' ')
{
nstate = STATE_PROMPT;
......@@ -353,7 +400,7 @@ server_got_reply(char *x)
}
}
else
skip_input || (len = printf("??? <%s>\n", x));
PRINTF(len, "??? <%s>\n", x);
if (skip_input)
return;
......
......@@ -33,6 +33,7 @@
#include "nest/bird.h"
#include "nest/route.h"
#include "nest/protocol.h"
#include "filter/filter.h"
#include "conf/conf.h"
#include "conf/cf-parse.tab.h"
......
......@@ -42,6 +42,7 @@ CF_DECLS
void *g;
bird_clock_t time;
struct prefix px;
struct proto_spec ps;
struct timeformat *tf;
}
......
......@@ -23,7 +23,7 @@ m4_define(CF_DECLS, `m4_divert(-1)')
m4_define(CF_DEFINES, `m4_divert(-1)')
# Keywords are translated to C initializers
m4_define(CF_handle_kw, `m4_divert(1){ "m4_translit($1,[[A-Z]],[[a-z]])", $1 },
m4_define(CF_handle_kw, `m4_divert(1){ "m4_translit($1,[[A-Z]],[[a-z]])", $1, NULL },
m4_divert(-1)')
m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)CF_handle_kw($1)]])')
m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token[[]]CF_toks
......@@ -34,7 +34,7 @@ m4_define(CF_CLI, `CF_KEYWORDS(m4_translit($1, [[ ]], [[,]]))
')
# Enums are translated to C initializers: use CF_ENUM(typename, prefix, values)
m4_define(CF_enum, `m4_divert(1){ "CF_enum_prefix[[]]$1", -((CF_enum_type<<16) | CF_enum_prefix[[]]$1) },
m4_define(CF_enum, `m4_divert(1){ "CF_enum_prefix[[]]$1", -((CF_enum_type<<16) | CF_enum_prefix[[]]$1), NULL },
m4_divert(-1)')
m4_define(CF_ENUM, `m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix]],$2)CF_iterate([[CF_enum]], [[m4_shift(m4_shift($@))]])DNL')
......@@ -42,7 +42,7 @@ m4_define(CF_ENUM, `m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix]],$
m4_m4wrap(`
m4_divert(0)
static struct keyword keyword_list[] = {
m4_undivert(1){ NULL, -1 } };
m4_undivert(1){ NULL, -1, NULL } };
')
# As we are processing C source, we must access all M4 primitives via
......
......@@ -8,7 +8,6 @@ AC_CONFIG_AUX_DIR(tools)
AC_ARG_ENABLE(debug,[ --enable-debug enable internal debugging routines (default: disabled)],,enable_debug=no)
AC_ARG_ENABLE(memcheck,[ --enable-memcheck check memory allocations when debugging (default: enabled)],,enable_memcheck=yes)
AC_ARG_ENABLE(warnings,[ --enable-warnings enable extra warnings (default: disabled)],,enable_warnings=no)
AC_ARG_ENABLE(client,[ --enable-client enable building of BIRD client (default: enabled)],,enable_client=yes)
AC_ARG_ENABLE(ipv6,[ --enable-ipv6 enable building of IPv6 version (default: disabled)],,enable_ipv6=no)
AC_ARG_WITH(sysconfig,[ --with-sysconfig=FILE use specified BIRD system configuration file])
......@@ -56,24 +55,17 @@ AC_SEARCH_LIBS(clock_gettime,[c rt posix4])
AC_CANONICAL_HOST
AC_PROG_CC
if test -z "$GCC" ; then
AC_MSG_ERROR([This program requires the GNU C Compiler.])
fi
AC_MSG_CHECKING([what CFLAGS should we use])
if test "$ac_test_CFLAGS" != set ; then
if test "$enable_warnings" = yes ; then
WARNS=" -Wmissing-prototypes -Wundef"
else
WARNS=" -Wno-unused"
fi
CFLAGS="$CFLAGS -Wall -W -Wstrict-prototypes -Wno-pointer-sign -Wno-parentheses$WARNS"
fi
if test "$with_sysinclude" != no -a -n "$with_sysinclude"; then
CPPFLAGS="$CPPFLAGS -I$with_sysinclude"
CFLAGS="$CFLAGS -Wall -Wstrict-prototypes -Wno-pointer-sign -Wno-parentheses"
fi
AC_MSG_RESULT($CFLAGS)
AC_PROG_CC
if test -z "$GCC" ; then
AC_MSG_ERROR([This program requires the GNU C Compiler.])
fi
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_RANLIB
......
......@@ -96,9 +96,9 @@ protocol static {
# honor neighbor; # To whom do we agree to send the routing table
# honor always;
# honor never;
# passwords { password "ahoj" from 0 to 10;
# password "nazdar" from 10;
# }
# passwords {
# password "nazdar";
# };
# authentication none;
# import filter { print "importing"; accept; };
# export filter { print "exporting"; accept; };
......@@ -143,6 +143,7 @@ protocol static {
# generate from "22-04-2003 11:00:07";
# accept from "17-01-2003 12:01:05";
# };
# };
# authentication cryptographic;
# };
# };
......@@ -163,7 +164,7 @@ protocol static {
#protocol bgp {
# disabled;
# description "My BGP uplink"
# description "My BGP uplink";
# local as 65000;
# neighbor 62.168.0.130 as 5588;
# multihop 20 via 62.168.0.13;
......@@ -181,17 +182,17 @@ protocol static {
# default bgp_med 0; # MED value we use for comparison when none is defined
# default bgp_local_pref 0; # The same for local preference
# source address 62.168.0.14; # What local address we use for the TCP connection
# password "secret" # Password used for MD5 authentication
# password "secret"; # Password used for MD5 authentication
# rr client; # I am a route reflector and the neighor is my client
# rr cluster id 1.0.0.1 # Use this value for cluster id instead of my router id
# rr cluster id 1.0.0.1; # Use this value for cluster id instead of my router id
# export where source=RTS_STATIC;
# export filter {
# if source = RTS_STATIC then {
## bgp_community = -empty-; bgp_community = add(bgp_community,(65000,5678));
## bgp_origin = 0;
# bgp_community = -empty-; bgp_community = add(bgp_community,(65000,5678));
# bgp_origin = 0;
# bgp_community = -empty-; bgp_community.add((65000,5678));
## if (65000,5678) ~ bgp_community then
## bgp_community.add((0, 1));
# if (65000,5678) ~ bgp_community then
# bgp_community.add((0, 1));
# if bgp_path ~ [= 65000 =] then
# bgp_path.prepend(65000);
# accept;
......
......@@ -824,7 +824,14 @@ defined by using the <cf>defined( <m>attribute</m> )</cf> operator.
Network the route is talking about. Read-only. (See the chapter about routing tables.)
<tag><m/enum/ scope</tag>
Address scope of the network (<cf/SCOPE_HOST/ for addresses local to this host, <cf/SCOPE_LINK/ for those specific for a physical link, <cf/SCOPE_SITE/ and <cf/SCOPE_ORGANIZATION/ for private addresses, <cf/SCOPE_UNIVERSE/ for globally visible addresses).
The scope of the route. Possible values: <cf/SCOPE_HOST/ for
routes local to this host, <cf/SCOPE_LINK/ for those specific
for a physical link, <cf/SCOPE_SITE/ and
<cf/SCOPE_ORGANIZATION/ for private routes and
<cf/SCOPE_UNIVERSE/ for globally visible routes. This
attribute is not interpreted by BIRD and can be used to mark
routes in filters. The default value for new routes is
<cf/SCOPE_UNIVERSE/.
<tag><m/int/ preference</tag>
Preference of the route. Valid values are 0-65535. (See the chapter about routing tables.)
......@@ -842,7 +849,11 @@ defined by using the <cf>defined( <m>attribute</m> )</cf> operator.
what protocol has told me about this route. Possible values: <cf/RTS_DUMMY/, <cf/RTS_STATIC/, <cf/RTS_INHERIT/, <cf/RTS_DEVICE/, <cf/RTS_STATIC_DEVICE/, <cf/RTS_REDIRECT/, <cf/RTS_RIP/, <cf/RTS_OSPF/, <cf/RTS_OSPF_IA/, <cf/RTS_OSPF_EXT/, <cf/RTS_BGP/, <cf/RTS_PIPE/.
<tag><m/enum/ cast</tag>
Route type (<cf/RTC_UNICAST/ for normal routes, <cf/RTC_BROADCAST/, <cf/RTC_MULTICAST/, <cf/RTC_ANYCAST/ for broadcast, multicast and anycast routes). Read-only.
Route type (Currently <cf/RTC_UNICAST/ for normal routes,
<cf/RTC_BROADCAST/, <cf/RTC_MULTICAST/, <cf/RTC_ANYCAST/ will
be used in the future for broadcast, multicast and anycast
routes). Read-only.
<tag><m/enum/ dest</tag>
Type of destination the packets should be sent to (<cf/RTD_ROUTER/ for forwarding to a neighboring router, <cf/RTD_NETWORK/ for routing to a directly-connected network, <cf/RTD_BLACKHOLE/ for packets to be silently discarded, <cf/RTD_UNREACHABLE/, <cf/RTD_PROHIBIT/ for packets that should be returned with ICMP host unreachable / ICMP administratively prohibited messages). Read-only.
......
......@@ -24,6 +24,7 @@ Reply codes of BIRD command-line interface
0013 Status report
0014 Route count
0015 Reloading
0016 Access restricted
1000 BIRD version
1001 Interface list
......@@ -51,6 +52,7 @@ Reply codes of BIRD command-line interface
8004 Stopped due to reconfiguration
8005 Protocol is down => cannot dump
8006 Reload failed
8007 Access denied
9000 Command too long
9001 Parse error
......
......@@ -273,16 +273,17 @@ fprefix_set:
;
switch_body: /* EMPTY */ { $$ = NULL; }
| set_item ':' cmds switch_body {
$$ = $1;
$$->data = $3;
$$->left = $4;
| switch_body set_item ':' cmds {
$$ = $2;
$$->data = $4;
$$->left = $1;
}
| ELSE ':' cmds {
| switch_body ELSE ':' cmds {
$$ = f_new_tree();
$$->from.type = T_VOID;
$$->to.type = T_VOID;
$$->data = $3;
$$->data = $4;
$$->left = $1;
}
;
......
......@@ -164,6 +164,11 @@ val_compare(struct f_val v1, struct f_val v2)
}
}
int
tree_compare(const void *p1, const void *p2)
{
return val_compare((* (struct f_tree **) p1)->from, (* (struct f_tree **) p2)->from);
}
void
f_prefix_get_bounds(struct f_prefix *px, int *l, int *h)
......
......@@ -91,6 +91,7 @@ void f_prefix_get_bounds(struct f_prefix *px, int *l, int *h);
void f_prefix_get_bounds(struct f_prefix *px, int *l, int *h);
int val_compare(struct f_val v1, struct f_val v2);
int tree_compare(const void *p1, const void *p2);
void val_print(struct f_val v);
#define F_NOP 0
......
......@@ -131,6 +131,9 @@ prefix px;
ip p;
pair pp;
int set is;
int set is1;
int set is2;
int set is3;
prefix set pxs;
string s;
{
......@@ -156,6 +159,18 @@ string s;
print " must be true: ", defined(1), ",", defined(1.2.3.4), ",", 1 != 2, ",", 1 <= 2;
print " data types: must be false: ", 1 ~ [ 2, 3, 4 ], ",", 5 ~ is, ",", 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ], ",", (1,2) > (2,2), ",", (1,1) > (1,1), ",", 1.0.0.0/9 ~ [ 1.0.0.0/8- ], ",", 1.2.0.0/17 ~ [ 1.0.0.0/8{ 15 , 16 } ], ",", true && false;
is1 = [2, 3, 5, 8, 11, 15, 17, 19];
is2 = [19, 17, 15, 11, 8, 5, 3, 2];
is3 = [5, 17, 2, 11, 8, 15, 3, 19];
print " must be true: ", 2 ~ is1, " ", 2 ~ is2, " ", 2 ~ is3;
print " must be false: ", 4 ~ is1, " ", 4 ~ is2, " ", 4 ~ is3;
print " must be false: ", 10 ~ is1, " ", 10 ~ is2, " ", 10 ~ is3;
print " must be true: ", 15 ~ is1, " ", 15 ~ is2, " ", 15 ~ is3;
print " must be false: ", 18 ~ is1, " ", 18 ~ is2, " ", 18 ~ is3;
print " must be true: ", 19 ~ is1, " ", 19 ~ is2, " ", 19 ~ is3;
print " must be false: ", 20 ~ is1, " ", 20 ~ is2, " ", 20 ~ is3;
px = 1.2.0.0/18;
print "Testing prefixes: 1.2.0.0/18 = ", px;
print " must be true: ", 192.168.0.0/16 ~ 192.168.0.0/16, " ", 192.168.0.0/17 ~ 192.168.0.0/16, " ", 192.168.254.0/24 ~ 192.168.0.0/16;
......
......@@ -6,61 +6,11 @@
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include "lib/alloca.h"
#include "nest/bird.h"
#include "conf/conf.h"
#include "filter/filter.h"
/*
* find_nth - finds n-th element in linked list. Don't be confused by types, it is really a linked list.
*/
static struct f_tree *
find_nth(struct f_tree *from, int nth)
{
struct f_tree *pivot;
int lcount = 0, rcount = 0;
struct f_tree *left, *right, *next;
pivot = from;
left = right = NULL;
next = from->right;
while (from = next) {
next = from->right;
if (val_compare(pivot->from, from->from)==1) {
from->right = left;
left = from;
lcount++;
} else {
from->right = right;
right = from;
rcount++;
}
}
if (lcount == nth)
return pivot;
if (lcount < nth)
return find_nth(right, nth-lcount-1);
return find_nth(left, nth);
}
/*
* find_median - Gets list linked by @left, finds its median, trashes pointers in @right.
*/
static struct f_tree *
find_median(struct f_tree *from)
{
struct f_tree *t = from;
int cnt = 0;
if (!from)
return NULL;
do {
t->right = t->left;
cnt++;
} while (t = t->left);
return find_nth(from, cnt/2);
}
/**
* find_tree
* @t: tree to search in
......@@ -87,6 +37,23 @@ find_tree(struct f_tree *t, struct f_val val)
return find_tree(t->left, val);
}
static struct f_tree *
build_tree_rec(struct f_tree **buf, int l, int h)
{
struct f_tree *n;
int pos;
if (l >= h)
return NULL;
pos = (l+h)/2;
n = buf[pos];
n->left = build_tree_rec(buf, l, pos);
n->right = build_tree_rec(buf, pos+1, h);
return n;
}
/**
* build_tree
* @from: degenerated tree (linked by @tree->left) to be transformed into form suitable for find_tree()
......@@ -96,29 +63,35 @@ find_tree(struct f_tree *t, struct f_val val)
struct f_tree *
build_tree(struct f_tree *from)
{
struct f_tree *median, *t = from, *next, *left = NULL, *right = NULL;
struct f_tree *tmp, *root;
struct f_tree **buf;
int len, i;
median = find_median(from);
if (!median)
if (from == NULL)
return NULL;
do {
next = t->left;
if (t == median)
continue;
if (val_compare(median->from, t->from)==1) {
t->left = left;
left = t;
} else {
t->left = right;
right = t;
}
} while(t = next);
median->left = build_tree(left);
median->right = build_tree(right);
return median;
len = 0;
for (tmp = from; tmp != NULL; tmp = tmp->left)
len++;
if (len <= 1024)
buf = alloca(len * sizeof(struct f_tree *));
else
buf = malloc(len * sizeof(struct f_tree *));
/* Convert a degenerated tree into an sorted array */
i = 0;
for (tmp = from; tmp != NULL; tmp = tmp->left)
buf[i++] = tmp;
qsort(buf, len, sizeof(struct f_tree *), tree_compare);
root = build_tree_rec(buf, 0, len);
if (len > 1024)
free(buf);
return root;
}
struct f_tree *
......
......@@ -49,7 +49,8 @@ static struct resclass ev_class = {
"Event",
sizeof(event),
(void (*)(resource *)) ev_postpone,
ev_dump
ev_dump,
NULL
};
/**
......
......@@ -46,10 +46,14 @@ char *ip_scope_text(unsigned);
struct prefix {
ip_addr addr;
int len;
unsigned int len;
};
#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
#define ipa_zero(x) (!ipa_nonzero(x))
static inline int ipa_classify_net(ip_addr a)
{ return ipa_zero(a) ? (IADDR_HOST | SCOPE_UNIVERSE) : ipa_classify(a); }
/*
* Conversions between internal and string representation
......
......@@ -72,7 +72,7 @@ int ipv4_classify(u32);
u32 ipv4_class_mask(u32);
byte *ipv4_skip_header(byte *, int *);
static inline int ipv4_has_link_scope(u32 a)
static inline int ipv4_has_link_scope(u32 a UNUSED)
{
return 0;
}
......
......@@ -9,6 +9,8 @@
#ifndef _BIRD_SOCKET_H_
#define _BIRD_SOCKET_H_
#include <errno.h>
#include "lib/resource.h"
typedef struct birdsock {
......@@ -67,6 +69,8 @@ int sk_leave_group(sock *s, ip_addr maddr);
int sk_set_ipv6_checksum(sock *s, int offset);
#endif
int sk_set_broadcast(sock *s, int enable);
static inline int
sk_send_buffer_empty(sock *sk)
{
......
......@@ -385,7 +385,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
struct pm_pos pos[2048 + 1];
int plen = parse_path(path, pos);
int l, h, i, nh, nl;
u32 val;
u32 val = 0;
/* l and h are bound of interval of positions where
are marked states */
......@@ -417,7 +417,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
goto step;
case PM_QUESTION:
step:
nh = -1;
nh = nl = -1;
for (i = h; i >= l; i--)
if (pos[i].mark)
{
......
......@@ -357,8 +357,8 @@ cli_echo(unsigned int class, byte *msg)
free = (c->ring_end - c->ring_buf) - (c->ring_write - c->ring_read + 1);
else
free = c->ring_read - c->ring_write - 1;
if (len > free ||
free < c->log_threshold && class < (unsigned) L_INFO[0])
if ((len > free) ||
(free < c->log_threshold && class < (unsigned) L_INFO[0]))
{
c->ring_overflow++;
continue;
......
......@@ -33,6 +33,7 @@ typedef struct cli {
void (*cleanup)(struct cli *c);
void *rover; /* Private to continuation routine */
int last_reply;
int restricted; /* CLI is restricted to read-only commands */
struct linpool *parser_pool; /* Pool used during parsing */
byte *ring_buf; /* Ring buffer for asynchronous messages */
byte *ring_end, *ring_read, *ring_write; /* Pointers to the ring buffer */
......@@ -60,6 +61,14 @@ void cli_kick(cli *);
void cli_written(cli *);
void cli_echo(unsigned int class, byte *msg);
static inline int cli_access_restricted(void)
{
if (this_cli && this_cli->restricted)
return (cli_printf(this_cli, 8007, "Access denied"), 1);
else
return 0;
}
/* Functions provided by sysdep layer */
void cli_write_trigger(cli *);
......
......@@ -45,7 +45,7 @@ CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILT
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
......@@ -59,7 +59,7 @@ CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT)
%type <s> optsym
%type <ra> r_args
%type <i> echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport
%type <t> proto_patt
%type <ps> proto_patt proto_patt2
CF_GRAMMAR
......@@ -324,11 +324,11 @@ CF_CLI_HELP(SHOW, ..., [[Show status information]])
CF_CLI(SHOW STATUS,,, [[Show router status]])
{ cmd_show_status(); } ;
CF_CLI(SHOW PROTOCOLS, optsym, [<name>], [[Show routing protocols]])
{ proto_show($3, 0); } ;
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
CF_CLI(SHOW PROTOCOLS ALL, optsym, [<name>], [[Show routing protocol details]])
{ proto_show($4, 1); } ;
CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
{ proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
optsym:
SYM
......@@ -459,34 +459,42 @@ echo_size:
;
CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
{ proto_xxable($2, XX_DISABLE); } ;
{ proto_apply_cmd($2, proto_cmd_disable, 1, 0); } ;
CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
{ proto_xxable($2, XX_ENABLE); } ;
{ proto_apply_cmd($2, proto_cmd_enable, 1, 0); } ;
CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
{ proto_xxable($2, XX_RESTART); } ;
{ proto_apply_cmd($2, proto_cmd_restart, 1, 0); } ;
CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
{ proto_xxable($2, XX_RELOAD); } ;
{ proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
{ proto_xxable($3, XX_RELOAD_IN); } ;
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
{ proto_xxable($3, XX_RELOAD_OUT); } ;
{ proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | interfaces | events | packets }), [[Control protocol debugging via BIRD logs]])
{ proto_debug($2, 0, $3); }
;
{ proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ;
CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | <pattern> | all) (all | off | { states | messages }), [[Control protocol debugging via MRTdump format]])
{ proto_debug($2, 1, $3); }
;
{ proto_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ;
CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
{ this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
proto_patt:
SYM { $$ = $1->name; }
| ALL { $$ = "*"; }
| TEXT
SYM { $$.ptr = $1; $$.patt = 0; }
| ALL { $$.ptr = NULL; $$.patt = 1; }
| TEXT { $$.ptr = $1; $$.patt = 1; }
;
proto_patt2:
SYM { $$.ptr = $1; $$.patt = 0; }
| { $$.ptr = NULL; $$.patt = 1; }
| TEXT { $$.ptr = $1; $$.patt = 1; }
;
CF_CODE
CF_END
......@@ -336,6 +336,15 @@ if_end_update(void)
}
}
void
if_flush_ifaces(struct proto *p)
{
if (p->debug & D_EVENTS)
log(L_TRACE "%s: Flushing interfaces", p->name);
if_start_update();
if_end_update();