]> git.proxmox.com Git - mirror_frr.git/blobdiff - vrrpd/vrrp.c
vrrpd: some more error logging fixes
[mirror_frr.git] / vrrpd / vrrp.c
index 5213b27d32c21fdc624b5ecc2ef91c31cf66163d..eed0e8a31a2f1d171fa4518780a29db8e422f203 100644 (file)
@@ -196,9 +196,20 @@ static struct vrrp_vrouter *vrrp_lookup_by_if_mvl(struct interface *mvl_ifp)
 {
        struct interface *p;
 
-       if (!mvl_ifp || !mvl_ifp->link_ifindex
-           || !vrrp_ifp_has_vrrp_mac(mvl_ifp))
+       if (!mvl_ifp || mvl_ifp->link_ifindex == 0
+           || !vrrp_ifp_has_vrrp_mac(mvl_ifp)) {
+               if (mvl_ifp && mvl_ifp->link_ifindex == 0)
+                       DEBUGD(&vrrp_dbg_zebra,
+                              VRRP_LOGPFX
+                              "Interface %s has no parent ifindex; disregarding",
+                              mvl_ifp->name);
+               if (mvl_ifp && !vrrp_ifp_has_vrrp_mac(mvl_ifp))
+                       DEBUGD(&vrrp_dbg_zebra,
+                              VRRP_LOGPFX
+                              "Interface %s has a non-VRRP MAC; disregarding",
+                              mvl_ifp->name);
                return NULL;
+       }
 
        p = if_lookup_by_index(mvl_ifp->link_ifindex, VRF_DEFAULT);
        uint8_t vrid = mvl_ifp->hw_addr[5];
@@ -278,27 +289,30 @@ void vrrp_check_start(struct vrrp_vrouter *vr)
        r = vr->v4;
        /* Must not already be started */
        start = r->fsm.state == VRRP_STATE_INITIALIZE;
+       whynot = (!start && !whynot) ? "Already running" : whynot;
        /* Must have a parent interface */
        start = start && (vr->ifp != NULL);
-       whynot = (!start && !whynot) ? "No base interface" : NULL;
+       whynot = (!start && !whynot) ? "No base interface" : whynot;
 #if 0
        /* Parent interface must be up */
        start = start && if_is_operative(vr->ifp);
+       start = (!start && !whynot) ? "Base interface inoperative" : whynot;
 #endif
        /* Parent interface must have at least one v4 */
-       start = start && vr->ifp->connected->count > 1;
-       whynot = (!start && !whynot) ? "No primary IPv4 address" : NULL;
+       start = start && connected_count_by_family(vr->ifp, AF_INET) > 0;
+       whynot = (!start && !whynot) ? "No primary IPv4 address" : whynot;
        /* Must have a macvlan interface */
        start = start && (r->mvl_ifp != NULL);
-       whynot = (!start && !whynot) ? "No VRRP interface" : NULL;
+       whynot = (!start && !whynot) ? "No VRRP interface" : whynot;
 #if 0
        /* Macvlan interface must be admin up */
        start = start && CHECK_FLAG(r->mvl_ifp->flags, IFF_UP);
+       start = (!start && !whynot) ? "Macvlan device admin down" : whynot;
 #endif
        /* Must have at least one VIP configured */
        start = start && r->addrs->count > 0;
-       whynot =
-               (!start && !whynot) ? "No Virtual IP address configured" : NULL;
+       whynot = (!start && !whynot) ? "No Virtual IP address configured"
+                                    : whynot;
        if (start)
                vrrp_event(r, VRRP_EVENT_STARTUP);
        else if (whynot)
@@ -306,39 +320,44 @@ void vrrp_check_start(struct vrrp_vrouter *vr)
                          "Refusing to start Virtual Router: %s",
                          vr->vrid, family2str(r->family), whynot);
 
+       whynot = NULL;
+
        r = vr->v6;
        /* Must not already be started */
        start = r->fsm.state == VRRP_STATE_INITIALIZE;
+       whynot = (!start && !whynot) ? "Already running" : whynot;
        /* Must not be v2 */
        start = start && vr->version != 2;
-       whynot = (!start && !whynot) ? "VRRPv2 does not support v6" : NULL;
+       whynot = (!start && !whynot) ? "VRRPv2 does not support v6" : whynot;
        /* Must have a parent interface */
        start = start && (vr->ifp != NULL);
