mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
proto.c: show protocol uses only proto id and attr table
This commit is contained in:
parent
f715b3decc
commit
b3e13eddb9
@ -650,6 +650,8 @@ mem_hash_mix_f_val(u64 *h, struct f_val *v)
|
|||||||
case T_NEXTHOP_LIST:
|
case T_NEXTHOP_LIST:
|
||||||
case T_HOSTENTRY:
|
case T_HOSTENTRY:
|
||||||
case T_IFACE:
|
case T_IFACE:
|
||||||
|
case T_ENUM_STATE:
|
||||||
|
case T_BTIME:
|
||||||
bug("Invalid type %s in f_val hashing", f_type_name(v->type));
|
bug("Invalid type %s in f_val hashing", f_type_name(v->type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,6 +219,7 @@ void lfjour_release(struct lfjour_recipient *r)
|
|||||||
void
|
void
|
||||||
lfjour_announce_now(struct lfjour *j)
|
lfjour_announce_now(struct lfjour *j)
|
||||||
{
|
{
|
||||||
|
log("announce now %i", j);
|
||||||
ASSERT_DIE(birdloop_inside(j->loop));
|
ASSERT_DIE(birdloop_inside(j->loop));
|
||||||
settle_cancel(&j->announce_timer);
|
settle_cancel(&j->announce_timer);
|
||||||
ev_postpone(&j->announce_kick_event);
|
ev_postpone(&j->announce_kick_event);
|
||||||
@ -226,6 +227,7 @@ lfjour_announce_now(struct lfjour *j)
|
|||||||
if (EMPTY_TLIST(lfjour_recipient, &j->recipients))
|
if (EMPTY_TLIST(lfjour_recipient, &j->recipients))
|
||||||
return lfjour_schedule_cleanup(j);
|
return lfjour_schedule_cleanup(j);
|
||||||
|
|
||||||
|
log("walk recipient list");
|
||||||
WALK_TLIST(lfjour_recipient, r, &j->recipients)
|
WALK_TLIST(lfjour_recipient, r, &j->recipients)
|
||||||
if (r->event)
|
if (r->event)
|
||||||
ev_send(r->target, r->event);
|
ev_send(r->target, r->event);
|
||||||
|
@ -377,6 +377,8 @@ void ea_list_copy(ea_list *dest, ea_list *src, uint size);
|
|||||||
#define EA_LITERAL_GENERIC(_id, _type, _flags, ...) \
|
#define EA_LITERAL_GENERIC(_id, _type, _flags, ...) \
|
||||||
((eattr) { .id = _id, .type = _type, .flags = _flags, __VA_ARGS__ })
|
((eattr) { .id = _id, .type = _type, .flags = _flags, __VA_ARGS__ })
|
||||||
|
|
||||||
|
#define EA_LITERAL_STORE_STRING(_class, _flags, string) ({EA_LITERAL_STORE_ADATA(_class, _flags, string, strlen(string)+1);})
|
||||||
|
|
||||||
static inline eattr *
|
static inline eattr *
|
||||||
ea_set_attr(ea_list **to, eattr a)
|
ea_set_attr(ea_list **to, eattr a)
|
||||||
{
|
{
|
||||||
@ -443,6 +445,9 @@ extern struct ea_class ea_gen_from;
|
|||||||
extern struct ea_class ea_gen_mpls_label,
|
extern struct ea_class ea_gen_mpls_label,
|
||||||
ea_gen_mpls_policy, ea_gen_mpls_class;
|
ea_gen_mpls_policy, ea_gen_mpls_class;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
/* Source: An old method to devise the route source protocol and kind.
|
/* Source: An old method to devise the route source protocol and kind.
|
||||||
* To be superseded in a near future by something more informative. */
|
* To be superseded in a near future by something more informative. */
|
||||||
|
@ -113,6 +113,10 @@ enum btype {
|
|||||||
|
|
||||||
T_SET = 0x80,
|
T_SET = 0x80,
|
||||||
T_PREFIX_SET = 0x84,
|
T_PREFIX_SET = 0x84,
|
||||||
|
|
||||||
|
/* protocol */
|
||||||
|
T_ENUM_STATE = 0xd1,
|
||||||
|
T_BTIME = 0xd4,
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
typedef enum btype btype;
|
typedef enum btype btype;
|
||||||
|
@ -65,9 +65,8 @@ xmalloc(uint size)
|
|||||||
void *
|
void *
|
||||||
xrealloc(void *ptr, uint size)
|
xrealloc(void *ptr, uint size)
|
||||||
{
|
{
|
||||||
void *p = realloc(ptr, size);
|
|
||||||
|
|
||||||
MINFO(ptr, 0, 2);
|
MINFO(ptr, 0, 2);
|
||||||
|
void *p = realloc(ptr, size);
|
||||||
MINFO(p, size, 3);
|
MINFO(p, size, 3);
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
|
223
nest/proto.c
223
nest/proto.c
@ -28,6 +28,9 @@ static TLIST_LIST(proto) global_proto_list;
|
|||||||
|
|
||||||
static list STATIC_LIST_INIT(protocol_list);
|
static list STATIC_LIST_INIT(protocol_list);
|
||||||
|
|
||||||
|
struct lfjour *proto_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); })
|
#define CD(c, msg, args...) ({ if (c->debug & D_STATES) log(L_TRACE "%s.%s: " msg, c->proto->name, c->name ?: "?", ## args); })
|
||||||
#define PD(p, msg, args...) ({ if (p->debug & D_STATES) log(L_TRACE "%s: " msg, p->name, ## args); })
|
#define PD(p, msg, args...) ({ if (p->debug & D_STATES) log(L_TRACE "%s: " msg, p->name, ## args); })
|
||||||
|
|
||||||
@ -45,6 +48,7 @@ static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
|
|||||||
static char *c_states[] = { "DOWN", "START", "UP", "STOP", "RESTART" };
|
static char *c_states[] = { "DOWN", "START", "UP", "STOP", "RESTART" };
|
||||||
|
|
||||||
extern struct protocol proto_unix_iface;
|
extern struct protocol proto_unix_iface;
|
||||||
|
struct proto_attrs *proto_attributes;
|
||||||
|
|
||||||
static void proto_rethink_goal(struct proto *p);
|
static void proto_rethink_goal(struct proto *p);
|
||||||
static char *proto_state_name(struct proto *p);
|
static char *proto_state_name(struct proto *p);
|
||||||
@ -64,6 +68,8 @@ static inline void channel_refeed(struct channel *c, struct rt_feeding_request *
|
|||||||
rt_export_refeed(&c->out_req, rfr);
|
rt_export_refeed(&c->out_req, rfr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_proto_journal(void);
|
||||||
|
|
||||||
static inline int proto_is_done(struct proto *p)
|
static inline int proto_is_done(struct proto *p)
|
||||||
{ return (p->proto_state == PS_DOWN) && proto_is_inactive(p); }
|
{ return (p->proto_state == PS_DOWN) && proto_is_inactive(p); }
|
||||||
|
|
||||||
@ -1235,6 +1241,7 @@ proto_init(struct proto_config *c, struct proto *after)
|
|||||||
struct proto *p = pr->init(c);
|
struct proto *p = pr->init(c);
|
||||||
|
|
||||||
p->loop = &main_birdloop;
|
p->loop = &main_birdloop;
|
||||||
|
int old_state = p->proto_state;
|
||||||
p->proto_state = PS_DOWN;
|
p->proto_state = PS_DOWN;
|
||||||
p->last_state_change = current_time();
|
p->last_state_change = current_time();
|
||||||
p->vrf = c->vrf;
|
p->vrf = c->vrf;
|
||||||
@ -1244,6 +1251,16 @@ proto_init(struct proto_config *c, struct proto *after)
|
|||||||
|
|
||||||
PD(p, "Initializing%s", p->disabled ? " [disabled]" : "");
|
PD(p, "Initializing%s", p->disabled ? " [disabled]" : "");
|
||||||
|
|
||||||
|
log("try to change state");
|
||||||
|
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)
|
||||||
|
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);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1665,6 +1682,9 @@ proto_rethink_goal(struct proto *p)
|
|||||||
struct proto_config *nc = p->cf_new;
|
struct proto_config *nc = p->cf_new;
|
||||||
struct proto *after = p->n.prev;
|
struct proto *after = p->n.prev;
|
||||||
|
|
||||||
|
hmap_clear(proto_attributes->proto_id_maker, p->id);
|
||||||
|
atomic_store(&proto_attributes->attrs[p->id], NULL);
|
||||||
|
|
||||||
DBG("%s has shut down for reconfiguration\n", p->name);
|
DBG("%s has shut down for reconfiguration\n", p->name);
|
||||||
p->cf->proto = NULL;
|
p->cf->proto = NULL;
|
||||||
config_del_obstacle(p->cf->global);
|
config_del_obstacle(p->cf->global);
|
||||||
@ -1955,6 +1975,8 @@ protos_build(void)
|
|||||||
{
|
{
|
||||||
proto_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Protocols");
|
proto_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Protocols");
|
||||||
|
|
||||||
|
init_proto_journal();
|
||||||
|
create_dummy_recipient();
|
||||||
protos_build_gen();
|
protos_build_gen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2254,8 +2276,14 @@ proto_notify_state(struct proto *p, uint state)
|
|||||||
if (state == ps)
|
if (state == ps)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
log("try to change state");
|
||||||
|
int old_state = p->proto_state;
|
||||||
p->proto_state = state;
|
p->proto_state = state;
|
||||||
p->last_state_change = current_time();
|
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);
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
@ -2314,6 +2342,19 @@ proto_state_name(struct proto *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
proto_state_name_from_int(int state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case PS_DOWN: return "flush or down";
|
||||||
|
case PS_START: return "start";
|
||||||
|
case PS_UP: return "up";
|
||||||
|
case PS_STOP: return "stop";
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
channel_show_stats(struct channel *c)
|
channel_show_stats(struct channel *c)
|
||||||
{
|
{
|
||||||
@ -2416,17 +2457,28 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
|
|||||||
cli_msg(-2002, "%-10s %-10s %-10s %-6s %-12s %s",
|
cli_msg(-2002, "%-10s %-10s %-10s %-6s %-12s %s",
|
||||||
"Name", "Proto", "Table", "State", "Since", "Info");
|
"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();
|
||||||
|
|
||||||
|
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;
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if (p->proto->get_status)
|
if (p->proto->get_status)
|
||||||
p->proto->get_status(p, buf);
|
p->proto->get_status(p, buf);
|
||||||
tm_format_time(tbuf, &config->tf_proto, p->last_state_change);
|
tm_format_time(tbuf, &config->tf_proto, *time);
|
||||||
cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
|
cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
|
||||||
p->name,
|
name,
|
||||||
p->proto->name,
|
proto,
|
||||||
p->main_channel ? p->main_channel->table->name : "---",
|
table,
|
||||||
proto_state_name(p),
|
proto_state_name_from_int(state),
|
||||||
tbuf,
|
tbuf,
|
||||||
buf);
|
info);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
@ -2724,3 +2776,162 @@ proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *ol
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
//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));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cleanup_journal_item(struct lfjour * UNUSED, struct lfjour_item *i)
|
||||||
|
{
|
||||||
|
log("clean 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);
|
||||||
|
if (new_ea->u.i)
|
||||||
|
ea_free_later(pupdate->proto_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
after_journal_birdloop_stop(void* UNUSED){}
|
||||||
|
|
||||||
|
void
|
||||||
|
init_proto_journal(void)
|
||||||
|
{
|
||||||
|
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->domain = proto_journal_domain.rtable;
|
||||||
|
|
||||||
|
lfjour_init(proto_journal, &cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
ea_list *
|
||||||
|
proto_state_to_eattr(struct proto *p, int old_state, int proto_deleting)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
ea_list l;
|
||||||
|
eattr a[8];
|
||||||
|
} 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_EMBEDDED(&ea_proto_id, 0, p->id);
|
||||||
|
eattrs.a[eattrs.l.count++] = EA_LITERAL_EMBEDDED(&ea_proto_deleted, 0, proto_deleting);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
log("no recievers");
|
||||||
|
//if (free_add_data)
|
||||||
|
// free_add_data(add_data);
|
||||||
|
log("returning");
|
||||||
|
UNLOCK_DOMAIN(rtable, proto_journal_domain);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*pupdate = (struct proto_pending_update) {
|
||||||
|
.li = pupdate->li, /* Keep the item's internal state */
|
||||||
|
.proto_attr = attr,
|
||||||
|
.old_attr = old_attr,
|
||||||
|
.protocol = p
|
||||||
|
};
|
||||||
|
lfjour_push_commit(proto_journal);
|
||||||
|
log("in journal state change, proto %s, jfjour %i - pushed", p->name, proto_journal);
|
||||||
|
UNLOCK_DOMAIN(rtable, proto_journal_domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_log_proto_attr_list(void)
|
||||||
|
{
|
||||||
|
//debugging function
|
||||||
|
ea_list *eal;
|
||||||
|
for(u32 i = 0; i < proto_attributes->length; i++)
|
||||||
|
{
|
||||||
|
rcu_read_lock();
|
||||||
|
eal = proto_attributes->attrs[i];
|
||||||
|
if (eal)
|
||||||
|
ea_free_later(ea_ref(eal));
|
||||||
|
rcu_read_unlock();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fc_for_dummy_recipient(void *rec)
|
||||||
|
{
|
||||||
|
struct lfjour_item *last_up;
|
||||||
|
struct proto_pending_update *pupdate;
|
||||||
|
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);
|
||||||
|
if (name && state)
|
||||||
|
log("protocol %s changed state to %i", name->u.ad->data, state->u.i);
|
||||||
|
else
|
||||||
|
log("not found in %i", pupdate->proto_attr);
|
||||||
|
lfjour_release(rec);
|
||||||
|
dummy_log_proto_attr_list();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
create_dummy_recipient(void)
|
||||||
|
{
|
||||||
|
struct lfjour_recipient *r = mb_allocz(&root_pool, sizeof(struct lfjour_recipient));
|
||||||
|
r->event = ev_new_init(&root_pool, fc_for_dummy_recipient, r);
|
||||||
|
struct birdloop *loop = birdloop_new(&root_pool, DOMAIN_ORDER(service), 1, "dummy recipient loop");
|
||||||
|
r->target = birdloop_event_list(loop);
|
||||||
|
|
||||||
|
LOCK_DOMAIN(rtable, proto_journal_domain);
|
||||||
|
lfjour_register(proto_journal, r);
|
||||||
|
UNLOCK_DOMAIN(rtable, proto_journal_domain);
|
||||||
|
log("recipient created r %i j %i", r, proto_journal);
|
||||||
|
dummy_log_proto_attr_list();
|
||||||
|
}
|
||||||
|
@ -172,6 +172,7 @@ struct proto {
|
|||||||
btime last_state_change; /* Time of last state transition */
|
btime last_state_change; /* Time of last state transition */
|
||||||
char *last_state_name_announced; /* Last state name we've announced to the user */
|
char *last_state_name_announced; /* Last state name we've announced to the user */
|
||||||
char *message; /* State-change message, allocated from proto_pool */
|
char *message; /* State-change message, allocated from proto_pool */
|
||||||
|
u32 id; /* Id of the protocol indexing its position in proto_attributes */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General protocol hooks:
|
* General protocol hooks:
|
||||||
@ -392,6 +393,28 @@ static inline int proto_is_inactive(struct proto *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct proto_attrs {
|
||||||
|
ea_list *_Atomic *attrs;
|
||||||
|
_Atomic u32 length;
|
||||||
|
struct hmap *proto_id_maker;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct lfjour *proto_journal;
|
||||||
|
extern struct proto_attrs *proto_attributes;
|
||||||
|
|
||||||
|
struct proto_pending_update {
|
||||||
|
LFJOUR_ITEM_INHERIT(li);
|
||||||
|
ea_list *proto_attr;
|
||||||
|
ea_list *old_attr;
|
||||||
|
struct proto *protocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
void proto_journal_state_changed(ea_list *attr, ea_list *old_attr, struct proto *p);
|
||||||
|
ea_list *proto_state_to_eattr(struct proto *p, int old_state, int protocol_deleting);
|
||||||
|
void create_dummy_recipient(void);
|
||||||
|
void protos_attr_field_grow(void);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debugging flags
|
* Debugging flags
|
||||||
*/
|
*/
|
||||||
|
@ -1765,6 +1765,52 @@ ea_show_list(struct cli *c, ea_list *eal)
|
|||||||
ea_show(c, &n->attrs[i]);
|
ea_show(c, &n->attrs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ea_class ea_proto_name = {
|
||||||
|
.name = "proto_name",
|
||||||
|
.type = T_STRING,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_protocol_name = {
|
||||||
|
.name = "proto_protocol_name",
|
||||||
|
.type = T_STRING,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_table = {
|
||||||
|
.name = "proto_table",
|
||||||
|
.type = T_STRING,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_state = {
|
||||||
|
.name = "proto_state",
|
||||||
|
.type = T_ENUM_STATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_old_state = {
|
||||||
|
.name = "proto_old_state",
|
||||||
|
.type = T_ENUM_STATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_last_modified = {
|
||||||
|
.name = "proto_last_modified",
|
||||||
|
.type = T_BTIME,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_info = {
|
||||||
|
.name = "proto_info",
|
||||||
|
.type = T_STRING,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_deleted = {
|
||||||
|
.name = "proto_deleted",
|
||||||
|
.type = T_INT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ea_class ea_proto_id = {
|
||||||
|
.name = "proto_id",
|
||||||
|
.type = T_INT,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rta_init - initialize route attribute cache
|
* rta_init - initialize route attribute cache
|
||||||
*
|
*
|
||||||
@ -1809,6 +1855,17 @@ rta_init(void)
|
|||||||
ea_register_init(&ea_gen_mpls_policy);
|
ea_register_init(&ea_gen_mpls_policy);
|
||||||
ea_register_init(&ea_gen_mpls_class);
|
ea_register_init(&ea_gen_mpls_class);
|
||||||
ea_register_init(&ea_gen_mpls_label);
|
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_proto_id);
|
||||||
|
ea_register_init(&ea_proto_deleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -340,6 +340,8 @@ rtex_export_subscribe(struct rt_exporter *e, struct rt_export_request *r)
|
|||||||
{
|
{
|
||||||
rt_export_change_state(r, BIT32_ALL(TES_DOWN), TES_FEEDING);
|
rt_export_change_state(r, BIT32_ALL(TES_DOWN), TES_FEEDING);
|
||||||
|
|
||||||
|
log("subscribe e=%p r=%p", e, r);
|
||||||
|
|
||||||
ASSERT_DIE(r->pool);
|
ASSERT_DIE(r->pool);
|
||||||
|
|
||||||
rt_feeder_subscribe(e, &r->feeder);
|
rt_feeder_subscribe(e, &r->feeder);
|
||||||
@ -357,6 +359,7 @@ rtex_export_subscribe(struct rt_exporter *e, struct rt_export_request *r)
|
|||||||
void
|
void
|
||||||
rtex_export_unsubscribe(struct rt_export_request *r)
|
rtex_export_unsubscribe(struct rt_export_request *r)
|
||||||
{
|
{
|
||||||
|
log("unsubscribe r=%p", r);
|
||||||
rt_feeder_unsubscribe(&r->feeder);
|
rt_feeder_unsubscribe(&r->feeder);
|
||||||
|
|
||||||
if (r->cur)
|
if (r->cur)
|
||||||
|
@ -1954,7 +1954,7 @@ bgp_tx_resend(struct bgp_proto *p, struct bgp_channel *bc)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_out_item_done(struct lfjour *j, struct lfjour_item *i)
|
bgp_out_item_done(struct lfjour *j UNUSED, struct lfjour_item *i UNUSED)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static struct rt_export_feed *
|
static struct rt_export_feed *
|
||||||
|
@ -28,6 +28,7 @@ proto: mrt_proto ;
|
|||||||
mrt_proto_start: proto_start MRT
|
mrt_proto_start: proto_start MRT
|
||||||
{
|
{
|
||||||
this_proto = proto_config_new(&proto_mrt, $1);
|
this_proto = proto_config_new(&proto_mrt, $1);
|
||||||
|
this_proto->loop_order = DOMAIN_ORDER(proto);
|
||||||
};
|
};
|
||||||
|
|
||||||
mrt_proto_item:
|
mrt_proto_item:
|
||||||
|
@ -271,7 +271,7 @@ mrt_open_file(struct mrt_table_dump_state *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->file = rf_open(s->pool, name, "a");
|
s->file = rf_open(s->pool, name, RF_APPEND, -1); //TODO: is this correct? Do we want to limit appending file (or does it even make sence for append)?
|
||||||
if (!s->file)
|
if (!s->file)
|
||||||
{
|
{
|
||||||
mrt_log(s, "Unable to open MRT file '%s': %m", name);
|
mrt_log(s, "Unable to open MRT file '%s': %m", name);
|
||||||
@ -359,7 +359,7 @@ mrt_peer_table_dump(struct mrt_table_dump_state *s)
|
|||||||
/* 0 is fake peer for non-BGP routes */
|
/* 0 is fake peer for non-BGP routes */
|
||||||
mrt_peer_table_entry(s, 0, 0, IPA_NONE);
|
mrt_peer_table_entry(s, 0, 0, IPA_NONE);
|
||||||
|
|
||||||
#ifdef CONFIG_BGP
|
/*#ifdef CONFIG_BGP
|
||||||
struct proto *P;
|
struct proto *P;
|
||||||
WALK_LIST(P, proto_list)
|
WALK_LIST(P, proto_list)
|
||||||
if ((P->proto == &proto_bgp) && (P->proto_state != PS_DOWN))
|
if ((P->proto == &proto_bgp) && (P->proto_state != PS_DOWN))
|
||||||
@ -367,7 +367,7 @@ mrt_peer_table_dump(struct mrt_table_dump_state *s)
|
|||||||
struct bgp_proto *p = (void *) P;
|
struct bgp_proto *p = (void *) P;
|
||||||
mrt_peer_table_entry(s, p->remote_id, p->remote_as, p->remote_ip);
|
mrt_peer_table_entry(s, p->remote_id, p->remote_as, p->remote_ip);
|
||||||
}
|
}
|
||||||
#endif
|
#endif*/
|
||||||
|
|
||||||
/* Fix Peer Count */
|
/* Fix Peer Count */
|
||||||
put_u16(s->buf.start + s->peer_count_offset, s->peer_count);
|
put_u16(s->buf.start + s->peer_count_offset, s->peer_count);
|
||||||
|
Loading…
Reference in New Issue
Block a user