]> git.proxmox.com Git - mirror_frr.git/blobdiff - bfdd/ptm_adapter.c
Merge pull request #3095 from pacovn/Coverity_1473199_1472624_dead_code
[mirror_frr.git] / bfdd / ptm_adapter.c
index 28e332626473ff26ad9bda88f3a558e94e0cd1e2..a5fae3383cd7248ba0994f318e2e877dd90f283f 100644 (file)
@@ -63,6 +63,8 @@ static int _ptm_msg_read(struct stream *msg, int command,
 
 static struct ptm_client *pc_lookup(uint32_t pid);
 static struct ptm_client *pc_new(uint32_t pid);
+static void pc_free(struct ptm_client *pc);
+static void pc_free_all(void);
 static struct ptm_client_notification *pcn_new(struct ptm_client *pc,
                                               struct bfd_session *bs);
 static struct ptm_client_notification *pcn_lookup(struct ptm_client *pc,
@@ -73,6 +75,7 @@ static void pcn_free(struct ptm_client_notification *pcn);
 static void bfdd_dest_register(struct stream *msg);
 static void bfdd_dest_deregister(struct stream *msg);
 static void bfdd_client_register(struct stream *msg);
+static void bfdd_client_deregister(struct stream *msg);
 
 /*
  * Functions
@@ -152,6 +155,8 @@ int ptm_bfd_notify(struct bfd_session *bs)
        struct stream *msg;
        struct sockaddr_any sac;
 
+       bs->stats.znotification++;
+
        /*
         * Message format:
         * - header: command, vrf
@@ -271,7 +276,7 @@ static void _ptm_msg_read_address(struct stream *msg, struct sockaddr_any *sa)
                return;
 
        default:
-               log_warning("%s: invalid family: %d", __func__, family);
+               log_warning("ptm-read-address: invalid family: %d", family);
                break;
        }
 
@@ -283,8 +288,8 @@ static int _ptm_msg_read(struct stream *msg, int command,
                         struct bfd_peer_cfg *bpc, struct ptm_client **pc)
 {
        uint32_t pid;
-       uint8_t ttl;
-       uint8_t ifnamelen;
+       uint8_t ttl __attribute__((unused));
+       size_t ifnamelen;
 
        /*
         * Register/Deregister/Update Message format:
@@ -326,7 +331,7 @@ static int _ptm_msg_read(struct stream *msg, int command,
 
        *pc = pc_new(pid);
        if (*pc == NULL) {
-               log_debug("%s: failed to allocate memory", __func__);
+               log_debug("ptm-read: failed to allocate memory");
                return -1;
        }
 
@@ -357,12 +362,6 @@ static int _ptm_msg_read(struct stream *msg, int command,
                /* Read multihop source address and TTL. */
                _ptm_msg_read_address(msg, &bpc->bpc_local);
                STREAM_GETC(msg, ttl);
-
-               /*
-                * TODO: use TTL for something. The line below removes
-                * an unused variable compiler warning.
-                */
-               ttl = ttl;
        } else {
                /* If target is IPv6, then we must obtain local address. */
                if (bpc->bpc_ipv4 == false)
@@ -373,8 +372,8 @@ static int _ptm_msg_read(struct stream *msg, int command,
                 * structure, otherwise fail.
                 */
                STREAM_GETC(msg, ifnamelen);
-               if (ifnamelen > sizeof(bpc->bpc_localif)) {
-                       log_error("%s: interface name is too big", __func__);
+               if (ifnamelen >= sizeof(bpc->bpc_localif)) {
+                       log_error("ptm-read: interface name is too big");
                        return -1;
                }
 
@@ -389,8 +388,7 @@ static int _ptm_msg_read(struct stream *msg, int command,
        if (bpc->bpc_local.sa_sin.sin_family != 0
            && (bpc->bpc_local.sa_sin.sin_family
                != bpc->bpc_peer.sa_sin.sin_family)) {
-               log_warning("%s: peer family doesn't match local type",
-                           __func__);
+               log_warning("ptm-read: peer family doesn't match local type");
                return -1;
        }
 
@@ -418,7 +416,7 @@ static void bfdd_dest_register(struct stream *msg)
        if (bs == NULL) {
                bs = ptm_bfd_sess_new(&bpc);
                if (bs == NULL) {
-                       log_debug("%s: failed to create BFD session", __func__);
+                       log_debug("ptm-add-dest: failed to create BFD session");
                        return;
                }
        } else {
@@ -431,7 +429,7 @@ static void bfdd_dest_register(struct stream *msg)
        /* Create client peer notification register. */
        pcn = pcn_new(pc, bs);
        if (pcn == NULL) {
-               log_error("%s: failed to registrate notifications", __func__);
+               log_error("ptm-add-dest: failed to registrate notifications");
                return;
        }
 
@@ -454,7 +452,7 @@ static void bfdd_dest_deregister(struct stream *msg)
        /* Find or start new BFD session. */
        bs = bs_peer_find(&bpc);
        if (bs == NULL) {
-               log_debug("%s: failed to create BFD session", __func__);
+               log_debug("ptm-del-dest: failed to find BFD session");
                return;
        }
 
@@ -477,14 +475,40 @@ static void bfdd_client_register(struct stream *msg)
 
        pc = pc_new(pid);
        if (pc == NULL) {
-               log_error("%s: failed to register client: %u", __func__, pid);
+               log_error("ptm-add-client: failed to register client: %u", pid);
+               return;
+       }
+
+       return;
+
+stream_failure:
+       log_error("ptm-add-client: failed to register client");
+}
+
+/*
+ * header: command, VRF
+ * l: pid
+ */
+static void bfdd_client_deregister(struct stream *msg)
+{
+       struct ptm_client *pc;
+       uint32_t pid;
+
+       /* Find or allocate process context data. */
+       STREAM_GETL(msg, pid);
+
+       pc = pc_lookup(pid);
+       if (pc == NULL) {
+               log_debug("ptm-del-client: failed to find client: %u", pid);
                return;
        }
 
+       pc_free(pc);
+
        return;
 
 stream_failure:
-       log_error("%s: failed to register client", __func__);
+       log_error("ptm-del-client: failed to deregister client");
 }
 
 static int bfdd_replay(int cmd, struct zclient *zc, uint16_t len, vrf_id_t vid)
@@ -505,16 +529,19 @@ static int bfdd_replay(int cmd, struct zclient *zc, uint16_t len, vrf_id_t vid)
        case ZEBRA_BFD_CLIENT_REGISTER:
                bfdd_client_register(msg);
                break;
+       case ZEBRA_BFD_CLIENT_DEREGISTER:
+               bfdd_client_deregister(msg);
+               break;
 
        default:
-               log_debug("%s: invalid message type %u", __func__, rcmd);
+               log_debug("ptm-replay: invalid message type %u", rcmd);
                return -1;
        }
 
        return 0;
 
 stream_failure:
-       log_error("%s: failed to find command", __func__);
+       log_error("ptm-replay: failed to find command");
        return -1;
 }
 
@@ -522,6 +549,9 @@ static void bfdd_zebra_connected(struct zclient *zc)
 {
        struct stream *msg = zc->obuf;
 
+       /* Clean-up and free ptm clients data memory. */
+       pc_free_all();
+
        /*
         * The replay is an empty message just to trigger client daemons
         * configuration replay.
@@ -554,6 +584,9 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
 void bfdd_zclient_stop(void)
 {
        zclient_stop(zclient);
+
+       /* Clean-up and free ptm clients data memory. */
+       pc_free_all();
 }
 
 
@@ -593,6 +626,33 @@ static struct ptm_client *pc_new(uint32_t pid)
        return pc;
 }
 
+static void pc_free(struct ptm_client *pc)
+{
+       struct ptm_client_notification *pcn;
+
+       if (pc == NULL)
+               return;
+
+       TAILQ_REMOVE(&pcqueue, pc, pc_entry);
+
+       while (!TAILQ_EMPTY(&pc->pc_pcnqueue)) {
+               pcn = TAILQ_FIRST(&pc->pc_pcnqueue);
+               pcn_free(pcn);
+       }
+
+       XFREE(MTYPE_BFDD_CONTROL, pc);
+}
+
+static void pc_free_all(void)
+{
+       struct ptm_client *pc;
+
+       while (!TAILQ_EMPTY(&pcqueue)) {
+               pc = TAILQ_FIRST(&pcqueue);
+               pc_free(pc);
+       }
+}
+
 static struct ptm_client_notification *pcn_new(struct ptm_client *pc,
                                               struct bfd_session *bs)
 {