-       whynot = (!start && !whynot) ? "No base interface" : NULL;
+       whynot = (!start && !whynot) ? "No base interface" : whynot;
 #if 0
        /* Parent interface must be up */
        start = start && if_is_operative(vr->ifp);
+       start = (!start && !whynot) ? "Base interface inoperative" : whynot;
 #endif
        /* Must have a macvlan interface */
        start = start && (r->mvl_ifp != NULL);
-       whynot = (!start && !whynot) ? "No VRRP interface" : NULL;
+       whynot = (!start && !whynot) ? "No VRRP interface" : whynot;
 #if 0
        /* Macvlan interface must be admin up */
        start = start && CHECK_FLAG(r->mvl_ifp->flags, IFF_UP);
+       start = (!start && !whynot) ? "Macvlan device admin down" : whynot;
        /* Macvlan interface must have a link local */
        start = start && connected_get_linklocal(r->mvl_ifp);
        whynot =
-               (!start && !whynot) ? "No link local address configured" : NULL;
+               (!start && !whynot) ? "No link local address configured" : whynot;
        /* Macvlan interface must have a v6 IP besides the link local */
-       start = start && (r->mvl_ifp->connected->count >= 2);
+       start = start && (connected_count_by_family(r->mvl_ifp, AF_INET6) > 1);
        whynot = (!start && !whynot)
-                        ? "No Virtual IP configured on macvlan device"
-                        : NULL;
+                        ? "No Virtual IPv6 address configured on macvlan device"
+                        : whynot;
 #endif
        /* Must have at least one VIP configured */
        start = start && r->addrs->count > 0;
        whynot =
-               (!start && !whynot) ? "No Virtual IP address configured" : NULL;
+               (!start && !whynot) ? "No Virtual IP address configured" : whynot;
        if (start)
                vrrp_event(r, VRRP_EVENT_STARTUP);
        else if (whynot)
