#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_packet.h>
#include <sys/errno.h>
#include <ctype.h>
#include "rpcclt_openapi.h"
#include "proc_util.h"
#define RPPI_APP_NAME "oscar"
#define XX_SELECT_TIMEOUT 1
#define XX_SERVICE_TIMEOUT 180
#define XX_ROUTES_MAX (16 * 1024)
#define XX_OWN_ROUTE_PREF 19
#define XX_AF_NUM 2
#define XX_INTF_IP_MAX 32
#define XX_MAX_STRING_LENGTH 256
typedef enum
{
XX_E_NONE = 0,
XX_E_FAIL = -1,
XX_E_AGAIN = -2,
XX_E_LIMIT = -3
} xx_error_t;
typedef enum
{
OPEN_ROUTER_EVENT_SVC = 0,
OPEN_BEST_ROUTE_SVC,
OPEN_POLICY_SVC,
OPEN_SERVICES_MAX
} OPEN_SERVICE_t;
char *openServiceName[OPEN_SERVICES_MAX] = {"Router Event", "Best Route", "Policy"};
char *protocolName = "xrp";
char *protocolCode = "X";
char *routeType1Name = "XRP Internal";
char *routeType1Code = "XI";
char *routeType2Name = "XRP External";
char *routeType2Code = "XE";
typedef struct xxRppiSvcReg_s
{
uint32_t inUse;
OPEN_SERVICE_t service;
char clientName[OPEN_RPPI_CLIENT_NAME_MAX_LEN + 1];
pid_t pid;
uint32_t clientId;
int32_t sockFd;
uint32_t lastKeepTime;
} xxRppiSvcReg_t;
typedef struct xxRoute_s
{
uint32_t inUse;
uint32_t isOurRoute;
uint32_t forwarding;
uint32_t permitted;
} xxRoute_t;
typedef struct xxRouteIntf_s
{
uint32_t inUse;
uint32_t intf;
char *intfName;
uint32_t vlanId;
uint32_t loopbackId;
uint32_t ifIndex;
uint32_t ipMtuIPv4;
uint32_t ipMtuIPv6;
uint32_t bandwidthIPv4;
uint32_t bandwidthIPv6;
}xxRouteIntf_t;
xxRppiSvcReg_t xxRppiServices[OPEN_SERVICES_MAX];
xxRoute_t xxRouteTable[XX_ROUTES_MAX];
xxRouteIntf_t *xxRouteIntfTable = NULL;
pid_t main_pid;
pthread_t receive_tid;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
uint32_t protoId;
uint32_t intRouteType;
uint32_t extRouteType;
uint32_t vrfId;
char *routeMapName = NULL;
char *pfxListName = NULL;
uint32_t xxMaxNextHops = 48;
uint32_t XX_INTF_NAME_LEN_MAX = 0;
uint32_t XX_ROUTE_INTF_MAX = 0;
uint32_t perfTest = 0;
uint32_t currentTimeGet(void);
void xxPerfTest(void);
void xxCleanup(void);
xx_error_t xxRouteMapSet(char *rmName);
xx_error_t xxPrefixListSet(char *plName);
void xxRouteMapReapply(void);
void xxPrefixListReapply(void);
uint32_t ownRoute, uint32_t forwarding, uint32_t permitted);
xx_error_t xxRouteIntfTableAdd(uint32_t intf);
xx_error_t xxRouteIntfTableDel(uint32_t intf);
xx_error_t xxGetInterfaceIndexFromTable(uint32_t intf);
void xxPopulateRoutingInterfaceTable(void);
xx_error_t xxIntfIpv4AddrsUpdate(uint32_t intf);
void *xxReceiveThread(void *arg);
xx_error_t xxRppiSvcAdd(OPEN_SERVICE_t svc, char *name, pid_t pid, uint32_t clientId, int32_t fd);
void xxRppiSvcDel(OPEN_SERVICE_t svc);
void xxKeepTimeUpdate(OPEN_SERVICE_t service);
void xxKeepaliveStatusCheck(void);
uint32_t xxPfxLenToMask(uint32_t pfxLen);
uint32_t xxInetMaskLengthGet(uint32_t mask);
uint32_t label[OPEN_MAX_MPLS_IMPOSE_LABELS]);
void xxWithdrawOwnRoutes(void);
void xxInterfacesShow(void);
void xxLimitsShow(void);
void xxRegistrationsShow(void);
void xxRoutesShow(void);
void xxOpenRoutesShow(uint32_t vrfId, uint32_t bestOnly);
void xxOpenBestRouteLookup(char **cmd_argv);
void xxOpenRouteFind(char **cmd_argv);
xx_error_t xxAddRoute(uint32_t cmd_argc, char **cmd_argv);
void xxDeleteRoute(uint32_t cmd_argc, char **cmd_argv);
void xxEventProcess(OPEN_SERVICE_t service, void *msg, uint32_t msgLen);
void xxSocketsRead(fd_set *readFds);
uint32_t xxReadFdsGet(fd_set *readFds);
xx_error_t rppiClientSockCreate(char *addrFormat, uint32_t clientId, int *fd);
xx_error_t xxRouterEventClientStart(pid_t myPid,
open_buffdesc *myName);
xx_error_t xxBestRouteClientStart(pid_t myPid,
open_buffdesc *myName);
xx_error_t xxPolicyClientStart(pid_t myPid,
open_buffdesc *myName);
xx_error_t xxRouteTypesRegister(void);
void xxServiceDeregister(OPEN_SERVICE_t service);
void nextHopListBuffDescSizeSet(
open_buffdesc *nextHopListBuffDesc);
void nextHopListBuffDescStorageFree(
open_buffdesc *nextHopListBuffDesc);
uint32_t nextHopListBuffDescStorageAllocate(
open_buffdesc *nextHopListBuffDesc);
char *xxMsgTypeNameGet(uint32_t msgType)
{
switch (msgType)
{
case OPENR_KEEPALIVE: return "KEEPALIVE";
case OPENR_BEST_ROUTE_CHANGE: return "BEST ROUTE CHANGE";
case OPENR_RTR_ENABLE: return "IPv4 ROUTING ENABLE";
case OPENR_RTR_DISABLE: return "IPv4 ROUTING DISABLE";
case OPENR_RTR_STARTUP_DONE: return "STARTUP DONE";
case OPENR_RTR_INTF_CREATE: return "INTERFACE CREATE";
case OPENR_RTR_INTF_DELETE: return "INTERFACE DELETE";
case OPENR_RTR_INTF_ENABLE: return "INTERFACE IPv4 ENABLE";
case OPENR_RTR_INTF_DISABLE: return "INTERFACE IPv4 DISABLE";
case OPENR_RTR_INTF_ADDR_CHANGE: return "IPv4 ADDRESS CHANGE";
case OPENR_RTR_INTF_MTU: return "IPv4 MTU CHANGE";
case OPENR_RTR_INTF_BW_CHANGE: return "BANDWIDTH CHANGE";
case OPENR_RTR_INTF_HOST_MODE: return "HOST INTERFACE FOR IPv4";
case OPENR_RTR_INTF_CFG_CHANGE: return "INTERFACE CONFIG CHANGED";
case OPENR_RTR6_ENABLE: return "IPv6 ROUTING ENABLE";
case OPENR_RTR6_DISABLE: return "IPv6 ROUTING DISABLE";
case OPENR_RTR6_STARTUP_DONE: return "IPv6 STARTUP DONE";
case OPENR_RTR6_INTF_CREATE: return "IPv6 INTERFACE CREATE";
case OPENR_RTR6_INTF_DELETE: return "IPv6 INTERFACE DELETE";
case OPENR_RTR6_INTF_ENABLE: return "INTERFACE IPv6 ENABLE";
case OPENR_RTR6_INTF_DISABLE: return "INTERFACE IPv6 DISABLE";
case OPENR_RTR6_INTF_ADDR_CHANGE: return "IPv6 ADDRESS CHANGE";
case OPENR_RTR6_INTF_MTU: return "IPv6 MTU CHANGE";
case OPENR_RTR6_INTF_BW_CHANGE: return "IPv6 BANDWIDTH CHANGE";
case OPENR_RTR6_INTF_HOST_MODE: return "HOST INTERFACE FOR IPv6";
case OPENR_POLICY_CHANGE: return "POLICY CHANGE";
default: return "UNKNOWN";
}
return "UNKNOWN";
}
char *cmd_list = "\n \
help\n \
show ip route\n \
show open routes\n \
show open routes best\n \
show open route <dest-addr>\n \
show open route <pfx> <pfx len>\n \
show interfaces\n \
show limits\n \
show registrations\n \
ip route\n \
no ip route\n \
route-map\n \
no route-map\n \
prefix-list\n \
no prefix-list\n \
quit\n";
uint32_t currentTimeGet(void)
{
struct timespec tp;
int rc;
static uint32_t beginningOfTime = 0;
rc = clock_gettime(CLOCK_MONOTONIC, &tp);
if (rc < 0)
{
struct timeval tv;
memset(&tv, 0, sizeof(tv));
gettimeofday(&tv, 0);
if (beginningOfTime == 0)
{
beginningOfTime = tv.tv_sec;
}
return ((1000 * (tv.tv_sec - beginningOfTime)) + (tv.tv_usec / 1000));
}
return ((1000 * tp.tv_sec) + (tp.tv_nsec / 1000000));
}
static void parse_cmd_buf(char *buf, int *argc, char **argv)
{
char *p = buf;
int len = strlen(buf);
char *end = buf + len;
int search_arg_start = 1;
*argc = 0;
while (p < end)
{
if (search_arg_start)
{
if (*p != ' ')
{
argv[*argc] = p;
(*argc)++;
search_arg_start = 0;
}
}
else
{
if (*p == ' ')
{
search_arg_start = 1;
}
}
if (*p == ' ') *p = 0;
p++;
}
}
void xxPerfTest(void)
{
char myNameStorage[32];
perfTest = 1;
xxServiceDeregister(OPEN_BEST_ROUTE_SVC);
memset(myNameStorage, 0, sizeof(myNameStorage));
snprintf(myNameStorage, sizeof(myNameStorage), RPPI_APP_NAME);
myName.
pstart = myNameStorage;
myName.
size = strlen(myNameStorage) + 1;
if (xxBestRouteClientStart(getpid(), &myName) != XX_E_NONE)
{
xxCleanup();
exit(0);
}
}
void xxTestAddrFormatter(void)
{
char buffer[XX_MAX_STRING_LENGTH];
memset(&addr, 0, sizeof(addr));
addr.
addr.
ipv6.
u.
addr32[0] = htonl(0x66000000);
addr.addr.ipv6.u.addr32[1] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[2] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[3] = htonl(0x00000000);
printf("%s\n", ipAddressFormat(&addr, buffer));
addr.addr.ipv6.u.addr32[0] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[1] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[2] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[3] = htonl(0x00000003);
printf("%s\n", ipAddressFormat(&addr, buffer));
addr.addr.ipv6.u.addr32[0] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[1] = htonl(0x000a0000);
addr.addr.ipv6.u.addr32[2] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[3] = htonl(0x00000000);
printf("%s\n", ipAddressFormat(&addr, buffer));
addr.addr.ipv6.u.addr32[0] = htonl(0x80000000);
addr.addr.ipv6.u.addr32[1] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[2] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[3] = htonl(0x00000001);
printf("%s\n", ipAddressFormat(&addr, buffer));
addr.addr.ipv6.u.addr32[0] = htonl(0x01234567);
addr.addr.ipv6.u.addr32[1] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[2] = htonl(0x00000000);
addr.addr.ipv6.u.addr32[3] = htonl(0x89abcdef);
printf("%s\n", ipAddressFormat(&addr, buffer));
addr.addr.ipv6.u.addr32[0] = htonl(0x01230000);
addr.addr.ipv6.u.addr32[1] = htonl(0xdeadbeef);
addr.addr.ipv6.u.addr32[2] = htonl(0xaffe0000);
addr.addr.ipv6.u.addr32[3] = htonl(0x89abcdef);
printf("%s\n", ipAddressFormat(&addr, buffer));
}
void xxProcessCommand(char *cmd_buf, uint32_t cmd_argc, char **cmd_argv)
{
pthread_mutex_lock(&mutex);
if (!strcmp("show", cmd_argv[0]))
{
if (!strcmp("interfaces", cmd_argv[1]))
{
xxInterfacesShow();
}
else if (!strcmp("registrations", cmd_argv[1]))
{
xxRegistrationsShow();
}
else if (!strcmp("limits", cmd_argv[1]))
{
xxLimitsShow();
}
else if (!strcmp("ip", cmd_argv[1]))
{
if (!strcmp("route", cmd_argv[2]))
{
xxRoutesShow();
}
else
{
printf("\n invalid command \n");
}
}
else if (!strcmp("open", cmd_argv[1]))
{
if (!strcmp("routes", cmd_argv[2]))
{
if (cmd_argc == 3)
xxOpenRoutesShow(vrfId, 1);
else if (!strcmp("all", cmd_argv[3]))
xxOpenRoutesShow(vrfId, 0);
}
else if (!strcmp("route", cmd_argv[2]))
{
if (cmd_argc == 4)
xxOpenBestRouteLookup(cmd_argv);
else if (cmd_argc == 5)
xxOpenRouteFind(cmd_argv);
}
else
{
printf("\n invalid command \n");
}
}
else
{
printf("\n invalid command \n");
}
}
else if (!strcmp("ip", cmd_argv[0]))
{
if (!strcmp("route",cmd_argv[1]))
{
if (xxAddRoute(cmd_argc, cmd_argv) == XX_E_NONE)
printf("\nRoute added successfully.");
else
printf("\nFailed to add route.");
}
else
{
printf("\n invalid command \n");
}
}
else if (!strcmp("route-map", cmd_argv[0]))
{
xxRouteMapSet(cmd_argv[1]);
xxRouteMapReapply();
}
else if (!strcmp("prefix-list", cmd_argv[0]))
{
xxPrefixListSet(cmd_argv[1]);
xxPrefixListReapply();
}
else if (!strcmp("no", cmd_argv[0]))
{
if (!strcmp("ip",cmd_argv[1]))
{
if (!strcmp("route",cmd_argv[2]))
{
xxDeleteRoute(cmd_argc, cmd_argv);
}
}
else if (!strcmp("route-map", cmd_argv[1]))
{
xxRouteMapSet(NULL);
xxRouteMapReapply();
}
else if (strcmp("prefix-list", cmd_argv[1]))
{
xxPrefixListSet(NULL);
xxPrefixListReapply();
}
}
else if (!strcmp("test", cmd_argv[0]))
{
if (!strcmp("addrfmt",cmd_argv[1]))
{
xxTestAddrFormatter();
}
}
else if (!strcmp("perftest", cmd_argv[0]))
{
xxPerfTest();
}
else
{
printf("\n");
}
pthread_mutex_unlock(&mutex);
return;
}
{
uint32_t ip4_addr;
uint8_t addr8[16];
int af;
switch (addr->family)
{
af = AF_INET;
ip4_addr = htonl(addr->addr.
ipv4);
memcpy(addr8, &ip4_addr, sizeof(ip4_addr));
break;
af = AF_INET6;
memcpy(addr8, addr->addr.ipv6.u.
addr8,
sizeof(addr8));
break;
default:
sprintf(buffer, "%u", 0);
return(buffer);
}
return(inet_ntop(af, addr8, buffer, INET6_ADDRSTRLEN));
}
char *ipAddressAndPrefixFormat(
open_inet_addr_t *addr,
int prefixLen,
char *buffer)
{
char addrBuf[INET6_ADDRSTRLEN];
if (ipAddressFormat(addr, addrBuf) != NULL)
{
snprintf(buffer, INET6_ADDRSTRLEN + 3, "%s/%-2u", addrBuf, prefixLen);
return(buffer);
}
else
return(NULL);
}
char* getInterfaceType(uint32_t intfType)
{
switch (intfType)
{
return "Port";
return "VLAN";
return "Loop";
return "Tnnl";
}
return "";
}
char* getInterfaceState(uint32_t ifState)
{
switch (ifState)
{
return "Up";
return "Down";
}
return "";
}
{
switch (method)
{
return "None";
return "Manual";
return "DHCP";
}
return "";
}
char* getYesNoString(uint32_t value)
{
switch (value)
{
case 0:
return "No";
}
return "Yes";
}
void nextHopListBuffDescSizeSet(
open_buffdesc *nextHopListBuffDesc)
{
nextHopListBuffDesc->size = xxMaxNextHops *
sizeof(
openNextHop_t);
}
uint32_t nextHopListBuffDescStorageAllocate(
open_buffdesc *nextHopListBuffDesc)
{
nextHopListBuffDescSizeSet(nextHopListBuffDesc);
if ((nextHopListBuffDesc->pstart = malloc(nextHopListBuffDesc->size)) == NULL)
{
printf("\nFailed to allocate storage for next hop open_buffdesc.");
nextHopListBuffDesc->size = 0;
}
memset(nextHopListBuffDesc->pstart, 0, nextHopListBuffDesc->size);
return(nextHopListBuffDesc->size);
}
void nextHopListBuffDescStorageFree(
open_buffdesc *nextHopListBuffDesc)
{
free(nextHopListBuffDesc->pstart);
nextHopListBuffDesc->size = 0;
nextHopListBuffDesc->pstart = NULL;
}
{
uint32_t i, j;
if (!routeNextHopList || !nextHopListBuff)
{
return(0);
}
for (i = 0; ((i < xxMaxNextHops) &&
{
for (j = 0; j < OPEN_MAX_MPLS_IMPOSE_LABELS; j++)
{
routeNextHopList[i].
label[j] = nhExternal->
label[j];
}
nhExternal++;
}
return(i);
}
{
uint32_t i, j;
if (!routeNextHopList || !nextHopListBuff)
{
return;
}
for (i = 0; ((i < listEntryCount) &&
{
for (j = 0; j < OPEN_MAX_MPLS_IMPOSE_LABELS; j++)
{
nhExternal->
label[j] = routeNextHopList[i].
label[j];
}
nhExternal++;
}
}
void xxLimitsShow(void)
{
uint32_t protoNameLen;
uint32_t routeTypeNameLen;
uint32_t maxNextHops;
uint32_t routingIntfMax;
uint32_t ifNameSize;
printf("\nMaximum protocol name length: %u characters", protoNameLen);
else
printf("\nFailed to get max protocol name length. Error %d.", err);
printf("\nMaximum route type name length: %u characters", routeTypeNameLen);
else
printf("\nFailed to get max route type name length. Error %d.", err);
printf("\nECMP limit: %u next hops", maxNextHops);
else
printf("\nFailed to get ECMP limit. Error %d.", err);
printf("\nMax routing interfaces: %u", routingIntfMax);
else
printf("\nFailed to get max routing interfaces. Error %d.", err);
printf("\nMax length of an interface name: %u characters", ifNameSize);
else
printf("\nFailed to get max interface name length. Error %d.", err);
}
void xxRegistrationsShow(void)
{
uint32_t i, now;
printf("\n");
printf(" Client Seconds Since \n");
printf("Service Name ID Last Keepalive\n");
printf("-------------------- ------ --------------\n");
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if (xxRppiServices[i].inUse)
{
now = currentTimeGet() / 1000;
printf("%-20s %-6d %-10d\n",
openServiceName[xxRppiServices[i].service],
xxRppiServices[i].clientId,
(now - xxRppiServices[i].lastKeepTime));
}
}
}
void xxInterfacesShow(void)
{
uint32_t i;
uint32_t index;
char ipAddrBuf[XX_MAX_STRING_LENGTH];
printf("\n");
printf(" Addr Bandwidth IP Stack\n");
printf("Intf Name IP Address(es) Type Method State VLANID IP MTU (kbps) IfIndex \n");
printf("---- ---------- ------------------ ----- ------ ----- ------ ------ --------- --------\n");
for (i = 0; i < XX_ROUTE_INTF_MAX; i++)
{
index = 0;
if (xxRouteIntfTable[i].inUse != 0)
{
ipAddressAndPrefixFormat(&xxRouteIntfTable[i].ipAddrListIPv4[index].ipAddr,
xxRouteIntfTable[i].ipAddrListIPv4[index].pfxLen,
ipAddrBuf);
printf("%-4d %-10s %-18s %-5s %-6s %-5s %-6d %-6d %-9d %-8d",
xxRouteIntfTable[i].intf, xxRouteIntfTable[i].intfName, ipAddrBuf,
getInterfaceType(xxRouteIntfTable[i].intfType),
getIpAddrMethod(xxRouteIntfTable[i].ipAddrMethod),
getInterfaceState(xxRouteIntfTable[i].ifStateIPv4),
xxRouteIntfTable[i].vlanId, xxRouteIntfTable[i].ipMtuIPv4,xxRouteIntfTable[i].bandwidthIPv4,
xxRouteIntfTable[i].ifIndex);
index ++;
while (xxRouteIntfTable[i].ipAddrListIPv4[index].ipAddr.addr.ipv4 != 0)
{
ipAddressAndPrefixFormat(&xxRouteIntfTable[i].ipAddrListIPv4[index].ipAddr,
xxRouteIntfTable[i].ipAddrListIPv4[index].pfxLen,
ipAddrBuf);
printf("\n");
printf("%16s%-18s", " ", ipAddrBuf);
index++;
}
printf("\n");
}
}
}
{
char destPfxStr[XX_MAX_STRING_LENGTH];
char nhAddr[XX_MAX_STRING_LENGTH];
uint32_t i;
protoNameBuf.size++;
protoNameBuf.pstart = malloc(protoNameBuf.size);
routeTypeNameBuf.size++;
routeTypeNameBuf.pstart = malloc(routeTypeNameBuf.size);
intfNameBuf.size = XX_INTF_NAME_LEN_MAX + 1;
intfNameBuf.pstart = malloc(intfNameBuf.size);
if (!protoNameBuf.pstart || !routeTypeNameBuf.pstart || !intfNameBuf.pstart)
{
printf("\nOut of memory.");
return;
}
printf("\n");
if (printHeader)
{
printf(" Reject +----- NextHop(s) -----+ \n");
printf("Destination Type Pref Metric Route Address Intf Name\n");
printf("----------------- --------------- ---- ------ ------ -------------- ------------------------------\n");
}
ipAddressAndPrefixFormat(&route->
destPfx, route->
pfxLen, destPfxStr);
{
strcpy(routeTypeNameBuf.pstart, "Unknown");
}
printf("%-17s %-15s %-4d %-6d %-6s ",
destPfxStr, (
char *) routeTypeNameBuf.pstart, route->
pref, route->
metric,
{
ipAddressFormat(&nextHops->
nhAddr, nhAddr);
if (i != 0)
{
printf("\n");
printf("%53s", " ");
}
printf("%-14s %s", nhAddr, (char *)intfNameBuf.pstart);
nextHops++;
}
free(protoNameBuf.pstart);
free(routeTypeNameBuf.pstart);
free(intfNameBuf.pstart);
}
void xxOpenRoutesShow(uint32_t vrfId, uint32_t bestOnly)
{
uint32_t printHeader = 1;
nextHopListBuff.pstart = malloc(xxMaxNextHops *
sizeof(
openNextHop_t));
if (nextHopListBuff.pstart == NULL)
{
printf("\nOut of memory");
return;
}
if (bestOnly)
else
{
xxOpenRoutePrint(&route, nextHops, printHeader);
printHeader = 0;
if (bestOnly)
else
}
{
printf("\nFailed to get next OPEN best route. Error %d.", err);
}
free(nextHopListBuff.pstart);
}
void xxOpenRouteFind(char **cmd_argv)
{
char pfxStr[32];
uint32_t pfxLen;
struct sockaddr_in sa;
strcpy(pfxStr, cmd_argv[3]);
if (inet_pton(AF_INET, pfxStr, &(sa.sin_addr)) > 0)
{
pfx.addr.ipv4 = ntohl(sa.sin_addr.s_addr);
}
else
{
printf("\n invalid IPv4 prefix %s \n", pfxStr);
return;
}
pfxLen = atoi(cmd_argv[4]);
if ((pfxLen < 4) || (pfxLen > 32))
{
printf("\nInvalid prefix length %u", pfxLen);
return;
}
nextHopListBuff.pstart = malloc(xxMaxNextHops *
sizeof(
openNextHop_t));
if (nextHopListBuff.pstart == NULL)
{
printf("\nOut of memory");
return;
}
{
printf("\nFailed to lookup best route to %s/%u. Error %d.", pfxStr, pfxLen, err);
free(nextHopListBuff.pstart);
return;
}
xxOpenRoutePrint(&route, nextHops, 1);
free(nextHopListBuff.pstart);
}
void xxOpenBestRouteLookup(char **cmd_argv)
{
char ipAddrStr[32];
struct sockaddr_in sa;
strcpy(ipAddrStr, cmd_argv[3]);
if (inet_pton(AF_INET, ipAddrStr, &(sa.sin_addr)) > 0)
{
dest.addr.ipv4 = ntohl(sa.sin_addr.s_addr);
}
else
{
printf("\n invalid IPv4 address \n");
return;
}
nextHopListBuff.pstart = malloc(xxMaxNextHops *
sizeof(
openNextHop_t));
if (nextHopListBuff.pstart == NULL)
{
printf("\nOut of memory");
return;
}
{
printf("\nFailed to lookup best route to %s. Error %d.", ipAddrStr, err);
free(nextHopListBuff.pstart);
return;
}
xxOpenRoutePrint(&route, nextHops, 1);
free(nextHopListBuff.pstart);
}
void xxRoutesShow(void)
{
uint32_t i;
uint32_t index;
char ipAddr[XX_MAX_STRING_LENGTH];
char nhAddr[XX_MAX_STRING_LENGTH];
protoNameBuf.size++;
protoNameBuf.pstart = malloc(protoNameBuf.size);
routeTypeNameBuf.size++;
routeTypeNameBuf.pstart = malloc(routeTypeNameBuf.size);
intfNameBuf.size = XX_INTF_NAME_LEN_MAX + 1;
intfNameBuf.pstart = malloc(intfNameBuf.size);
if (!protoNameBuf.pstart || !routeTypeNameBuf.pstart || !intfNameBuf.pstart)
{
printf("\nOut of memory.");
return;
}
printf("\n");
printf("VRF ID = %d\n", vrfId);
printf("\n");
printf(" Reject Own +----- NextHop(s) -----+ \n");
printf("Destination Type Pref Metric Route Route Fwd Permit Address Intf Name MPLS Label(s)\n");
printf("----------------- --------------- ---- ------ ------ ----- --- ------ -------------- ------------------------------\n");
for (i = 0; i < XX_ROUTES_MAX; i++)
{
index = 0;
if (xxRouteTable[i].inUse != 0)
{
ipAddressAndPrefixFormat(&xxRouteTable[i].routeAttrs.destPfx,
xxRouteTable[i].routeAttrs.pfxLen,
ipAddr);
{
strcpy(routeTypeNameBuf.pstart, "Unknown");
}
printf("%-17s %-15s %-4d %-6d %-6s %-5s %-3s %-6s ",
ipAddr, (char *)routeTypeNameBuf.pstart,
xxRouteTable[i].routeAttrs.pref, xxRouteTable[i].routeAttrs.metric,
getYesNoString(xxRouteTable[i].routeAttrs.rejectRoute),
getYesNoString(xxRouteTable[i].isOurRoute),
getYesNoString(xxRouteTable[i].forwarding),
getYesNoString(xxRouteTable[i].permitted));
for (index = 0; index < xxRouteTable[i].routeAttrs.numNextHops; index++)
{
ipAddressFormat(&xxRouteTable[i].routeNextHopList[index].nhAddr, nhAddr);
if (index != 0)
{
printf("\n");
printf("%70s", " ");
}
printf("%-14s %-9s", nhAddr, (char *)intfNameBuf.pstart);
if (xxRouteTable[i].routeNextHopList[index].label[0])
{
printf(" %5u,%u,%u", xxRouteTable[i].routeNextHopList[index].label[0],
xxRouteTable[i].routeNextHopList[index].label[1],
xxRouteTable[i].routeNextHopList[index].label[2]);
}
}
printf("\n");
}
}
free(protoNameBuf.pstart);
free(routeTypeNameBuf.pstart);
free(intfNameBuf.pstart);
}
xx_error_t xxAddRoute(uint32_t cmd_argc, char **cmd_argv)
{
uint8_t pfxLen;
char strIPaddr[XX_MAX_STRING_LENGTH];
char strSubnetMask[XX_MAX_STRING_LENGTH];
char strNextHopRtr[XX_MAX_STRING_LENGTH];
char metricStr[XX_MAX_STRING_LENGTH];
char labelStr[XX_MAX_STRING_LENGTH];
uint32_t netMask;
uint32_t metric;
uint32_t label[OPEN_MAX_MPLS_IMPOSE_LABELS];
struct sockaddr_in sa;
if ((cmd_argc < 5) || (cmd_argc > 9))
{
printf("\nUsage: ip route <destination prefix> <subnet mask> <next hop address> [<metric>] "
"[<mpls-label1>] [<mpls-label2>] [<mpls-label3>]");
return(XX_E_FAIL);
}
strcpy(strIPaddr,cmd_argv[2]);
if (inet_pton(AF_INET, strIPaddr, &(sa.sin_addr)) > 0)
{
destPfx.addr.ipv4 = ntohl(sa.sin_addr.s_addr);
}
else
{
printf("\n invalid ip address \n");
return(XX_E_FAIL);
}
strcpy(strSubnetMask,cmd_argv[3]);
if (inet_pton(AF_INET,strSubnetMask,&(sa.sin_addr)) > 0)
{
netMask = ntohl(sa.sin_addr.s_addr);
pfxLen = xxInetMaskLengthGet(netMask);
}
else
{
printf("\n invalid subnet mask \n");
return(XX_E_FAIL);
}
strcpy(strNextHopRtr,cmd_argv[4]);
if (inet_pton(AF_INET,strNextHopRtr,&(sa.sin_addr)) > 0)
{
nhAddr.addr.ipv4 = ntohl(sa.sin_addr.s_addr);
}
else
{
printf("\n invalid next hop address \n");
return(XX_E_FAIL);
}
if (cmd_argc == 6)
{
strcpy(metricStr,cmd_argv[5]);
metric = atoi(metricStr);
}
else
{
metric = 1;
}
if (cmd_argc >= 7)
{
strcpy(labelStr,cmd_argv[6]);
label[0] = atoi(labelStr);
}
else
{
label[0] = 0;
}
if (cmd_argc >= 8)
{
strcpy(labelStr,cmd_argv[7]);
label[1] = atoi(labelStr);
}
else
{
label[1] = 0;
}
if (cmd_argc >= 9)
{
strcpy(labelStr,cmd_argv[8]);
label[2] = atoi(labelStr);
}
else
{
label[2] = 0;
}
return(xxOwnRouteAdd(destPfx, pfxLen, nhAddr, metric, label));
}
void xxDeleteRoute(uint32_t cmd_argc, char **cmd_argv)
{
uint8_t pfxLen;
char strIPaddr[XX_MAX_STRING_LENGTH];
char strSubnetMask[XX_MAX_STRING_LENGTH];
char strNextHopRtr[XX_MAX_STRING_LENGTH];
uint32_t netMask;
struct sockaddr_in sa;
if ((cmd_argc < 5) || (cmd_argc > 6))
{
printf("\nUsage: no ip route <destination prefix> <subnet mask> [<next hop address>] ");
return;
}
strcpy(strIPaddr,cmd_argv[3]);
if (inet_pton(AF_INET,strIPaddr,&(sa.sin_addr)) > 0)
{
destPfx.addr.ipv4 = ntohl(sa.sin_addr.s_addr);
}
else
{
printf("\n invalid ip address \n");
return;
}
strcpy(strSubnetMask,cmd_argv[4]);
if (inet_pton(AF_INET,strSubnetMask,&(sa.sin_addr)) > 0)
{
netMask = ntohl(sa.sin_addr.s_addr);
pfxLen = xxInetMaskLengthGet(netMask);
}
else
{
printf("\n invalid subnet mask \n");
return;
}
if (cmd_argc == 6)
{
strcpy(strNextHopRtr,cmd_argv[5]);
if (inet_pton(AF_INET,strNextHopRtr,&(sa.sin_addr)) > 0)
{
nhAddr.addr.ipv4 = ntohl(sa.sin_addr.s_addr);
}
else
{
printf("\n invalid next hop Address \n");
return;
}
}
xxOwnRouteDelete(destPfx, pfxLen, nhAddr);
}
uint32_t xxPfxLenToMask(uint32_t pfxLen)
{
if (pfxLen > 32)
{
printf("\nInvalid prefix length %u", pfxLen);
return 32;
}
if (pfxLen == 0)
return 0;
else
return 0xFFFFFFFF << (32 - pfxLen);
}
uint32_t xxInetMaskLengthGet(uint32_t mask)
{
uint32_t maskSize,maskLen, tempLen;
uint32_t maskBit;
uint32_t zeroFound = 0;
maskSize = sizeof(uint32_t) <<3;
maskBit =0x1 << (maskSize-1);
maskLen=0;
for (tempLen =0;tempLen <maskSize;tempLen++)
{
if (!(mask & maskBit))
{
if (zeroFound == 0)
{
zeroFound = 1;
}
}
else
{
if (zeroFound == 1)
{
return -1;
}
maskLen++;
}
mask = mask << 1;
}
return maskLen;
}
xx_error_t xxRouteMapSet(char *rmName)
{
uint32_t nameLen;
if (routeMapName)
{
free(routeMapName);
routeMapName = NULL;
}
if (rmName)
{
nameLen = strlen(rmName) + 1;
if (nameLen > XX_MAX_STRING_LENGTH)
return XX_E_FAIL;
routeMapName = (char*) malloc(nameLen);
if (routeMapName == NULL)
return XX_E_FAIL;
strcpy(routeMapName, rmName);
}
return XX_E_NONE;
}
xx_error_t xxPrefixListSet(char *plName)
{
uint32_t nameLen;
if (pfxListName)
{
free(pfxListName);
pfxListName = NULL;
}
if (plName)
{
nameLen = strlen(plName) + 1;
if (nameLen > XX_MAX_STRING_LENGTH)
return XX_E_FAIL;
pfxListName = (char*) malloc(nameLen);
if (pfxListName == NULL)
return XX_E_FAIL;
strcpy(pfxListName, plName);
}
return XX_E_NONE;
}
{
int permitted = 1;
if (routeMapName)
{
policy.pstart = routeMapName;
policy.size = strlen(routeMapName) + 1;
matchParams.
prefix = route->
destPfx;
matchParams.
prefixLen = route->pfxLen;
if (permitted == 1)
{
{
route->
metric = setParams.
metric;
}
}
else if (permitted < 0)
{
printf("\nError %d applying route map %s", permitted, routeMapName);
permitted = 0;
}
}
if (permitted && pfxListName)
{
policy.pstart = pfxListName;
policy.size = strlen(pfxListName) + 1;
if (permitted < 0)
{
printf("\nError %d applying prefix list %s", permitted, pfxListName);
permitted = 0;
}
}
return(uint32_t) permitted;
}
void xxRouteMapReapply(void)
{
uint32_t i;
int permitted = 1;
if (routeMapName)
{
policy.pstart = routeMapName;
policy.size = strlen(routeMapName) + 1;
}
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if ((xxRouteTable[i].inUse) && (xxRouteTable[i].forwarding))
{
if (routeMapName)
{
matchParams.prefix = xxRouteTable[i].routeAttrs.destPfx;
matchParams.prefixLen = xxRouteTable[i].routeAttrs.pfxLen;
}
if (permitted >= 0)
{
xxRouteTable[i].permitted = permitted;
if (permitted && setParams.setMetric)
xxRouteTable[i].routeAttrs.metric = setParams.metric;
}
}
}
}
void xxPrefixListReapply(void)
{
uint32_t i;
int permitted = 1;
if (pfxListName)
{
policy.pstart = pfxListName;
policy.size = strlen(pfxListName) + 1;
}
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if ((xxRouteTable[i].inUse) && (xxRouteTable[i].forwarding))
{
if (pfxListName)
{
xxRouteTable[i].routeAttrs.pfxLen);
}
if (permitted >= 0)
{
xxRouteTable[i].permitted = permitted;
}
}
}
}
void xxRouteTableEntryClear(xxRoute_t *entry)
{
uint32_t i;
if (!entry)
{
return;
}
entry->forwarding = 0;
entry->isOurRoute = 0;
entry->permitted = 0;
for (i = 0; i < xxMaxNextHops; i++)
{
}
entry->inUse = 0;
}
uint32_t ownRoute, uint32_t forwarding, uint32_t permitted)
{
uint32_t i;
char addrBuf[INET6_ADDRSTRLEN];
ipAddressFormat(&route->
destPfx, addrBuf);
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if (xxRouteTable[i].inUse == 0)
{
xxRouteTable[i].inUse = 1;
memcpy(&xxRouteTable[i].routeAttrs, route,
sizeof(
openRoute_t));
xxRouteTable[i].isOurRoute = ownRoute;
xxRouteTable[i].forwarding = forwarding;
xxRouteTable[i].permitted = permitted;
xxRouteTable[i].routeAttrs.numNextHops =
nextHopBuffDescUnpack(xxRouteTable[i].routeNextHopList, nextHopListBuff);
printf("%s: Added route to %s\n", __FUNCTION__, addrBuf);
return XX_E_NONE;
}
}
return XX_E_FAIL;
}
{
uint32_t i;
uint32_t j;
char addrBuf[INET6_ADDRSTRLEN];
ipAddressFormat(&destPfx, addrBuf);
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if (xxRouteTable[i].inUse != 0)
{
if (OPEN_IS_ADDR_EQUAL(&xxRouteTable[i].routeAttrs.destPfx, &destPfx) &&
(xxRouteTable[i].routeAttrs.pfxLen == pfxLen) &&
(xxRouteTable[i].routeAttrs.routeType == routeType))
{
if ((nhAddr.addr.ipv4 == 0) ||
((xxRouteTable[i].routeAttrs.numNextHops == 1) &&
(nhAddr.addr.ipv4 == xxRouteTable[i].routeNextHopList[0].nhAddr.addr.ipv4)))
{
xxRouteTableEntryClear(&xxRouteTable[i]);
printf("%s: Deleted route to %s\n", __FUNCTION__, addrBuf);
return XX_E_NONE;
}
else
{
for (j = 0; j < xxMaxNextHops; j++)
{
if (nhAddr.addr.ipv4 == xxRouteTable[i].routeNextHopList[j].nhAddr.addr.ipv4)
{
xxRouteTable[i].routeAttrs.numNextHops--;
memset(&xxRouteTable[i].routeNextHopList[j], 0,
sizeof(
openNextHop_t));
for ( ; j < xxMaxNextHops-1; j++)
{
if (xxRouteTable[i].routeNextHopList[j+1].nhAddr.addr.ipv4 != 0)
xxRouteTable[i].routeNextHopList[j] = xxRouteTable[i].routeNextHopList[j+1];
else
break;
}
if (j < xxMaxNextHops)
{
memset(&xxRouteTable[i].routeNextHopList[j], 0,
sizeof(
openNextHop_t));
}
return XX_E_NONE;
}
}
}
}
}
}
return XX_E_FAIL;
}
void xxRoutingTableUpdate(void)
{
uint32_t i;
uint32_t index;
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if (xxRouteTable[i].inUse != 0)
{
for (index = 0; index < xxRouteTable[i].routeAttrs.numNextHops; index++)
{
if (xxAddressResolve(xxRouteTable[i].routeNextHopList[index].nhAddr,
&xxRouteTable[i].routeNextHopList[index].ifNum) != XX_E_NONE)
{
xxRouteTable[i].routeNextHopList[index].ifNum = 0;
}
}
}
}
}
{
uint32_t intfMask;
uint32_t i, j;
for (i = 0; i < XX_ROUTE_INTF_MAX; i++)
{
if (xxRouteIntfTable[i].inUse != 0)
{
for (j = 0; j < XX_INTF_IP_MAX; j++)
{
if (xxRouteIntfTable[i].ipAddrListIPv4[j].ipAddr.addr.ipv4 != 0)
{
intfMask = xxPfxLenToMask(xxRouteIntfTable[i].ipAddrListIPv4[j].pfxLen);
if ((nhAddr.addr.ipv4 & intfMask) ==
(xxRouteIntfTable[i].ipAddrListIPv4[j].ipAddr.addr.ipv4 & intfMask))
{
*intIfNum = xxRouteIntfTable[i].intf;
return XX_E_NONE;
}
}
}
}
}
return XX_E_FAIL;
}
{
uint32_t i;
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if (xxRouteTable[i].inUse != 0)
{
if ((xxRouteTable[i].routeAttrs.routeType == intRouteType) &&
(xxRouteTable[i].routeAttrs.pfxLen == pfxLen) &&
(OPEN_IS_ADDR_EQUAL(&xxRouteTable[i].routeAttrs.destPfx, &destPfx)))
{
return &xxRouteTable[i];
}
}
}
return NULL;
}
uint32_t label[OPEN_MAX_MPLS_IMPOSE_LABELS])
{
xxRoute_t *ownRoute;
uint32_t intIfNum = 0, j;
int result;
if (vrfId == 0)
{
if (xxAddressResolve(nhAddr, &intIfNum) != XX_E_NONE)
{
printf("\n Failed to find an interface for the next hop address \n");
return XX_E_FAIL;
}
}
else
{
intIfNum = 100;
}
route.pfxLen = pfxLen;
route.
pref = XX_OWN_ROUTE_PREF;
nextHopList[0].
ifNum = intIfNum;
nextHopList[0].
nhAddr = nhAddr;
for (j = 0; j < OPEN_MAX_MPLS_IMPOSE_LABELS; j++)
{
nextHopList[0].
label[j] = label[j];
}
if (nextHopListBuffDescStorageAllocate(&nextHopListBuffDesc) == 0)
{
printf("\n Failed to allocate storage for the next hop list.\n");
return XX_E_FAIL;
}
ownRoute = xxOwnRouteFind(destPfx, pfxLen);
if (ownRoute)
{
if (metric < ownRoute->routeAttrs.metric)
{
noNextHop.family = destPfx.family;
xxRouteTableDel(destPfx, pfxLen, noNextHop, intRouteType);
nextHopBuffDescPack(nextHopList, 1, &nextHopListBuffDesc);
xxRouteTableAdd(&route, &nextHopListBuffDesc, 1, 0, 0);
{
printf("\nFailed to modify route in OPEN route table");
}
nextHopListBuffDescStorageFree(&nextHopListBuffDesc);
return(result);
}
else if (metric == ownRoute->routeAttrs.metric)
{
uint32_t i, foundNextHop;
foundNextHop = 0;
for (i=0; ((i < xxMaxNextHops) &&
(ownRoute->routeNextHopList[i].nhAddr.addr.ipv4 != 0)); i++)
{
if (ownRoute->routeNextHopList[i].nhAddr.addr.ipv4 == nhAddr.addr.ipv4)
{
foundNextHop = 1;
break;
}
}
if ((!foundNextHop) && (i < xxMaxNextHops))
{
if (ownRoute->routeNextHopList[i].nhAddr.addr.ipv4 == 0)
{
ownRoute->routeNextHopList[i].nhAddr = nhAddr;
ownRoute->routeNextHopList[i].ifNum = intIfNum;
for (j = 0; j < OPEN_MAX_MPLS_IMPOSE_LABELS; j++)
{
ownRoute->routeNextHopList[i].label[j] = label[j];
}
ownRoute->routeAttrs.numNextHops++;
nextHopBuffDescPack(ownRoute->routeNextHopList, ownRoute->routeAttrs.numNextHops, &nextHopListBuffDesc);
{
printf("\nFailed to modify route in OPEN route table");
}
foundNextHop = 1;
}
}
nextHopListBuffDescStorageFree(&nextHopListBuffDesc);
if (foundNextHop)
{
return XX_E_NONE;
}
else
{
return XX_E_FAIL;
}
}
}
nextHopBuffDescPack(nextHopList, 1, &nextHopListBuffDesc);
if (xxRouteTableAdd(&route, &nextHopListBuffDesc, 1, 0, 0) != XX_E_NONE)
{
printf("\nFailed to add route to the local routing table ");
nextHopListBuffDescStorageFree(&nextHopListBuffDesc);
return XX_E_FAIL;
}
{
printf("\nFailed to add route to the NOS routing table. result = %d", result);
}
nextHopListBuffDescStorageFree(&nextHopListBuffDesc);
return XX_E_NONE;
}
void xxWithdrawOwnRoutes(void)
{
uint32_t i;
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if ((xxRouteTable[i].inUse != 0) &&
(xxRouteTable[i].isOurRoute))
{
route.
destPfx = xxRouteTable[i].routeAttrs.destPfx;
route.pfxLen = xxRouteTable[i].routeAttrs.pfxLen;
route.
routeType = xxRouteTable[i].routeAttrs.routeType;
}
}
}
{
xxRoute_t *routeTableEntry;
routeTableEntry = xxOwnRouteFind(destPfx, pfxLen);
if (!routeTableEntry)
return XX_E_FAIL;
route.pfxLen = pfxLen;
if ((nhAddr.addr.ipv4 == 0) ||
((nhAddr.addr.ipv4 == routeTableEntry->routeNextHopList[0].nhAddr.addr.ipv4) &&
(routeTableEntry->routeAttrs.numNextHops == 1)))
{
{
printf("\nFailed to delete route from switch");
}
if (xxRouteTableDel(destPfx, pfxLen, nhAddr, intRouteType) != XX_E_NONE)
{
printf("\nFailed to delete route from local routing table");
}
}
else
{
if (xxRouteTableDel(destPfx, pfxLen, nhAddr, intRouteType) != XX_E_NONE)
{
printf("\nFailed to delete route from local routing table");
}
if (routeTableEntry)
{
route.
numNextHops = routeTableEntry->routeAttrs.numNextHops;
nextHopListBuffDescStorageAllocate(&nextHopList);
nextHopBuffDescPack(routeTableEntry->routeNextHopList, routeTableEntry->routeAttrs.numNextHops, &nextHopList);
{
printf("\nFailed to modify route in switch");
}
nextHopListBuffDescStorageFree(&nextHopList);
}
}
return XX_E_NONE;
}
xx_error_t xxRppiSvcAdd(OPEN_SERVICE_t svc, char *name, pid_t pid, uint32_t clientId, int32_t fd)
{
uint32_t i;
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if (xxRppiServices[i].inUse == 0)
{
xxRppiServices[i].inUse = 1;
xxRppiServices[i].service = svc;
strncpy(xxRppiServices[i].clientName, name, OPEN_RPPI_CLIENT_NAME_MAX_LEN);
xxRppiServices[i].pid = pid;
xxRppiServices[i].clientId = clientId;
xxRppiServices[i].sockFd = fd;
xxRppiServices[i].lastKeepTime = currentTimeGet() / 1000;
printf("\nSuccessfully registered for OPEN %s service with client ID %u and socket fd %d.",
openServiceName[svc], clientId, fd);
return XX_E_NONE;
}
}
return XX_E_FAIL;
}
void xxRppiSvcDel(OPEN_SERVICE_t svc)
{
uint32_t i;
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if ((xxRppiServices[i].inUse != 0) && (xxRppiServices[i].service == svc))
{
xxRppiServices[i].inUse = 0;
xxRppiServices[i].service = 0;
xxRppiServices[i].clientId = 0;
xxRppiServices[i].sockFd = -1;
xxRppiServices[i].lastKeepTime = 0;
printf("\nSuccessfully removed RPPI service entry for %s service.\n",
openServiceName[svc]);
return;
}
}
return;
}
uint32_t xxClientIdGet(OPEN_SERVICE_t svc)
{
uint32_t i;
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if ((xxRppiServices[i].inUse != 0) && (xxRppiServices[i].service == svc))
{
return xxRppiServices[i].clientId;
}
}
return 0;
}
void xxKeepTimeUpdate(OPEN_SERVICE_t service)
{
uint32_t now = currentTimeGet() / 1000;
uint32_t i;
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if ((xxRppiServices[i].inUse != 0) && (xxRppiServices[i].service == service))
{
xxRppiServices[i].lastKeepTime = now;
}
}
}
void xxKeepaliveStatusCheck(void)
{
uint32_t now = currentTimeGet() / 1000;
uint32_t i;
xx_error_t xxerr;
char myNameStorage[32];
OPEN_SERVICE_t service;
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if (xxRppiServices[i].inUse != 0)
{
if ((now - xxRppiServices[i].lastKeepTime) > XX_SERVICE_TIMEOUT)
{
printf("\nKeepalive timeout for %s service",
openServiceName[xxRppiServices[i].service]);
xxServiceDeregister(xxRppiServices[i].service);
if (xxRppiServices[i].sockFd)
{
close(xxRppiServices[i].sockFd);
xxRppiServices[i].sockFd = -1;
}
service = xxRppiServices[i].service;
xxRppiSvcDel(xxRppiServices[i].service);
memset(myNameStorage, 0, sizeof(myNameStorage));
snprintf(myNameStorage, sizeof(myNameStorage), RPPI_APP_NAME);
myName.pstart = myNameStorage;
myName.size = strlen(myNameStorage) + 1;
xxerr = XX_E_FAIL;
switch (service)
{
case OPEN_ROUTER_EVENT_SVC:
xxerr = xxRouterEventClientStart(getpid(), &myName);
break;
case OPEN_BEST_ROUTE_SVC:
xxerr = xxBestRouteClientStart(getpid(), &myName);
break;
case OPEN_POLICY_SVC:
xxerr = xxPolicyClientStart(getpid(), &myName);
break;
default:
;
}
if (xxerr != XX_E_NONE)
{
xxCleanup();
exit(1);
}
}
}
}
}
uint32_t xxReadFdsGet(fd_set *readFds)
{
uint32_t i;
int32_t maxFd = -1;
FD_ZERO(readFds);
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if (xxRppiServices[i].inUse && (xxRppiServices[i].sockFd > 0))
{
FD_SET(xxRppiServices[i].sockFd, readFds);
if (xxRppiServices[i].sockFd > maxFd)
{
maxFd = xxRppiServices[i].sockFd;
}
}
}
return maxFd + 1;
}
void xxPolicyChangeMsgProcess(void *msg, uint32_t msgLen)
{
char polName[XX_MAX_STRING_LENGTH + 1];
uint32_t nameLen;
{
printf("\nInvalid policy change message length %u", msgLen);
return;
}
if (nameLen >= XX_MAX_STRING_LENGTH)
{
printf("\nPolicy name too long -- %u characters", nameLen);
return;
}
memset(polName, 0, sizeof(polName));
strncpy(polName, p, nameLen);
printf("\nReceived policy change message with len %u, seqNo %u, policy type %s, change type %s, %s",
(m->
policyType == OPEN_POLICY_ROUTE_MAP) ?
"Route Map" :
(m->policyType == OPEN_POLICY_PREFIX_LIST) ? "Prefix List" : "Invalid",
polName);
{
printf("\nACK failed");
}
if (routeMapName &&
(m->policyType == OPEN_POLICY_ROUTE_MAP) &&
(strcmp(routeMapName, polName) == 0))
{
xxRouteMapReapply();
}
else if (pfxListName &&
(m->policyType == OPEN_POLICY_PREFIX_LIST) &&
(strcmp(pfxListName, polName) == 0))
{
xxPrefixListReapply();
}
}
void xxEventProcess(OPEN_SERVICE_t service, void *msg, uint32_t msgLen)
{
uint32_t clientId;
int index;
m = msg;
{
printf("\nError. Read %u bytes of message %u from service %u, but message reports its length as %u\n",
msgLen, m->
msgType, service, m->msgLen);
return;
}
if (m->msgType == OPENR_KEEPALIVE)
{
xxKeepTimeUpdate(service);
return;
}
printf("\nReceived message for %s service with msg type %s and length %u bytes\n",
openServiceName[service], xxMsgTypeNameGet(m->msgType), msgLen);
clientId = xxClientIdGet(service);
switch (m->msgType)
{
case OPENR_RTR_ENABLE:
break;
case OPENR_RTR_DISABLE:
break;
case OPENR_RTR_STARTUP_DONE:
xxPopulateRoutingInterfaceTable();
break;
case OPENR_RTR_INTF_CREATE:
xxRouteIntfTableAdd(m->
ifNum);
break;
case OPENR_RTR_INTF_DELETE:
xxRouteIntfTableDel(m->ifNum);
break;
case OPENR_RTR_INTF_ENABLE:
xxRouteIntfTableAdd(m->ifNum);
xxRoutingTableUpdate();
break;
case OPENR_RTR_INTF_DISABLE:
index = xxGetInterfaceIndexFromTable(m->ifNum);
if (index >= 0)
{
xxRouteIntfTableDel(m->ifNum);
}
xxRoutingTableUpdate();
break;
case OPENR_RTR_INTF_MTU:
index = xxGetInterfaceIndexFromTable(m->ifNum);
if (index >= 0)
{
}
break;
case OPENR_RTR_INTF_BW_CHANGE:
index = xxGetInterfaceIndexFromTable(m->ifNum);
if (index >= 0)
{
}
break;
case OPENR_RTR_INTF_ADDR_CHANGE:
(void) xxIntfIpv4AddrsUpdate(m->ifNum);
xxRoutingTableUpdate();
break;
case OPENR_RTR_INTF_HOST_MODE:
xxRouteIntfTableDel(m->ifNum);
xxRoutingTableUpdate();
break;
case OPENR_BEST_ROUTE_CHANGE:
break;
case OPENR_POLICY_CHANGE:
xxPolicyChangeMsgProcess(msg, msgLen);
break;
default:
break;
}
if ((m->msgType >= OPENR_RTR_ENABLE) && (m->msgType < OPENR_POLICY_CHANGE))
{
}
return;
}
{
uint32_t i;
uint32_t routeFound = 0;
uint32_t permitted;
permitted = xxPolicyApply(route);
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if (!xxRouteTable[i].inUse)
continue;
if ((xxRouteTable[i].routeAttrs.pfxLen == route->pfxLen) &&
OPEN_IS_ADDR_EQUAL(&xxRouteTable[i].routeAttrs.destPfx, &route->
destPfx))
{
if (xxRouteTable[i].routeAttrs.routeType == route->
routeType)
{
routeFound = 1;
if (xxRouteTable[i].isOurRoute)
{
xxRouteTable[i].forwarding = 1;
xxRouteTable[i].permitted = permitted;
}
else
{
memcpy(&xxRouteTable[i].routeAttrs, route,
sizeof(
openRoute_t));
xxRouteTable[i].routeAttrs.numNextHops =
nextHopBuffDescUnpack(xxRouteTable[i].routeNextHopList, nextHopListBuff);
xxRouteTable[i].forwarding = 1;
xxRouteTable[i].permitted = permitted;
}
}
else
{
if (xxRouteTable[i].isOurRoute)
{
xxRouteTable[i].forwarding = 0;
}
else
{
xxRouteTableEntryClear(&xxRouteTable[i]);
}
}
}
}
if (!routeFound)
{
xxRouteTableAdd(route, nextHopListBuff, 0, 1, permitted);
}
}
{
uint32_t i;
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if (!xxRouteTable[i].inUse)
continue;
if ((xxRouteTable[i].routeAttrs.pfxLen == route->pfxLen) &&
OPEN_IS_ADDR_EQUAL(&xxRouteTable[i].routeAttrs.destPfx, &route->
destPfx))
{
if (xxRouteTable[i].isOurRoute)
{
xxRouteTable[i].forwarding = 0;
}
else
{
xxRouteTableEntryClear(&xxRouteTable[i]);
}
}
}
}
{
uint32_t numChanges = 0;
uint32_t startTime = currentTimeGet();
if (nextHopListBuffDescStorageAllocate(&nextHopListBuffDesc) == 0)
{
printf("\n Failed to allocate storage for the next hop list.\n");
return;
}
{
if (perfTest == 0)
{
switch (chType)
{
case OPEN_ADD_ROUTE: xxBestRouteAdd(&route, &nextHopListBuffDesc); break;
case OPEN_CHANGE_ROUTE: xxBestRouteAdd(&route, &nextHopListBuffDesc); break;
case OPEN_DELETE_ROUTE: xxBestRouteDel(&route) ; break;
default:
printf("\nInvalid route change type %d", chType);
}
}
numChanges++;
nextHopListBuffDescSizeSet(&nextHopListBuffDesc);
}
nextHopListBuffDescStorageFree(&nextHopListBuffDesc);
{
printf("\nError %d retrieving best route changes.", err);
}
else if (perfTest)
{
uint32_t endTime = currentTimeGet();
printf("\nProcessed %u changes in %u ms (%u changes/sec)\n",
numChanges, endTime - startTime, (1000 * numChanges) / (endTime - startTime));
perfTest = 0;
}
}
void xxSocketsRead(fd_set *readFds)
{
uint32_t i;
uint32_t bytesRcvd;
unsigned char buffer[RPPI_MSG_SIZE_MAX];
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if (xxRppiServices[i].inUse && FD_ISSET(xxRppiServices[i].sockFd, readFds))
{
do
{
bytesRcvd = recvfrom(xxRppiServices[i].sockFd, &buffer, sizeof(buffer), 0, 0, 0);
} while ((bytesRcvd < 0) && (EINTR == errno));
if (bytesRcvd <= 0)
{
printf("\nFailed to read socket with fd %d for service %d error %s",
xxRppiServices[i].sockFd, xxRppiServices[i].service, (bytesRcvd < 0) ? strerror(errno) : "no data");
}
else
{
xxEventProcess(xxRppiServices[i].service, buffer, bytesRcvd);
}
}
}
}
void *xxReceiveThread(void *arg)
{
struct timeval timeout;
int32_t ret;
fd_set readFds;
int32_t maxFds = -1;
while (1)
{
maxFds = xxReadFdsGet(&readFds);
timeout.tv_sec = XX_SELECT_TIMEOUT;
timeout.tv_usec = 0;
ret = select(maxFds, &readFds, NULL, NULL, &timeout);
if (ret < 0)
{
printf("\nselect() error %d", errno);
}
else if (ret == 0)
{
}
else
{
pthread_mutex_lock(&mutex);
xxSocketsRead(&readFds);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex);
xxKeepaliveStatusCheck();
pthread_mutex_unlock(&mutex);
}
}
void xxCleanup(void)
{
uint32_t i;
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if (xxRppiServices[i].inUse == 1)
{
xxServiceDeregister(xxRppiServices[i].service);
}
}
xxWithdrawOwnRoutes();
{
L7PROC_LOGF (L7PROC_LOG_SEVERITY_ERROR, 0, "Failed to De-register External "
"route save mechanism with RTO");
}
{
printf("\nError %d deregistering protoId %u", err, protoId);
}
sleep(1);
if (routeMapName)
free(routeMapName);
if (pfxListName)
free(pfxListName);
L7PROC_LOGF(L7PROC_LOG_SEVERITY_INFO, 0, "Stopping RPPI example application");
return;
}
xx_error_t rppiClientSockCreate(char *addrFormat, uint32_t clientId, int *fd)
{
struct sockaddr_un fpsockaddr;
int addrlen, sockfd = -1;
unsigned int rcvSize = (10 * 1024);
if (fd == NULL)
{
return XX_E_FAIL;
}
memset(&fpsockaddr, 0, sizeof(fpsockaddr));
fpsockaddr.sun_family = AF_UNIX;
snprintf(fpsockaddr.sun_path, sizeof(fpsockaddr.sun_path) - 1, addrFormat, clientId);
addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(fpsockaddr.sun_path);
if (0 > (sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)))
{
return XX_E_FAIL;
}
unlink((const char *)fpsockaddr.sun_path);
if (0 > bind(sockfd, (const struct sockaddr *)&fpsockaddr, addrlen))
{
close(sockfd);
return XX_E_FAIL;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvSize, sizeof(rcvSize)) == -1)
{
close(sockfd);
return XX_E_FAIL;
}
*fd = sockfd;
return XX_E_NONE;
}
void xxServiceDeregister(OPEN_SERVICE_t service)
{
uint32_t i;
for (i = 0; i < OPEN_SERVICES_MAX; i++)
{
if ((xxRppiServices[i].inUse == 1) && (xxRppiServices[i].service == service))
{
switch (service)
{
case OPEN_ROUTER_EVENT_SVC:
break;
case OPEN_BEST_ROUTE_SVC:
break;
case OPEN_POLICY_SVC:
nameBuf.pstart = xxRppiServices[i].clientName;
nameBuf.size = strlen(xxRppiServices[i].clientName) + 1;
break;
default:
printf("\nAttempt to deregister from unknown RPPI service %u", service);
}
if (xxRppiServices[i].sockFd)
{
close(xxRppiServices[i].sockFd);
xxRppiServices[i].sockFd = -1;
}
xxRppiSvcDel(service);
}
}
}
xx_error_t xxRouterEventClientStart(pid_t myPid,
open_buffdesc *myName)
{
xx_error_t xxerr;
uint32_t clientId;
int32_t fd = -1;
{
printf("\nFailed to register as router event client (err = %d) -", err);
switch (err)
{
case OPEN_E_FULL: printf(
"Client list already full\n");
break;
case OPEN_E_EXISTS: printf(
"Client name already registered\n");
break;
default: printf("Other failure\n");
}
return XX_E_FAIL;
}
xxerr = rppiClientSockCreate(ROUTER_EVENT_CLIENT_ADDR, clientId, &fd);
if (xxerr != XX_E_NONE)
{
printf("\nFailed to create router event client socket.");
return xxerr;
}
xxRppiSvcAdd(OPEN_ROUTER_EVENT_SVC, myName->pstart, myPid, clientId, fd);
return XX_E_NONE;
}
xx_error_t xxBestRouteClientStart(pid_t myPid,
open_buffdesc *myName)
{
xx_error_t xxerr;
uint32_t clientId;
int32_t fd = -1;
{
sleep(1);
}
{
printf("\nFailed to register as best route change client");
switch (err)
{
case OPEN_E_FULL: printf(
"\nClient list already full");
break;
case OPEN_E_EXISTS: printf(
"\nClient name already registered");
break;
default: printf("\nOther failure");
}
return XX_E_FAIL;
}
printf("RPPI returned client id %d for VRF %d\n", clientId, vrfId);
if (xxerr != XX_E_NONE)
{
printf("\nFailed to create router event client socket.");
return xxerr;
}
xxRppiSvcAdd(OPEN_BEST_ROUTE_SVC, myName->pstart, myPid, clientId, fd);
return XX_E_NONE;
}
xx_error_t xxPolicyClientStart(pid_t myPid,
open_buffdesc *myName)
{
xx_error_t xxerr;
uint32_t clientId;
int32_t fd = -1;
OPEN_POLICY_ROUTE_MAP | OPEN_POLICY_PREFIX_LIST,
&clientId);
{
sleep(1);
OPEN_POLICY_ROUTE_MAP | OPEN_POLICY_PREFIX_LIST,
&clientId);
}
{
printf("\nFailed to register as routing policy change client");
switch (err)
{
case OPEN_E_FULL: printf(
"\nClient list already full");
break;
default: printf("\nOther failure");
}
return XX_E_FAIL;
}
xxerr = rppiClientSockCreate(RPPI_POLICY_CLIENT_ADDR, clientId, &fd);
if (xxerr != XX_E_NONE)
{
printf("\nFailed to create policy event client socket.");
return xxerr;
}
xxRppiSvcAdd(OPEN_POLICY_SVC, myName->pstart, myPid, clientId, fd);
return XX_E_NONE;
}
void xxPopulateRoutingInterfaceTable(void)
{
uint32_t intf = 0;
{
xxRouteIntfTableAdd(intf);
}
{
{
}
}
}
{
}
{
uint32_t i;
for (i = 0; i < XX_ROUTE_INTF_MAX; i++)
{
if (xxRouteIntfTable[i].inUse != 0)
{
}
}
}
xx_error_t xxIntfIpv4AddrsUpdate(uint32_t intf)
{
uint32_t j;
int32_t index;
xxRouteIntf_t *intfEntry;
index = xxGetInterfaceIndexFromTable(intf);
if (index < 0)
{
return(xx_error_t) index;
}
intfEntry = &xxRouteIntfTable[index];
memset(&intfEntry->ipAddrListIPv4, 0,
sizeof(
open_inet_pfx_t) * XX_INTF_IP_MAX);
for (j = 0; j < XX_INTF_IP_MAX; j++)
{
{
}
{
return XX_E_NONE;
}
{
return XX_E_AGAIN;
}
else
{
printf("\nFailed to retrieve IP address on interface %s. Error %d.",
intfEntry->intfName, err);
return XX_E_FAIL;
}
}
return XX_E_FAIL;
}
xx_error_t xxRouteIntfTableAdd(uint32_t intf)
{
uint32_t i;
xx_error_t xxerr;
xxerr = xxGetInterfaceIndexFromTable(intf);
if (xxerr >= 0)
{
i = xxerr;
}
else
{
for (i = 0; i < XX_ROUTE_INTF_MAX; i++)
{
if (xxRouteIntfTable[i].inUse == 0)
break;
}
}
if (i >= XX_ROUTE_INTF_MAX)
{
printf("\nFailed to add routing interface to local table because table is full.");
return XX_E_FAIL;
}
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
xxRouteIntfTable[i].inUse = 1;
xxRouteIntfTable[i].intf = intf;
{
printf("\nFailed to get interface type for interface %u", intf);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
intfNameBuf.size = XX_INTF_NAME_LEN_MAX + 1;
xxRouteIntfTable[i].intfName = malloc(intfNameBuf.size);
intfNameBuf.pstart = xxRouteIntfTable[i].intfName;
{
printf("\nFailed to get interface %u name. Error %d", intf, err);
free(xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
{
{
printf("\nFailed to get VLAN ID for interface %s", xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
}
{
{
printf("\nFailed to get loopback ID for interface %s", xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
}
{
printf("\nFailed to get IP stack interface index for interface %s",
xxRouteIntfTable[i].intfName);
}
{
printf("\nFailed to get IP address method of interface %s", xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
if (xxIntfIpv4AddrsUpdate(intf) != XX_E_NONE)
{
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
{
printf("\nFailed to get IPv4 addresses for interface %s", xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
{
printf("\nFailed to get IPv4 bandwidth of interface %s", xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
{
printf("\nFailed to get IPv4 operational state of interface %s", xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
return XX_E_FAIL;
}
printf("\nAdded routing interface %s to local interface table",
xxRouteIntfTable[i].intfName);
return XX_E_NONE;
}
xx_error_t xxRouteIntfTableDel(uint32_t intf)
{
uint32_t i;
for (i = 0; i < XX_ROUTE_INTF_MAX; i++)
{
if (xxRouteIntfTable[i].inUse != 0)
{
if (xxRouteIntfTable[i].intf == intf)
{
if (xxRouteIntfTable[i].intfName)
free(xxRouteIntfTable[i].intfName);
memset(&xxRouteIntfTable[i], 0, sizeof(xxRouteIntf_t));
xxRouteIntfTable[i].inUse = 0;
return XX_E_NONE;
}
}
}
return XX_E_FAIL;
}
xx_error_t xxGetInterfaceIndexFromTable(uint32_t intf)
{
uint32_t i;
for (i = 0; i < XX_ROUTE_INTF_MAX; i++)
{
if (xxRouteIntfTable[i].inUse != 0)
{
if (xxRouteIntfTable[i].intf == intf)
{
return i;
}
}
}
return XX_E_FAIL;
}
xx_error_t xxRouteTypesRegister(void)
{
char pCode[2];
char rtCode[3];
protoName.size = strlen(protocolName) + 1;
protoName.pstart = malloc(protoName.size);
if (protoName.pstart == NULL)
{
printf("Out of memory");
xxCleanup();
exit(1);
}
strcpy(protoName.pstart, protocolName);
strcpy(pCode, protocolCode);
protoCode.size = strlen(pCode) + 1;
protoCode.pstart = pCode;
{
printf("\nRegistered protocol ID %u", protoId);
free(protoName.pstart);
return XX_E_FAIL;
}
else
{
free(protoName.pstart);
}
if (strlen(routeType1Name) > strlen(routeType2Name))
routeTypeName.size = strlen(routeType1Name) + 1;
else
routeTypeName.size = strlen(routeType2Name) + 1;
routeTypeName.pstart = malloc(routeTypeName.size);
if (routeTypeName.pstart == NULL)
{
printf("Out of memory");
xxCleanup();
exit(1);
}
strcpy(routeTypeName.pstart, routeType1Name);
strcpy(rtCode, routeType1Code);
routeTypeCode.size = strlen(rtCode) + 1;
routeTypeCode.pstart = rtCode;
{
free(routeTypeName.pstart);
return XX_E_FAIL;
}
strcpy(routeTypeName.pstart, routeType2Name);
strcpy(rtCode, routeType2Code);
routeTypeCode.size = strlen(rtCode) + 1;
routeTypeCode.pstart = rtCode;
{
free(routeTypeName.pstart);
return XX_E_FAIL;
}
free(routeTypeName.pstart);
{
L7PROC_LOGF (L7PROC_LOG_SEVERITY_ERROR, 0, "Failed to Register External "
"route save mechanism with RTO");
}
return XX_E_NONE;
}
int main(int argc, char **argv)
{
int rc;
pid_t mainPid;
char myNameStorage[32];
char cmd_buf[256];
int cmd_argc;
char *cmd_argv[16];
uint32_t openInitComplete;
uint32_t i;
char openr_app_name[16];
mainPid = getpid();
l7proc_crashlog_register();
if (argc == 2)
{
vrfId = atoi(argv[1]);
}
else
{
vrfId = 0;
}
memset(myNameStorage, 0, sizeof(myNameStorage));
snprintf(myNameStorage, sizeof(myNameStorage), "%s-%u:%u", RPPI_APP_NAME, vrfId, mainPid);
myName.pstart = myNameStorage;
myName.size = strlen(myNameStorage) + 1;
snprintf(openr_app_name, 16, "%s-%d%c", RPPI_APP_NAME, vrfId, '\0');
{
printf("\nFailed to initialize RPC to OpEN. Exiting (result = %d)\n", rc);
exit(2);
}
{
sleep(1);
}
if (xxRouteTypesRegister() != XX_E_NONE)
{
xxCleanup();
exit(0);
}
{
printf("\nFailed to get the OPEN maximum number of next hops. Error %d.", err);
exit(1);
}
{
printf("\nFailed to get the maximum length of an OPEN interface name. Error %d.", err);
exit(1);
}
{
printf("\nFailed to get the maximum number of OPEN routing interfaces. Error %d.", err);
exit(1);
}
xxRouteIntfTable = (xxRouteIntf_t*) malloc(sizeof(xxRouteIntf_t) * XX_ROUTE_INTF_MAX);
if (xxRouteIntfTable == NULL)
{
printf("\nFailed to allocate local interface table.");
exit(1);
}
memset(xxRouteIntfTable, 0, sizeof(xxRouteIntf_t) * XX_ROUTE_INTF_MAX);
for (i = 0; i < XX_ROUTES_MAX; i++)
{
if ((xxRouteTable[i].routeNextHopList = malloc(xxMaxNextHops *
sizeof(
openNextHop_t))) == NULL)
{
printf("\nFailed to allocate storage for next hops.");
exit(1);
}
memset(xxRouteTable[i].routeNextHopList, 0, xxMaxNextHops *
sizeof(
openNextHop_t));
}
if (vrfId == 0)
{
if (xxRouterEventClientStart(mainPid, &myName) != XX_E_NONE)
{
xxCleanup();
exit(0);
}
#if 0
if (xxPolicyClientStart(mainPid, &myName) != XX_E_NONE)
{
xxCleanup();
exit(0);
}
#endif
}
if (xxBestRouteClientStart(mainPid, &myName) != XX_E_NONE)
{
xxCleanup();
exit(0);
}
{
printf("\nFailed to retrieve OPEN initialization status. Error %d.", err);
xxCleanup();
exit(0);
}
else if (openInitComplete)
{
if (!vrfId)
xxPopulateRoutingInterfaceTable();
}
if ((rc = pthread_create(&receive_tid, 0, xxReceiveThread, NULL)) != 0)
{
printf("Failed to create receive thread. Error %d.", rc);
xxCleanup();
exit(0);
}
L7PROC_LOGF(L7PROC_LOG_SEVERITY_INFO, 0, "Successfully started RPPI example application");
while (1)
{
printf("\n%s> ", RPPI_APP_NAME);
fgets(cmd_buf, 255, stdin);
if (cmd_buf[strlen(cmd_buf)-1] == 0x0a)
{
cmd_buf[strlen(cmd_buf)-1] = 0;
}
parse_cmd_buf(cmd_buf, &cmd_argc, cmd_argv);
if (cmd_argc > 0)
{
if (!strcmp("quit", cmd_argv[0]))
{
if (cmd_argc == 1)
{
break;
}
else
{
printf("\n Invalid Command \n");
}
}
else if (!strcmp("?", cmd_argv[0]))
{
if (cmd_argc == 1)
{
printf("%s\n", cmd_list);
}
else
{
printf("\n Invalid Command \n");
}
}
else if (!strcmp("help", cmd_argv[0]))
{
if (cmd_argc == 1)
{
printf("%s\n", cmd_list);
}
else
{
printf("\n Invalid Command \n");
}
}
else
{
xxProcessCommand(cmd_buf, cmd_argc, cmd_argv);
}
}
}
xxCleanup();
return 0;
}