]> git.proxmox.com Git - mirror_frr.git/blobdiff - bfdd/bfd.c
Merge pull request #11502 from donaldsharp/zebra_dplane_fini
[mirror_frr.git] / bfdd / bfd.c
index c9a327490caa4aa24812d1e3f076353460072911..483beb1b17ceeca46dbd06f065e6f807f98c78c2 100644 (file)
@@ -51,8 +51,6 @@ static void bs_admin_down_handler(struct bfd_session *bs, int nstate);
 static void bs_down_handler(struct bfd_session *bs, int nstate);
 static void bs_init_handler(struct bfd_session *bs, int nstate);
 static void bs_up_handler(struct bfd_session *bs, int nstate);
-static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
-                                           uint8_t diag);
 
 /**
  * Remove BFD profile from all BFD sessions so we don't leave dangling
@@ -456,7 +454,17 @@ void ptm_bfd_start_xmt_timer(struct bfd_session *bfd, bool is_echo)
 static void ptm_bfd_echo_xmt_TO(struct bfd_session *bfd)
 {
        /* Send the scheduled echo  packet */
-       ptm_bfd_echo_snd(bfd);
+       /* if ipv4 use the new echo implementation that causes
+        * the packet to be looped in forwarding plane of peer
+        */
+       if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6) == 0)
+#ifdef BFD_LINUX
+               ptm_bfd_echo_fp_snd(bfd);
+#else
+               ptm_bfd_echo_snd(bfd);
+#endif
+       else
+               ptm_bfd_echo_snd(bfd);
 
        /* Restart the timer for next time */
        ptm_bfd_start_xmt_timer(bfd, true);
@@ -560,6 +568,12 @@ void ptm_bfd_sess_dn(struct bfd_session *bfd, uint8_t diag)
                                   state_list[bfd->ses_state].str,
                                   get_diag_str(bfd->local_diag));
        }
+
+       /* clear peer's mac address */
+       UNSET_FLAG(bfd->flags, BFD_SESS_FLAG_MAC_SET);
+       memset(bfd->peer_hw_addr, 0, sizeof(bfd->peer_hw_addr));
+       /* reset local address ,it might has been be changed after bfd is up*/
+       memset(&bfd->local_address, 0, sizeof(bfd->local_address));
 }
 
 static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa,
@@ -611,27 +625,23 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp,
        return bfd_key_lookup(key);
 }
 
-int bfd_xmt_cb(struct thread *t)
+void bfd_xmt_cb(struct thread *t)
 {
        struct bfd_session *bs = THREAD_ARG(t);
 
        ptm_bfd_xmt_TO(bs, 0);
-
-       return 0;
 }
 
-int bfd_echo_xmt_cb(struct thread *t)
+void bfd_echo_xmt_cb(struct thread *t)
 {
        struct bfd_session *bs = THREAD_ARG(t);
 
        if (bs->echo_xmt_TO > 0)
                ptm_bfd_echo_xmt_TO(bs);
-
-       return 0;
 }
 
 /* Was ptm_bfd_detect_TO() */
-int bfd_recvtimer_cb(struct thread *t)
+void bfd_recvtimer_cb(struct thread *t)
 {
        struct bfd_session *bs = THREAD_ARG(t);
 
@@ -641,12 +651,10 @@ int bfd_recvtimer_cb(struct thread *t)
                ptm_bfd_sess_dn(bs, BD_CONTROL_EXPIRED);
                break;
        }
-
-       return 0;
 }
 
 /* Was ptm_bfd_echo_detect_TO() */
-int bfd_echo_recvtimer_cb(struct thread *t)
+void bfd_echo_recvtimer_cb(struct thread *t)
 {
        struct bfd_session *bs = THREAD_ARG(t);
 
@@ -656,8 +664,6 @@ int bfd_echo_recvtimer_cb(struct thread *t)
                ptm_bfd_sess_dn(bs, BD_ECHO_FAILED);
                break;
        }
-
-       return 0;
 }
 
 struct bfd_session *bfd_session_new(void)
@@ -779,7 +785,7 @@ static void _bfd_session_update(struct bfd_session *bs,
         * Apply profile last: it also calls `bfd_set_shutdown`.
         *
         * There is no problem calling `shutdown` twice if the value doesn't
-        * change or if it is overriden by peer specific configuration.
+        * change or if it is overridden by peer specific configuration.
         */
        if (bpc->bpc_has_profile)
                bfd_profile_apply(bpc->bpc_profile, bs);
@@ -997,9 +1003,18 @@ static void bs_down_handler(struct bfd_session *bs, int nstate)
                 */
                bs->ses_state = PTM_BFD_INIT;
 
-               /* Answer peer with INIT immediately in passive mode. */
+               /*
+                * RFC 5880, Section 6.1.
+                * A system taking the Passive role MUST NOT begin
+                * sending BFD packets for a particular session until
+                * it has received a BFD packet for that session, and thus
+                * has learned the remote system's discriminator value.
+                *
+                * Now we can start transmission timer in passive mode.
+                */
                if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_PASSIVE))