@@ -882,7 +901,7 @@ static int vrrp_recv_advertisement(struct vrrp_router *r, struct ipaddr *src,
                        THREAD_OFF(r->t_adver_timer);
                        thread_add_timer_msec(
                                master, vrrp_adver_timer_expire, r,
-                               r->vr->advertisement_interval * 10,
+                               r->vr->advertisement_interval * CS2MS,
                                &r->t_adver_timer);
                } else if (pkt->hdr.priority > r->priority
                           || ((pkt->hdr.priority == r->priority)
@@ -902,7 +921,7 @@ static int vrrp_recv_advertisement(struct vrrp_router *r, struct ipaddr *src,
                        THREAD_OFF(r->t_master_down_timer);
                        thread_add_timer_msec(master,
                                              vrrp_master_down_timer_expire, r,
-                                             r->master_down_interval * 10,
+                                             r->master_down_interval * CS2MS,
                                              &r->t_master_down_timer);
                        vrrp_change_state(r, VRRP_STATE_BACKUP);
                } else {
@@ -920,7 +939,7 @@ static int vrrp_recv_advertisement(struct vrrp_router *r, struct ipaddr *src,
                        THREAD_OFF(r->t_master_down_timer);
                        thread_add_timer_msec(
                                master, vrrp_master_down_timer_expire, r,
-                               r->skew_time * 10, &r->t_master_down_timer);
+                               r->skew_time * CS2MS, &r->t_master_down_timer);
                } else if (r->vr->preempt_mode == false
                           || pkt->hdr.priority >= r->priority) {
                        if (r->vr->version == 3) {
@@ -931,7 +950,7 @@ static int vrrp_recv_advertisement(struct vrrp_router *r, struct ipaddr *src,
                        THREAD_OFF(r->t_master_down_timer);
                        thread_add_timer_msec(master,
                                              vrrp_master_down_timer_expire, r,
-                                             r->master_down_interval * 10,
+                                             r->master_down_interval * CS2MS,
                                              &r->t_master_down_timer);
                } else if (r->vr->preempt_mode == true
                           && pkt->hdr.priority < r->priority) {
@@ -1054,8 +1073,7 @@ static int vrrp_socket(struct vrrp_router *r)
        int ret;
        bool failed = false;
 
-       frr_elevate_privs(&vrrp_privs)
-       {
+       frr_with_privs(&vrrp_privs) {
                r->sock_rx = socket(r->family, SOCK_RAW, IPPROTO_VRRP);
                r->sock_tx = socket(r->family, SOCK_RAW, IPPROTO_VRRP);
        }
@@ -1091,8 +1109,7 @@ static int vrrp_socket(struct vrrp_router *r)
                setsockopt_ipv4_multicast_loop(r->sock_tx, 0);
 
                /* Bind Rx socket to exact interface */
-               frr_elevate_privs(&vrrp_privs)
-               {
+               frr_with_privs(&vrrp_privs) {
                        ret = setsockopt(r->sock_rx, SOL_SOCKET,
                                         SO_BINDTODEVICE, r->vr->ifp->name,
                                         strlen(r->vr->ifp->name));
@@ -1202,8 +1219,7 @@ static int vrrp_socket(struct vrrp_router *r)
                setsockopt_ipv6_multicast_loop(r->sock_tx, 0);
 
                /* Bind Rx socket to exact interface */
-               frr_elevate_privs(&vrrp_privs)
-               {
+               frr_with_privs(&vrrp_privs) {
                        ret = setsockopt(r->sock_rx, SOL_SOCKET,
                                         SO_BINDTODEVICE, r->vr->ifp->name,
                                         strlen(r->vr->ifp->name));
@@ -1448,7 +1464,7 @@ static int vrrp_adver_timer_expire(struct thread *thread)
 
                /* Reset the Adver_Timer to Advertisement_Interval */
                thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
-                                     r->vr->advertisement_interval * 10,
+                                     r->vr->advertisement_interval * CS2MS,
                                      &r->t_adver_timer);
        } else {
                zlog_err(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
@@ -1472,7 +1488,7 @@ static int vrrp_master_down_timer_expire(struct thread *thread)
                  r->vr->vrid, family2str(r->family));
 
        thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
-                             r->vr->advertisement_interval * 10,
+                             r->vr->advertisement_interval * CS2MS,
                              &r->t_adver_timer);
        vrrp_change_state(r, VRRP_STATE_MASTER);
 
@@ -1548,14 +1564,14 @@ static int vrrp_startup(struct vrrp_router *r)
 
        if (r->priority == VRRP_PRIO_MASTER) {
                thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
-                                     r->vr->advertisement_interval * 10,
+                                     r->vr->advertisement_interval * CS2MS,
                                      &r->t_adver_timer);
                vrrp_change_state(r, VRRP_STATE_MASTER);
        } else {
                r->master_adver_interval = r->vr->advertisement_interval;
                vrrp_recalculate_timers(r);
                thread_add_timer_msec(master, vrrp_master_down_timer_expire, r,
-                                     r->master_down_interval * 10,
+                                     r->master_down_interval * CS2MS,
                                      &r->t_master_down_timer);
                vrrp_change_state(r, VRRP_STATE_BACKUP);
        }
@@ -2028,9 +2044,19 @@ static void vrrp_bind_pending(struct interface *mvl_ifp)
 {
        struct vrrp_vrouter *vr;
 
+       DEBUGD(&vrrp_dbg_zebra,
+              VRRP_LOGPFX
+              "Searching for instances that could use interface %s",
+              mvl_ifp->name);
+
        vr = vrrp_lookup_by_if_mvl(mvl_ifp);
 
        if (vr) {
+               DEBUGD(&vrrp_dbg_zebra,
+                      VRRP_LOGPFX VRRP_LOGPFX_VRID
+                      "<-- This instance can probably use interface %s",
+                      vr->vrid, mvl_ifp->name);
+
                if (mvl_ifp->hw_addr[4] == 0x01 && !vr->v4->mvl_ifp)
                        vrrp_attach_interface(vr->v4);
                else if (mvl_ifp->hw_addr[4] == 0x02 && !vr->v6->mvl_ifp)
@@ -2112,9 +2138,13 @@ void vrrp_if_down(struct interface *ifp)
        struct listnode *ln;
        struct list *vrs;
 
+       vrrp_bind_pending(ifp);
+
        vrs = vrrp_lookup_by_if_any(ifp);
 
        for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr)) {
+               vrrp_check_start(vr);
+
                if (vr->ifp == ifp || vr->v4->mvl_ifp == ifp
                    || vr->v6->mvl_ifp == ifp) {
                        DEBUGD(&vrrp_dbg_auto,