Open Ethernet Networking (OpEN) API Guide and Reference Manual  3.6.0.3
rx_pkt_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 rx_packet_example.c
*
* @purpose Example for Packet receive funcationality using TCAM API
*
* @detail Example application that uses the OpEN API to insert
* various policies in the TCAM and sets up to receives those packets.
*
* @component TCAM API Example
*
* @note none
* @end
*
**********************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include "rpcclt_openapi.h"
#include "proc_util.h"
#include "openapi_common.h"
#include "openapi_tcam.h"
#define TCAM_MAX_STR_LENGTH 256
static open_error_t getIpAddrFromStr(int af, char *strIpAddr, open_inet_addr_t *addr)
{
struct sockaddr_in sa;
/* read the ip address */
if (af == AF_INET)
{
if (inet_pton(af,strIpAddr,&(sa.sin_addr)) > 0)
{
addr->addr.ipv4 = ntohl(sa.sin_addr.s_addr);
return OPEN_E_NONE;
}
}
else if (af == AF_INET6)
{
if (inet_pton(AF_INET6, strIpAddr, (void*)&(addr->addr.ipv6)) > 0)
{
return OPEN_E_NONE;
}
}
return OPEN_E_PARAM;
}
static open_error_t getMacAddrFromInput (char * input_mac, unsigned char * mac)
{
int i;
unsigned char c;
unsigned char temp_mac [12];
for ( i = 0; i < 12; i++ )
{
c = input_mac [i];
if ( (c >= '0') && (c <= '9') )
temp_mac[i] = c - '0';
else if ( (c >= 'a') && (c <= 'f') )
temp_mac[i] = c - 'a' + 10;
else if ( (c >= 'A') && (c <= 'F') )
temp_mac[i] = c - 'A' + 10;
else return(1); /* Invalid character */
};
for ( i = 0; i < 12; i+= 2 )
{
mac[i/2] = (temp_mac[i] * 16) + temp_mac[i+1];
};
return(0);
};
char intfString[100];
static void openapiReceivePackets(uint32_t agentNum, uint32_t packetCount,
char *fileName)
{
uint32_t i, pktCount, offset;
uint32_t bytesRcvd;
int sockfd = -1;
open_buffdesc agentNameBuff;
char agentName[] = "Test Agent";
unsigned char buffer[OPEN_TXRX_MAX_FRAME_SIZE + 64];
FILE *fp = NULL;
fp = fopen(fileName, "w");
if (fp == NULL)
{
printf("Could not open file for writing...\n");
return;
}
agentNameBuff.pstart = agentName;
agentNameBuff.size = sizeof(agentName);
if (rc != OPEN_E_NONE)
{
printf("Failed to register as rx agent\n");
return;
}
/* Create the socket end-point to receive frames */
if (l7proc_extagentpkt_rxsockcreate(agentNum, &sockfd) != 0)
{
fclose(fp);
return;
}
/* Child*/
pktCount = 0;
while (pktCount < packetCount)
{
memset(buffer, 0, sizeof(buffer));
bytesRcvd = recvfrom(sockfd, buffer, sizeof(buffer), 0, 0, 0);
if (bytesRcvd <= 0)
{
continue;
}
pktDesc = (open_sysExtAgentPktRxDesc_t *)buffer;
fprintf(fp, "Packet Received from ifNum %d, pktLen %d\n",
pktDesc->rxIfNum, pktDesc->pktLength);
fprintf(fp,"Packet content: \n");
offset = pktDesc->descLen;
for (i = 0; i < pktDesc->pktLength; i++)
{
fprintf(fp,"%2.2x ", buffer[offset + i]);
}
fprintf(fp, "\n\n");
pktCount++;
fflush(fp);
}
l7proc_extagentpkt_rxsockclose(agentNum, sockfd);
fclose(fp);
exit(0);
return;
}
/***************************************************************/
static void openBuildHeader(open_tcamApiPolicy_t *policyInfo)
{
uint32_t prio;
uint32_t policyType = 0;
memset(policyInfo,0, sizeof(*policyInfo));
policyInfo->policyHeader.versionInfo.versionMajor =OPEN_TCAM_API_CURR_VER_MAJOR;
policyInfo->policyHeader.versionInfo.versionMinor = OPEN_TCAM_API_CURR_VER_MINOR;
policyInfo->policyHeader.headerLen = sizeof(policyInfo->policyHeader);
printf("Enter policy priority \n");
scanf("%d", &prio);
policyInfo->policyPrio = prio;
printf("Select policy type 1 for openflow 2 for Gen (IPv6) 3 for Egress \n");
scanf("%d", &policyType);
switch (policyType)
{
case 1:
policyInfo->policyType = OPEN_TCAM_POLICY_TYPE_OPENFLOW ;
break;
case 2:
policyInfo->policyType = OPEN_TCAM_POLICY_TYPE_GEN ;
break;
case 3:
policyInfo->policyType = OPEN_TCAM_POLICY_TYPE_EGRESS ;
break;
}
}
/***************************************************************/
static void openAddClassifiers(open_tcamApiPolicy_t *policyInfo)
{
char mac[TCAM_MAX_STR_LENGTH];
uint32_t response;
uint32_t value;
char strSubnetMask[TCAM_MAX_STR_LENGTH];
char strIpaddr[TCAM_MAX_STR_LENGTH];
printf("This selection will add multiple classifiers to the policy\n");
do
{
response = 0;
printf("Enter classification type \n"
"1 to match dest MAC\n"
"2 to match Src MAC\n"
"3 to match VLAN\n"
"4 to match VLAN Priority\n"
"5 to match ether type\n"
"6 to match dest IP address\n"
"7 to match src IP address \n"
"8 to match dest IPv6 address\n"
"9 to match src IPv6 address\n"
"10 quit \n");
scanf("%d", &response);
/* Classification*/
switch (response)
{
case 1:
memset(mac, 0, sizeof(mac));
printf("Enter Mac address\n");
scanf("%s", mac);
if (getMacAddrFromInput(mac, policyInfo->matchDstMac))
printf("Error: Invalid input\n");
break;
case 2:
memset(mac, 0, sizeof(mac));
printf("Enter Mac address\n");
scanf("%s", mac);
if (getMacAddrFromInput(mac, policyInfo->matchSrcMac))
printf("Error: Invalid input\n");
break;
case 3:
printf("Enter VLAN id \n");
scanf("%d",&value);
policyInfo->matchVlanVal = value;
break;
case 4:
printf("Enter VLAN priority \n");
scanf("%d",&value);
policyInfo->matchVlanPrio = value;
break;
case 5:
printf("Enter ether type in hex\n");
scanf("%x",&value);
policyInfo->matchEthType = value;
break;
case 6:
printf("Enter Dest IP address \n");
scanf("%s",strIpaddr);
if (getIpAddrFromStr(AF_INET, strIpaddr, &addr) == OPEN_E_NONE)
{
policyInfo->matchDstIp = addr.addr.ipv4;
printf("Enter Mask \n");
scanf("%s",strSubnetMask);
if (getIpAddrFromStr(AF_INET, strSubnetMask, &addr) == OPEN_E_NONE)
{
policyInfo->matchDstIpMask = addr.addr.ipv4;
break;
}
}
printf("Error: Incorrect Input\n");
break;
case 7:
printf("Enter Src IP address \n");
scanf("%s",strIpaddr);
if (getIpAddrFromStr(AF_INET, strIpaddr, &addr) == OPEN_E_NONE)
{
policyInfo->matchSrcIp = addr.addr.ipv4;
printf("Enter Mask \n");
scanf("%s",strSubnetMask);
if (getIpAddrFromStr(AF_INET, strSubnetMask, &addr) == OPEN_E_NONE)
{
policyInfo->matchSrcIpMask = addr.addr.ipv4;
break;
}
}
printf("Error: Incorrect Input\n");
break;
case 8:
printf("Enter Dest IPv6 address \n");
scanf("%s",strIpaddr);
if (getIpAddrFromStr(AF_INET6, strIpaddr, &addr) == OPEN_E_NONE)
{
memcpy(&policyInfo->matchDstIpv6Addr, &addr.addr.ipv6,
sizeof(policyInfo->matchDstIpv6Addr));
printf("Enter Mask \n");
scanf("%s",strSubnetMask);
if (getIpAddrFromStr(AF_INET6, strSubnetMask, &addr) == OPEN_E_NONE)
{
memcpy(&policyInfo->matchDstIpv6Mask, &addr.addr.ipv6,
sizeof(policyInfo->matchDstIpv6Mask));
break;
}
}
printf("Error: Incorrect Input\n");
break;
case 9:
printf("Enter Src IPv6 address \n");
scanf("%s",strIpaddr);
if (getIpAddrFromStr(AF_INET6, strIpaddr, &addr) == OPEN_E_NONE)
{
memcpy(&policyInfo->matchSrcIpv6Addr, &addr.addr.ipv6,
sizeof(policyInfo->matchSrcIpv6Addr));
printf("Enter Mask \n");
scanf("%s",strSubnetMask);
if (getIpAddrFromStr(AF_INET6, strSubnetMask, &addr) == OPEN_E_NONE)
{
memcpy(&policyInfo->matchSrcIpv6Mask, &addr.addr.ipv6,
sizeof(policyInfo->matchSrcIpv6Mask));
break;
}
}
printf("Error: Incorrect Input\n");
break;
case 10:
default:
return;
}
} while (response != 10);
}
/***************************************************************/
static void openAddPolicyAction(openapiClientHandle_t *clientHandle, open_tcamApiPolicy_t *policyInfo,
uint32_t agentCookie)
{
/* Action*/
policyInfo->actionType |= OPEN_TCAM_ACTION_REDIRECT_CPU;
policyInfo->ruleNum = agentCookie;
}
/***************************************************************/
static int openPacketRx(openapiClientHandle_t *clientHandle, uint32_t agentCookie, uint32_t packetCount,
char *fileName)
{
open_tcamApiPolicy_t policyInfo;
open_error_t errorCode;
uint32_t intfNum;
uint32_t len;
open_buffdesc buffDesc;
/* Initialize TCAM API*/
openapiTcamApiInit(clientHandle);
do
{
/* set up the policy*/
openBuildHeader(&policyInfo);
/* Add classifiers*/
openAddClassifiers(&policyInfo);
/* add actions */
openAddPolicyAction(clientHandle, &policyInfo, agentCookie);
errorCode = openapiTcamPolicyCreate(clientHandle, policyInfo, &policyHandle);
if (errorCode != OPEN_E_NONE)
{
printf("Error: Policy could not be created Reason %d", errorCode);
break;
}
else
{
printf("Policy succesfully added,handle is %d \n", policyHandle);
}
/* Add/Remove interfaces*/
if (policyHandle == OPEN_TCAM_API_POLICYID_INVALID)
{
printf("Error: Create policy first \n");
}
else
{
printf("Enter intf string\n");
scanf("%s", intfString);
len = strlen(intfString);
buffDesc.size = len < (sizeof(intfString) -1) ? len : (sizeof(intfString) -1);
buffDesc.pstart = intfString;
if (openapiIfNumGet(clientHandle,&buffDesc,&intfNum) != OPEN_E_NONE)
{
printf("Error: Incorrect interface name %s \n", intfString);
break;
}
else
{
errorCode = openapiTcamPolicyIntfAdd(clientHandle, &policyHandle, intfNum);
if (errorCode != OPEN_E_NONE)
{
printf("Error: Policy could not be applied to intf(%d) %d", intfNum, errorCode);
break;
}
}
openapiReceivePackets(agentCookie, packetCount, fileName);
}
/* Destroy*/
}
while (0);
openapiTcamApiFini(clientHandle);
(void) openapiClientTearDown(clientHandle);
return 0;
}
/***************************************************************/
int
main (int argc, char **argv)
{
openapiClientHandle_t clientHandle;
open_error_t result;
open_buffdesc switch_os_revision;
char switch_os_revision_string[100];
uint32_t packetCount;
uint32_t agentCookie;
char *fileName;
if (argc != 4)
{
printf ("Usage: %s <agentNum> <packetCount> <fileName>\n", argv[0]);
exit (1);
}
agentCookie = atoi(argv[1]);
packetCount = atoi(argv[2]);
fileName = argv[3];
printf("cookie %d count %d and name %s \n", agentCookie, packetCount, fileName);
l7proc_crashlog_register ();
/* Register with OpEN */
if ((result =
openapiClientRegister ("RX-Packet 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 TCAM API example application");
printf ("\n");
switch_os_revision.pstart = switch_os_revision_string;
switch_os_revision.size = sizeof (switch_os_revision_string);
if (openapiNetworkOSVersionGet (&clientHandle, &switch_os_revision) == OPEN_E_NONE)
{
printf ("Network OS version = %s\n", switch_os_revision_string);
}
else
{
printf ("Network OS version retrieve error\n");
}
if (openapiTcamApiVersionGet (&clientHandle, &ver) == OPEN_E_NONE)
{
printf ("TCAM API version = %d.%d\n", ver.versionMajor, ver.versionMinor);
}
else
{
printf ("Network OS Version retrieve error\n");
}
printf ("\n");
return openPacketRx(&clientHandle, agentCookie, packetCount, fileName);
}