Open Ethernet Networking (OpEN) API Guide and Reference Manual  3.6.0.3
ospf_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 ospf_example.c
*
* @purpose OSPF APIs Example.
*
* @component OPEN
*
* @note
*
* @create 05/01/2013
*
* @end
*
**********************************************************************/
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include "rpcclt_openapi.h"
#include "proc_util.h"
#include "openapi_common.h"
#define PRINTSANITYRESULTS(result, test, msg) \
if ((result==OPEN_E_NONE) && (test)) { printf("Sanity Success - %s\n", msg); } \
else { printf("Sanity Failure - %s\n", msg); }
#define PRINTBADRESULT(result, msg) \
if (result!=OPEN_E_NONE) { printf("Test Failure - %s (err %d)\n", msg, result); }
/* Maximum string length to be used for inputs */
#define XX_MAX_STRING_LENGTH 256
/* Maximum number of protocol names */
#define XX_PROTO_MAX 10
/*****************************************************************/
open_error_t getFirstRoutingInterface(openapiClientHandle_t *clientHandle,
uint32_t *interface)
{
uint32_t intf = 0;
if (!clientHandle || !interface)
{
result = OPEN_E_PARAM;
}
if (result == OPEN_E_NONE)
{
result = openapiRtrIntfNextGet(clientHandle, intf, &intf);
}
if (result == OPEN_E_NONE)
{
*interface = intf;
}
return result;
}
/*****************************************************************/
open_error_t getFirstRoutingProtocolName(openapiClientHandle_t *clientHandle,
open_buffdesc *protoName)
{
uint32_t i;
uint32_t protoId = 0;
uint32_t nextProtoId = 0;
for (i = 0; i < XX_PROTO_MAX; i++)
{
result = openapiIpRouterProtoNameNextGet(clientHandle, protoId, protoName, &nextProtoId);
/* Get the first available protocol name */
if (result == OPEN_E_NONE && (strlen(protoName->pstart)>0)) { break; }
protoId = nextProtoId;
}
return result;
}
/*****************************************************************/
void test1583(openapiClientHandle_t *clientHandle,
{
uint32_t tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapRfc1583CompatibilitySet (clientHandle, mode);
PRINTBADRESULT(result, "openapiOspfMapRfc1583CompatibilitySet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapRfc1583CompatibilityGet (clientHandle, &tmp);
PRINTBADRESULT(result, "openapiOspfMapRfc1583CompatibilityGet");
}
PRINTSANITYRESULTS(result, mode==tmp, __func__);
return;
}
/*****************************************************************/
void testAdvertisement(openapiClientHandle_t *clientHandle,
uint32_t duration,
bool override,
uint32_t metric)
{
uint32_t tmpMode;
uint32_t tmpDuration;
uint32_t tmpMetric;
bool tmpOverride;
bool test;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapStubRtrModeSet (clientHandle,
mode,
duration);
PRINTBADRESULT(result, "openapiOspfMapStubRtrModeSet");
}
if (result == OPEN_E_NONE)
{
override,
metric);
PRINTBADRESULT(result, "openapiOspfMapStubRtrSumLsaMetricOverride");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapStubRtrModeGet (clientHandle,
&tmpMode,
&tmpDuration,
&tmpOverride,
&tmpMetric);
PRINTBADRESULT(result, "openapiOspfMapStubRtrModeGet");
}
test = tmpMode==mode &&
tmpDuration==duration &&
tmpOverride==override &&
tmpMetric==metric;
PRINTSANITYRESULTS(result, test, __func__);
return;
}
/*****************************************************************/
void testAutoCost(openapiClientHandle_t *clientHandle,
uint32_t autoCost)
{
uint32_t tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapAutoCostRefBwSet (clientHandle, autoCost);
PRINTBADRESULT(result, "openapiOspfMapAutoCostRefBwSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapAutoCostRefBwGet (clientHandle, &tmp);
PRINTBADRESULT(result, "openapiOspfMapAutoCostRefBwGet");
}
PRINTSANITYRESULTS(result, autoCost==tmp, __func__);
return;
}
/*****************************************************************/
void testRouterId(openapiClientHandle_t *clientHandle,
char *routerId)
{
uint32_t tmp;
memset(&ipAddr, 0, sizeof(ipAddr));
if (inet_pton(AF_INET, routerId, (void*)&(ipAddr.addr.ipv4)) > 0)
{
ipAddr.addr.ipv4 = ntohl(ipAddr.addr.ipv4);
ipAddr.family = OPEN_AF_INET;
}
else
{
printf("Bad return code trying to convert ip address.\n");
result = OPEN_E_PARAM;
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapRouterIdSet (clientHandle, ipAddr.addr.ipv4);
PRINTBADRESULT(result, "openapiOspfMapRouterIdSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapRouterIdGet (clientHandle, &tmp);
PRINTBADRESULT(result, "openapiOspfMapRouterIdGet");
}
PRINTSANITYRESULTS(result, ipAddr.addr.ipv4==tmp, __func__);
return;
}
/*****************************************************************/
void testArea(openapiClientHandle_t *clientHandle,
char *area,
{
uint32_t areaId;
if (inet_pton(AF_INET, area, &areaId) != 1)
{
printf("Bad return code trying to convert area id.\n");
result = OPEN_E_PARAM;
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapImportAsExternSet(clientHandle, areaId, import);
PRINTBADRESULT(result, "openapiOspfMapImportAsExternSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapImportAsExternGet(clientHandle, areaId, &tmp);
PRINTBADRESULT(result, "openapiOspfMapImportAsExternGet");
}
PRINTSANITYRESULTS(result, import==tmp, __func__);
return;
}
/*****************************************************************/
void testAreaSummary(openapiClientHandle_t *clientHandle,
char *area,
{
uint32_t areaId;
if (inet_pton(AF_INET, area, &areaId) != 1)
{
printf("Bad return code trying to convert area id.\n");
result = OPEN_E_PARAM;
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapAreaSummarySet(clientHandle, areaId, summary);
PRINTBADRESULT(result, "openapiOspfMapAreaSummarySet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapAreaSummaryGet(clientHandle, areaId, &tmp);
PRINTBADRESULT(result, "openapiOspfMapAreaSummaryGet");
}
PRINTSANITYRESULTS(result, summary==tmp, __func__);
return;
}
/*****************************************************************/
void testDistance(openapiClientHandle_t *clientHandle,
uint32_t extPref,
uint32_t intPref,
uint32_t locPref)
{
uint32_t tmp;
/* Internal test */
result = openapiIpRouterPreferenceSet (clientHandle, OPEN_PREF_OSPF_INTRA_AREA, intPref);
PRINTBADRESULT(result, "openapiIpRouterPreferenceSet INTRA");
if (result == OPEN_E_NONE)
{
result = openapiIpRouterPreferenceGet (clientHandle, OPEN_PREF_OSPF_INTRA_AREA, &tmp);
PRINTBADRESULT(result, "openapiIpRouterPreferenceGet INTRA");
}
PRINTSANITYRESULTS(result, intPref==tmp, __func__);
/* External test */
result = openapiIpRouterPreferenceSet (clientHandle, OPEN_PREF_OSPF_EXTERNAL, extPref);
PRINTBADRESULT(result, "openapiIpRouterPreferenceSet EXTERNAL");
if (result == OPEN_E_NONE)
{
result = openapiIpRouterPreferenceGet (clientHandle, OPEN_PREF_OSPF_EXTERNAL, &tmp);
PRINTBADRESULT(result, "openapiIpRouterPreferenceGet EXTERNAL");
}
PRINTSANITYRESULTS(result, extPref==tmp, __func__);
/* Local test */
result = openapiIpRouterPreferenceSet (clientHandle, OPEN_PREF_OSPF_INTER_AREA, locPref);
PRINTBADRESULT(result, "openapiIpRouterPreferenceSet Local INTER");
if (result == OPEN_E_NONE)
{
result = openapiIpRouterPreferenceGet (clientHandle, OPEN_PREF_OSPF_INTER_AREA, &tmp);
PRINTBADRESULT(result, "openapiIpRouterPreferenceGet Local INTER");
}
PRINTSANITYRESULTS(result, locPref==tmp, __func__);
return;
}
/*****************************************************************/
void testIPArea(openapiClientHandle_t *clientHandle,
uint32_t intf,
char *area,
{
OPEN_CONTROL_t tmpMode;
uint32_t areaId;
uint32_t tmpArea;
if (inet_pton(AF_INET, area, &areaId) != 1)
{
printf("Bad return code trying to convert area id.\n");
result = OPEN_E_PARAM;
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfAreaIdSet (clientHandle, intf, areaId, mode);
PRINTBADRESULT(result, "openapiOspfMapIntfAreaIdSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfAreaIdGet (clientHandle, intf, &tmpArea, &tmpMode);
PRINTBADRESULT(result, "openapiOspfMapIntfAreaIdGet");
}
PRINTSANITYRESULTS(result, (areaId==tmpArea&&mode==tmpMode), __func__);
return;
}
/*****************************************************************/
void testIPCost(openapiClientHandle_t *clientHandle,
uint32_t intf,
char *ipAddr,
uint32_t metric)
{
uint32_t tmpAddr;
uint32_t tmp;
if (inet_pton(AF_INET, ipAddr, &tmpAddr) != 1)
{
tmpAddr = atoi(ipAddr);
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfMetricValueSet (clientHandle, intf, tmpAddr, tos, metric);
PRINTBADRESULT(result, "openapiOspfMapIntfMetricValueSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfMetricValueGet (clientHandle, intf, tos, &tmp);
PRINTBADRESULT(result, "openapiOspfMapIntfMetricValueGet");
}
PRINTSANITYRESULTS(result, metric==tmp, __func__);
return;
}
/*****************************************************************/
void testIPDeadInterval(openapiClientHandle_t *clientHandle,
uint32_t intf,
uint32_t seconds)
{
uint32_t tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfDeadIntervalSet (clientHandle, intf, seconds);
PRINTBADRESULT(result, "openapiOspfMapIntfDeadIntervalSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfDeadIntervalGet (clientHandle, intf, &tmp);
PRINTBADRESULT(result, "openapiOspfMapIntfDeadIntervalGet");
}
PRINTSANITYRESULTS(result, seconds==tmp, __func__);
return;
}
/*****************************************************************/
void testIPHelloInterval(openapiClientHandle_t *clientHandle,
uint32_t intf,
uint32_t seconds)
{
uint32_t tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfHelloIntervalSet (clientHandle, intf, seconds);
PRINTBADRESULT(result, "openapiOspfMapIntfHelloIntervalSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfHelloIntervalGet (clientHandle, intf, &tmp);
PRINTBADRESULT(result, "openapiOspfMapIntfHelloIntervalGet");
}
PRINTSANITYRESULTS(result, seconds==tmp, __func__);
return;
}
/*****************************************************************/
void testIPNetworkType(openapiClientHandle_t *clientHandle,
uint32_t intf,
{
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfTypeSet (clientHandle, intf, type);
PRINTBADRESULT(result, "openapiOspfMapIntfTypeSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfTypeGet (clientHandle, intf, &tmp);
PRINTBADRESULT(result, "openapiOspfMapIntfTypeGet");
}
PRINTSANITYRESULTS(result, type==tmp, __func__);
return;
}
/*****************************************************************/
void testIPSecondaries(openapiClientHandle_t *clientHandle,
uint32_t intf,
uint32_t secondaries)
{
uint32_t tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfSecondariesFlagSet (clientHandle, intf, secondaries);
PRINTBADRESULT(result, "openapiOspfMapIntfSecondariesFlagSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfSecondariesFlagGet (clientHandle, intf, &tmp);
PRINTBADRESULT(result, "openapiOspfMapIntfSecondariesFlagGet");
}
PRINTSANITYRESULTS(result, (secondaries==tmp), __func__);
return;
}
/*****************************************************************/
void testLogNeighbor(openapiClientHandle_t *clientHandle,
bool detail)
{
bool tmpDetail;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapLogAdjChngSet (clientHandle, log, detail);
PRINTBADRESULT(result, "openapiOspfMapLogAdjChngSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapLogAdjChngGet (clientHandle, &tmpLog, &tmpDetail);
PRINTBADRESULT(result, "openapiOspfMapLogAdjChngGet");
}
PRINTSANITYRESULTS(result, (log==tmpLog && detail==tmpDetail), __func__);
return;
}
/*****************************************************************/
void testMaxPaths(openapiClientHandle_t *clientHandle)
{
uint32_t maxPaths;
uint32_t tmpPaths;
/* Get max # of ECMP next hops supported for the active template */
result = openapiOspfEqualCostRoutesMax(clientHandle, &maxPaths);
if (result == OPEN_E_NONE)
{
result = openapiOspfMapMaxPathsSet (clientHandle, maxPaths);
PRINTBADRESULT(result, "openapiOspfMapMaxPathsSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapMaxPathsGet (clientHandle, &tmpPaths);
PRINTBADRESULT(result, "openapiOspfMapMaxPathsGet");
}
PRINTSANITYRESULTS(result, (maxPaths==tmpPaths), __func__);
return;
}
/*****************************************************************/
void testNetwork(openapiClientHandle_t *clientHandle,
char *ipAddr,
char *mask,
uint32_t areaId,
bool create)
{
uint32_t tmpAddr;
uint32_t tmpMask;
bool tmp = true;
if (inet_pton(AF_INET, ipAddr, &tmpAddr) != 1)
{
tmpAddr = atoi(ipAddr);
}
if (inet_pton(AF_INET, mask, &tmpMask) != 1)
{
tmpMask = atoi(mask);
}
if (create)
{
if (result == OPEN_E_NONE)
{
result = openapiOspfMapNetworkAreaEntrySet (clientHandle, tmpAddr, tmpMask, areaId, areaIdFmt);
PRINTBADRESULT(result, "openapiOspfMapNetworkAreaEntrySet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapNetworkAreaEntryGet (clientHandle, tmpAddr, tmpMask, areaId, &tmp);
PRINTBADRESULT(result, "openapiOspfMapNetworkAreaEntryGet");
}
}
else
{
result = openapiOspfMapNetworkAreaEntryDelete (clientHandle, tmpAddr, tmpMask, areaId);
PRINTBADRESULT(result, "openapiOspfMapNetworkAreaEntryDelete");
}
PRINTSANITYRESULTS(result, tmp, __func__);
return;
}
/*****************************************************************/
void testPassive(openapiClientHandle_t *clientHandle,
uint32_t intf,
bool mode)
{
bool tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfPassiveModeSet (clientHandle, intf, mode);
PRINTBADRESULT(result, "openapiOspfMapIntfPassiveModeSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapIntfPassiveModeGet (clientHandle, intf, &tmp);
PRINTBADRESULT(result, "openapiOspfMapIntfPassiveModeGet");
}
PRINTSANITYRESULTS(result, mode==tmp, __func__);
return;
}
/*****************************************************************/
void testRedistribution(openapiClientHandle_t *clientHandle,
bool redistribute,
uint32_t distList,
uint32_t metric,
uint32_t type,
int32_t tag,
bool subnets)
{
open_buffdesc protoName;
open_error_t result;
openapiRouteProtoNameLenMax(clientHandle, &protoName.size);
protoName.size++; /* leave room for NULL terminator */
protoName.pstart = malloc(protoName.size);
result = getFirstRoutingProtocolName(clientHandle, &protoName);
if (result == OPEN_E_NONE)
{
result = openapiOspfMapRedistributionSet(clientHandle,
redistribute,
&protoName,
distList,
metric,
type,
tag,
subnets);
}
PRINTBADRESULT(result, "openapiOspfMapRedistributionSet");
PRINTSANITYRESULTS(result, 1==1, __func__);
free(protoName.pstart);
return;
}
/*****************************************************************/
void testSPFDelayTime(openapiClientHandle_t *clientHandle,
uint32_t time)
{
uint32_t tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapSpfDelayTimeSet (clientHandle, time);
PRINTBADRESULT(result, "openapiOspfMapSpfDelayTimeSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapSpfDelayTimeGet (clientHandle, &tmp);
PRINTBADRESULT(result, "openapiOspfMapSpfDelayTimeGet");
}
PRINTSANITYRESULTS(result, time==tmp, __func__);
return;
}
/*****************************************************************/
void testSPFHoldTime(openapiClientHandle_t *clientHandle,
uint32_t time)
{
uint32_t tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfMapSpfHoldTimeSet (clientHandle, time);
PRINTBADRESULT(result, "openapiOspfMapSpfHoldTimeSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfMapSpfHoldTimeGet (clientHandle, &tmp);
PRINTBADRESULT(result, "openapiOspfMapSpfHoldTimeGet");
}
PRINTSANITYRESULTS(result, time==tmp, __func__);
return;
}
/*****************************************************************/
void testTrapFlags(openapiClientHandle_t *clientHandle,
bool mode)
{
bool tmp;
if (result == OPEN_E_NONE)
{
result = openapiOspfTrapModeSet (clientHandle, trapType, mode);
PRINTBADRESULT(result, "openapiOspfTrapModeSet");
}
if (result == OPEN_E_NONE)
{
result = openapiOspfTrapModeGet (clientHandle, trapType, &tmp);
PRINTBADRESULT(result, "openapiOspfTrapModeGet");
}
PRINTSANITYRESULTS(result, mode==tmp, __func__);
return;
}
/***************************************************************/
int main (int argc, char **argv)
{
openapiClientHandle_t clientHandle;
OPEN_OSPF_TRAP_TYPES_t trapFlags = 0;
uint32_t source = 0;
open_error_t result;
l7proc_crashlog_register();
/* Register with OpEN */
if ((result =
openapiClientRegister ("ospf_example", &clientHandle)) != OPEN_E_NONE)
{
printf ("\nFailed to initialize RPC to OpEN. Exiting (result = %d)\n", result);
exit (2);
}
/* 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 OSPF API example application");
printf ("\n");
/* Execute sanity tests */
printf ("Begin Sanity tests...\n");
/**************************************************************************/
/* Global OSPF specific tests */
/**************************************************************************/
printf ("\nEstablish OSPF and global parameters...\n");
testRouterId(&clientHandle, "9.0.0.3");
test1583(&clientHandle, OPEN_ENABLE);
testAutoCost(&clientHandle, 4294967);
testSPFDelayTime(&clientHandle, 65535);
testSPFHoldTime(&clientHandle, 65535);
testLogNeighbor(&clientHandle, OPEN_ENABLE, true);
testAdvertisement(&clientHandle, OPEN_OSPF_STUB_RTR_CFG_STARTUP, 86400, true, 16777215);
testDistance(&clientHandle, 10, 20, 30);
testMaxPaths(&clientHandle);
testRedistribution(&clientHandle, true, 199, 16777214, OPEN_OSPF_METRIC_EXT_TYPE1, 4294967295UL, true);
/* Demonstrate setting various OSPF trap flags */
testTrapFlags(&clientHandle, trapFlags, true);
testTrapFlags(&clientHandle, trapFlags, false);
testNetwork(&clientHandle, "172.0.0.0", "0.255.255.255", 0, OPEN_OSPF_AREA_ID_DOTTED_DECIMAL_FORMAT, true);
testNetwork(&clientHandle, "5000", "0", 0, OPEN_OSPF_AREA_ID_INTEGER_FORMAT, true);
testNetwork(&clientHandle, "5000", "0", 0, OPEN_OSPF_AREA_ID_INTEGER_FORMAT, false);
testArea(&clientHandle, "1.1.1.1", OPEN_OSPF_AREA_IMPORT_NSSA);
testAreaSummary(&clientHandle, "1.1.1.1", OPEN_OSPF_AREA_NO_SUMMARY);
testArea(&clientHandle, "2.2.2.2", OPEN_OSPF_AREA_IMPORT_NO_EXT);
testAreaSummary(&clientHandle, "2.2.2.2", OPEN_OSPF_AREA_NO_SUMMARY);
/* Test to see if we have a routing interface */
if (getFirstRoutingInterface(&clientHandle, &source) == OPEN_E_NONE)
{
printf ("Configure IP area with miscellaneous interface related parameters...\n");
testIPArea(&clientHandle, source, "0.0.0.0", OPEN_ENABLE);
testIPSecondaries(&clientHandle, source, OPEN_OSPF_INTF_SECONDARIES_NONE);
testIPCost(&clientHandle, source, "0.0.0.0", OPEN_OSPF_TOS_NORMAL_SERVICE, 65535);
testIPNetworkType(&clientHandle, source, OPEN_OSPF_INTF_PTP);
testIPDeadInterval(&clientHandle, source, 65535);
testIPHelloInterval(&clientHandle, source, 65535);
testPassive(&clientHandle, source, true);
}
else
{
printf ("Sanity tests are incomplete because no routing interfaces are available!\n");
printf ("Please configure a routing interface and re-run test.\n\n");
}
printf ("Complete.\n");
/* Log goodbye message with OPEN */
L7PROC_LOGF (L7PROC_LOG_SEVERITY_INFO, 0, "Stopping OSPF API example application");
(void) openapiClientTearDown(&clientHandle);
return 0;
}