summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/config.Y12
-rw-r--r--nest/proto.c61
-rw-r--r--nest/protocol.h18
-rw-r--r--nest/route.h3
4 files changed, 68 insertions, 26 deletions
diff --git a/nest/config.Y b/nest/config.Y
index ad45a39d..555c9e05 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -756,12 +756,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 opttext, (<protocol> | \"<pattern>\" | all) [message], [[Disable protocol]])
+{ proto_apply_cmd($2, proto_cmd_disable, 1, (uintptr_t) $3); } ;
+CF_CLI(ENABLE, proto_patt opttext, (<protocol> | \"<pattern>\" | all) [message], [[Enable protocol]])
+{ proto_apply_cmd($2, proto_cmd_enable, 1, (uintptr_t) $3); } ;
+CF_CLI(RESTART, proto_patt opttext, (<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 ecc3b0fe..a2a2bc7e 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -980,6 +980,7 @@ proto_rethink_goal(struct proto *p)
proto_remove_channels(p);
rem_node(&p->n);
rfree(p->event);
+ mb_free(p->message);
mb_free(p);
if (!nc)
return;
@@ -1334,6 +1335,39 @@ proto_schedule_down(struct proto *p, byte restart, byte code)
tm_start_max(proto_shutdown_timer, restart ? 250 MS : 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;
+}
+
static const char *
channel_limit_name(struct channel_limit *l)
@@ -1622,7 +1656,7 @@ channel_show_info(struct channel *c)
}
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];
@@ -1646,6 +1680,8 @@ 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);
if (p->vrf)
@@ -1665,7 +1701,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)
{
@@ -1676,12 +1712,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)
{
@@ -1691,12 +1728,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)
{
@@ -1707,6 +1745,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);
@@ -1714,7 +1753,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)
{
struct channel *c;
@@ -1753,19 +1792,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)
{
@@ -1778,7 +1817,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)
{
struct proto *p;
int cnt = 0;
@@ -1794,8 +1833,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 d7e84a44..c8f37367 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -162,6 +162,7 @@ struct proto {
u32 hash_key; /* Random key used for hashing of neighbors */
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 */
/*
* General protocol hooks:
@@ -238,6 +239,7 @@ struct proto_spec {
void *proto_new(struct proto_config *);
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 graceful_restart_recovery(void);
void graceful_restart_init(void);
@@ -250,15 +252,15 @@ void channel_graceful_restart_unlock(struct channel *c);
void channel_show_limit(struct channel_limit *l, const char *dsc);
void channel_show_info(struct channel *c);
-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
diff --git a/nest/route.h b/nest/route.h
index c9e2b3bf..bb0cb4a4 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -470,7 +470,8 @@ typedef struct eattr {
#define EAP_OSPF 3 /* OSPF */
#define EAP_KRT 4 /* Kernel route attributes */
#define EAP_BABEL 5 /* Babel attributes */
-#define EAP_MAX 6
+#define EAP_RADV 6 /* Router advertisment attributes */
+#define EAP_MAX 7
#define EA_CODE(proto,id) (((proto) << 8) | (id))
#define EA_PROTO(ea) ((ea) >> 8)