0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-08 12:18:42 +00:00

bmp and its channels in progress (no, it can not be compiled)

This commit is contained in:
Katerina Kubecova 2024-07-04 13:13:38 +02:00
parent b6c17abd61
commit 9e3d6a9d6e
21 changed files with 476 additions and 180 deletions

View File

@ -308,6 +308,7 @@ if test "$enable_mpls_kernel" != no ; then
fi
fi
<<<<<<< HEAD
BIRD_CHECK_CLOCK(CLOCK_MONOTONIC)
if test "$bird_cv_clock_CLOCK_MONOTONIC" != yes ; then
AC_MSG_ERROR([Monotonic clock not supported])
@ -320,7 +321,7 @@ else
AC_DEFINE([HAVE_CLOCK_MONOTONIC_COARSE], [1], [Define to 1 if coarse clock is available])
fi
all_protocols="aggregator bfd babel bgp l3vpn ospf pipe radv rip rpki static mrt"
all_protocols="aggregator bfd babel bgp l3vpn ospf pipe radv rip rpki static mrt bmp"
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
if test "$with_protocols" = all ; then

View File

@ -654,6 +654,8 @@ mem_hash_mix_f_val(u64 *h, struct f_val *v)
case T_PTR:
case T_ENUM_STATE:
case T_BTIME:
case T_POINTER:
case T_BGP_CONN:
bug("Invalid type %s in f_val hashing", f_type_name(v->type));
}
}

View File

@ -467,11 +467,11 @@ extern struct ea_class ea_gen_mpls_label,
ea_gen_mpls_policy, ea_gen_mpls_class;
/* protocol journal attributes */
extern struct ea_class ea_proto_name, ea_proto_protocol_name, ea_proto_table,
ea_proto_state, ea_proto_old_state, ea_proto_last_modified, ea_proto_info,
ea_proto_id, ea_proto_deleted;
extern struct ea_class ea_name, ea_protocol_name, ea_protocol_type, ea_table,
ea_state, ea_old_state, ea_last_modified, ea_info, ea_proto_id,
ea_channel_id, ea_deleted, ea_bgp_conn, ea_rtable, ea_bgp_afi;
/* bgp protocol journal attributes */
extern struct ea_class ea_proto_bgp_rem_id, ea_proto_bgp_rem_as, ea_proto_bgp_rem_ip;
extern struct ea_class ea_bgp_rem_id, ea_bgp_rem_as, ea_bgp_rem_ip;
/* Source: An old method to devise the route source protocol and kind.
* To be superseded in a near future by something more informative. */

View File

@ -98,6 +98,7 @@ enum btype {
T_ENUM_ROA = 0x39,
T_ENUM_NETTYPE = 0x3b,
T_ENUM_AF = 0x3d,
T_RTABLE = 0x3e,
/* new enums go here */
@ -120,6 +121,8 @@ enum btype {
/* protocol */
T_ENUM_STATE = 0xd1,
T_BTIME = 0xd4,
T_POINTER = 0xd8,
T_BGP_CONN = 0xcb,
} PACKED;
typedef enum btype btype;

View File

@ -692,10 +692,10 @@ CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
{ cmd_show_memory(); } ;
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
{ proto_apply_cmd_no_lock($3, proto_cmd_show, 0, (union cmd_arg){.verbose = 0}); } ;
CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
{ proto_apply_cmd($4, proto_cmd_show, 0, 1); } ;
{ proto_apply_cmd_no_lock($4, proto_cmd_show, 0, (union cmd_arg){.verbose = 1}); } ;
optproto:
CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$ = $1; }

View File

