summaryrefslogtreecommitdiffstats
path: root/vrrpd
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2019-01-25 18:54:34 +0100
committerQuentin Young <qlyoung@cumulusnetworks.com>2019-05-17 02:27:08 +0200
commit6287cefe9cefc32bda53dd7aa30adb3be8869443 (patch)
treebef1ea9cfb97bd777faac4ccef343ff066829008 /vrrpd
parentvrrpd: unset active flag on shutdown (diff)
downloadfrr-6287cefe9cefc32bda53dd7aa30adb3be8869443.tar.xz
frr-6287cefe9cefc32bda53dd7aa30adb3be8869443.zip
vrrpd: implement `no` variants of commands
Except removing v4/v6 addresses Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'vrrpd')
-rw-r--r--vrrpd/vrrp.c24
-rw-r--r--vrrpd/vrrp.h4
-rw-r--r--vrrpd/vrrp_vty.c36
3 files changed, 48 insertions, 16 deletions
diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c
index f0f7aedb8..c6ca897f4 100644
--- a/vrrpd/vrrp.c
+++ b/vrrpd/vrrp.c
@@ -194,6 +194,12 @@ void vrrp_add_ip(struct vrrp_vrouter *vr, struct ipaddr ip)
/* Creation and destruction ------------------------------------------------ */
+static void vrrp_router_addr_list_del_cb(void *val)
+{
+ struct ipaddr *ip = val;
+ XFREE(MTYPE_TMP, ip);
+}
+
static struct vrrp_router *vrrp_router_create(struct vrrp_vrouter *vr,
int family)
{
@@ -204,6 +210,7 @@ static struct vrrp_router *vrrp_router_create(struct vrrp_vrouter *vr,
r->sock_tx = -1;
r->vr = vr;
r->addrs = list_new();
+ r->addrs->del = vrrp_router_addr_list_del_cb;
r->priority = vr->priority;
r->fsm.state = VRRP_STATE_INITIALIZE;
vrrp_mac_set(&r->vmac, family == AF_INET6, vr->vrid);
@@ -261,10 +268,14 @@ static struct vrrp_router *vrrp_router_create(struct vrrp_vrouter *vr,
static void vrrp_router_destroy(struct vrrp_router *r)
{
+ if (r->is_active)
+ vrrp_event(r, VRRP_EVENT_SHUTDOWN);
+
if (r->sock_rx >= 0)
close(r->sock_rx);
if (r->sock_tx >= 0)
close(r->sock_tx);
+
/* FIXME: also delete list elements */
list_delete(&r->addrs);
XFREE(MTYPE_TMP, r);
@@ -272,8 +283,12 @@ static void vrrp_router_destroy(struct vrrp_router *r)
struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid)
{
- struct vrrp_vrouter *vr =
- XCALLOC(MTYPE_TMP, sizeof(struct vrrp_vrouter));
+ struct vrrp_vrouter *vr = vrrp_lookup(vrid);
+
+ if (vr)
+ return vr;
+
+ vr = XCALLOC(MTYPE_TMP, sizeof(struct vrrp_vrouter));
vr->ifp = ifp;
vr->vrid = vrid;
@@ -293,9 +308,9 @@ struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid)
void vrrp_vrouter_destroy(struct vrrp_vrouter *vr)
{
- vr->ifp = NULL;
vrrp_router_destroy(vr->v4);
vrrp_router_destroy(vr->v6);
+ vr->ifp = NULL;
hash_release(vrrp_vrouters_hash, vr);
XFREE(MTYPE_TMP, vr);
}
@@ -913,6 +928,9 @@ void (*vrrp_change_state_handlers[])(struct vrrp_router *vr) = {
*/
static void vrrp_change_state(struct vrrp_router *r, int to)
{
+ if (r->fsm.state == to)
+ return;
+
/* Call our handlers, then any subscribers */
vrrp_change_state_handlers[to](r);
hook_call(vrrp_change_state_hook, r, to);
diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h
index f68ff8522..417b23a03 100644
--- a/vrrpd/vrrp.h
+++ b/vrrpd/vrrp.h
@@ -219,7 +219,9 @@ void vrrp_init(void);
struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid);
/*
- * Destroy a VRRP Virtual Router.
+ * Destroy a VRRP Virtual Router, freeing all its resources.
+ *
+ * If there are any running VRRP instances, these are stopped and destroyed.
*/
void vrrp_vrouter_destroy(struct vrrp_vrouter *vr);
diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c
index 3726841ed..6edde0ca0 100644
--- a/vrrpd/vrrp_vty.c
+++ b/vrrpd/vrrp_vty.c
@@ -37,6 +37,7 @@
#define VRRP_STR "Virtual Router Redundancy Protocol\n"
#define VRRP_VRID_STR "Virtual Router ID\n"
#define VRRP_PRIORITY_STR "Virtual Router Priority\n"
+#define VRRP_ADVINT_STR "Virtual Router Advertisement Interval\n"
#define VRRP_IP_STR "Virtual Router IPv4 address\n"
#define VROUTER_GET_VTY(_vty, _vrid, _vr) \
@@ -71,7 +72,18 @@ DEFPY(vrrp_vrid,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
- vrrp_vrouter_create(ifp, vrid);
+ struct vrrp_vrouter *vr = vrrp_lookup(vrid);
+
+ if (no && vr)
+ vrrp_vrouter_destroy(vr);
+ else if (no && !vr)
+ vty_out(vty, "%% VRRP instance %ld does not exist on %s\n",
+ vrid, ifp->name);
+ else if (!vr)
+ vrrp_vrouter_create(ifp, vrid);
+ else if (vr)
+ vty_out(vty, "%% VRRP instance %ld already exists on %s\n",
+ vrid, ifp->name);
return CMD_SUCCESS;
}
@@ -89,22 +101,24 @@ DEFPY(vrrp_priority,
struct vrrp_router *r;
bool nr[2] = { false, false };
int ret = CMD_SUCCESS;
+ uint8_t newprio = no ? VRRP_DEFAULT_PRIORITY : priority;
VROUTER_GET_VTY(vty, vrid, vr);
r = vr->v4;
for (int i = 0; i < 2; i++) {
- nr[i] = r->is_active && r->fsm.state != VRRP_STATE_INITIALIZE;
+ nr[i] = r->is_active && r->fsm.state != VRRP_STATE_INITIALIZE
+ && vr->priority != newprio;
if (nr[i]) {
vty_out(vty,
- "%% WARNING: Restarting Virtual Router %ld (%s) to update priority\n",
- vrid, r->family == AF_INET ? "v4" : "v6");
+ "%% WARNING: Restarting %s Virtual Router %ld to update priority\n",
+ family2str(r->family), vrid);
(void)vrrp_event(r, VRRP_EVENT_SHUTDOWN);
}
r = vr->v6;
}
- vrrp_set_priority(vr, priority);
+ vrrp_set_priority(vr, newprio);
r = vr->v4;
for (int i = 0; i < 2; i++) {
@@ -113,7 +127,7 @@ DEFPY(vrrp_priority,
if (ret < 0)
vty_out(vty,
"%% Failed to start Virtual Router %ld (%s)\n",
- vrid, r->family == AF_INET ? "v4" : "v6");
+ vrid, family2str(r->family));
}
r = vr->v6;
}
@@ -124,16 +138,14 @@ DEFPY(vrrp_priority,
DEFPY(vrrp_advertisement_interval,
vrrp_advertisement_interval_cmd,
"[no] vrrp (1-255)$vrid advertisement-interval (1-4096)",
- NO_STR
- VRRP_STR
- VRRP_VRID_STR
- VRRP_PRIORITY_STR
- "Priority value; set 255 to designate this Virtual Router as Master\n")
+ NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
+ "Advertisement interval in centiseconds")
{
struct vrrp_vrouter *vr;
+ uint16_t newadvint = no ? VRRP_DEFAULT_ADVINT : advertisement_interval;
VROUTER_GET_VTY(vty, vrid, vr);
- vrrp_set_advertisement_interval(vr, advertisement_interval);
+ vrrp_set_advertisement_interval(vr, newadvint);
return CMD_SUCCESS;
}