-                       ptm_bfd_snd(bs, 0);
+                       ptm_bfd_xmt_TO(bs, 0);
+
                break;
 
        case PTM_BFD_INIT:
@@ -1026,7 +1041,7 @@ static void bs_init_handler(struct bfd_session *bs, int nstate)
                 * Remote peer doesn't want to talk, so lets make the
                 * connection down.
                 */
-               bs->ses_state = PTM_BFD_DOWN;
+               ptm_bfd_sess_dn(bs, BD_NEIGHBOR_DOWN);
                break;
 
        case PTM_BFD_DOWN:
@@ -1047,46 +1062,10 @@ static void bs_init_handler(struct bfd_session *bs, int nstate)
        }
 }
 
-static void bs_neighbour_admin_down_handler(struct bfd_session *bfd,
-                                           uint8_t diag)
-{
-       int old_state = bfd->ses_state;
-
-       bfd->local_diag = diag;
-       bfd->discrs.remote_discr = 0;
-       bfd->ses_state = PTM_BFD_DOWN;
-       bfd->polling = 0;
-       bfd->demand_mode = 0;
-       monotime(&bfd->downtime);
-
-       /* Slow down the control packets, the connection is down. */
-       bs_set_slow_timers(bfd);
-
-       /* only signal clients when going from up->down state */
-       if (old_state == PTM_BFD_UP)
-               control_notify(bfd, PTM_BFD_ADM_DOWN);
-
-       /* Stop echo packet transmission if they are active */
-       if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE))
-               ptm_bfd_echo_stop(bfd);
-
-       if (old_state != bfd->ses_state) {
-               bfd->stats.session_down++;
-               if (bglobal.debug_peer_event)
-                       zlog_debug("state-change: [%s] %s -> %s reason:%s",
-                                  bs_to_string(bfd), state_list[old_state].str,
-                                  state_list[bfd->ses_state].str,
-                                  get_diag_str(bfd->local_diag));
-       }
-}
-
 static void bs_up_handler(struct bfd_session *bs, int nstate)
 {
        switch (nstate) {
        case PTM_BFD_ADM_DOWN:
-               bs_neighbour_admin_down_handler(bs, BD_ADMIN_DOWN);
-               break;
-
        case PTM_BFD_DOWN:
                /* Peer lost or asked to shutdown connection. */
                ptm_bfd_sess_dn(bs, BD_NEIGHBOR_DOWN);
@@ -1453,7 +1432,7 @@ int strtosa(const char *addr, struct sockaddr_any *sa)
 
 void integer2timestr(uint64_t time, char *buf, size_t buflen)
 {
-       unsigned int year, month, day, hour, minute, second;
+       uint64_t year, month, day, hour, minute, second;
        int rv;
 
 #define MINUTES (60)
@@ -1465,7 +1444,7 @@ void integer2timestr(uint64_t time, char *buf, size_t buflen)
                year = time / YEARS;
                time -= year * YEARS;
 
-               rv = snprintf(buf, buflen, "%u year(s), ", year);
+               rv = snprintfrr(buf, buflen, "%" PRIu64 " year(s), ", year);
                buf += rv;
                buflen -= rv;
        }
@@ -1473,7 +1452,7 @@ void integer2timestr(uint64_t time, char *buf, size_t buflen)
                month = time / MONTHS;
                time -= month * MONTHS;
 
-               rv = snprintf(buf, buflen, "%u month(s), ", month);
+               rv = snprintfrr(buf, buflen, "%" PRIu64 " month(s), ", month);
                buf += rv;
                buflen -= rv;
        }
@@ -1481,7 +1460,7 @@ void integer2timestr(uint64_t time, char *buf, size_t buflen)
                day = time / DAYS;
                time -= day * DAYS;
 
-               rv = snprintf(buf, buflen, "%u day(s), ", day);
+               rv = snprintfrr(buf, buflen, "%" PRIu64 " day(s), ", day);
                buf += rv;
                buflen -= rv;
        }
@@ -1489,7 +1468,7 @@ void integer2timestr(uint64_t time, char *buf, size_t buflen)
                hour = time / HOURS;
                time -= hour * HOURS;
 
-               rv = snprintf(buf, buflen, "%u hour(s), ", hour);
+               rv = snprintfrr(buf, buflen, "%" PRIu64 " hour(s), ", hour);
                buf += rv;
                buflen -= rv;
        }
@@ -1497,12 +1476,12 @@ void integer2timestr(uint64_t time, char *buf, size_t buflen)
                minute = time / MINUTES;
                time -= minute * MINUTES;
 
-               rv = snprintf(buf, buflen, "%u minute(s), ", minute);
+               rv = snprintfrr(buf, buflen, "%" PRIu64 " minute(s), ", minute);
                buf += rv;
                buflen -= rv;
        }
        second = time % MINUTES;
-       snprintf(buf, buflen, "%u second(s)", second);
+       snprintfrr(buf, buflen, "%" PRIu64 " second(s)", second);
 }
 
 const char *bs_to_string(const struct bfd_session *bs)