/* 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)
{
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);
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);
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;
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);
}
*/
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);
#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) \
{
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;
}
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++) {
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;
}
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;
}