diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/config.Y | 12 | ||||
-rw-r--r-- | nest/proto.c | 63 | ||||
-rw-r--r-- | nest/protocol.h | 18 |
3 files changed, 68 insertions, 25 deletions
diff --git a/nest/config.Y b/nest/config.Y index 025e8969..f51be6ea 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -696,12 +696,12 @@ echo_size: } ; -CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]]) -{ proto_apply_cmd($2, proto_cmd_disable, 1, 0); } ; -CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]]) -{ proto_apply_cmd($2, proto_cmd_enable, 1, 0); } ; -CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]]) -{ proto_apply_cmd($2, proto_cmd_restart, 1, 0); } ; +CF_CLI(DISABLE, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Disable protocol]]) +{ proto_apply_cmd($2, proto_cmd_disable, 1, (uintptr_t) $3); } ; +CF_CLI(ENABLE, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Enable protocol]]) +{ proto_apply_cmd($2, proto_cmd_enable, 1, (uintptr_t) $3); } ; +CF_CLI(RESTART, proto_patt text_or_none, (<protocol> | \"<pattern>\" | all) [message], [[Restart protocol]]) +{ proto_apply_cmd($2, proto_cmd_restart, 1, (uintptr_t) $3); } ; CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]]) { proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ; CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]]) diff --git a/nest/proto.c b/nest/proto.c index 64422ee3..552d53ae 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -610,6 +610,7 @@ proto_rethink_goal(struct proto *p) config_del_obstacle(p->cf->global); rem_node(&p->n); rem_node(&p->glob_node); + mb_free(p->message); mb_free(p); if (!nc) return; @@ -1096,6 +1097,39 @@ proto_schedule_down(struct proto *p, byte restart, byte code) tm_start_max(proto_shutdown_timer, restart ? 2 : 0); } +/** + * proto_set_message - set administrative message to protocol + * @p: protocol + * @msg: message + * @len: message length (-1 for NULL-terminated string) + * + * The function sets administrative message (string) related to protocol state + * change. It is called by the nest code for manual enable/disable/restart + * commands all routes to the protocol, and by protocol-specific code when the + * protocol state change is initiated by the protocol. Using NULL message clears + * the last message. The message string may be either NULL-terminated or with an + * explicit length. + */ +void +proto_set_message(struct proto *p, char *msg, int len) +{ + mb_free(p->message); + p->message = NULL; + + if (!msg || !len) + return; + + if (len < 0) + len = strlen(msg); + + if (!len) + return; + + p->message = mb_alloc(proto_pool, len + 1); + memcpy(p->message, msg, len); + p->message[len] = 0; +} + /** * proto_request_feeding - request feeding routes to the protocol @@ -1497,7 +1531,7 @@ proto_show_basic_info(struct proto *p) } void -proto_cmd_show(struct proto *p, uint verbose, int cnt) +proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt) { byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE]; @@ -1520,6 +1554,10 @@ proto_cmd_show(struct proto *p, uint verbose, int cnt) { if (p->cf->dsc) cli_msg(-1006, " Description: %s", p->cf->dsc); + + if (p->message) + cli_msg(-1006, " Message: %s", p->message); + if (p->cf->router_id) cli_msg(-1006, " Router ID: %R", p->cf->router_id); @@ -1533,7 +1571,7 @@ proto_cmd_show(struct proto *p, uint verbose, int cnt) } void -proto_cmd_disable(struct proto *p, uint arg UNUSED, int cnt UNUSED) +proto_cmd_disable(struct proto *p, uintptr_t arg, int cnt UNUSED) { if (p->disabled) { @@ -1544,12 +1582,13 @@ proto_cmd_disable(struct proto *p, uint arg UNUSED, int cnt UNUSED) log(L_INFO "Disabling protocol %s", p->name); p->disabled = 1; p->down_code = PDC_CMD_DISABLE; + proto_set_message(p, (char *) arg, -1); proto_rethink_goal(p); cli_msg(-9, "%s: disabled", p->name); } void -proto_cmd_enable(struct proto *p, uint arg UNUSED, int cnt UNUSED) +proto_cmd_enable(struct proto *p, uintptr_t arg, int cnt UNUSED) { if (!p->disabled) { @@ -1559,12 +1598,13 @@ proto_cmd_enable(struct proto *p, uint arg UNUSED, int cnt UNUSED) log(L_INFO "Enabling protocol %s", p->name); p->disabled = 0; + proto_set_message(p, (char *) arg, -1); proto_rethink_goal(p); cli_msg(-11, "%s: enabled", p->name); } void -proto_cmd_restart(struct proto *p, uint arg UNUSED, int cnt UNUSED) +proto_cmd_restart(struct proto *p, uintptr_t arg, int cnt UNUSED) { if (p->disabled) { @@ -1575,6 +1615,7 @@ proto_cmd_restart(struct proto *p, uint arg UNUSED, int cnt UNUSED) log(L_INFO "Restarting protocol %s", p->name); p->disabled = 1; p->down_code = PDC_CMD_RESTART; + proto_set_message(p, (char *) arg, -1); proto_rethink_goal(p); p->disabled = 0; proto_rethink_goal(p); @@ -1582,7 +1623,7 @@ proto_cmd_restart(struct proto *p, uint arg UNUSED, int cnt UNUSED) } void -proto_cmd_reload(struct proto *p, uint dir, int cnt UNUSED) +proto_cmd_reload(struct proto *p, uintptr_t dir, int cnt UNUSED) { if (p->disabled) { @@ -1624,19 +1665,19 @@ proto_cmd_reload(struct proto *p, uint dir, int cnt UNUSED) } void -proto_cmd_debug(struct proto *p, uint mask, int cnt UNUSED) +proto_cmd_debug(struct proto *p, uintptr_t mask, int cnt UNUSED) { p->debug = mask; } void -proto_cmd_mrtdump(struct proto *p, uint mask, int cnt UNUSED) +proto_cmd_mrtdump(struct proto *p, uintptr_t mask, int cnt UNUSED) { p->mrtdump = mask; } static void -proto_apply_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, uint, int), uint arg) +proto_apply_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg) { if (s->class != SYM_PROTO) { @@ -1649,7 +1690,7 @@ proto_apply_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, uint, int) } static void -proto_apply_cmd_patt(char *patt, void (* cmd)(struct proto *, uint, int), uint arg) +proto_apply_cmd_patt(char *patt, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg) { int cnt = 0; @@ -1669,8 +1710,8 @@ proto_apply_cmd_patt(char *patt, void (* cmd)(struct proto *, uint, int), uint a } void -proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uint, int), - int restricted, uint arg) +proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), + int restricted, uintptr_t arg) { if (restricted && cli_access_restricted()) return; diff --git a/nest/protocol.h b/nest/protocol.h index 18dfbd6f..5aca9a4e 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -164,6 +164,7 @@ struct proto { u32 hash_key; /* Random key used for hashing of neighbors */ bird_clock_t 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 */ struct proto_stats stats; /* Current protocol statistics */ /* @@ -250,6 +251,7 @@ struct proto_spec { void *proto_new(struct proto_config *, unsigned size); void *proto_config_new(struct protocol *, int class); void proto_copy_config(struct proto_config *dest, struct proto_config *src); +void proto_set_message(struct proto *p, char *msg, int len); void proto_request_feeding(struct proto *p); static inline void @@ -267,15 +269,15 @@ void proto_graceful_restart_unlock(struct proto *p); void proto_show_limit(struct proto_limit *l, const char *dsc); void proto_show_basic_info(struct proto *p); -void proto_cmd_show(struct proto *, uint, int); -void proto_cmd_disable(struct proto *, uint, int); -void proto_cmd_enable(struct proto *, uint, int); -void proto_cmd_restart(struct proto *, uint, int); -void proto_cmd_reload(struct proto *, uint, int); -void proto_cmd_debug(struct proto *, uint, int); -void proto_cmd_mrtdump(struct proto *, uint, int); +void proto_cmd_show(struct proto *, uintptr_t, 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); +void proto_cmd_reload(struct proto *, uintptr_t, int); +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 *, uint, int), int restricted, uint arg); +void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg); struct proto *proto_get_named(struct symbol *, struct protocol *); #define CMD_RELOAD 0 |