diff options
author | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-01-25 18:54:34 +0100 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-05-17 02:27:08 +0200 |
commit | 6287cefe9cefc32bda53dd7aa30adb3be8869443 (patch) | |
tree | bef1ea9cfb97bd777faac4ccef343ff066829008 /vrrpd | |
parent | vrrpd: unset active flag on shutdown (diff) | |
download | frr-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.c | 24 | ||||
-rw-r--r-- | vrrpd/vrrp.h | 4 | ||||
-rw-r--r-- | vrrpd/vrrp_vty.c | 36 |
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; } |