]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/bfd.c
Merge pull request #8459 from taspelund/no_rmac_on_mac_only
[mirror_frr.git] / lib / bfd.c
index d22a9150d19fc80967b8b66f897c6797ab8547cf..0974c268096d4bd1fe9896d169d901312125b1e1 100644 (file)
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -619,8 +619,6 @@ struct bfd_session_params {
 
        /** BFD session installation state. */
        bool installed;
-       /** BFD session enabled. */
-       bool enabled;
 
        /** Global BFD paramaters list. */
        TAILQ_ENTRY(bfd_session_params) entry;
@@ -748,6 +746,21 @@ static int _bfd_sess_send(struct thread *t)
                        bsp->installed = false;
                else if (bsp->args.command == ZEBRA_BFD_DEST_REGISTER)
                        bsp->installed = true;
+       } else {
+               struct ipaddr src, dst;
+
+               src.ipa_type = bsp->args.family;
+               src.ipaddr_v6 = bsp->args.src;
+               dst.ipa_type = bsp->args.family;
+               dst.ipaddr_v6 = bsp->args.dst;
+
+               zlog_err(
+                       "%s: BFD session %pIA -> %pIA interface %s VRF %s(%u) was not %s",
+                       __func__, &src, &dst,
+                       bsp->args.ifnamelen ? bsp->args.ifname : "*",
+                       vrf_id_to_name(bsp->args.vrf_id), bsp->args.vrf_id,
+                       bsp->lastev == BSE_INSTALL ? "installed"
+                                                  : "uninstalled");
        }
 
        return 0;
@@ -782,18 +795,33 @@ void bfd_sess_free(struct bfd_session_params **bsp)
        XFREE(MTYPE_BFD_INFO, (*bsp));
 }
 
-void bfd_sess_enable(struct bfd_session_params *bsp, bool enable)
+static bool bfd_sess_address_changed(const struct bfd_session_params *bsp,
+                                    uint32_t family,
+                                    const struct in6_addr *src,
+                                    const struct in6_addr *dst)
 {
-       /* Remove the session when disabling. */
-       if (!enable)
-               _bfd_sess_remove(bsp);
+       size_t addrlen;
+
+       if (bsp->args.family != family)
+               return true;
 
-       bsp->enabled = enable;
+       addrlen = (family == AF_INET) ? sizeof(struct in_addr)
+                                     : sizeof(struct in6_addr);
+       if ((src == NULL && memcmp(&bsp->args.src, &i6a_zero, addrlen))
+           || (src && memcmp(src, &bsp->args.src, addrlen))
+           || memcmp(dst, &bsp->args.dst, addrlen))
+               return true;
+
+       return false;
 }
 
 void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp,
                             struct in_addr *src, struct in_addr *dst)
 {
+       if (!bfd_sess_address_changed(bsp, AF_INET, (struct in6_addr *)src,
+                                     (struct in6_addr *)dst))
+               return;
+
        /* If already installed, remove the old setting. */
        _bfd_sess_remove(bsp);
 
@@ -814,6 +842,10 @@ void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp,
 void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp,
                             struct in6_addr *src, struct in6_addr *dst)
 {
+       if (!bfd_sess_address_changed(bsp, AF_INET, (struct in6_addr *)src,
+                                     (struct in6_addr *)dst))
+               return;
+
        /* If already installed, remove the old setting. */
        _bfd_sess_remove(bsp);
 
@@ -831,6 +863,10 @@ void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp,
 
 void bfd_sess_set_interface(struct bfd_session_params *bsp, const char *ifname)
 {
+       if ((ifname == NULL && bsp->args.ifnamelen == 0)
+           || (ifname && strcmp(bsp->args.ifname, ifname) == 0))
+               return;
+
        /* If already installed, remove the old setting. */
        _bfd_sess_remove(bsp);
 
@@ -864,6 +900,9 @@ void bfd_sess_set_profile(struct bfd_session_params *bsp, const char *profile)
 
 void bfd_sess_set_vrf(struct bfd_session_params *bsp, vrf_id_t vrf_id)
 {
+       if (bsp->args.vrf_id == vrf_id)
+               return;
+
        /* If already installed, remove the old setting. */
        _bfd_sess_remove(bsp);
 
@@ -874,6 +913,9 @@ void bfd_sess_set_mininum_ttl(struct bfd_session_params *bsp, uint8_t min_ttl)
 {
        assert(min_ttl != 0);
 
+       if (bsp->args.ttl == ((BFD_SINGLE_HOP_TTL + 1) - min_ttl))
+               return;
+
        /* If already installed, remove the old setting. */
        _bfd_sess_remove(bsp);
 
@@ -885,6 +927,9 @@ void bfd_sess_set_mininum_ttl(struct bfd_session_params *bsp, uint8_t min_ttl)
 
 void bfd_sess_set_hop_count(struct bfd_session_params *bsp, uint8_t min_ttl)
 {
+       if (bsp->args.ttl == min_ttl)
+               return;
+
        /* If already installed, remove the old setting. */
        _bfd_sess_remove(bsp);
 
@@ -909,10 +954,6 @@ void bfd_sess_set_timers(struct bfd_session_params *bsp,
 
 void bfd_sess_install(struct bfd_session_params *bsp)
 {
-       /* Don't attempt to install/update when disabled. */
-       if (!bsp->enabled)
-               return;
-
        bsp->lastev = BSE_INSTALL;
        thread_add_event(bsglobal.tm, _bfd_sess_send, bsp, 0, &bsp->installev);
 }
@@ -1060,8 +1101,8 @@ static int zclient_bfd_session_reply(ZAPI_CALLBACK_ARGS)
 
        /* Replay all activated peers. */
        TAILQ_FOREACH (bsp, &bsglobal.bsplist, entry) {
-               /* Skip disabled sessions. */
-               if (!bsp->enabled)
+               /* Skip not installed sessions. */
+               if (!bsp->installed)
                        continue;
 
                /* We are reconnecting, so we must send installation. */
@@ -1080,7 +1121,7 @@ static int zclient_bfd_session_reply(ZAPI_CALLBACK_ARGS)
 
 static int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS)
 {
-       struct bfd_session_params *bsp;
+       struct bfd_session_params *bsp, *bspn;
        size_t sessions_updated = 0;
        struct interface *ifp;
        int remote_cbit = false;
@@ -1137,9 +1178,9 @@ static int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS)
        now = monotime(NULL);
 
        /* Notify all matching sessions about update. */
-       TAILQ_FOREACH (bsp, &bsglobal.bsplist, entry) {
-               /* Skip disabled or not installed entries. */
-               if (!bsp->enabled || !bsp->installed)
+       TAILQ_FOREACH_SAFE (bsp, &bsglobal.bsplist, entry, bspn) {
+               /* Skip not installed entries. */
+               if (!bsp->installed)
                        continue;
                /* Skip different VRFs. */
                if (bsp->args.vrf_id != vrf_id)