diff options
| -rw-r--r-- | vrrpd/vrrp.c | 59 | ||||
| -rw-r--r-- | vrrpd/vrrp.h | 17 |
2 files changed, 65 insertions, 11 deletions
diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index 0fd5e25481..bf43255d1c 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -105,17 +105,44 @@ static void vrrp_reset_times(struct vrrp_vrouter *vr) vrrp_update_times(vr, vr->advertisement_interval, 0); } +/* + * Determines if a VRRP router is the owner of the specified address. + * + * vr + * VRRP router + * + * Returns: + * whether or not vr owns the specified address + */ +static bool vrrp_is_owner(struct vrrp_vrouter *vr, struct ipaddr *addr) +{ + struct prefix *p; + struct prefix_ipv4 p4; + struct prefix_ipv6 p6; + + if (IS_IPADDR_V4(addr)) { + p4.family = AF_INET; + p4.prefixlen = IPV4_MAX_BITLEN; + p4.prefix = addr->ipaddr_v4; + p = (struct prefix *)&p4; + } else { + p6.family = AF_INET6; + p6.prefixlen = IPV6_MAX_BITLEN; + memcpy(&p6.prefix, &addr->ipaddr_v6, sizeof(struct in6_addr)); + p = (struct prefix *)&p6; + } + + return !!connected_lookup_prefix_exact(vr->ifp, p); +} + /* Configuration controllers ----------------------------------------------- */ void vrrp_set_priority(struct vrrp_vrouter *vr, uint8_t priority) { - if (vr->priority == priority) + if (vr->priority_conf == priority) return; - vr->priority = priority; - /* Timers depend on priority value, need to recalculate them */ - vrrp_update_times(vr, vr->advertisement_interval, - vr->master_adver_interval); + vr->priority_conf = priority; } void vrrp_set_advertisement_interval(struct vrrp_vrouter *vr, @@ -148,7 +175,7 @@ struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid) vr->vrid = vrid; vr->v4 = list_new(); vr->v6 = list_new(); - vr->is_master = false; + vr->priority_conf = VRRP_DEFAULT_PRIORITY; vr->priority = VRRP_DEFAULT_PRIORITY; vr->preempt_mode = true; vr->accept_mode = false; @@ -421,6 +448,26 @@ static int vrrp_startup(struct vrrp_vrouter *vr) /* Schedule listener */ /* ... */ + /* configure effective priority */ + struct in_addr *primary = (struct in_addr *) listhead(vr->v4)->data; + struct ipaddr primary_ipaddr; + primary_ipaddr.ipa_type = IPADDR_V4; + primary_ipaddr.ipaddr_v4 = *primary; + + char ipbuf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, primary, ipbuf, sizeof(ipbuf)); + + if (vrrp_is_owner(vr, &primary_ipaddr)) { + vr->priority = VRRP_PRIO_MASTER; + /* Timers depend on priority value, need to recalculate them */ + vrrp_update_times(vr, vr->advertisement_interval, + vr->master_adver_interval); + zlog_info( + VRRP_LOGPFX VRRP_LOGPFX_VRID + "%s owns primary Virtual Router IP %s; electing self as Master", + vr->vrid, vr->ifp->name, ipbuf); + } + if (vr->priority == VRRP_PRIO_MASTER) { vrrp_send_advertisement(vr); vrrp_garp_send_all(vr); diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h index 6ce0e03bf4..b86aba9939 100644 --- a/vrrpd/vrrp.h +++ b/vrrpd/vrrp.h @@ -71,10 +71,14 @@ struct vrrp_vrouter { */ struct list *v6; - /* Whether this VRRP Router is currently the master */ - bool is_master; + /* Configured priority */ + uint8_t priority_conf; - /* Priority */ + /* + * Effective priority + * => priority if we are Backup + * => 255 if we are Master + */ uint8_t priority; /* @@ -159,9 +163,12 @@ void vrrp_vrouter_destroy(struct vrrp_vrouter *vr); /* Configuration controllers ----------------------------------------------- */ /* - * Change the priority of a VRRP Virtual Router. + * Change the configured priority of a VRRP Virtual Router. * - * Also recalculates timers using new priority. + * Note that this only changes the configured priority of the Virtual Router. + * The currently effective priority will not be changed; to change the + * effective priority, the Virtual Router must be restarted by issuing a + * VRRP_EVENT_SHUTDOWN followed by a VRRP_EVENT_STARTUP. * * vr * Virtual Router to change priority of |
