#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include "rpcclt_openapi.h"
#include "proc_util.h"
static const char cSep = ':';
static unsigned char *convertMacAddressStringIntoByte
(const char *pszMACAddress, unsigned char *pbyAddress)
{
int iCounter;
for (iCounter = 0; iCounter < 6; ++iCounter)
{
unsigned int iNumber = 0;
char ch;
ch = toupper (*pszMACAddress++);
if ((ch < '0' || ch > '9') && (ch < 'A' || ch > 'F'))
{
return NULL;
}
iNumber = isdigit (ch) ? (ch - '0') : (ch - 'A' + 10);
ch = toupper (*pszMACAddress);
if ((iCounter < 5 && ch != cSep) || (iCounter == 5 && ch != '\0' && !isspace (ch)))
{
++pszMACAddress;
if ((ch < '0' || ch > '9') && (ch < 'A' || ch > 'F'))
{
return NULL;
}
iNumber <<= 4;
iNumber += isdigit (ch) ? (ch - '0') : (ch - 'A' + 10);
ch = *pszMACAddress;
if (iCounter < 5 && ch != cSep)
{
return NULL;
}
}
pbyAddress[iCounter] = (unsigned char) iNumber;
++pszMACAddress;
}
return pbyAddress;
}
{
char *name = "";
switch (error)
{
name = "OPEN_E_NONE";
break;
name = "OPEN_E_RPC";
break;
name = "OPEN_E_INTERNAL";
break;
name = "OPEN_E_PARAM";
break;
name = "OPEN_E_FULL";
break;
name = "OPEN_E_EXISTS";
break;
name = "OPEN_E_TIMEOUT";
break;
name = "OPEN_E_FAIL";
break;
name = "OPEN_E_DISABLED";
break;
name = "OPEN_E_UNAVAIL";
break;
name = "OPEN_E_NOT_FOUND";
break;
name = "OPEN_E_EMPTY";
break;
name = "OPEN_E_ERROR";
break;
default:
name = "Unknown or Undefined Error";
break;
}
return name;
}
uint32_t tenant,
unsigned char *macAddr,
uint32_t destIntfHandle )
{
macAddrBuf.
pstart = (
char *) macAddr;
{
printf ("L2 entry add failed, rc=%s\n", openapiErrorStrGet (retVal));
}
else
{
printf ("L2 entry add success, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
uint32_t tenant,
unsigned char *macAddr )
{
macAddrBuf.pstart = (char *) macAddr;
macAddrBuf.size = 6;
{
printf ("L2 entry delete failed, rc=%s\n", openapiErrorStrGet (retVal));
}
else
{
printf ("L2 entry delete success, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
uint32_t tenant,
unsigned char * macAddr )
{
uint32_t count = 0;
char macAddress[OPEN_MAC_ADDR_LEN];
char *ptr = NULL;
memcpy (macAddress, macAddr, OPEN_MAC_ADDR_LEN);
macAddrBuf.pstart = (char *) macAddress;
macAddrBuf.size = OPEN_MAC_ADDR_LEN;
&macAddrBuf, &macEntry );
{
printf("Found MAC entry!\n\n");
printf ("+--------------------------------------------------------+\n");
printf ("| Sl Tenant MAC Address destHandle Static |\n");
printf ("+--------------------------------------------------------+\n");
printf ("| %-5u %-10d %02x:%02x:%02x:%02x:%02x:%02x %-5d %d |\n",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5],
printf ("+--------------------------------------------------------+\n");
}
else
{
printf("Failed to find MAC entry. RC=%s\n", openapiErrorStrGet(retVal));
}
return;
}
uint32_t tenant )
{
uint32_t count = 0, seed = tenant;
char macAddr[OPEN_MAC_ADDR_LEN];
char *ptr = NULL;
memset (macAddr, 0, OPEN_MAC_ADDR_LEN);
macAddrBuf.pstart = (char *) macAddr;
macAddrBuf.size = OPEN_MAC_ADDR_LEN;
if (tenant)
{
printf ("Forwarding entries for tenant=%d:\n\n", tenant);
}
else
{
printf ("Forwarding entries in database:\n\n");
}
printf ("+--------------------------------------------------------+\n");
printf ("| Sl Tenant MAC Address destHandle Static |\n");
printf ("+--------------------------------------------------------+\n");
do
{
&macAddrBuf, &nextMacEntry );
{
if ( (seed == 0) ||
(seed && (seed == nextMacEntry.
tenantId)))
{
printf ("| %-5u %-10d %02x:%02x:%02x:%02x:%02x:%02x %-5d %d |\n",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5],
}
memcpy (macAddrBuf.pstart, nextMacEntry.
macAddress, OPEN_MAC_ADDR_LEN);
}
printf ("+--------------------------------------------------------+\n");
return;
}
{
uint32_t capabilities = 0;
{
printf ("Switch Overlay Capabilities Get Failed. rc=%s\n",
openapiErrorStrGet (retVal));
return;
}
if (!capabilities)
{
printf ("Switch does not support Overlay Capabilities.\n");
return;
}
printf ("Switch supports below overlay types:\n");
{
printf("\t VXLAN \n");
}
{
printf("\t NVGRE \n");
}
return;
}
{
uint32_t udpPort = 0;
{
printf ("Overlay Configuration Mode Get Failed for Tunnel Type=%d rc=%s\n",
tunnelType, openapiErrorStrGet (retVal));
}
else
{
printf ("Overlay Configuration Mode is %s for Tunnel Type=%d. rc=%s\n",
tunnelType, openapiErrorStrGet (retVal));
}
if (tunnelType != OPEN_L2OL3_TUNNEL_TYPE_VXLAN)
{
return;
}
{
printf ("VXLAN UDP port is configured to %d.\n", udpPort);
}
else
{
printf ("VXLAN UDP port configured get has failed. rc=%s.\n",
openapiErrorStrGet (retVal));
}
return;
}
{
{
printf ("Overlay Configuration Mode Set Failed for Tunnel Type=%d rc=%s\n",
tunnelType, openapiErrorStrGet (retVal));
}
else
{
printf ("Overlay Configuration Mode is set to %s for Tunnel Type=%d. rc=%s\n",
tunnelType, openapiErrorStrGet (retVal));
}
return;
}
uint32_t udpPort)
{
{
printf ("VXLAN UDP destination port=%d configuration on Swtich failed. rc=%s\n",
udpPort, openapiErrorStrGet (retVal));
}
else
{
printf ("VXLAN UDP destination port=%d configuration on Switch is successful. rc=%s\n",
udpPort, openapiErrorStrGet (retVal));
}
return;
}
uint32_t tenant,
uint32_t vlanId, uint32_t srcIP,
uint32_t configType)
{
memset (&config, 0, sizeof (config));
{
printf ("Tenant configuration successful\n");
}
else
{
printf ("Tenant configuration failed, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
{
uint32_t display_count = 1;
uint32_t nextTenant = 0;
char ipAddrString[INET_ADDRSTRLEN+1];
do
{
memset (&nextTenantConfig, 0, sizeof (nextTenantConfig));
&nextTenant, &nextTenantConfig);
{
tenant = nextTenant;
printf (" %-8u %-8u %s %-5u %-15s \n",
display_count++,
nextTenant,
(nextTenantConfig.
tunnelType == OPEN_L2OL3_TUNNEL_TYPE_VXLAN ?
"VXLAN" :
"NVGRE"),
inet_ntop(AF_INET, &nextTenantConfig.
localTepIpAddr, ipAddrString, INET_ADDRSTRLEN));
}
}
}
{
uint32_t count = 1;
char ipAddrString[INET_ADDRSTRLEN+1];
memset (&config, 0, sizeof (config));
if (tenant)
{
{
printf ("+----------------------------------------------------------------+\n");
printf (" Sl Tenant Tunnel-Type VLAN ID Local TEP \n");
printf ("+----------------------------------------------------------------+\n");
printf (" %-8u %-8u %s %-5u %-15s \n",
count++,
tenant,
(config.
tunnelType == OPEN_L2OL3_TUNNEL_TYPE_VXLAN ?
"VXLAN" :
"NVGRE"),
printf ("+----------------------------------------------------------------+\n");
}
else
{
printf ("Tenant %d info get failed. rc=%s\n",
tenant, openapiErrorStrGet (retVal));
}
}
else
{
printf ("+----------------------------------------------------------------+\n");
printf (" Sl Tenant Tunnel-Type VLAN ID Local TEP \n");
printf ("+----------------------------------------------------------------+\n");
display_tenants (clientHandle, 0);
printf ("+----------------------------------------------------------------+\n");
}
return;
}
{
{
printf ("Tenant deleted\n");
}
else
{
printf ("Tenant deletion failed, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
{
if (accessId)
{
{
printf("------------------------------------------------------------------------\n");
printf(" Tenant Tunnel-Type Access-Handle VLAN intIfNum Match-Type \n");
printf("------------------------------------------------------------------------\n");
printf(" %-10d %s %-4d %-4d %d %d\n",
(accessInfo.
tunnelType == OPEN_L2OL3_TUNNEL_TYPE_VXLAN ?
"VXLAN" :
"NVGRE"),
printf("------------------------------------------------------------------------\n");
}
else
{
printf("Access port identifier = %d information not found!\n", accessId);
}
}
else
{
printf(" Invalid access port identifier = %d\n", accessId);
}
}
{
uint32_t count = 0;
uint32_t accessHandle = 0;
printf("------------------------------------------------------------------------\n");
printf(" Tenant Tunnel-Type Access-Handle VLAN intIfNum Match-Type \n");
printf("------------------------------------------------------------------------\n");
if (tenant)
{
do
{
{
{
printf(" %-10d %s %-4d %-4d %d %d\n",
(accessInfoNext.
tunnelType == OPEN_L2OL3_TUNNEL_TYPE_VXLAN ?
"VXLAN" :
"NVGRE"),
count++;
}
}
printf("------------------------------------------------------------------------\n");
printf("\n\nTenant %d has %d Access Ports\n", tenant, count);
}
else
{
do
{
{
printf(" %-10d %s %-4d %-4d %d %d\n",
(accessInfoNext.
tunnelType == OPEN_L2OL3_TUNNEL_TYPE_VXLAN ?
"VXLAN" :
"NVGRE"),
count++;
}
printf("------------------------------------------------------------------------\n");
printf("\n\nTotal Access Ports of All Tenants = %d\n", count);
}
return;
}
uint32_t tenant,
uint32_t remoteIP,
uint32_t tunnelHandle)
{
uint32_t handle;
handle = tunnelHandle;
{
printf ("Tunnel created, handle %d\n", handle);
}
else
{
printf ("Tunnel creation failed rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
{
{
printf ("Tunnel deleted\n");
}
else
{
printf ("Tunnel deletion failed, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
{
uint32_t tunnelHandle = 0, count = 0;
char ipAddrString[INET_ADDRSTRLEN+1];
printf("------------------------------------------------------------------------\n");
printf(" Tenant Tunnel-Type Tunnel-Handle Remote-TEP Status Reason \n");
printf("------------------------------------------------------------------------\n");
do
{
{
printf(" %-9d %s %-4d %-15s %d %d\n",
(tunnelInfoNext.
tunnelType == OPEN_L2OL3_TUNNEL_TYPE_VXLAN ?
"VXLAN" :
"NVGRE"),
inet_ntop(AF_INET, &tunnelInfoNext.
remoteIPAddr, ipAddrString, INET_ADDRSTRLEN),
count++;
}
}
printf("------------------------------------------------------------------------\n");
printf("\n\nTotal Tenant Tunnels = %d\n", count);
}
{
{
printf("\n\nERROR: Failed to get resource limits. RC=%s\n\n", openapiErrorStrGet(retVal));
return;
}
printf("\n\n<<<<< RESOURCE ALLOWED LIMITS >>>>>\n\n");
printf(
"Maximum Number of Tenants Allowed : %d\n", resourceLimits.
maxNumTenants);
printf(
"Maximum Number of Access Ports Allowed : %d\n", resourceLimits.
maxNumAccessPorts);
printf(
"Maximum Number of Tenant Tunnels Allowed : %d\n", resourceLimits.
maxNumTunnelPorts);
printf(
"Maximum Number of Shared Tunnels Allowed : %d\n", resourceLimits.
maxNumTunnelsInHw);
printf("Maximum Number of User configured host \n"
printf("Maximum Number of User configured host \n"
printf("Maximum Number of User configured host \n"
printf(
"Overlay forwarding database size : %d\n", resourceLimits.
maxNumFwdEntries);
{
printf("\n\nERROR: Failed to get resource limits. RC=%s\n\n", openapiErrorStrGet(retVal));
return;
}
printf("\n\n<<<<< RESOURCE USAGE STATISTICS >>>>>\n\n");
printf(
"Number of Tenants Configured : %d\n", resourceUsage.
numTenants);
printf(
"Number of Tenant VLANs Configured : %d\n", resourceUsage.
numTenantVlans);
printf(
"Number of Access Ports Configured : %d\n", resourceUsage.
numAccessPorts);
printf(
"Number of Tenant Tunnels Configured : %d\n", resourceUsage.
numTenantTunnels);
printf("\n\n<<<<< SOFTWARE ERROR STATISTICS >>>>>\n\n");
return;
}
{
{
printf ("Tunnel Status:\n");
{
printf (" Reason - INITIATOR_NOT_RESOLVED\n");
break;
printf (" Reason - INITIATOR_INSTALL_FAILED\n");
break;
printf (" Reason - TERMINATOR_INSTALL_FAILED\n");
break;
default:
printf (" Reason - None\n");
break;
}
printf ("\nTunnel status get success, rc=%s\n", openapiErrorStrGet (retVal));
}
else
{
printf ("Tunne status get failed, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
{
memset (&tunnelStats, 0, sizeof (tunnelStats));
{
printf ("Tunnel counters for handle=%d:\n", tunnelHandle);
printf (
"rxPackts = %u\n", tunnelStats.
rxPkts);
printf (
"rxBytes = %u\n", tunnelStats.
rxBytes);
printf (
"txPackts = %u\n", tunnelStats.
txPkts);
printf (
"txBytes = %u\n", tunnelStats.
txBytes);
printf ("\nTunnel counters get success, rc=%s\n", openapiErrorStrGet (retVal));
}
else
{
printf ("Tunnel counters get failed, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
{
{
printf ("Tunnel counters clear success. rc=%s\n", openapiErrorStrGet (retVal));
}
else
{
printf ("Tunnel counters clear failed, rc=%s\n", openapiErrorStrGet (retVal));
}
return;
}
void printUsage (char *app)
{
printf ("Usage: %s -o <option> -g -d -c <config flags>"
" -t <tenant> -y <tunnel Type> -v <vlanId>"
" -s <srcIP> -r <remoteIP> -u <tunnel Id> -i <access Id>"
" -h \n", app);
printf ("\n");
printf ("\t o \t option should be one of the following based on action desired, \n");
printf ("\t\t config - to initialize required overlay service. \n"
"\t\t options needed to enable: -y [-p] \n"
"\t\t options needed to disable: -d -y \n"
"\t\t options needed to get: -g [-y] \n");
printf ("\t\t tenant - to perform tenant configuration and retrive status. \n"
"\t\t options needed to create/modify: -c -t -y <[-v] | [-s]> \n"
"\t\t options needed to delete: -d -t \n"
"\t\t options needed to get: -g [-t ] \n");
printf ("\t\t access - to get configured access ports information. \n"
"\t\t options needed to get: -g [-t | -i] \n");
printf ("\t\t tunnel - to perform tunnel configuration and fetch status. \n"
"\t\t options needed to create: -c -t -r \n"
"\t\t options needed to delete: -d -u \n"
"\t\t options needed to get: -g [-u] \n");
printf ("\t\t l2entry - to configure and list bridging entries. \n");
printf ("\t\t options needed to create: -t -m <[-i] | [-u]> \n");
printf ("\t\t options needed to delete: -t -m -d \n");
printf ("\t\t options needed to get: -g [-t -m | -t] \n");
printf ("\t\t stats - to get stats or clear tunnel counters. \n"
"\t\t to get tunnel stats : -g [-u] \n"
"\t\t to clear tunnel stats : -d -u \n"
"\t\t Note: to get global usage & error stats: -g \n");
printf ("\t c \t Configuration flags. (%d-Create, %d-Modify) \n",
printf ("\t d \t To delete configuration. \n");
printf ("\t g \t To fetch configuration/status. \n");
printf ("\t h \t Usage help. \n");
printf ("\t i \t Access Interface Handle. \n");
printf ("\t m \t MAC Address (xx:xx:xx:xx:xx:xx). \n");
printf ("\t p \t VXLAN destination UDP port number. \n");
printf ("\t r \t IP address of Remote TEP (Tunnel end point) in a.b.c.d format. \n");
printf ("\t s \t IP address of Source TEP or Local Gateway in a.b.c.d format. \n");
printf ("\t t \t Tenant Id (VNID for VXLAN;VSID for NVGRE). Range: %d-%d. \n",
printf ("\t u \t Tunnel handle. \n");
printf ("\t v \t VLAN Identifier or Tenant VLAN. \n");
printf ("\t y \t Tenant or Tunnel type.(VXLAN - %d, NVGRE - %d) \n",
}
int main (int argc, char **argv)
{
char switch_os_revision_string[100];
uint32_t tenant = 0, accessIntfNum = 0, vlanId = 0;
uint32_t configFlags = 0;
uint32_t tunnel_type = 0;
uint32_t remoteIP = 0, srcIP = 0, tunnelHandle = 0;
uint32_t dstUdp = 0;
uint32_t l2DestIntf = 0;
unsigned char macAddr[6];
unsigned char nullMac[6];
int c;
int addFlag = 1;
int getFlag = 0;
int udpFlag = 0;
int macFlag = 0;
char option_name[80] = {0};
int option_len;
l7proc_crashlog_register ();
{
printf ("\nFailed to initialize RPC to OpEN. Exiting (result = %d)\n", result);
exit (2);
}
{
sleep (1);
}
L7PROC_LOGF (L7PROC_LOG_SEVERITY_INFO, 0, "Starting Overlay API example application (%s)", argv[0]);
printf ("\n");
switch_os_revision.pstart = switch_os_revision_string;
switch_os_revision.size = sizeof (switch_os_revision_string);
{
printf ("Network OS version = %s\n", switch_os_revision_string);
}
else
{
printf ("Network OS version retrieve error\n");
}
opterr = 0;
memset (nullMac, 0, sizeof (nullMac));
while ((c = getopt (argc, argv, "hdgy:c:v:t:m:o:i:r:s:u:p:")) != -1)
{
switch (c)
{
case 't':
tenant = atoi (optarg);
break;
case 'u':
tunnelHandle = atoi (optarg);
break;
case 'i':
accessIntfNum = atoi (optarg);
break;
case 'v':
vlanId = atoi (optarg);
break;
case 'c':
configFlags = atoi (optarg);
break;
case 'y':
tunnel_type = atoi (optarg);
break;
case 'p':
dstUdp = atoi (optarg);
udpFlag = 1;
break;
case 'r':
inet_pton (AF_INET, optarg, &remoteIP);
remoteIP = ntohl(remoteIP);
break;
case 's':
inet_pton (AF_INET, optarg, &srcIP);
srcIP = ntohl(srcIP);
break;
case 'm':
convertMacAddressStringIntoByte (optarg, macAddr);
macFlag = 1;
break;
case 'd':
addFlag = 0;
break;
case 'g':
getFlag = 1;
break;
case 'o':
strncpy (option_name, optarg, (sizeof(option_name) - 1));
break;
case 'h':
printUsage (argv[0]);
return 0;
case '?':
if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
return 1;
default:
abort ();
}
}
printf ("\n");
option_len = strlen (option_name);
if ((memcmp (option_name, "config", option_len) == 0) &&
(option_len == strlen ("config")))
{
if (getFlag)
{
switch_capabilities_get (&clientHandle);
if (tunnel_type)
{
tunnel_services_config_get (&clientHandle, tunnel_type);
}
}
else if (addFlag && tunnel_type)
{
tunnel_services_config_set (&clientHandle, tunnel_type,
OPEN_ENABLE);
if (udpFlag)
{
tunnel_services_config_vxlan_udp_port (&clientHandle, dstUdp);
}
}
else if (tunnel_type)
{
tunnel_services_config_set (&clientHandle, tunnel_type,
OPEN_DISABLE);
}
else
{
printUsage (argv[0]);
return 1;
}
}
else if ((memcmp (option_name, "l2entry", option_len) == 0) &&
(option_len == strlen ("l2entry")))
{
if (getFlag && macFlag)
{
get_l2Entry (&clientHandle, tenant, macAddr);
}
else if (getFlag)
{
get_l2Entries (&clientHandle, tenant);
}
else if (addFlag && macFlag && (tunnelHandle || accessIntfNum))
{
if ((tenant == 0) || (memcmp (macAddr, nullMac, sizeof (nullMac)) == 0))
{
printUsage (argv[0]);
return 1;
}
if (tunnelHandle)
{
l2DestIntf = tunnelHandle;
}
else
{
l2DestIntf = accessIntfNum;
}
add_l2Entry (&clientHandle, tenant, macAddr, l2DestIntf);
}
else if (!addFlag && macFlag && tenant)
{
if (memcmp (macAddr, nullMac, sizeof (nullMac)) == 0)
{
printUsage (argv[0]);
return 1;
}
del_l2Entry (&clientHandle, tenant, macAddr);
}
else
{
printUsage (argv[0]);
return 1;
}
}
else if ((memcmp (option_name, "tenant", option_len) == 0) && (option_len == strlen ("tenant")))
{
if (getFlag)
{
get_tenant (&clientHandle, tenant);
}
else if (addFlag)
{
create_tenant (&clientHandle, tenant, tunnel_type, vlanId, srcIP, configFlags);
}
else
{
delete_tenant (&clientHandle, tenant);
}
}
else if ((memcmp (option_name, "access", option_len) == 0) && (option_len == strlen ("access")))
{
if (getFlag && accessIntfNum)
{
get_access_port (&clientHandle, accessIntfNum);
}
else if (getFlag)
{
get_access_ports (&clientHandle, tenant);
}
else
{
printUsage (argv[0]);
return 1;
}
}
else if ((memcmp (option_name, "tunnel", option_len) == 0) && (option_len == strlen ("tunnel")))
{
if (getFlag)
{
if (tunnelHandle)
{
get_tunnel_status (&clientHandle, tunnelHandle);
}
else
{
get_all_tunnels (&clientHandle);
}
}
else if (addFlag)
{
create_tunnel (&clientHandle, tenant, remoteIP, configFlags, tunnelHandle);
}
else
{
delete_tunnel (&clientHandle, tunnelHandle);
}
}
else if ((memcmp (option_name, "stats", option_len) == 0) && (option_len == strlen ("stats")))
{
if ((getFlag) && (tunnelHandle))
{
tunnel_stats_get (&clientHandle, tunnelHandle);
}
else if ((!addFlag) && (tunnelHandle))
{
tunnel_stats_clear (&clientHandle, tunnelHandle);
}
else if (getFlag)
{
resource_stats_get (&clientHandle);
}
else
{
printf ("Incorrect options specified!\n");
printUsage (argv[0]);
}
}
else
{
printf ("Incorrect option specified %s \n", option_name);
printUsage (argv[0]);
}
L7PROC_LOGF(L7PROC_LOG_SEVERITY_INFO, 0, "Stopping Overlay API example application");
return 0;
}