@ -30,6 +30,7 @@ static TLIST_LIST(proto) global_proto_list;
static list STATIC_LIST_INIT(protocol_list);
struct lfjour *proto_journal;
struct lfjour *channel_journal;
DOMAIN(rtable) proto_journal_domain;
#define CD(c, msg, args...) ({ if (c->debug & D_STATES) log(L_TRACE "%s.%s: " msg, c->proto->name, c->name ?: "?", ## args); })
@ -49,7 +50,8 @@ static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
static char *c_states[] = { "DOWN", "START", "UP", "STOP", "RESTART" };
extern struct protocol proto_unix_iface;
struct proto_attrs *proto_attributes;
struct proto_attrs *proto_state_table;
struct proto_attrs *channel_state_table;
static void proto_rethink_goal(struct proto *p);
static char *proto_state_name(struct proto *p);
@ -58,6 +60,7 @@ static void channel_update_limit(struct channel *c, struct limit *l, int dir, st
static void channel_reset_limit(struct channel *c, struct limit *l, int dir);
static void channel_stop_export(struct channel *c);
static void channel_check_stopped(struct channel *c);
void init_journals(void);
static inline void channel_reimport(struct channel *c, struct rt_feeding_request *rfr)
{
rt_export_refeed(&c->reimporter, rfr);
@ -257,6 +260,16 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
return c;
}
struct channel *
proto_add_main_channel(struct proto *p, struct channel_config *cf)
{
p->main_channel = proto_add_channel(p, cf);
ea_list *eal = proto_state_table->attrs[p->id];
ea_set_attr(&eal, EA_LITERAL_STORE_STRING(&ea_table, 0, p->main_channel->table->name));
proto_journal_state_push(eal, p);
return p->main_channel;
}
void
proto_remove_channel(struct proto *p UNUSED, struct channel *c)
{
@ -264,6 +277,10 @@ proto_remove_channel(struct proto *p UNUSED, struct channel *c)
CD(c, "Removed", c->name);
ea_list *eal = *get_channel_ea(c)->attrs;
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_deleted, 0, 1));
channel_journal_state_push(eal,c);
rt_unlock_table(c->table);
rem_node(&c->n);
mb_free(c);
@ -1261,14 +1278,13 @@ proto_init(struct proto_config *c, struct proto *after)
PD(p, "Initializing%s", p->disabled ? " [disabled]" : "");
p->id = hmap_first_zero(proto_attributes->proto_id_maker);
hmap_set(proto_attributes->proto_id_maker, p->id);
if (p->id >= proto_attributes->length)
p->id = hmap_first_zero(proto_state_table->proto_id_maker);
hmap_set(proto_state_table->proto_id_maker, p->id);
if (p->id >= proto_state_table->length)
protos_attr_field_grow();
ea_list *eal = proto_state_to_eattr(p, old_state, 0);
ea_list *old_eal = proto_attributes->attrs[p->id];
atomic_store(&proto_attributes->attrs[p->id], eal);
proto_journal_state_changed(eal, old_eal, p);
proto_journal_state_push(eal, p);
return p;
}
@ -1692,8 +1708,12 @@ proto_rethink_goal(struct proto *p)
struct proto_config *nc = p->cf_new;
struct proto *after = p->n.prev;
hmap_clear(proto_attributes->proto_id_maker, p->id);
atomic_store(&proto_attributes->attrs[p->id], NULL);
ea_list *eal = proto_state_table->attrs[p->id];
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_deleted, 0, 1));
proto_journal_state_push(eal, p);
log("deleting %i", p->id);
hmap_clear(proto_state_table->proto_id_maker, p->id);
atomic_store(&proto_state_table->attrs[p->id], NULL);
DBG("%s has shut down for reconfiguration\n", p->name);
p->cf->proto = NULL;
@ -1988,7 +2008,7 @@ protos_build(void)
{
proto_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Protocols");
init_proto_journal();
init_journals();
//create_dummy_recipient();
protos_build_gen();
}
@ -2292,10 +2312,11 @@ proto_notify_state(struct proto *p, uint state)
int old_state = p->proto_state;
p->proto_state = state;
p->last_state_change = current_time();
ea_list *eal = proto_state_to_eattr(p, old_state, 0);
ea_list *old_eal = proto_attributes->attrs[p->id];
atomic_store(&proto_attributes->attrs[p->id], eal);
proto_journal_state_changed(eal, old_eal, p);
ea_list *eal = proto_state_table->attrs[p->id];
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_state, 0, p->proto_state));
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_old_state, 0, old_state));
proto_journal_state_push(eal, p);
switch (state)
{
@ -2460,7 +2481,7 @@ channel_cmd_debug(struct channel *c, uint mask)
}
void
proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
proto_cmd_show(struct proto *p, union cmd_arg verbose, int cnt)
{
byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
@ -2469,34 +2490,33 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
cli_msg(-2002, "%-10s %-10s %-10s %-6s %-12s %s",
"Name", "Proto", "Table", "State", "Since", "Info");
rcu_read_lock();
ea_list *eal = proto_attributes->attrs[p->id];
ea_free_later(ea_ref(eal));
rcu_read_unlock();
ea_list *eal = proto_get_state_list(p->id);
const char *name = ea_find(eal, &ea_proto_name)->u.ad->data;
const char *proto = ea_find(eal, &ea_proto_protocol_name)->u.ad->data;
const int state = ea_find(eal, &ea_proto_state)->u.i;
const char *table = ea_find(eal, &ea_proto_table)->u.ad->data;
const char *info = ea_find(eal, &ea_proto_info)->u.ad->data;
const btime *time = (btime*) ea_find(eal, &ea_proto_last_modified)->u.ad->data;
const char *name = ea_get_adata(eal, &ea_name)->data;
struct protocol **type = (struct protocol **)ea_get_adata(eal, &ea_protocol_type)->data;
const int state = ea_get_int(eal, &ea_state, 0);
const char *table = ea_get_adata(eal, &ea_table)->data;
buf[0] = 0;
if (p->proto->get_status)
p->proto->get_status(p, buf);
{
PROTO_LOCKED_FROM_MAIN(p)
p->proto->get_status(p, buf);
}
const btime *time = (btime *)ea_get_adata(eal, &ea_last_modified)->data;
tm_format_time(tbuf, &config->tf_proto, *time);
rcu_read_lock();
tm_format_time(tbuf, &atomic_load_explicit(&global_runtime, memory_order_acquire)->tf_proto, p->last_state_change);
rcu_read_unlock();
cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
name,
proto,
table,
(*type)->name,
table ? table : "---",
proto_state_name_from_int(state),
tbuf,
info);
buf);
if (verbose)
if (verbose.verbose)
{
PROTO_LOCKED_FROM_MAIN(p)
{
if (p->cf->dsc)
cli_msg(-1006, " Description: %s", p->cf->dsc);
if (p->message)
@ -2516,6 +2536,7 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
}
cli_msg(-1006, "");
}
}
}
@ -2718,6 +2739,46 @@ proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, in
proto_apply_cmd_symbol(ps.ptr, cmd, arg);
}
void
proto_apply_cmd_no_lock(struct proto_spec ps, void (* cmd)(struct proto *, union cmd_arg, int),
int restricted, union cmd_arg arg)
{
if (restricted && cli_access_restricted())
return;
if (ps.patt)
{
int cnt = 0;
const char *patt = ps.ptr;
WALK_TLIST(proto, p, &global_proto_list)
if (!patt || patmatch(patt, p->name))
cmd(p, arg, cnt++);
if (!cnt)
cli_msg(8003, "No protocols match");
else
cli_msg(0, "");
}
else
{
const struct symbol *s = ps.ptr;
if (s->class != SYM_PROTO)
{
cli_msg(9002, "%s is not a protocol", s->name);
return;
}
if (s->proto->proto)
{
struct proto *p = s->proto->proto;
cmd(p, arg, 0);
cli_msg(0, "");
}
else
cli_msg(9002, "%s does not exist", s->name);
}
}
struct proto *
proto_get_named(struct symbol *sym, struct protocol *pr)
{
@ -2797,85 +2858,124 @@ proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *ol
void
protos_attr_field_init(void)
{
proto_attributes = mb_allocz(&root_pool, sizeof(struct proto_attrs));
proto_attributes->attrs = mb_allocz(&root_pool, sizeof(ea_list *_Atomic)*16);
proto_attributes->length = 16;
proto_attributes->proto_id_maker = mb_allocz(&root_pool, sizeof(struct hmap));
hmap_init(proto_attributes->proto_id_maker, &root_pool, 16);
proto_state_table = mb_allocz(&root_pool, sizeof(struct proto_attrs));
proto_state_table->attrs = mb_allocz(&root_pool, sizeof(ea_list *_Atomic)*16);
proto_state_table->length = 16;
proto_state_table->proto_id_maker = mb_allocz(&root_pool, sizeof(struct hmap));
proto_state_table->channel_id_maker = mb_allocz(&root_pool, sizeof(struct hmap));
hmap_init(proto_state_table->proto_id_maker, &root_pool, 16);
hmap_init(proto_state_table->channel_id_maker, &root_pool, 16*2);
//TODO free? or have self pool?
}
void
protos_attr_field_grow(void)
{
ea_list *_Atomic * new_field = mb_allocz(&root_pool, sizeof(ea_list *_Atomic)*proto_attributes->length*2);
memcpy(new_field, proto_attributes->attrs, proto_attributes->length*(sizeof(ea_list* _Atomic)));
atomic_store(&proto_attributes->attrs, new_field);
atomic_store(&proto_attributes->length, (proto_attributes->length*2));
log("grow");
ea_list *_Atomic * new_field = mb_allocz(&root_pool, sizeof(ea_list *_Atomic)*proto_state_table->length*2);
memcpy(new_field, proto_state_table->attrs, proto_state_table->length*(sizeof(ea_list* _Atomic)));
atomic_store(&proto_state_table->attrs, new_field);
atomic_store(&proto_state_table->length, (proto_state_table->length*2));
}
void
cleanup_journal_item(struct lfjour * journal UNUSED, struct lfjour_item *i)
{
log("cleanup_journal_item");
struct proto_pending_update *pupdate = SKIP_BACK(struct proto_pending_update, li, i);
ea_free_later(pupdate->old_attr);
eattr *new_ea = ea_find(pupdate->proto_attr, &ea_proto_deleted);
eattr *new_ea = ea_find(pupdate->proto_attr, &ea_deleted);
if (new_ea->u.i)
{
log("try to delete");
ea_free_later(pupdate->proto_attr);
}
}
void
after_journal_birdloop_stop(void* arg UNUSED){}
void
init_proto_journal(void)
init_journal(int item_size, char *loop_name)
{
protos_attr_field_init();
proto_journal = mb_allocz(&root_pool, sizeof(struct lfjour));
struct settle_config cf = {.min = 0, .max = 0};
proto_journal->item_done = cleanup_journal_item;
proto_journal->item_size = sizeof(struct proto_pending_update);
proto_journal->loop = birdloop_new(&root_pool, DOMAIN_ORDER(service), 1, "Protocol state journal");
proto_journal_domain = DOMAIN_NEW_RCU_SYNC(rtable);
proto_journal->item_size = item_size;
proto_journal->loop = birdloop_new(&root_pool, DOMAIN_ORDER(service), 1, loop_name);
proto_journal->domain = proto_journal_domain.rtable;
lfjour_init(proto_journal, &cf);
}
void
init_journals(void)
{
protos_attr_field_init();
proto_journal_domain = DOMAIN_NEW_RCU_SYNC(rtable);
init_journal(sizeof(struct proto_pending_update), "proto journal loop");
init_journal(sizeof(struct channel_pending_update), "channel journal loop");
}
ea_list *
proto_state_to_eattr(struct proto *p, int old_state, int proto_deleting)
{
int eatt_len = 8;
if (p->proto == &proto_bgp)
eatt_len += 3;
struct {
ea_list l;
eattr a[eatt_len];
eattr a[15];
} eattrs;
eattrs.l = (ea_list) {};
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_proto_name, 0, p->name);
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_proto_protocol_name, 0, p->proto->name);
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_proto_table, 0, p->main_channel ? p->main_channel->table->name : "---");
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_state, 0, p->proto_state);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_old_state, 0, old_state);
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_ADATA(&ea_proto_last_modified, 0, &p->last_state_change, sizeof(btime));
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_name, 0, p->name);
//eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_protocol_name, 0, p->proto->name); this info is stored in ea_protocol_type
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_ADATA(&ea_protocol_type, 0, &p->proto, sizeof(struct protocol *));
if (p->main_channel)
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_table, 0, p->main_channel->table->name);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_state, 0, p->proto_state);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_old_state, 0, old_state);
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_ADATA(&ea_last_modified, 0, &p->last_state_change, sizeof(btime));
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_id, 0, p->id);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_deleted, 0, proto_deleting);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_deleted, 0, proto_deleting);
if (p->proto == &proto_bgp)
bgp_state_to_eattr(p, &eattrs.l, eattrs.a);
byte buf[256];
buf[0] = 0;
if (p->proto->get_status)
p->proto->get_status(p, buf);
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_proto_info, 0, buf);
return ea_lookup_slow(&eattrs.l, 0, EALS_CUSTOM);
}
void
proto_journal_state_changed(ea_list *attr, ea_list *old_attr, struct proto *p)
ea_list *
channel_state_to_eattr(struct channel *ch, int proto_deleting)
{
struct {
ea_list l;
eattr a[5];
} eattrs;
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_STRING(&ea_name, 0, ch->name);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_id, 0, ch->proto->id);
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_deleted, 0, proto_deleting);
if (ch->table)
{
struct rtable_adata rad = (struct rtable_adata){.table = h->table};
eattrs.a[eattrs.l.count++] = EA_LITERAL_STORE_ADATA(&ea_gen_rtable, 0, &rad, sizeof(rtable *));
}
if (ch->proto->proto == &proto_bgp && ch != ch->proto->mpls_channel)
{
struct bgp_channel *bc = (struct bgp_channel *) ch;
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_bgp_afi, 0, bc->afi);
}
return ea_lookup_slow(&eattrs.l, 0, EALS_CUSTOM);
}
//mpls!!!!! ch nonskip
void
proto_journal_state_push(ea_list *attr, struct proto *p)
{
ea_set_attr(&attr, EA_LITERAL_STORE_ADATA(&ea_last_modified, 0, &p->last_state_change, sizeof(btime)));
attr = ea_lookup(attr, 0, EALS_CUSTOM);
atomic_store(&proto_state_table->attrs[p->id], attr);
ea_list *old_attr = proto_state_table->attrs[p->id];
LOCK_DOMAIN(rtable, proto_journal_domain);
struct proto_pending_update *pupdate = SKIP_BACK(struct proto_pending_update, li, lfjour_push_prepare(proto_journal));
if (!pupdate)
@ -2885,7 +2985,7 @@ proto_journal_state_changed(ea_list *attr, ea_list *old_attr, struct proto *p)
}
*pupdate = (struct proto_pending_update) {
.li = pupdate->li, /* Keep the item's internal state */
.proto_attr = attr,
.proto_attr = proto_state_table->attrs[p->id],
.old_attr = old_attr,
.protocol = p
};
@ -2893,25 +2993,86 @@ proto_journal_state_changed(ea_list *attr, ea_list *old_attr, struct proto *p)
UNLOCK_DOMAIN(rtable, proto_journal_domain);
}
ea_list *
proto_get_state_list(int id)
{
rcu_read_lock();
ea_list *eal = proto_state_table->attrs[id];
if (eal)
ea_free_later(ea_ref(eal));
rcu_read_unlock();
return eal;
}
struct channel_attrs *
get_channel_ea(struct channel *ch)
{
struct channel_attrs *chan_att;
WALK_LIST(chan_att, proto_state_table->channels_attrs[ch->proto->id])
{
const int id = ea_get_int(*chan_att->attrs, &ea_channel_id, 0);
if (ch->id == id)
return chan_att;
}
return NULL;
}
void
channel_journal_state_push(ea_list *attr, struct channel *ch)
{
ea_list *old_attr = *get_channel_ea(ch)->attrs;
LOCK_DOMAIN(rtable, proto_journal_domain);
struct channel_pending_update *pupdate = SKIP_BACK(struct channel_pending_update, li, lfjour_push_prepare(channel_journal));
if (!pupdate)
{
UNLOCK_DOMAIN(rtable, proto_journal_domain);
return;
}
*pupdate = (struct channel_pending_update) {
.li = pupdate->li, /* Keep the item's internal state */
.channel_attr = attr,
.old_attr = old_attr,
.channel = ch
};
lfjour_push_commit(channel_journal);
UNLOCK_DOMAIN(rtable, proto_journal_domain);
}
/*void
channel_journal_state_change(struct channel *ch, int old_state, int new_state)
{
ea_list *eal = channel_state_to_eattr(ch, new_state);
struct channel_attrs *chan_att = get_channel_ea(ch);
atomic_store(&chan_att->attrs, eal);
channel_journal_state_changed(eal, old_eal, ch);
}*/
void
add_journal_channel(struct channel *ch, int new_state)
{
ea_list *eal = channel_state_to_eattr(ch, new_state);
struct channel_attrs *attr = mb_allocz(&root_pool, sizeof(struct channel_attrs));
atomic_store(attr->attrs, eal);
ASSERT_DIE(proto_state_table->attrs[ch->proto->id] != NULL);
add_tail(&proto_state_table->channels_attrs[ch->proto->id], &ch->n);
}
void dummy_log_proto_attr_list(void)
{
//debugging function
ea_list *eal;
for(u32 i = 0; i < proto_attributes->length; i++)
for(u32 i = 0; i < proto_state_table->length; i++)
{
rcu_read_lock();
eal = proto_attributes->attrs[i];
if (eal)
ea_free_later(ea_ref(eal));
rcu_read_unlock();
eal = proto_get_state_list(i);
if (eal)
{
const char *name = ea_find(eal, &ea_proto_name)->u.ad->data;
const char *type = ea_find(eal, &ea_proto_protocol_name)->u.ad->data;
const int state = ea_find(eal, &ea_proto_state)->u.i;
const char *table = ea_find(eal, &ea_proto_table)->u.ad->data;
const btime *time = (btime*) ea_find(eal, &ea_proto_last_modified)->u.ad->data;
log("protocol %s of type %s is in state %i (table %s, last modified %t)", name, type, state, table, time);
const char *name = ea_find(eal, &ea_name)->u.ad->data;
struct protocol **t = (struct protocol **)ea_get_adata(eal, &ea_protocol_type)->data;
const int state = ea_get_int(eal, &ea_state, 0);
const char *table = ea_get_adata(eal, &ea_table)->data;
const btime *time = (btime *)ea_get_adata(eal, &ea_last_modified)->data;
log("protocol %s of type %s is in state %i (table %s, last modified %t)", name, (*t)->name, state, table, time);
}
}
}
@ -2924,10 +3085,10 @@ fc_for_dummy_recipient(void *rec)
while (last_up = lfjour_get((struct lfjour_recipient *)rec))
{
pupdate = SKIP_BACK(struct proto_pending_update, li, last_up);
eattr *name = ea_find(pupdate->proto_attr, &ea_proto_name);
eattr *state = ea_find(pupdate->proto_attr, &ea_proto_state);
const char *name = ea_get_adata(pupdate->proto_attr, &ea_name)->data;
int state = ea_get_int(pupdate->proto_attr, &ea_state, 0);
if (name && state)
log("protocol %s changed state to %i", name->u.ad->data, state->u.i);
log("protocol %s changed state to %i", name, state);
else
log("not found in %i", pupdate->proto_attr);
lfjour_release(rec);

View File

@ -174,7 +174,7 @@ struct proto {
btime last_state_change; /* Time of last state transition */
char *last_state_name_announced; /* Last state name we've announced to the user */
char *message; /* State-change message, allocated from proto_pool */
u32 id; /* Id of the protocol indexing its position in proto_attributes */
u32 id; /* Id of the protocol indexing its position in proto_state_table */
/*
* General protocol hooks:
@ -262,7 +262,13 @@ void channel_show_limit(struct limit *l, const char *dsc, int active, int action
void channel_show_info(struct channel *c);
void channel_cmd_debug(struct channel *c, uint mask);
void proto_cmd_show(struct proto *, uintptr_t, int);
union cmd_arg {
int verbose;
struct proto_reload_request *prr;
char *msg;
};
void proto_cmd_show(struct proto *, union cmd_arg verbose, int);
void proto_cmd_disable(struct proto *, uintptr_t, int);
void proto_cmd_enable(struct proto *, uintptr_t, int);
void proto_cmd_restart(struct proto *, uintptr_t, int);
@ -271,6 +277,7 @@ void proto_cmd_debug(struct proto *, uintptr_t, int);
void proto_cmd_mrtdump(struct proto *, uintptr_t, int);
void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg);
void proto_apply_cmd_no_lock(struct proto_spec ps, void (* cmd)(struct proto *, union cmd_arg, int), int restricted, union cmd_arg arg);
struct proto *proto_get_named(struct symbol *, struct protocol *);
struct proto *proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *old);
@ -397,12 +404,20 @@ static inline int proto_is_inactive(struct proto *p)
struct proto_attrs {
ea_list *_Atomic *attrs;
list *channels_attrs;
_Atomic u32 length;
struct hmap *proto_id_maker;
struct hmap *channel_id_maker;
};
extern struct lfjour *proto_journal;
extern struct proto_attrs *proto_attributes;
extern struct lfjour *channel_journal;
extern struct proto_attrs *proto_state_table;
struct channel_attrs {
node n;
ea_list *_Atomic *attrs;
};
struct proto_pending_update {
LFJOUR_ITEM_INHERIT(li);
@ -411,10 +426,20 @@ struct proto_pending_update {
struct proto *protocol;
};
void proto_journal_state_changed(ea_list *attr, ea_list *old_attr, struct proto *p);
struct channel_pending_update {
LFJOUR_ITEM_INHERIT(li);
ea_list *channel_attr;
ea_list *old_attr;
struct channel *channel;
};
void proto_journal_state_push(ea_list *attr, struct proto *p);
void channel_journal_state_push(ea_list *attr, struct channel *ch);
ea_list *proto_state_to_eattr(struct proto *p, int old_state, int protocol_deleting);
struct channel_attrs *get_channel_ea(struct channel *ch);
void create_dummy_recipient(void);
void protos_attr_field_grow(void);
ea_list *proto_get_state_list(int id);
/*
@ -550,6 +575,7 @@ struct channel {
node n; /* Node in proto->channels */
const char *name; /* Channel name (may be NULL) */
int id;
const struct channel_class *class;
struct proto *proto;
@ -685,6 +711,7 @@ static inline struct channel_config *proto_cf_mpls_channel(struct proto_config *
struct channel *proto_find_channel_by_table(struct proto *p, rtable *t);
struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
struct channel *proto_add_main_channel(struct proto *p, struct channel_config *cf);
void proto_remove_channel(struct proto *p, struct channel *c);
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);

View File

@ -883,6 +883,11 @@ struct hostentry_adata {
u32 labels[0];
};
struct rtable_adata {
adata ad;
struct rtable *table;
};
#define HOSTENTRY_LABEL_COUNT(head) (head->ad.length + sizeof(struct adata) - sizeof(struct hostentry_adata)) / sizeof(u32)
void

View File

@ -168,6 +168,29 @@ struct ea_class ea_gen_hostentry_version = {
.hidden = 1,
};
static void
ea_gen_rtable_stored(const eattr *ea)
{
struct rtable_adata *had = (struct rtable_adata *) ea->u.ptr;
rt_lock_table(had->table);
}
static void
ea_gen_rtable_freed(const eattr *ea)
{
struct rtable_adata *had = (struct rtable_adata *) ea->u.ptr;
rt_unlock_table(had->table);
}
struct ea_class ea_gen_rtable = {
.name = "rtable",
.type = T_RTABLE,
.readonly = 1,
.stored = ea_gen_rtable_stored,
.freed = ea_gen_rtable_freed,
};
const char * rta_dest_names[RTD_MAX] = {
[RTD_NONE] = "",
[RTD_UNICAST] = "unicast",
@ -1824,66 +1847,86 @@ ea_show_list(struct cli *c, ea_list *eal)
}
struct ea_class ea_proto_name = {
struct ea_class ea_name = {
.name = "proto_name",
.type = T_STRING,
};
struct ea_class ea_proto_protocol_name = {
struct ea_class ea_protocol_name = {
.name = "proto_protocol_name",
.type = T_STRING,
};
struct ea_class ea_proto_table = {
struct ea_class ea_protocol_type = {
.name = "proto_protocol_type",
.type = T_POINTER,
};
struct ea_class ea_table = {
.name = "proto_table",
.type = T_STRING,
};
struct ea_class ea_proto_state = {
struct ea_class ea_state = {
.name = "proto_state",
.type = T_ENUM_STATE,
};
struct ea_class ea_proto_old_state = {
struct ea_class ea_old_state = {
.name = "proto_old_state",
.type = T_ENUM_STATE,
};
struct ea_class ea_proto_last_modified = {
struct ea_class ea_last_modified = {
.name = "proto_last_modified",
.type = T_BTIME,
};
struct ea_class ea_proto_info = {
struct ea_class ea_info = {
.name = "proto_info",
.type = T_STRING,
};
struct ea_class ea_proto_deleted = {
struct ea_class ea_deleted = {
.name = "proto_deleted",
.type = T_INT,
};
struct ea_class ea_proto_id = {
.name = "proto_id",
.name = "proto_proto_id",
.type = T_INT,
};
struct ea_class ea_proto_bgp_rem_id = {
struct ea_class ea_channel_id = {
.name = "proto_channel_id",
.type = T_INT,
};
struct ea_class ea_bgp_rem_id = {
.name = "proto_bgp_rem_id",
.type = T_INT,
};
struct ea_class ea_proto_bgp_rem_as = {
struct ea_class ea_bgp_rem_as = {
.name = "proto_bgp_rem_as",
.type = T_INT,
};
struct ea_class ea_proto_bgp_rem_ip = {
struct ea_class ea_bgp_rem_ip = {
.name = "proto_bgp_rem_ip",
.type = T_IP,
};
struct ea_class ea_bgp_conn = {
.name = "proto_bgp_rem_conn",
.type = T_BGP_CONN,
};
struct ea_class ea_bgp_afi = {
.name = "bgp_afi",
.type = T_INT,
};
/**
* rta_init - initialize route attribute cache
*
@ -1926,20 +1969,26 @@ rta_init(void)
ea_register_init(&ea_gen_mpls_label);
/* Protocol attributes */
ea_register_init(&ea_proto_name);
ea_register_init(&ea_proto_protocol_name);
ea_register_init(&ea_proto_table);
ea_register_init(&ea_proto_state);
ea_register_init(&ea_proto_old_state);
ea_register_init(&ea_proto_last_modified);
ea_register_init(&ea_proto_info);
ea_register_init(&ea_name);
ea_register_init(&ea_protocol_name);
ea_register_init(&ea_protocol_type);
ea_register_init(&ea_table);
ea_register_init(&ea_state);
ea_register_init(&ea_old_state);
ea_register_init(&ea_last_modified);
ea_register_init(&ea_info);
ea_register_init(&ea_proto_id);
ea_register_init(&ea_proto_deleted);
ea_register_init(&ea_channel_id);
ea_register_init(&ea_deleted);
/* Protocol bgp attributes */
ea_register_init(&ea_proto_bgp_rem_id);
ea_register_init(&ea_proto_bgp_rem_as);
ea_register_init(&ea_proto_bgp_rem_ip);
ea_register_init(&ea_bgp_rem_id);
ea_register_init(&ea_bgp_rem_as);
ea_register_init(&ea_bgp_rem_ip);
ea_register_init(&ea_bgp_conn);
ea_register_init(&ea_rtable);
ea_register_init(&ea_bgp_afi);
ea_register_init(&ea_gen_rtable);
}
/*

View File

@ -2578,9 +2578,20 @@ void
bgp_state_to_eattr(struct proto *P, ea_list *l, eattr *attributes)
{
struct bgp_proto *p = (struct bgp_proto *) P;
attributes[l->count++] = EA_LITERAL_EMBEDDED(&ea_proto_bgp_rem_id, 0, p->remote_id);
attributes[l->count++] = EA_LITERAL_EMBEDDED(&ea_proto_bgp_rem_as, 0, p->remote_as);
attributes[l->count++] = EA_LITERAL_STORE_ADATA(&ea_proto_bgp_rem_ip, 0, &p->remote_ip, sizeof(ip_addr));
attributes[l->count++] = EA_LITERAL_EMBEDDED(&ea_bgp_rem_id, 0, p->remote_id);
attributes[l->count++] = EA_LITERAL_EMBEDDED(&ea_bgp_rem_as, 0, p->remote_as);
attributes[l->count++] = EA_LITERAL_STORE_ADATA(&ea_bgp_rem_ip, 0, &p->remote_ip, sizeof(ip_addr));
if (p->conn)
{
struct journal_bgp_conn conn = {
.state = p->conn->state,
.local_open_msg = p->conn->local_open_msg,
.remote_open_msg = p->conn->remote_open_msg,
.local_open_length = p->conn->local_open_length,
.remote_open_length = p->conn->remote_open_length,
};
attributes[l->count++] = EA_LITERAL_STORE_ADATA(&ea_bgp_conn, 0, &conn, sizeof(struct journal_bgp_conn));
}
}
static void

View File

@ -290,6 +290,15 @@ struct bgp_stats {
uint fsm_established_transitions;
};
struct journal_bgp_conn {
u8 state;
byte *local_open_msg;
byte *remote_open_msg;
uint local_open_length;
uint remote_open_length;
};
struct bgp_conn {
struct bgp_proto *bgp;
struct birdsock *sk;

View File

@ -2463,7 +2463,6 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
struct bgp_write_state s = {
.proto = p,
.channel = c,
.pool = tmp_linpool,
.mp_reach = (c->afi != BGP_AF_IPV4) || rem->ext_next_hop,
.as4_session = 1,
@ -2517,13 +2516,14 @@ bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n,
init_list(&b->prefixes);
if (attrs)
memcpy(b->eattrs, attrs, ea_size);
memcpy(b->attrs, attrs, ea_size);
/* Temporary prefix */
struct bgp_prefix *px = tmp_allocz(prefix_size);
px->path_id = (u32) src->private_id;
net_copy(px->net, n);
add_tail(&b->prefixes, &px->buck_node_xx);
px->src = tmp_allocz(sizeof(struct rte_src));
memcpy(px->src, src, sizeof(struct rte_src));
//FIXME net_copy(px->net, n);
add_tail(&b->prefixes, &px->buck_node); // why was there _xx ?
byte *end = bgp_create_update_bmp(c, pkt, b, !!new);

View File

@ -219,7 +219,7 @@ static void bmp_sock_err(sock *sk, int err);
static void bmp_close_socket(struct bmp_proto *p);
static void
bmp_send_peer_up_notif_msg(struct bmp_proto *p, const struct bgp_proto *bgp,
bmp_send_peer_up_notif_msg(struct bmp_proto *p, const ea_list *bgp,
const byte *tx_data, const size_t tx_data_size,
const byte *rx_data, const size_t rx_data_size);
@ -482,13 +482,13 @@ bmp_peer_down_notif_msg_serialize(buffer *stream, const bool is_peer_global,
*/
static struct bmp_table *
bmp_find_table(struct bmp_proto *p, struct rtable *tab)
bmp_find_table(struct bmp_proto *p, rtable *tab)
{
return HASH_FIND(p->table_map, HASH_TABLE, tab);
}
static struct bmp_table *
bmp_add_table(struct bmp_proto *p, struct rtable *tab)
bmp_add_table(struct bmp_proto *p, rtable *tab)
{
struct bmp_table *bt = mb_allocz(p->p.pool, sizeof(struct bmp_table));
bt->table = tab;
@ -498,12 +498,12 @@ bmp_add_table(struct bmp_proto *p, struct rtable *tab)
struct channel_config cc = {
.name = "monitor",
.channel = &channel_basic,
//.channel = &channel_basic,
.table = tab->config,
.in_filter = FILTER_REJECT,
.net_type = tab->addr_type,
.ra_mode = RA_ANY,
.bmp_hack = 1,
//.bmp_hack = 1,
};
bt->channel = proto_add_channel(&p->p, &cc);
@ -515,7 +515,7 @@ bmp_add_table(struct bmp_proto *p, struct rtable *tab)
static void
bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt)
{
channel_set_state(bt->channel, CS_FLUSHING);
channel_set_state(bt->channel, CS_STOP);
channel_set_state(bt->channel, CS_DOWN);
proto_remove_channel(&p->p, bt->channel);
@ -527,7 +527,7 @@ bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt)
mb_free(bt);
}
static inline struct bmp_table *bmp_get_table(struct bmp_proto *p, struct rtable *tab)
static inline struct bmp_table *bmp_get_table(struct bmp_proto *p, rtable *tab)
{ return bmp_find_table(p, tab) ?: bmp_add_table(p, tab); }
static inline void bmp_lock_table(struct bmp_proto *p UNUSED, struct bmp_table *bt)
@ -551,13 +551,13 @@ static inline bool bmp_stream_policy(struct bmp_stream *bs)
{ return !!(bs->key & BMP_STREAM_KEY_POLICY); }
static struct bmp_stream *
bmp_find_stream(struct bmp_proto *p, const struct bgp_proto *bgp, u32 afi, bool policy)
bmp_find_stream(struct bmp_proto *p, ea_list *bgp_attr, u32 afi, bool policy)
{
return HASH_FIND(p->stream_map, HASH_STREAM, bgp, bmp_stream_key(afi, policy));
return HASH_FIND(p->stream_map, HASH_STREAM, (void*)bgp_attr, bmp_stream_key(afi, policy));
}
static struct bmp_stream *
bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, struct rtable *tab, struct bgp_channel *sender)
bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, rtable *tab, ea_list *sender, int in_pre_policy)
{
struct bmp_stream *bs = mb_allocz(p->p.pool, sizeof(struct bmp_stream));
bs->bgp = bp->bgp;
@ -571,6 +571,7 @@ bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, s
bs->sender = sender;
bs->sync = false;
bs->in_pre_policy = in_pre_policy;
return bs;
}
@ -593,29 +594,32 @@ bmp_remove_stream(struct bmp_proto *p, struct bmp_stream *bs)
*/
static struct bmp_peer *
bmp_find_peer(struct bmp_proto *p, const struct bgp_proto *bgp)
bmp_find_peer(struct bmp_proto *p, ea_list *bgp_attr)
{
return HASH_FIND(p->peer_map, HASH_PEER, bgp);
return HASH_FIND(p->peer_map, HASH_PEER, (void *)bgp_attr); //TODO this is wrong, hash find is not for eattrs. but.
}
static struct bmp_peer *
bmp_add_peer(struct bmp_proto *p, struct bgp_proto *bgp)
bmp_add_peer(struct bmp_proto *p, ea_list *bgp_attr)
{
struct bmp_peer *bp = mb_allocz(p->p.pool, sizeof(struct bmp_peer));
bp->bgp = bgp;
bp->bgp = bgp_attr;
init_list(&bp->streams);
HASH_INSERT(p->peer_map, HASH_PEER, bp);
struct bgp_channel *c;
BGP_WALK_CHANNELS(bgp, c)
{
if (p->monitoring_rib.in_pre_policy && c->c.in_table)
bmp_add_stream(p, bp, c->afi, false, c->c.in_table, c);
int proto_id = ea_get_int(bgp_attr, &ea_proto_id, 0);
if (p->monitoring_rib.in_post_policy && c->c.table)
bmp_add_stream(p, bp, c->afi, true, c->c.table, c);
ea_list *chan_attr;
WALK_LIST(chan_attr, proto_state_table->channels_attrs[proto_id])
{
rtable *ch_table = (rtable *) ea_get_adata(chan_attr, &ea_rtable)->data;
if (p->monitoring_rib.in_pre_policy && ch_table)
bmp_add_stream(p, bp, ea_get_int(chan_attr, &ea_bgp_afi, 0), false, ch_table, chan_attr, 1);
if (p->monitoring_rib.in_post_policy && ch_table)
bmp_add_stream(p, bp, ea_get_int(chan_attr, &ea_bgp_afi, 0), true, ch_table, chan_attr, 0);
}
return bp;
@ -634,22 +638,23 @@ bmp_remove_peer(struct bmp_proto *p, struct bmp_peer *bp)
}
static void
bmp_peer_up_(struct bmp_proto *p, struct bgp_proto *bgp, bool sync,
bmp_peer_up_(struct bmp_proto *p, ea_list *bgp_attr, bool sync,
const byte *tx_open_msg, uint tx_open_length,
const byte *rx_open_msg, uint rx_open_length)
{
if (!p->started)
return;
struct bmp_peer *bp = bmp_find_peer(p, bgp);
struct bmp_peer *bp = bmp_find_peer(p, bgp_attr);
if (bp)
return;
TRACE(D_STATES, "Peer up for %s", bgp->p.name);
const char *name = ea_find(bgp_attr, &ea_name)->u.ad->data;
TRACE(D_STATES, "Peer up for %s", name);
bp = bmp_add_peer(p, bgp);
bp = bmp_add_peer(p, bgp_attr);
bmp_send_peer_up_notif_msg(p, bgp, tx_open_msg, tx_open_length, rx_open_msg, rx_open_length);
bmp_send_peer_up_notif_msg(p, bgp_attr, tx_open_msg, tx_open_length, rx_open_msg, rx_open_length);
/*
* We asssume peer_up() notifications are received before any route
@ -668,7 +673,7 @@ bmp_peer_up_(struct bmp_proto *p, struct bgp_proto *bgp, bool sync,
}
void
bmp_peer_up(struct bgp_proto *bgp,
bmp_peer_up(ea_list *bgp,
const byte *tx_open_msg, uint tx_open_length,
const byte *rx_open_msg, uint rx_open_length)
{
@ -678,15 +683,15 @@ bmp_peer_up(struct bgp_proto *bgp,
}
static void
bmp_peer_init(struct bmp_proto *p, struct bgp_proto *bgp)
bmp_peer_init(struct bmp_proto *p, ea_list *bgp_attr)
{
struct bgp_conn *conn = bgp->conn;
struct journal_bgp_conn *conn = (struct journal_bgp_conn *) ea_find(bgp_attr, &ea_bgp_conn)->u.ad->data;
if (!conn || (conn->state != BS_ESTABLISHED) ||
!conn->local_open_msg || !conn->remote_open_msg)
return;
bmp_peer_up_(p, bgp, false, conn->local_open_msg, conn->local_open_length,
bmp_peer_up_(p, bgp_attr, false, conn->local_open_msg, conn->local_open_length,
conn->remote_open_msg, conn->remote_open_length);
}
@ -855,7 +860,7 @@ bmp_route_monitor_commit(void *p_)
static void
bmp_route_monitor_end_of_rib(struct bmp_proto *p, struct bmp_stream *bs)
{
TRACE(D_PACKETS, "Sending END-OF-RIB for %s.%s", bs->bgp->p.name, bs->sender->c.name);
TRACE(D_PACKETS, "Sending END-OF-RIB for %s.%s", bs->bgp->p.name, ea_get_adata(bs->sender, &ea_name)->adata);
byte rx_end_payload[DEFAULT_MEM_BLOCK_SIZE];
byte *pos = bgp_create_end_mark_(bs->sender, rx_end_payload + BGP_HEADER_LENGTH);
@ -979,19 +984,26 @@ bmp_send_termination_msg(struct bmp_proto *p,
int
bmp_preexport(struct channel *C UNUSED, rte *e)
{
/* Reject non-direct routes */
if (e->src->proto != e->sender->proto)
/* Reject non-direct routes. Check if sender proto is the same as proto which created the route.
* It assumes that route was created in a protocol.
*/
struct rt_import_request *req = e->sender->req;
struct channel *ch = SKIP_BACK(struct channel, in_req, req);
struct rte_owner *owner = e->src->owner;
struct proto *p = SKIP_BACK(struct proto, sources, owner);
if (ch->proto != p)
return -1;
/* Reject non-BGP routes */
if (e->sender->channel != &channel_bgp)
if (p->proto != &proto_bgp)
return -1;
return 1;
}
static void
bmp_rt_notify(struct proto *P, struct channel *c, struct network *net,
bmp_rt_notify(struct proto *P, struct channel *c, const net_addr *net,
struct rte *new, struct rte *old)
{
struct bmp_proto *p = (void *) P;
@ -1011,7 +1023,7 @@ bmp_rt_notify(struct proto *P, struct channel *c, struct network *net,
if (!bs)
return;
bmp_route_monitor_notify(p, bs, net->n.addr, new, (new ?: old)->src);
bmp_route_monitor_notify(p, bs, net, new, (new ?: old)->src);
}
static void
@ -1068,10 +1080,21 @@ bmp_startup(struct bmp_proto *p)
bmp_buffer_free(&payload);
/* Send Peer Up messages */
struct proto *peer;
for (int i = 0; i < bgp_attributes->length; i++)
{
ea_list *bgp_attr = bgp_attributes->attrs[i];
if (bgp_attr == NULL)
continue;
struct protocol *proto = (struct protocol *) ea_find(bgp_attr, &ea_protocol_type)->u.ad->data;
const int state = ea_find(bgp_attr, &ea_state)->u.i;
if (proto != &proto_bgp || state != PS_UP)
continue;
bmp_peer_init(p, bgp_attr);
}
/*struct proto *peer;
WALK_LIST(peer, proto_list)
if ((peer->proto->class == PROTOCOL_BGP) && (peer->proto_state == PS_UP))
bmp_peer_init(p, (struct bgp_proto *) peer);
if ((peer->proto != &proto_bgp) && (peer->proto_state == PS_UP))
bmp_peer_init(p, (struct bgp_proto *) peer);*/
}
/**

View File

@ -78,23 +78,24 @@ struct bmp_proto {
};
struct bmp_peer {
struct bgp_proto *bgp;
ea_list *bgp;
struct bmp_peer *next;
list streams;
};
struct bmp_stream {
node n;
struct bgp_proto *bgp;
ea_list *bgp;
u32 key;
bool sync;
struct bmp_stream *next;
struct bmp_table *table;
struct bgp_channel *sender;
ea_list *sender;
int in_pre_policy;
};
struct bmp_table {
struct rtable *table;
rtable *table;
struct bmp_table *next;
struct channel *channel;
u32 uc;

View File

@ -68,6 +68,7 @@
log(L_ERR "%s: " msg, s->proto->p.name, ## args); \
})
extern struct proto_attrs *proto_state_table;
/*
* MRT buffer code
@ -381,10 +382,10 @@ mrt_peer_table_dump(struct mrt_table_dump_state *s)
mrt_peer_table_entry(s, 0, 0, IPA_NONE);
#ifdef CONFIG_BGP
for(u32 i = 0; i<proto_attributes->length; i++)
for(u32 i = 0; i<proto_state_table->length; i++)
{
rcu_read_lock();
ea_list *eal = proto_attributes->attrs[i];
ea_list *eal = proto_state_table->attrs[i];
if (eal)
ea_free_later(ea_ref(eal));
else
@ -393,14 +394,14 @@ mrt_peer_table_dump(struct mrt_table_dump_state *s)
continue;
}
rcu_read_unlock();
eattr *name = ea_find(proto_attributes->attrs[i], &ea_proto_protocol_name);
eattr *state = ea_find(proto_attributes->attrs[i], &ea_proto_state);
if ((strcmp(name->u.ad->data, "BGP") == 0) && (state->u.i != PS_DOWN))
struct protocol **type = (struct protocol **)ea_get_adata(eal, &ea_protocol_type)->data;
int state = ea_get_int(eal, &ea_state, 0);
if ((*type == &proto_bgp) && (state != PS_DOWN))
{
eattr *rem_id = ea_find(proto_attributes->attrs[i], &ea_proto_bgp_rem_id);
eattr *rem_as = ea_find(proto_attributes->attrs[i], &ea_proto_bgp_rem_as);
eattr *rem_ip = ea_find(proto_attributes->attrs[i], &ea_proto_bgp_rem_ip);
mrt_peer_table_entry(s, rem_id->u.i, rem_as->u.i, *((ip_addr*) rem_ip->u.ad->data));
int rem_id = ea_get_int(eal, &ea_bgp_rem_id, 0);
int rem_as = ea_get_int(eal, &ea_bgp_rem_as, 0);
ip_addr *rem_ip = (ip_addr *)ea_get_adata(eal, &ea_bgp_rem_ip)->data;
mrt_peer_table_entry(s, rem_id, rem_as, *rem_ip);
}
}
#endif
@ -789,6 +790,7 @@ mrt_bgp_buffer(void)
static buffer b;
ASSERT(this_metaloop);
log("loop in mrt %x, pool %i (main loop is %x, pool %i)", this_metaloop, this_metaloop->pool, &main_birdloop, main_birdloop.pool);
ASSERT(this_metaloop->pool);
if (!b.start)
mrt_buffer_init(&b, this_metaloop->pool, 1024);

View File

@ -368,7 +368,7 @@ ospf_init(struct proto_config *CF)
struct ospf_config *cf = (struct ospf_config *) CF;
struct proto *P = proto_new(CF);
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
proto_add_main_channel(P, proto_cf_main_channel(CF));
P->rt_notify = ospf_rt_notify;
P->iface_sub.if_notify = ospf_if_notify;

View File

@ -579,7 +579,7 @@ radv_init(struct proto_config *CF)
{
struct proto *P = proto_new(CF);
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
proto_add_main_channel(P, proto_cf_main_channel(CF));
P->preexport = radv_preexport;
P->rt_notify = radv_rt_notify;

View File

@ -1162,7 +1162,7 @@ rip_init(struct proto_config *CF)
{
struct proto *P = proto_new(CF);
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
proto_add_main_channel(P, proto_cf_main_channel(CF));
P->iface_sub.if_notify = rip_if_notify;
P->rt_notify = rip_rt_notify;

View File

@ -507,7 +507,7 @@ static_init(struct proto_config *CF)
struct static_proto *p = (void *) P;
struct static_config *cf = (void *) CF;
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
proto_add_main_channel(P, proto_cf_main_channel(CF));
proto_configure_mpls_channel(P, CF, RTS_STATIC);

View File

@ -1416,12 +1416,14 @@ birdloop_init(void)
main_birdloop.time.domain = the_bird_domain.the_bird;
main_birdloop.time.loop = &main_birdloop;
main_birdloop.pool = rp_new(&root_pool, the_bird_domain.the_bird, "Main loop");
times_update();
timers_init(&main_birdloop.time, &root_pool);
birdloop_enter_locked(&main_birdloop);
this_birdloop = this_metaloop = &main_birdloop;
this_thread = &main_thread;
defer_init(lp_new(&root_pool));

View File

@ -835,7 +835,7 @@ krt_init(struct proto_config *CF)
struct krt_proto *p = proto_new(CF);
// struct krt_config *cf = (void *) CF;
p->p.main_channel = proto_add_channel(&p->p, proto_cf_main_channel(CF));
proto_add_main_channel(&p->p, proto_cf_main_channel(CF));
p->p.preexport = krt_preexport;
p->p.rt_notify = krt_rt_notify;