Commit 11fabd2d authored by Pavel Tvrdík's avatar Pavel Tvrdík

Integrate MRT Table Dump (RFC 6396) into BIRD

Asynchronous periodic mrt table dumps of routes configuration in bird.conf:
mrtdump routes {
  [ filename "<format>"; ]
  [ table <name>|"<wildcard name>"; ]
  [ period <num>; ]
  [ filter <filter>|where <condition>; ]
}

Synchronous mrt table dumps of routes in BIRD client:
mrtdump routes [table <name>|"<wildcard name>"] [to "<filename format>"] [filter <filter>|where <condition>]
parent de77e5cd
......@@ -53,6 +53,7 @@
#include "lib/string.h"
#include "lib/event.h"
#include "lib/timer.h"
#include "lib/unix.h"
#include "conf/conf.h"
#include "filter/filter.h"
......@@ -91,7 +92,7 @@ config_alloc(byte *name)
linpool *l = lp_new(p, 4080);
struct config *c = lp_allocz(l, sizeof(struct config));
c->mrtdump_file = -1; /* Hack, this should be sysdep-specific */
c->mrt_proto_file = -1; /* Indication that the file descriptor should not be used */
c->pool = p;
cfg_mem = c->mem = l;
c->file_name = cfg_strdup(name);
......
......@@ -14,8 +14,36 @@
#include "lib/resource.h"
#include "lib/timer.h"
/* Configuration structures */
#define MRT_TABLE_NOT_CONFIGURED -1
#define MRT_TABLE_DEFAULT_PERIOD 60
#define MRT_TABLE_DEFAULT_FILENAME_FMT "%f_%F_%T.mrt"
#define MRT_TABLE_DEFAULT_TABLENAME_PATTERN "*"
struct mrt_table_common_config {
u32 period; /* Time in seconds between Table Dump */
char *filename_fmt;
struct filter *filter;
struct cli *cli; /* Client console or NULL */
struct config *config; /* Configuration or NULL */
};
/* Template of configuration that can be apply at any table */
struct mrt_table_config {
node n; /* Node in config->mrt_table_dumps */
struct mrt_table_common_config c;
char *rtable_wildcard_name;
};
/* Configuration structure */
/* Configuration that is specific per table */
struct mrt_table_individual_config {
node n; /* Node in rtable_config->mrt_table_dumps */
struct mrt_table_common_config c;
timer *timer; /* Timer for periodic dumps */
struct rtable_config *table_cf;
bird_clock_t next_dump;
};
struct config {
pool *pool; /* Pool the configuration is stored in */
......@@ -23,9 +51,10 @@ struct config {
list protos; /* Configured protocol instances (struct proto_config) */
list tables; /* Configured routing tables (struct rtable_config) */
list roa_tables; /* Configured ROA tables (struct roa_table_config) */
list logfiles; /* Configured log fils (sysdep) */
list logfiles; /* Configured log files (sysdep) */
list mrt_table_dumps; /* Configured MRT table dumps (struct mrt_table_config) */
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
int mrt_proto_file; /* Configured MRTDump file (sysdep, fd in unix) for Protocols*/
char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
struct rtable_config *master_rtc; /* Configuration of master routing table */
struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */
......
......@@ -362,16 +362,49 @@ protocol rip {
seconds, zero means disabled. Default: disabled (0).
<tag>mrtdump "<m/filename/"</tag>
Set MRTdump file name. This option must be specified to allow MRTdump
feature. Default: no dump file.
Set MRTdump protocols file name. This option must be specified to allow MRTdump
protocols feature. Default: no dump file.
<tag>mrtdump protocols all|off|{ states, messages }</tag>
Set global defaults of MRTdump options. See <cf/mrtdump/ in the
Set global defaults of MRTdump protocol options. See <ref id="protocol-mrtdump" name="mrtdump"> in the
following section. Default: off.
<tag>filter <m/name local variables/{ <m/commands/ }</tag>
Define a filter. You can learn more about filters in the following
chapter.
<tag><label id="dsc-mrtdump-routes">mrtdump routes [ { <m/option1; option2; .../ } ]</tag>
Configure periodic <htmlurl url="https://tools.ietf.org/html/rfc6396#section-4.3" name="MRT Table Dump v2 (RFC 6396)">
of routes (not only BGP).
All mrtdump options are optional. Default: disabled
<descrip>
<tag/ <cf>filename "<m/format/" </cf> /
Configure file to output.
Filename format is the <it/strftime(3)/-like format (see
<it/man strftime/ for details) extended of a key <cf/%f/ for replacing with the name of the table.
Default: <cf>"%f_%F_%T.mrt"</cf>
<tag/ <cf>table <m/name/|"<m/pattern/" </cf> /
Choosing tables from which will be routes taken.
Can be used wildcards <cf>*</cf> and <cf>?</cf>.
Default: <cf>"*"</cf> for all tables
<tag/ <cf>period <m/num/ </cf> /
Configures the interval in seconds between mrt table dumps.
Default: <cf>60</cf> seconds
<tag/ <cf>filter <m/filter/ | where <m/condition/</cf> /
Configure filtering dumping routes. Filters are more described in <ref id="chapt-filters" name="the chapter Filters">.
Default: Accept all
</descrip>
Example:
<p><code>
mrtdump routes {
filename "%f-%s.mrt"; # dumps will be saved into files named like 'tableA-1437119435.mrt'
table "t*"; # only routes from tables starts with character 't'
period 10; # 10 seconds interval between dumps
where source = RTS_BGP; # only routes from BGP protocols
}
mrtdump routes; # another mrtdump route config with default options</code>
<tag>filter <m/name local variables/ { <m/commands/ }</tag>
Define a filter. You can learn more about filters in <ref id="chapt-filters" name="the chapter Filters">.
<tag>function <m/name/ (<m/parameters/) <m/local variables/ { <m/commands/ }</tag>
Define a function. You can learn more about functions in the following chapter.
......@@ -453,13 +486,13 @@ protocol rip {
hh:mm:ss) for <cf/base/ and <cf/log/. These timeformats could be set by
<cf/old short/ and <cf/old long/ compatibility shorthands.
<tag>table <m/name/ [sorted]</tag>
Create a new routing table. The default routing table is created
<tag>table <m/name/ [sorted] </tag>
Create a new routing table. The default <cf/master/ routing table is created
implicitly, other routing tables have to be added by this command.
Option <cf/sorted/ can be used to enable sorting of routes, see
<ref id="dsc-sorted" name="sorted table"> description for details.
<tag>roa table <m/name/ [ { roa table options ... } ]</tag>
<tag>roa table <m/name/ [ { <m/roa table options/ } ]</tag>
Create a new ROA (Route Origin Authorization) table. ROA tables can be
used to validate route origination of BGP routes. A ROA table contains
ROA entries, each consist of a network prefix, a max prefix length and
......@@ -511,8 +544,9 @@ agreement").
protocol, <cf/events/ for events internal to the protocol and <cf/packets/
for packets sent and received by the protocol. Default: off.
<tag>mrtdump all|off|{ states, messages }</tag>
Set protocol MRTdump flags. MRTdump is a standard binary format for
<tag><label id="protocol-mrtdump">mrtdump all|off|{ states, messages }</tag>
Set protocol MRTdump flags. MRTdump is a standard binary format (see
<htmlurl url="https://tools.ietf.org/html/rfc6396#section-4.4" name="BGP4MP in RFC 6396">)) for
logging information from routing protocols and daemons. These flags
control what kind of information is logged from the protocol to the
MRTdump file (which must be specified by global <cf/mrtdump/ option, see
......@@ -752,7 +786,7 @@ This argument can be omitted if there exists only a single instance.
Show the list of symbols defined in the configuration (names of
protocols, routing tables etc.).
<tag>show route [[for] <m/prefix/|<m/IP/] [table <m/sym/] [filter <m/f/|where <m/c/] [(export|preexport|noexport) <m/p/] [protocol <m/p/] [<m/options/]</tag>
<tag>show route [[for] <m/prefix/|<m/IP/] [table <m/name/] [filter <m/f/|where <m/c/] [(export|preexport|noexport) <m/p/] [protocol <m/p/] [<m/options/]</tag>
Show contents of a routing table (by default of the main one or the
table attached to a respective protocol), that is routes, their metrics
and (in case the <cf/all/ switch is given) all their attributes.
......@@ -787,7 +821,7 @@ This argument can be omitted if there exists only a single instance.
number of networks, number of routes before and after filtering). If
you use <cf/count/ instead, only the statistics will be printed.
<tag>show roa [<m/prefix/ | in <m/prefix/ | for <m/prefix/] [as <m/num/] [table <m/t/>]</tag>
<tag>show roa [<m/prefix/ | in <m/prefix/ | for <m/prefix/] [as <m/num/] [table <m/name/]</tag>
Show contents of a ROA table (by default of the first one). You can
specify a <m/prefix/ to print ROA entries for a specific network. If you
use <cf>for <m/prefix/</cf>, you'll get all entries relevant for route
......@@ -796,16 +830,16 @@ This argument can be omitted if there exists only a single instance.
entries covered by the network prefix. You could also use <cf/as/ option
to show just entries for given AS.
<tag>add roa <m/prefix/ max <m/num/] as <m/num/ [table <m/t/>]</tag>
<tag>add roa <m/prefix/ max <m/num/ as <m/num/ [table <m/name/]</tag>
Add a new ROA entry to a ROA table. Such entry is called <it/dynamic/
compared to <it/static/ entries specified in the config file. These
dynamic entries survive reconfiguration.
<tag>delete roa <m/prefix/ max <m/num/] as <m/num/ [table <m/t/>]</tag>
<tag>delete roa <m/prefix/ max <m/num/ as <m/num/ [table <m/name/]</tag>
Delete the specified ROA entry from a ROA table. Only dynamic ROA
entries (i.e., the ones added by <cf/add roa/ command) can be deleted.
<tag>flush roa [table <m/t/>]</tag>
<tag>flush roa [table <m/name/]</tag>
Remove all dynamic ROA entries from a ROA table.
<tag>configure [soft] ["<m/config file/"] [timeout [<m/num/]]</tag>
......@@ -873,6 +907,11 @@ This argument can be omitted if there exists only a single instance.
<tag>dump resources|sockets|interfaces|neighbors|attributes|routes|protocols</tag>
Dump contents of internal data structures to the debugging output.
<tag>mrtdump routes [table <m/name/|"<m/pattern/"] [to "<m/filename/"] [filter <m/filter/ | where <m/condition/]</tag>
Once the specified routes will be saved into file(s) named based on <m/filename/ format.
For more details about mrtdump options see <ref id="dsc-mrtdump-routes" name="mrtdump routes in the chapter Configuration">.
<tag>echo all|off|{ <m/list of log classes/ } [ <m/buffer-size/ ]</tag>
Control echoing of log messages to the command-line output.
See <ref id="dsc-log" name="log option"> for a list of log classes.
......@@ -882,7 +921,7 @@ This argument can be omitted if there exists only a single instance.
</descrip>
<chapt>Filters
<chapt><label id="chapt-filters">Filters
<sect>Introduction
......
......@@ -16,7 +16,7 @@
#endif
int
MATCH_FUNC_NAME(byte *p, byte *s)
MATCH_FUNC_NAME(const byte *p, const byte *s)
{
while (*p)
{
......
......@@ -24,6 +24,6 @@ int buffer_vprint(buffer *buf, const char *fmt, va_list args);
int buffer_print(buffer *buf, const char *fmt, ...);
void buffer_puts(buffer *buf, const char *str);
int patmatch(byte *pat, byte *str);
int patmatch(const byte *pat, const byte *str);
#endif
source=rt-table.c rt-fib.c rt-attr.c rt-roa.c proto.c iface.c rt-dev.c password.c cli.c locks.c cmds.c neighbor.c \
a-path.c a-set.c
a-path.c a-set.c mrtdump.c
root-rel=../
dir-name=nest
......
......@@ -23,6 +23,7 @@ static struct roa_table_config *this_roa_table;
static list *this_p_list;
static struct password_item *this_p_item;
static int password_id;
static struct mrt_table_config *this_mrt_table_config;
static void
iface_patt_check(void)
......@@ -60,7 +61,7 @@ CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFA
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE, ROA)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS, PERIOD, FILENAME)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
......@@ -80,6 +81,7 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode roa_mode limit_action tab_sorted tos
%type <ps> proto_patt proto_patt2
%type <g> limit_spec
%type <t> mrtdump_table_config_table_option
CF_GRAMMAR
......@@ -87,7 +89,7 @@ CF_GRAMMAR
CF_ADDTO(conf, rtrid)
rtrid:
rtrid:
ROUTER ID idval ';' { new_config->router_id = $3; }
| ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
;
......@@ -114,7 +116,7 @@ listen_opts:
| listen_opts listen_opt
;
listen_opt:
listen_opt:
ADDRESS ipa { new_config->listen_bgp_addr = $2; }
| PORT expr { new_config->listen_bgp_port = $2; }
| V6ONLY { new_config->listen_bgp_flags = 0; }
......@@ -280,7 +282,7 @@ iface_negate:
;
iface_patt_node:
iface_patt_node_init iface_negate iface_patt_node_body
iface_patt_node_init iface_negate iface_patt_node_body
;
......@@ -358,7 +360,7 @@ debug_flag:
| PACKETS { $$ = D_PACKETS; }
;
/* MRTDump flags */
/* MRTDump Protocol flags */
mrtdump_mask:
ALL { $$ = ~0; }
......@@ -376,6 +378,50 @@ mrtdump_flag:
| MESSAGES { $$ = MD_MESSAGES; }
;
/* MRT Table Dump */
mrtdump_table_config_init:
{
this_mrt_table_config = mrt_table_new_config();
}
;
mrtdump_table_config:
'{' mrtdump_table_config_init mrtdump_table_config_list '}'
| mrtdump_table_config_init ';'
;
mrtdump_table_filter_option:
where_filter {
if (this_mrt_table_config->c.filter != FILTER_ACCEPT)
cf_error("Filter specified twice");
this_mrt_table_config->c.filter = $1;
}
| FILTER filter {
if (this_mrt_table_config->c.filter != FILTER_ACCEPT)
cf_error("Filter specified twice");
this_mrt_table_config->c.filter = $2;
}
;
mrtdump_table_config_list:
/* empty */
| mrtdump_table_config_option ';'
| mrtdump_table_config_list mrtdump_table_config_option ';'
;
mrtdump_table_config_table_option:
rtable { $$ = $1->name; }
| TEXT { $$ = $1; }
;
mrtdump_table_config_option:
PERIOD expr { this_mrt_table_config->c.period = $2; }
| FILENAME text { this_mrt_table_config->c.filename_fmt = $2; }
| TABLE mrtdump_table_config_table_option { this_mrt_table_config->rtable_wildcard_name = $2; }
| mrtdump_table_filter_option
;
/* Password lists */
password_list:
......@@ -383,7 +429,7 @@ password_list:
| password_item
;
password_items:
password_items:
/* empty */
| password_item ';' password_items
;
......@@ -412,7 +458,7 @@ password_item_begin:
;
password_item_params:
/* empty */ { }
/* empty */ { }
| GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
| GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
| ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
......@@ -588,7 +634,7 @@ sym_args:
roa_table_arg:
/* empty */ {
/* empty */ {
if (roa_table_default == NULL)
cf_error("No ROA table defined");
$$ = roa_table_default;
......@@ -684,6 +730,30 @@ 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_apply_cmd($2, proto_cmd_mrtdump, 1, $3); } ;
CF_CLI_HELP(MRTDUMP ROUTES, [table <name>|\"<pattern>\"] [to \"<file>\"] [filter <filter>|where <where filter>] , [[Save MRT Table Dump into a file]])
CF_CLI(MRTDUMP ROUTES, mrtdump_table_cli_config, [table <name>|\"<pattern>\"] [to \"<file>\"] [filter <filter>|where <where filter>], [[Save mrt table dump v2 of table name <t> right now]])
{
this_mrt_table_config->c.cli = this_cli;
this_mrt_table_config->c.config = NULL;
mrt_table_cli_cmd(this_mrt_table_config);
} ;
mrtdump_table_cli_config:
mrtdump_table_config_init mrtdump_table_cli_config_list
;
mrtdump_table_cli_config_list:
/* empty */
| mrtdump_table_cli_config_option
| mrtdump_table_cli_config_list mrtdump_table_cli_config_option
;
mrtdump_table_cli_config_option:
TABLE mrtdump_table_config_table_option { this_mrt_table_config->rtable_wildcard_name = $2; }
| TO text { this_mrt_table_config->c.filename_fmt = $2; }
| mrtdump_table_filter_option
;
CF_CLI(RESTRICT,,,[[Restrict current CLI session to safe commands]])
{ this_cli->restricted = 1; cli_msg(16, "Access restricted"); } ;
......
......@@ -6,154 +6,259 @@
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#undef LOCAL_DEBUG
#include "nest/mrtdump.h"
#include "nest/route.h"
/*
* MRTDump: Table Dump: Base
*/
static void
mrt_buffer_reset(struct mrt_buffer *buf)
{
buf->msg_capacity = MRT_BUFFER_DEFAULT_CAPACITY;
buf->msg_length = MRT_HDR_LENGTH; /* Reserved for the main MRT header */
}
void
mrt_msg_init(struct mrt_msg *msg, pool *mem_pool)
mrt_buffer_alloc(struct mrt_buffer *buf)
{
msg->mem_pool = mem_pool;
msg->msg_capacity = MRT_MSG_DEFAULT_CAPACITY;
msg->msg_length = 0;
msg->msg = mb_alloc(msg->mem_pool, msg->msg_capacity);
mrt_buffer_reset(buf);
buf->msg = mb_allocz(&root_pool, buf->msg_capacity);
}
void
mrt_msg_free(struct mrt_msg *msg)
mrt_buffer_free(struct mrt_buffer *buf)
{
mb_free(msg->msg);
if (buf->msg != NULL)
{
mb_free(buf->msg);
buf->msg = NULL;
}
}
static void
mrt_buffer_enlarge(struct mrt_buffer *buf, size_t min_required_capacity)
{
if (min_required_capacity < buf->msg_capacity)
{
buf->msg_capacity *= 2;
if (min_required_capacity > buf->msg_capacity)
buf->msg_capacity = min_required_capacity;
buf->msg = mb_realloc(buf->msg, buf->msg_capacity);
}
}
/*
* Return pointer to the actual position in the msg buffer
*/
static byte *
mrt_peer_index_table_get_peer_count(struct mrt_peer_index_table *pit_msg)
mrt_buffer_get_cursor(struct mrt_buffer *buf)
{
struct mrt_msg * msg = pit_msg->msg;
uint collector_bgp_id_size = 4;
uint name_length_size = 2;
uint name_size = pit_msg->name_length;
uint peer_count_offset = collector_bgp_id_size + name_length_size + name_size;
return &(msg->msg[peer_count_offset]);
return &buf->msg[buf->msg_length];
}
static void
mrt_grow_msg_buffer(struct mrt_msg * msg, size_t min_required_capacity)
mrt_buffer_write_show_debug(struct mrt_buffer *buf, size_t data_size)
{
msg->msg_capacity *= 2;
if (min_required_capacity > msg->msg_capacity)
msg->msg_capacity = min_required_capacity;
msg->msg = mb_realloc(msg->msg, msg->msg_capacity);
#if defined(LOCAL_DEBUG) || defined(GLOBAL_DEBUG)
byte *data = mrt_buffer_get_cursor(buf) - data_size;
#endif
DBG("(%d) ", data_size);
u32 i;
for (i = 0; i < data_size; i++)
DBG("%02X ", data[i]);
DBG("| ");
}
static void
mrt_write_to_msg(struct mrt_msg * msg, const void *data, size_t data_size)
mrt_buffer_put_raw(struct mrt_buffer *buf, const void *data, size_t data_size)
{
if (data_size == 0)
return;
u32 i;
for (i = 0; i < data_size; i++)
debug("%02X ", ((byte*)data)[i]);
debug("| ");
size_t required_size = data_size + buf->msg_length;
mrt_buffer_enlarge(buf, required_size);
memcpy(mrt_buffer_get_cursor(buf), data, data_size);
buf->msg_length += data_size;
mrt_buffer_write_show_debug(buf, data_size);
}
static void
mrt_buffer_put_ipa(struct mrt_buffer *buf, ip_addr addr, size_t write_size)
{
ip_addr addr_network_formatted = ipa_hton(addr);
mrt_buffer_put_raw(buf, &addr_network_formatted, write_size);
}
/*
* The data will be transformed (put_u16(), put_u32(), ...) to the network format before writing
*/
static void
mrt_buffer_put_var(struct mrt_buffer *buf, const void *data, size_t data_size)
{
if (data_size == 0)
return;
size_t required_size = data_size + msg->msg_length;
if (msg->msg_capacity < required_size)
mrt_grow_msg_buffer(msg, required_size);
byte *actual_position;
memcpy(&msg->msg[msg->msg_length], data, data_size);
msg->msg_length += data_size;
size_t required_size = data_size + buf->msg_length;
mrt_buffer_enlarge(buf, required_size);
switch (data_size)
{
case 8:
put_u64(mrt_buffer_get_cursor(buf), *(u64*)data);
break;
case 4:
put_u32(mrt_buffer_get_cursor(buf), *(u32*)data);
break;
case 2:
put_u16(mrt_buffer_get_cursor(buf), *(u16*)data);
break;
case 1:
actual_position = mrt_buffer_get_cursor(buf);
*actual_position = *(byte*)data;
break;
default:
log(L_WARN "Unexpected size %zu byte(s) of data. Allowed are 1, 2, 4 or 8 bytes.", data_size);
}
buf->msg_length += data_size;
mrt_buffer_write_show_debug(buf, data_size);
}
#define mrt_write_to_msg_(msg, data) mrt_write_to_msg(msg, &data, sizeof(data))
#define mrt_buffer_put_var_autosize(msg, data) mrt_buffer_put_var(msg, &data, sizeof(data))
/*
* MRTDump: Table Dump: Peer Index Table
*/
void
mrt_peer_index_table_init(struct mrt_peer_index_table *pit_msg, u32 collector_bgp_id, const char *name)
mrt_peer_index_table_header(struct mrt_peer_index_table *state, u32 collector_bgp_id, const char *name)
{
struct mrt_msg * msg = pit_msg->msg;
pit_msg->peer_count = 0;
pit_msg->name_length = strlen(name);
struct mrt_buffer *buf = &state->msg;
mrt_buffer_alloc(buf);
mrt_write_to_msg_(msg, collector_bgp_id);
mrt_write_to_msg_(msg, pit_msg->name_length);
mrt_write_to_msg(msg, name, pit_msg->name_length);
mrt_write_to_msg_(msg, pit_msg->peer_count);
debug("\n");
state->peer_count = 0;
u16 name_length = 0;
if (name != NULL)
name_length = strlen(name);
mrt_buffer_put_var_autosize(buf, collector_bgp_id);
mrt_buffer_put_var_autosize(buf, name_length);
mrt_buffer_put_raw(buf, name, name_length);
state->peer_count_offset = state->msg.msg_length;
mrt_buffer_put_var(buf, &state->peer_count, sizeof(u16));
DBG("\n");
}
static void
mrt_peer_index_table_inc_peer_count(struct mrt_peer_index_table *pit_msg)
mrt_peer_index_table_inc_peer_count(struct mrt_peer_index_table *state)
{
pit_msg->peer_count++;
byte *peer_count = mrt_peer_index_table_get_peer_count(pit_msg);
put_u16(peer_count, pit_msg->peer_count);
state->peer_count++;
byte *peer_count = &state->msg.msg[state->peer_count_offset];
put_u16(peer_count, state->peer_count);
}
void
mrt_peer_index_table_add_peer(struct mrt_peer_index_table *pit_msg, u32 peer_bgp_id, ip_addr *peer_ip_addr, u32 peer_as)
mrt_peer_index_table_add_peer(struct mrt_peer_index_table *state, u32 peer_bgp_id, u32 peer_as, ip_addr peer_ip_addr)
{
struct mrt_msg * msg = pit_msg->msg;
struct mrt_buffer *msg = &state->msg;
u8 peer_type = PEER_TYPE_AS_32BIT;
if (sizeof(*peer_ip_addr) > sizeof(ip4_addr))
peer_type |= PEER_TYPE_IPV6;
u8 peer_type = MRT_PEER_TYPE_32BIT_ASN;
if (sizeof(peer_ip_addr) > sizeof(ip4_addr))
peer_type |= MRT_PEER_TYPE_IPV6;
mrt_write_to_msg_(msg, peer_type);
mrt_write_to_msg_(msg, peer_bgp_id);
mrt_write_to_msg_(msg, *peer_ip_addr);
mrt_write_to_msg_(msg, peer_as);
mrt_buffer_put_var_autosize(msg, peer_type);
mrt_buffer_put_var_autosize(msg, peer_bgp_id);
mrt_buffer_put_ipa(msg, peer_ip_addr, sizeof(ip_addr));
mrt_buffer_put_var_autosize(msg, peer_as);
mrt_peer_index_table_inc_peer_count(pit_msg);
debug("\n");
mrt_peer_index_table_inc_peer_count(state);
DBG("\n");
}
void
mrt_rib_table_init(struct mrt_rib_table *rt_msg, u32 sequence_number, u8 prefix_length, ip_addr *prefix)
mrt_peer_index_table_dump(struct mrt_peer_index_table *state, int file_descriptor)