]> 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 5ca109eef7bc2afbd568c846150c27b49f24974a..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);
 
@@ -639,22 +649,12 @@ int bfd_recvtimer_cb(struct thread *t)
        case PTM_BFD_INIT:
        case PTM_BFD_UP:
                ptm_bfd_sess_dn(bs, BD_CONTROL_EXPIRED);
-               bfd_recvtimer_update(bs);
-               break;
-
-       default:
-               /* Second detect time expiration, zero remote discr (section
-                * 6.5.1)
-                */
-               bs->discrs.remote_discr = 0;
                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);
 
@@ -664,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)
@@ -787,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);
@@ -1005,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:
@@ -1034,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:
@@ -1055,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);
@@ -1461,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)
@@ -1473,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;
        }
@@ -1481,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;
        }
@@ -1489,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;
        }
@@ -1497,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;
        }
@@ -1505,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)
@@ -1954,19 +1925,6 @@ static int bfd_vrf_delete(struct vrf *vrf)
        return 0;
 }
 
-static int bfd_vrf_update(struct vrf *vrf)
-{
-       if (!vrf_is_enabled(vrf))
-               return 0;
-
-       if (bglobal.debug_zebra)
-               zlog_debug("VRF update: %s(%u)", vrf->name, vrf->vrf_id);
-
-       /* a different name is given; update bfd list */
-       bfdd_sessions_enable_vrf(vrf);
-       return 0;
-}
-
 static int bfd_vrf_enable(struct vrf *vrf)
 {
        struct bfd_vrf_global *bvrf;
@@ -2078,8 +2036,7 @@ static int bfd_vrf_disable(struct vrf *vrf)
 
 void bfd_vrf_init(void)
 {
-       vrf_init(bfd_vrf_new, bfd_vrf_enable, bfd_vrf_disable,
-                bfd_vrf_delete, bfd_vrf_update);
+       vrf_init(bfd_vrf_new, bfd_vrf_enable, bfd_vrf_disable, bfd_vrf_delete);
 }
 
 void bfd_vrf_terminate(void)
@@ -2104,63 +2061,6 @@ struct bfd_vrf_global *bfd_vrf_look_by_session(struct bfd_session *bfd)
        return bfd->vrf->info;
 }
 
-void bfd_session_update_vrf_name(struct bfd_session *bs, struct vrf *vrf)
-{
-       if (!vrf || !bs)
-               return;
-       /* update key */
-       hash_release(bfd_key_hash, bs);
-       /*
-        * HACK: Change the BFD VRF in the running configuration directly,
-        * bypassing the northbound layer. This is necessary to avoid deleting
-        * the BFD and readding it in the new VRF, which would have
-        * several implications.
-        */
-       if (yang_module_find("frr-bfdd") && bs->key.vrfname[0]) {
-               struct lyd_node *bfd_dnode;
-               char xpath[XPATH_MAXLEN], xpath_srcaddr[XPATH_MAXLEN + 32];
-               char oldpath[XPATH_MAXLEN], newpath[XPATH_MAXLEN];
-               char addr_buf[INET6_ADDRSTRLEN];
-               int slen;
-
-               /* build xpath */
-               if (bs->key.mhop) {
-                       inet_ntop(bs->key.family, &bs->key.local, addr_buf, sizeof(addr_buf));
-                       snprintf(xpath_srcaddr, sizeof(xpath_srcaddr), "[source-addr='%s']",
-                                addr_buf);
-               } else
-                       xpath_srcaddr[0] = 0;
-               inet_ntop(bs->key.family, &bs->key.peer, addr_buf, sizeof(addr_buf));
-               slen = snprintf(xpath, sizeof(xpath),
-                               "/frr-bfdd:bfdd/bfd/sessions/%s%s[dest-addr='%s']",
-                               bs->key.mhop ? "multi-hop" : "single-hop", xpath_srcaddr,
-                               addr_buf);
-               if (bs->key.ifname[0])
-                       slen += snprintf(xpath + slen, sizeof(xpath) - slen,
-                                        "[interface='%s']", bs->key.ifname);
-               else
-                       slen += snprintf(xpath + slen, sizeof(xpath) - slen,
-                                        "[interface='*']");
-               snprintf(xpath + slen, sizeof(xpath) - slen, "[vrf='%s']/vrf",
-                        bs->key.vrfname);
-
-               bfd_dnode = yang_dnode_getf(running_config->dnode, xpath,
-                                           bs->key.vrfname);
-               if (bfd_dnode) {
-                       yang_dnode_get_path(lyd_parent(bfd_dnode), oldpath,
-                                           sizeof(oldpath));
-                       yang_dnode_change_leaf(bfd_dnode, vrf->name);
-                       yang_dnode_get_path(lyd_parent(bfd_dnode), newpath,
-                                           sizeof(newpath));
-                       nb_running_move_tree(oldpath, newpath);
-                       running_config->version++;
-               }
-       }
-       memset(bs->key.vrfname, 0, sizeof(bs->key.vrfname));
-       strlcpy(bs->key.vrfname, vrf->name, sizeof(bs->key.vrfname));
-       hash_get(bfd_key_hash, bs, hash_alloc_intern);
-}
-
 unsigned long bfd_get_session_count(void)
 {
        return bfd_key_hash->count;