mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 01:31:55 +00:00
TMP/CLI: show proto rework to not lock all protocols
This commit is contained in:
parent
8a46316bb3
commit
ef8f7934e6
@ -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; }
|
||||
|
100
nest/proto.c
100
nest/proto.c
@ -293,6 +293,19 @@ 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;
|
||||
|
||||
eal = p->ea_state;
|
||||
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_main_table_id, 0, p->main_channel->table->id));
|
||||
proto_announce_state(p, eal);
|
||||
|
||||
return p->main_channel;
|
||||
}
|
||||
|
||||
void
|
||||
proto_remove_channel(struct proto *p UNUSED, struct channel *c)
|
||||
{
|
||||
@ -2089,6 +2102,7 @@ extern void bfd_init_all(void);
|
||||
|
||||
void protos_build_gen(void);
|
||||
|
||||
|
||||
/**
|
||||
* protos_build - build a protocol list
|
||||
*
|
||||
@ -2488,6 +2502,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
|
||||
channel_show_stats(struct channel *c)
|
||||
{
|
||||
@ -2581,7 +2608,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];
|
||||
|
||||
@ -2590,22 +2617,36 @@ 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");
|
||||
|
||||
PST_LOCKED(ts)
|
||||
{
|
||||
ea_list *eal = ts->states[p->id];
|
||||
|
||||
const char *name = ea_get_adata(eal, &ea_name)->data;
|
||||
struct protocol *proto = (struct protocol *) ea_get_ptr(eal, &ea_protocol_type, 0);
|
||||
const int state = ea_get_int(eal, &ea_state, 0);
|
||||
ea_list *chan_ea = ts->channels[ea_get_int(eal, &ea_main_table_id, 0)];
|
||||
const char *table = ea_get_adata(chan_ea, &ea_name)->data;
|
||||
buf[0] = 0;
|
||||
if (p->proto->get_status)
|
||||
{
|
||||
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, &atomic_load_explicit(&global_runtime, memory_order_acquire)->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",
|
||||
p->name,
|
||||
p->proto->name,
|
||||
p->main_channel ? p->main_channel->table->name : "---",
|
||||
proto_state_name(p),
|
||||
name,
|
||||
proto->name,
|
||||
table ? table : "---",
|
||||
proto_state_name_from_int(state),
|
||||
tbuf,
|
||||
buf);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose.verbose)
|
||||
{
|
||||
PROTO_LOCKED_FROM_MAIN(p)
|
||||
{
|
||||
if (p->cf->dsc)
|
||||
cli_msg(-1006, " Description: %s", p->cf->dsc);
|
||||
@ -2628,6 +2669,7 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
|
||||
cli_msg(-1006, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
proto_cmd_disable(struct proto *p, uintptr_t arg, int cnt UNUSED)
|
||||
@ -2828,6 +2870,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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
@ -714,6 +721,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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -820,7 +820,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;
|
||||
|
Loading…
Reference in New Issue
Block a user