int iccp_mclagsyncd_msg_handler()

in src/iccpd/src/mlacp_link_handler.c [3338:3570]


int iccp_mclagsyncd_msg_handler(struct System *sys)
{
    int num_bytes_rxed = 0;
    char *msg_buf = g_iccp_mlagsyncd_recv_buf;
    struct IccpSyncdHDr * msg_hdr;
    int pos = 0;
    int recv_len = 0;
    int num_retry = 0;
    errno = 0;

    if (sys == NULL)
        return MCLAG_ERROR;
    memset(msg_buf, 0, ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE);

    /* read (max_size - msg_size) so that we have space to
       accomodate anything remaining in the last message */
    num_bytes_rxed = recv(sys->sync_fd, msg_buf,
            ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE - MCLAG_MAX_MSG_LEN, MSG_DONTWAIT );

    if (num_bytes_rxed <= 0)
    {
        // if received count is 0 socket is closed.
        if (num_bytes_rxed == 0)
        {
            ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd read erro:%d ", num_bytes_rxed);
            SYSTEM_INCR_RX_READ_SOCK_ZERO_COUNTER(system_get_instance());
            return MCLAG_ERROR;
        }

        while( num_bytes_rxed < 0 )
        {
            recv_len = recv(sys->sync_fd, msg_buf,
                        ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE - MCLAG_MAX_MSG_LEN, MSG_DONTWAIT );

            if (recv_len == -1)
            {
                if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
                {
                    ICCPD_LOG_NOTICE(
                        "ICCP_FSM", "Recv fom Mclagsyncd Non-blocking recv errno %d, num_retry %d",
                        errno, num_retry);
                    ++num_retry;
                    if (num_retry > SYNCD_RECV_RETRY_MAX)
                    {
                        ICCPD_LOG_NOTICE(
                            "ICCP_FSM", "Recv fom Mclagsyncd retry failed recv_len: %d", recv_len);
                        SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(system_get_instance());
                        return MCLAG_ERROR;
                    }
                    else
                    {
                        usleep(SYNCD_RECV_RETRY_INTERVAL_USEC);
                        recv_len = 0;
                    }
                }
                else
                {
                    ICCPD_LOG_NOTICE("ICCP_FSM", "Recv fom Mclagsyncd retry failed recv_len: %d", recv_len);
                    SYSTEM_INCR_HDR_READ_SOCK_ERR_COUNTER(system_get_instance());
                    return MCLAG_ERROR;
                }
            }
            else if (recv_len == 0)
            {
                ICCPD_LOG_NOTICE("ICCP_FSM", "Recv fom Mclagsyncd error %d connection closed ", recv_len );
                SYSTEM_INCR_HDR_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
                return MCLAG_ERROR;
            }

            num_bytes_rxed += recv_len;
        }
    }

    num_retry = 0;
    while (pos < num_bytes_rxed) //iterate through all msgs
    {
        if ((num_bytes_rxed - pos) < sizeof(struct IccpSyncdHDr))
        {
            int recv_len = 0, len = 0;
            int pending_len = sizeof(struct IccpSyncdHDr) - (num_bytes_rxed - pos);

            ICCPD_LOG_NOTICE(__FUNCTION__, "Recv fom Mclagsync header less than expected, trying to retrieve %d bytes more ", pending_len);

            while (recv_len < pending_len)
            {
                int remaining_len = pending_len-recv_len;
                len = recv(sys->sync_fd, msg_buf+num_bytes_rxed+recv_len, remaining_len, MSG_DONTWAIT);
                if (len <= 0)
                {
                    if (len == 0)
                    {
                        ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsync header less than expected data read error; recv_len:%d pending_len:%d ", recv_len, pending_len);
                        SYSTEM_INCR_HDR_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
                        return MCLAG_ERROR;
                    }

                    if (len == -1)
                    {
                        if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
                        {
                            ICCPD_LOG_NOTICE(
                                "ICCP_FSM", "Recv fom Mclagsync header less than expected Non-blocking recv errno %d, num_retry %d",
                                errno, num_retry);
                            ++num_retry;
                            if (num_retry > SYNCD_RECV_RETRY_MAX)
                            {
                                ICCPD_LOG_ERR(
                                    "ICCP_FSM", "Recv fom Mclagsync header less than expected Non-blocking recv() retry failed, len: %d, errno: %d", len, errno);
                                SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(system_get_instance());
                                return MCLAG_ERROR;
                            }
                            else
                            {
                                usleep(SYNCD_RECV_RETRY_INTERVAL_USEC);
                                len = 0;
                            }
                        }
                        else
                        {
                            ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd header less than expected error; recv_len:%d errno %d",
                                           recv_len, errno);
                            SYSTEM_INCR_HDR_READ_SOCK_ERR_COUNTER(system_get_instance());
                            return MCLAG_ERROR;
                        }
                    }
                }
                ICCPD_LOG_NOTICE("ICCP_FSM", "received %d pending bytes", len);
                recv_len += len;
            }
        }

        msg_hdr = (struct IccpSyncdHDr *)(&msg_buf[pos]);
        ICCPD_LOG_DEBUG(__FUNCTION__, "rcv msg version %d type %d len %d pos:%d num_bytes_rxed:%d ",
                msg_hdr->ver , msg_hdr->type, msg_hdr->len, pos, num_bytes_rxed);

        if (!msg_hdr->len)
        {
            ICCPD_LOG_ERR(__FUNCTION__, "msg length zero!!!!! ");
            return MCLAG_ERROR;
        }
        if (msg_hdr->ver != 1)
        {
            ICCPD_LOG_ERR(__FUNCTION__, "msg version %d wrong!!!!! ", msg_hdr->ver);
            pos += msg_hdr->len;
            continue;
        }
        if ((pos + msg_hdr->len) > num_bytes_rxed)
        {
            int recv_len = 0, len = 0;
            int pending_len = pos + msg_hdr->len - num_bytes_rxed;

            ICCPD_LOG_NOTICE(__FUNCTION__, "Recv fom Mclagsyncd msg less than expected, trying to retrieve %d bytes more ",
                pending_len);

            while (recv_len < pending_len)
            {
                int remaining_len = pending_len-recv_len;
                len = recv(sys->sync_fd, msg_buf+num_bytes_rxed+recv_len, remaining_len, MSG_DONTWAIT);
                if (len <= 0)
                {
                    if (len == 0)
                    {
                        ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd msg less than expected read error; len:%d ",len);
                        SYSTEM_INCR_TLV_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
                        return MCLAG_ERROR;
                    }

                    if (len == -1)
                    {
                        if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
                        {
                            ICCPD_LOG_NOTICE(
                                "ICCP_FSM", "Recv fom Mclagsyncd msg less than expected Non-blocking recv errno %d, num_retry %d",
                                errno, num_retry);
                            ++num_retry;
                            if (num_retry > SYNCD_RECV_RETRY_MAX)
                            {
                                ICCPD_LOG_ERR("ICCP_FSM", "Recv fom Mclagsyncd msg less than expected Non-blocking recv() retry failed len %d",len);
                                SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(system_get_instance());
                                return MCLAG_ERROR;
                            }
                            else
                            {
                                usleep(SYNCD_RECV_RETRY_INTERVAL_USEC);
                                len = 0;
                            }
                        }
                        else
                        {
                            ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd msg less than expectedread retry error len:%d , errno %d",
                                           len, errno);
                            SYSTEM_INCR_TLV_READ_SOCK_ERR_COUNTER(system_get_instance());
                            return MCLAG_ERROR;
                        }
                    }

                }
                ICCPD_LOG_NOTICE(__FUNCTION__, "received %d pending bytes", len);
                recv_len += len;
            }
        }

        if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION)
        {
            iccp_receive_fdb_handler_from_syncd(sys, &msg_buf[pos]);
        }
        else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_DOMAIN)
        {
            iccp_mclagsyncd_mclag_domain_cfg_handler(sys, &msg_buf[pos]);
        }
        else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_IFACE)
        {
            iccp_mclagsyncd_mclag_iface_cfg_handler(sys, &msg_buf[pos]);
        }
        else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_UNIQUE_IP)
        {
            iccp_mclagsyncd_mclag_unique_ip_cfg_handler(sys, &msg_buf[pos]);
        }
        else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_VLAN_MBR_UPDATES)
        {
            iccp_mclagsyncd_vlan_mbr_update_handler(sys, &msg_buf[pos]);
        }
        else 
        {
            ICCPD_LOG_ERR(__FUNCTION__, "recv unknown msg type %d ", msg_hdr->type);
            pos += msg_hdr->len;
            continue;
        }
        pos += msg_hdr->len;
        SYSTEM_SET_SYNCD_RX_DBG_COUNTER(sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
    }
    return 0;
}