Open Ethernet Networking (OpEN) API Guide and Reference Manual  3.6.0.3
intf_stats_example.c
/*********************************************************************
*
* Copyright 2016-2018 Broadcom.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************
*
* @filename intf_stats_example.c
*
* @purpose Interface and Statistics APIs example.
*
* @component OPEN
*
* @note
*
* @create 08/29/2012
*
* @end
*
**********************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include "rpcclt_openapi.h"
#include "proc_util.h"
#include "openapi_common.h"
#include "openapi_if.h"
#include "openapi_stats.h"
typedef struct
{
uint32_t ctrId;
char ctrName[40];
} ctrIdToStrMap_t;
static ctrIdToStrMap_t ctrIdToStr[] =
{
{OPEN_CTR_RESERVED, "OPEN_CTR_RESERVED"},
{OPEN_CTR_RX_TOTAL_BYTES, "OPEN_CTR_RX_TOTAL_BYTES"},
{OPEN_CTR_RX_64,"OPEN_CTR_RX_64"},
{OPEN_CTR_RX_65_127, "OPEN_CTR_RX_65_127"},
{OPEN_CTR_RX_128_255, "OPEN_CTR_RX_128_255"},
{OPEN_CTR_RX_256_511, "OPEN_CTR_RX_256_511"},
{OPEN_CTR_RX_512_1023, "OPEN_CTR_RX_512_1023"},
{OPEN_CTR_RX_1024_1518, "OPEN_CTR_RX_1024_1518"},
{OPEN_CTR_RX_1519_1530, "OPEN_CTR_RX_1519_1530"},
{OPEN_CTR_RX_GOOD_OVERSIZE, "OPEN_CTR_RX_GOOD_OVERSIZE"},
{OPEN_CTR_RX_ERROR_OVERSIZE, "OPEN_CTR_RX_ERROR_OVERSIZE"},
{OPEN_CTR_RX_GOOD_UNDERSIZE, "OPEN_CTR_RX_GOOD_UNDERSIZE"},
{OPEN_CTR_RX_ERROR_UNDERSIZE, "OPEN_CTR_RX_ERROR_UNDERSIZE"},
{OPEN_CTR_RX_UCAST_FRAMES, "OPEN_CTR_RX_UCAST_FRAMES"},
{OPEN_CTR_RX_MCAST_FRAMES, "OPEN_CTR_RX_MCAST_FRAMES"},
{OPEN_CTR_RX_BCAST_FRAMES, "OPEN_CTR_RX_BCAST_FRAMES"},
{OPEN_CTR_RX_ALIGN_ERRORS, "OPEN_CTR_RX_ALIGN_ERRORS"},
{OPEN_CTR_RX_FCS_ERRORS, "OPEN_CTR_RX_FCS_ERRORS"},
{OPEN_CTR_RX_OVERRUNS, "OPEN_CTR_RX_OVERRUNS"},
{OPEN_CTR_RX_FRAME_TOO_LONG, "OPEN_CTR_RX_FRAME_TOO_LONG"},
{OPEN_CTR_TX_TOTAL_BYTES, "OPEN_CTR_TX_TOTAL_BYTES"},
{OPEN_CTR_TX_64, "OPEN_CTR_TX_64"},
{OPEN_CTR_TX_65_127, "OPEN_CTR_TX_65_127"},
{OPEN_CTR_TX_128_255, "OPEN_CTR_TX_128_255"},
{OPEN_CTR_TX_256_511, "OPEN_CTR_TX_256_511"},
{OPEN_CTR_TX_512_1023, "OPEN_CTR_TX_512_1023"},
{OPEN_CTR_TX_1024_1518, "OPEN_CTR_TX_1024_1518"},
{OPEN_CTR_TX_1519_1530, "OPEN_CTR_TX_1519_1530"},
{OPEN_CTR_TX_UCAST_FRAMES, "OPEN_CTR_TX_UCAST_FRAMES"},
{OPEN_CTR_TX_MCAST_FRAMES, "OPEN_CTR_TX_MCAST_FRAMES"},
{OPEN_CTR_TX_BCAST_FRAMES, "OPEN_CTR_TX_BCAST_FRAMES"},
{OPEN_CTR_TX_FCS_ERRORS, "OPEN_CTR_TX_FCS_ERRORS"},
{OPEN_CTR_TX_OVERSIZED, "OPEN_CTR_TX_OVERSIZED"},
{OPEN_CTR_TX_UNDERRUN_ERRORS, "OPEN_CTR_TX_UNDERRUN_ERRORS"},
{OPEN_CTR_TX_ONE_COLLISION, "OPEN_CTR_TX_ONE_COLLISION"},
{OPEN_CTR_TX_MULTIPLE_COLLISION, "OPEN_CTR_TX_MULTIPLE_COLLISION"},
{OPEN_CTR_TX_EXCESSIVE_COLLISION, "OPEN_CTR_TX_EXCESSIVE_COLLISION"},
{OPEN_CTR_TX_LATE_COLLISION, "OPEN_CTR_TX_LATE_COLLISION"},
{OPEN_CTR_TX_RX_64, "OPEN_CTR_TX_RX_64"},
{OPEN_CTR_TX_RX_65_127, "OPEN_CTR_TX_RX_65_127"},
{OPEN_CTR_TX_RX_128_255, "OPEN_CTR_TX_RX_128_255"},
{OPEN_CTR_TX_RX_256_511, "OPEN_CTR_TX_RX_256_511"},
{OPEN_CTR_TX_RX_512_1023, "OPEN_CTR_TX_RX_512_1023"},
{OPEN_CTR_TX_RX_1024_1518, "OPEN_CTR_TX_RX_1024_1518"},
{OPEN_CTR_TX_RX_1519_1522, "OPEN_CTR_TX_RX_1519_1522"},
{OPEN_CTR_TX_RX_1523_2047, "OPEN_CTR_TX_RX_1523_2047"},
{OPEN_CTR_TX_RX_2048_4095, "OPEN_CTR_TX_RX_2048_4095"},
{OPEN_CTR_TX_RX_4096_9216, "OPEN_CTR_TX_RX_4096_9216"},
{OPEN_CTR_ETHER_STATS_DROP_EVENTS, "OPEN_CTR_ETHER_STATS_DROP_EVENTS"},
{OPEN_CTR_SNMPIFOUTDISCARD_FRAMES, "OPEN_CTR_SNMPIFOUTDISCARD_FRAMES"},
{OPEN_CTR_SNMPIFINDISCARD_FRAMES, "OPEN_CTR_SNMPIFINDISCARD_FRAMES"},
{OPEN_CTR_RX_TOTAL_FRAMES, "OPEN_CTR_RX_TOTAL_FRAMES"},
{OPEN_CTR_RX_TOTAL_ERROR_FRAMES, "OPEN_CTR_RX_TOTAL_ERROR_FRAMES"},
{OPEN_CTR_TX_TOTAL_FRAMES, "OPEN_CTR_TX_TOTAL_FRAMES"},
{OPEN_CTR_TX_TOTAL_ERROR_FRAMES, "OPEN_CTR_TX_TOTAL_ERROR_FRAMES"},
{OPEN_CTR_TX_TOTAL_COLLISION_FRAMES, "OPEN_CTR_TX_TOTAL_COLLISION_FRAMES"},
{OPEN_CTR_RX_CRC_ERRORS, "OPEN_CTR_RX_CRC_ERRORS"},
{OPEN_CTR_RX_TOTAL_MAC_ERROR_FRAMES, "OPEN_CTR_RX_TOTAL_MAC_ERROR_FRAMES"},
{OPEN_CTR_RX_RATE_BITS, "OPEN_CTR_RX_RATE_BITS"},
{OPEN_CTR_TX_RATE_BITS, "OPEN_CTR_TX_RATE_BITS"},
{OPEN_CTR_RX_RATE_FRAMES, "OPEN_CTR_RX_RATE_FRAMES"},
{OPEN_CTR_TX_RATE_FRAMES, "OPEN_CTR_TX_RATE_FRAMES"},
{OPEN_CTR_ETHER_STATS_HOLD, "OPEN_CTR_ETHER_STATS_HOLD"},
{OPEN_CTR_RX_JABBER_FRAMES, "OPEN_CTR_RX_JABBER_FRAMES"},
{OPEN_CTR_PORT_LINK_DOWN_COUNTER, "OPEN_CTR_PORT_LINK_DOWN_COUNTER"}
};
#define NUM_COUNTERS (sizeof(ctrIdToStr)/sizeof(ctrIdToStrMap_t))
/*****************************************************************/
void intfStatsBulkDisplay(openapiClientHandle_t *clientHandle, uint32_t ifNum)
{
char *ctrArray = NULL;
char linkName[256];
open_error_t result;
uint32_t i;
uint32_t bufSize;
uint64_t *pCtr;
uint32_t maxCtrIdx;
uint64_t ctrValue;
printf("\n");
/* get the size and allocate a counter array buffer */
result = openapiInterfaceStatsBufSizeGet(clientHandle, &bufSize);
if (result != OPEN_E_NONE)
{
printf("Error obtaining counter buffer size (rc = %d)\n\n", result);
return;
}
ctrArray = (char *)malloc(bufSize);
if (ctrArray == NULL)
{
printf("Cannot allocate memory for counter collection buffer\n\n");
return;
}
/* get all interface counters in a single OpEN API call */
memset(ctrArray, 0, bufSize);
bufd.pstart = ctrArray;
bufd.size = bufSize;
result = openapiInterfaceStatsGet(clientHandle, ifNum, &bufd);
if (result != OPEN_E_NONE)
{
printf("Error obtaining counters using bulk get method (rc = %d)\n", result);
free(ctrArray);
return;
}
memset(linkName, 0, sizeof(linkName));
bufd.pstart = linkName;
bufd.size = sizeof(linkName);
if (openapiIfNameGet(clientHandle, ifNum, &bufd) == OPEN_E_NONE)
{
printf("Bulk statistics for interface %s:\n", linkName);
}
else
{
printf("Interface name retrieval error for ifNum %d\n\n", ifNum);
printf("Bulk statistics for ifNum %u\n", ifNum);
}
printf("\n");
/* Display all the counters for the interface */
pCtr = (uint64_t *)ctrArray;
maxCtrIdx = (uint32_t)*pCtr++; /* index 0 contains total number of counters provided */
for (i = 1; i < NUM_COUNTERS; i++)
{
if (i < maxCtrIdx)
{
ctrValue = *pCtr++;
}
else
{
ctrValue = 0;
}
printf("%40s - 0x%016llx\n", ctrIdToStr[i].ctrName, ctrValue);
}
printf("\n");
free(ctrArray);
}
/***************************************************************/
int main(int argc, char **argv)
{
openapiClientHandle_t clientHandle;
uint32_t ifNum;
uint64_t ctrValue;
open_buffdesc linkNameBuff;
char linkName[256];
open_buffdesc statValStrBuff;
char statValStr[OPEN_MIN_U64_STR_BUFFER_SIZE];
OPEN_LINK_STATE_t linkState;
uint32_t i;
uint32_t lastResetSecs;
l7proc_crashlog_register();
/* Register with OpEN */
if ((rc = openapiClientRegister("intf_stats_example", &clientHandle)) != OPEN_E_NONE)
{
printf("\nFailed to initialize RPC to OpEN. Exiting (result = %d)\n", rc);
exit(1);
}
/* RPC call can fail until server starts. Keep trying */
while (openapiConnectivityCheck(&clientHandle) != OPEN_E_NONE)
{
sleep(1);
}
L7PROC_LOGF(L7PROC_LOG_SEVERITY_INFO, 0, "Starting interface statistics example application");
linkNameBuff.pstart = linkName;
linkNameBuff.size = sizeof(linkName);
printf("\n");
if (openapiNetworkOSVersionGet(&clientHandle, &linkNameBuff) == OPEN_E_NONE)
printf("Network OS version = %s\n", (char *) linkNameBuff.pstart);
else
printf("Network OS Version retrieve error\n");
printf("\n");
printf(" Intf %s\n", ctrIdToStr[OPEN_CTR_RX_TOTAL_FRAMES].ctrName);
printf("ifNum Interface Name State Value \n");
printf("----- -------------------------------- ----- ------------------------\n");
for (i = 0; i < OPEN_INTF_TYPE_ANY; i++)
{
switch (i)
{
break;
break;
break;
break;
default:
continue;
}
if (openapiIfFirstGet(&clientHandle, ifType, &ifNum) == OPEN_E_NONE)
{
do
{
printf("%5u ", ifNum);
linkNameBuff.size = sizeof(linkName);
if (openapiIfNameGet(&clientHandle, ifNum, &linkNameBuff) == OPEN_E_NONE)
printf("%-32s ", (char *)linkNameBuff.pstart);
else
printf("%-32s ", "link name retrieve error");
if (openapiIfLinkStateGet(&clientHandle, ifNum, &linkState) == OPEN_E_NONE)
printf("%-5s ", (linkState == OPEN_LINK_UP) ? "UP":"DOWN");
else
printf("%-5s ", "???");
/* only retrieve counters for physical and LAG interfaces */
if ((ifType == OPEN_INTF_TYPE_PHY) ||
(ifType == OPEN_INTF_TYPE_LAG))
{
ctrValue = -1;
rc = openapiStatGet(&clientHandle, ctrIdToStr[OPEN_CTR_RX_TOTAL_FRAMES].ctrId, ifNum, &ctrValue);
switch (rc)
{
printf("0x%016llx\n", ctrValue);
break;
printf("Counter unavailable\n");
break;
default:
printf("Counter get failed (rc = %d)\n", rc);
break;
}
}
} while (openapiIfNextGet(&clientHandle, ifType, ifNum, &ifNum) == OPEN_E_NONE);
printf("\n");
}
}
printf("\n");
if (openapiIfFirstGet(&clientHandle, OPEN_INTF_TYPE_PHY, &ifNum) == OPEN_E_NONE)
{
memset(linkName, 0, sizeof(linkName));
linkNameBuff.pstart = linkName;
linkNameBuff.size = sizeof(linkName);
if (openapiIfNameGet(&clientHandle, ifNum, &linkNameBuff) == OPEN_E_NONE)
printf("Displaying statistics of %s\n", (char *)linkNameBuff.pstart);
else
printf("link name retrieval error\n");
printf("\n");
statValStrBuff.pstart = statValStr;
/* Display all the counters on an interface using single get method */
for (i = 1; i < NUM_COUNTERS; i++)
{
ctrValue = -1;
memset(statValStr, 0, sizeof(statValStr));
statValStrBuff.size = sizeof(statValStr);
rc = openapiStatGet(&clientHandle, ctrIdToStr[i].ctrId, ifNum, &ctrValue);
switch (rc)
{
printf("%40s - 0x%016llx\n", ctrIdToStr[i].ctrName, ctrValue);
break;
printf("%40s - Counter unavailable\n", ctrIdToStr[i].ctrName);
break;
default:
printf("%40s - Counter get failed (rc = %d)\n", ctrIdToStr[i].ctrName, rc);
break;
}
rc = openapiStatStringGet(&clientHandle, ctrIdToStr[i].ctrId, ifNum, &statValStrBuff);
switch (rc)
{
printf("%40s - %s\n", ctrIdToStr[i].ctrName, (char *)statValStrBuff.pstart);
break;
printf("%40s - Counter unavailable\n", ctrIdToStr[i].ctrName);
break;
default:
printf("%40s - Counter get failed (rc = %d)\n", ctrIdToStr[i].ctrName, rc);
break;
}
}
/* Display all the counters on an interface using bulk get method */
intfStatsBulkDisplay(&clientHandle, ifNum);
/* Resetting a counter on an interface */
printf("\n");
printf("Resetting OPEN_CTR_RX_TOTAL_BYTES on an interface.\n");
rc = openapiStatReset(&clientHandle, OPEN_CTR_RX_TOTAL_BYTES, ifNum);
if (rc == OPEN_E_NONE)
{
printf("Statistics reset successfully on interface %d.\n", ifNum);
}
else if (rc == OPEN_E_FAIL)
{
printf("Failed to reset statistics on interface %d.\n", ifNum);
}
else if (rc == OPEN_E_NOT_FOUND)
{
printf("Error resetting stats.\n");
}
else
{
printf("Internal error.\n");
}
printf("\n");
/* Resetting all the counters on an interface */
rc = openapiInterfaceStatsResetTimeGet(&clientHandle, ifNum, &lastResetSecs);
if (rc == OPEN_E_NONE)
{
printf("Seconds since stats last reset on interface %d: %8u (before)\n", ifNum, lastResetSecs);
}
else
{
printf("Failed to get last reset time on interface %d.\n", ifNum);
}
printf("Resetting all the counters on an interface.\n");
rc = openapiInterfaceStatsReset(&clientHandle, ifNum);
if (rc == OPEN_E_NONE)
{
printf("Statistics reset successfully on interface %d.\n", ifNum);
}
else if (rc == OPEN_E_FAIL)
{
printf("Failed to reset statistics on interface %d.\n", ifNum);
}
else
{
printf("Internal error.\n");
}
rc = openapiInterfaceStatsResetTimeGet(&clientHandle, ifNum, &lastResetSecs);
if (rc == OPEN_E_NONE)
{
printf("Seconds since stats last reset on interface %d: %8u (after)\n", ifNum, lastResetSecs);
}
else
{
printf("Failed to get last reset time on interface %d.\n", ifNum);
}
}
printf("\n");
/* Log goodbye message with OPEN */
L7PROC_LOGF(L7PROC_LOG_SEVERITY_INFO, 0, "Stopping interface statistics example application");
(void) openapiClientTearDown(&clientHandle);
return 0;
}