NETAPI updates to support enhanced route types.
authorTinku Mannan <tmannan@ti.com>
Thu, 24 Oct 2013 19:27:47 +0000 (15:27 -0400)
committerTinku Mannan <tmannan@ti.com>
Thu, 24 Oct 2013 19:27:47 +0000 (15:27 -0400)
ti/runtime/netapi/applications/ipsec_offload/ipsecmgr/src/netapi_ipsecmgr.c
ti/runtime/netapi/applications/ipsec_offload/ipsecmgr/src/netapilib_interface.c
ti/runtime/netapi/makefile_armv7
ti/runtime/netapi/netcp_cfg.h
ti/runtime/netapi/src/netapi_init.c
ti/runtime/netapi/src/netapi_loc.h
ti/runtime/netapi/src/netapi_sec.c
ti/runtime/netapi/src/netcp_cfg.c

index eefd5adced05d695302be7d206fd40d22f643e62..943018216b2e3663effd9b0d831032ef080b1f99 100755 (executable)
@@ -64,7 +64,9 @@
  ************************** Local Definitions *************************
  **********************************************************************/
 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
- "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue",
+ "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
+
+#if 0
  "/proc/device-tree/soc/pktdma@2004000/channels/netrx1/complete-queue",
  "/proc/device-tree/soc/pktdma@2004000/channels/netrx2/complete-queue",
  "/proc/device-tree/soc/pktdma@2004000/channels/netrx3/complete-queue",
@@ -81,8 +83,10 @@ char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
  "/proc/device-tree/soc/pktdma@2004000/channels/netrx14/complete-queue",
  "/proc/device-tree/soc/pktdma@2004000/channels/netrx15/complete-queue"
 };
+#endif
 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
-"/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow",
+"/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
+#if 0
 "/proc/device-tree/soc/pktdma@2004000/channels/netrx1/flow",
 "/proc/device-tree/soc/pktdma@2004000/channels/netrx2/flow",
 "/proc/device-tree/soc/pktdma@2004000/channels/netrx3/flow",
@@ -99,7 +103,7 @@ char*  DTS_LOG_FILE_FLOW_ETHx[] = {
 "/proc/device-tree/soc/pktdma@2004000/channels/netrx14/flow",
 "/proc/device-tree/soc/pktdma@2004000/channels/netrx15/flow",
 };
-
+#endif
 /**********************************************************************
  ************************** Global Variables **************************
  **********************************************************************/
@@ -126,13 +130,13 @@ static NETAPI_CFG_T our_netapi_default_cfg=
     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
     64, //#descriptors w/o buffers in default heap
     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
-    128   ,  //tail room
-    256      //extra room
+    128,    //tail room
+    256,    //extra room,
+    0
 };
 
 
 
-
 static int QUIT = 0;
 
 /* stub functions */
@@ -199,10 +203,81 @@ void cleanup_sa_sp()
     }
 }
 
+//void netTest_utilsStatsCb(NETAPI_T h, paSysStats_t* pPaStats)
+NETAPI_SA_STATS_T netapi_sa_statsrx;
+NETAPI_SA_STATS_T netapi_sa_statstx;
+
+
+void printIPSecStats(Sa_IpsecStats_t* p_saIpsecStats,
+                     nwal_saAALG auth,
+                     nwal_saEALG cipher,
+                     uint32_t    saAppId)
+{
+
+    printf("\n appId: 0x%x: Autentication mode: %d, Encryption Mode: %d\n",
+                saAppId,
+                auth,
+                cipher);
+                
+    printf("IPSec replayOld:0x%x,replayDup:0x%x,authFail:0x%x \n",
+                   p_saIpsecStats->replayOld,p_saIpsecStats->replayDup,p_saIpsecStats->authFail);
+    printf("IPSec txESN:0x%x,rxESN:0x%x,pktEncHi:0x%x,pktEncLo:0x%x,pktDecHi:0x%x,pktDecLo:0x%x \n",
+                   p_saIpsecStats->txESN,p_saIpsecStats->rxESN,p_saIpsecStats->pktEncHi,
+                   p_saIpsecStats->pktEncLo,p_saIpsecStats->pktDecHi,p_saIpsecStats->pktDecLo);
+}
+
+
+
+
+
+void utilsStatsCb(NETAPI_T h)
+{
+    uint32_t numFreeDataPackets;
+    uint32_t            numZeroBufferPackets;
+    uint32_t            numPacketsinGarbage;
+    Pktlib_HeapStats    pktLibHeapStats;
+    int i,j;
+
+
+
+
+        if(globalDB.rx_sa[0].saAppId)
+        {
+            /* Statistics for RX Tunnel */
+            memset(&netapi_sa_statsrx, 0, sizeof(netapi_sa_statsrx));
+            netapi_getSaStats(netapi_handle,
+                              globalDB.rx_sa[0].saAppId,
+                              &netapi_sa_statsrx);
+            if (netapi_sa_statsrx.validParams & NETAPI_IPSEC_STAT_VALID)
+            {
+                printIPSecStats(&netapi_sa_statsrx.saIpsecStats,
+                                 NWAL_SA_AALG_HMAC_SHA1,
+                                 NWAL_SA_EALG_AES_CBC,
+                                 globalDB.rx_sa[0].saAppId);
+            }
+        }
+#if 1
+        if (globalDB.tx_sa[0].saAppId)
+        {
+            memset(&netapi_sa_statstx, 0, sizeof(netapi_sa_statstx));
+            netapi_getSaStats(netapi_handle,
+                              globalDB.tx_sa[0].saAppId,
+                              &netapi_sa_statstx);
+            if (netapi_sa_statstx.validParams & NETAPI_IPSEC_STAT_VALID)
+            {
+                 printIPSecStats(&netapi_sa_statstx.saIpsecStats,
+                                   NWAL_SA_AALG_HMAC_SHA1,
+                                   NWAL_SA_EALG_AES_CBC,
+                                   globalDB.tx_sa[0].saAppId);
+            }
+        }
+#endif
+}
 static void* snoop_run_thread (void* arg)
 {
-    ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
-        "snoop_run_thread: daemon entering forever event loop\n");
+    printf(        "snoop_run_thread: daemon entering forever event loop\n");
+    int count=0;
+    int sat=500000;
     while (1)
     {
         /* Poll for message from user application */
@@ -210,11 +285,18 @@ static void* snoop_run_thread (void* arg)
 
         /* Poll for message from Kernel */
         ipsecmgr_snoop_run();
+#if 1
+        if((count % 50000) == 0)
+            utilsStatsCb(netapi_handle);
+        
+#endif
+        count++;
         if (QUIT == 1)
             break;
     }
     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
         "snoop_run_thread: calling shutdown\n");
+    utilsStatsCb(netapi_handle);
     ipsecmgr_snoop_shutdown ();
     cleanup_sa_sp();
     netapi_shutdown(netapi_handle);
@@ -797,11 +879,16 @@ int32_t main (int argc, char* argv[])
     int family, s;
     char host[NI_MAXHOST];
     struct sockaddr_in6 ipv6_addr;
-
+    cpu_set_t cpu_set;
     ipsecmgr_syslog_init();
 
     memset(&globalDB, 0, sizeof(globalDB));
     memset(&ipConfigList, 0, sizeof(ipConfigList));
+
+        /* assign main net_test thread to run on core 0 */
+    CPU_ZERO( &cpu_set);
+    CPU_SET( 0, &cpu_set);
+    hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
     /* create netapi */
     netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
 
@@ -813,7 +900,7 @@ int32_t main (int argc, char* argv[])
     else
         netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
 
-    for (i = 0; i < 16; i++)
+    for (i = 0; i < 1; i++)
     {
         if (get_kernel_config(i))
         {
@@ -837,11 +924,14 @@ int32_t main (int argc, char* argv[])
         printf ("Usage format: netfpproxy.out [-f <log_file>]\n");
         return -1;
     }
-    printf("main: calling daemonize\n");
+    
 
     /* Create the proxy daemon. */
-    daemonize (LOCK_FILE);
+    /*printf("main: calling daemonize\n");
+    daemonize (LOCK_FILE); */
 
+
+#if to_delete
     if (getifaddrs(&ifaddr) == -1)
     {
         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
@@ -936,7 +1026,7 @@ int32_t main (int argc, char* argv[])
 
     if (ifaddr)
         freeifaddrs(ifaddr);
-
+#endif
     /* Initialize and start the IPSec Mgr Snoop functionality */
     if ((retVal = init_ipsecmgr ()) < 0)
     {
index 73a196c190f26118e2b678941c5ddf28a52b812a..37a88e5dd1d97a87b2c28a2343c4de25b7dc7a72 100755 (executable)
@@ -151,9 +151,276 @@ int netapilib_ifAddSA
     NETCP_CFG_SA_HANDLE_T pSaHandle;
     char* pTok = NULL;
     int iface;
+    cpu_set_t cpu_set;
     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
                 "netapilib_ifAddSA:, DEBUG: Translating SA\n");
 
+
+    /* assign main net_test thread to run on core 0 */
+    CPU_ZERO( &cpu_set);
+    CPU_SET( 0, &cpu_set);
+    hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
+
+    memset((void *)&saInfo, 0, sizeof (NETAPI_SEC_SA_INFO_T));
+    memset((void *)&keyParams, 0, sizeof (nwalSecKeyParams_t));
+    memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
+    memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
+
+    /* Initialize the SA Config structure. */
+    /* Get the IP protocol version. */
+    if (af == IPSECMGR_AF_IPV4)
+    {
+        saInfo.ipType = nwal_IPV4;
+        /* Populate the source and destination IP addresses. */
+        for (index = 0; index < NWAL_IPV4_ADDR_SIZE; index++)
+        {
+            saInfo.dst.ipv4[index] = sa_id->daddr.ipv4[index];
+            saInfo.src.ipv4[index] = sa_info->saddr.ipv4[index];
+        }
+    }
+    else if (af == IPSECMGR_AF_IPV6)
+    { 
+        saInfo.ipType = nwal_IPV6;
+
+        /* Populate the source and destination IP addresses. */
+        for (index = 0; index < NWAL_IPV6_ADDR_SIZE; index++)
+        {
+            saInfo.dst.ipv6[index] = sa_id->daddr.ipv6[index];
+            saInfo.src.ipv6[index] = sa_info->saddr.ipv6[index];
+        }
+    }
+    else
+    {
+        ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
+            "netapilib_ifAddSA: Address family (%d) is invalid\n", af);
+        return -1;
+    }
+    /* Get the SPI. */
+    saInfo.spi = sa_id->spi;
+
+    /* Get the SA direction. */
+    if (sa_info->dir == DIR_INBOUND)
+    {
+        slot = findFreeAppIdSlot(&globalDB.rx_sa[0]);
+        if (slot == -1)
+        {
+            ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
+                "netapilib_ifAddSA:, Too many INBOUND SAs already offloaded\n");
+            return -1;
+        }
+        saInfo.dir = NWAL_SA_DIR_INBOUND;
+        /* need to check which interface this SA will be attached to */
+
+                globalDB.rx_sa[slot].iface = iface;
+                flow.dma_engine= 1;
+                flow.flowid = globalDB.flowId[0];
+                printf("add_sa: iface: %d, flowid: %d\n",
+                    iface,
+                    flow.flowid);
+
+                route.p_flow = &flow;
+                route.p_dest_q = globalDB.pktio_channel[0];
+
+                printf("add_sa: p_dest_q: 0x%x, flowId: 0x%x\n",
+                route.p_dest_q, 
+                route.p_flow->flowid);
+
+                route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
+                route.routeType = NWAL_ROUTE_RX_INTF;
+    }
+    else if (sa_info->dir == DIR_OUTBOUND)
+    {
+        slot = findFreeAppIdSlot(&globalDB.tx_sa[0]);
+        if (slot == -1)
+        {
+            ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
+                "netapilib_ifAddSA:, Too many OUTBOUND SAs already offloaded\n");
+            return -1;
+        }
+        saInfo.dir = NWAL_SA_DIR_OUTBOUND;
+    }
+    else
+    {
+        ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
+            "netapilib_ifAddSA: IPSec direction (%d) is invalid\n", sa_info->dir);
+        return -1;
+    }
+    
+
+    /* Get the replay Window */
+    saInfo.replayWindow = sa_info->replay_window;
+   
+    /* Get the IPSec protocol. */
+    if (sa_id->proto == SA_PROTO_AH)
+        saInfo.proto = nwal_IpSecProtoAH;
+    else if (sa_id->proto == SA_PROTO_ESP)
+        saInfo.proto = nwal_IpSecProtoESP;
+    else
+    {
+        ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
+            "netapilib_ifAddSA: IPSec protocol (%d) is invalid.\n", sa_id->proto);
+        return -1;
+    }
+    /* Get the IPSec mode. */
+    if (sa_info->mode == SA_MODE_TRANSPORT)
+        saInfo.saMode = nwal_SA_MODE_TRANSPORT;
+    else if (sa_info->mode == SA_MODE_TUNNEL)
+        saInfo.saMode = nwal_SA_MODE_TUNNEL;
+    else
+    {
+        ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
+            "netapilib_ifAddSA: IPSec mode (%d) is invalid.\n", sa_info->mode);
+        return -1;
+    }
+    /* Get the authentication mode algorithm. */
+    if (sa_info->auth.algo == SA_AALG_HMAC_SHA1)
+        saInfo.authMode = NWAL_SA_AALG_HMAC_SHA1;
+    else if (sa_info->auth.algo == SA_AALG_HMAC_MD5)
+        saInfo.authMode = NWAL_SA_AALG_HMAC_MD5;
+    else if (sa_info->auth.algo == SA_AALG_AES_XCBC)
+        saInfo.authMode = NWAL_SA_AALG_AES_XCBC;
+    else if (sa_info->auth.algo == SA_AALG_NONE || sa_info->auth.algo == SA_AALG_NULL)  
+        saInfo.authMode = NWAL_SA_AALG_NULL;
+    else
+    {
+        ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
+            "netapilib_ifAddSA: Authentication algorithm (%d) is invalid\n", sa_info->auth.algo);
+        return -1;
+    }
+
+    /* Get the encryption mode algorithm. */
+    if (sa_info->enc.algo == SA_EALG_NULL) 
+        saInfo.cipherMode = NWAL_SA_EALG_NULL;
+    else if (sa_info->enc.algo == SA_EALG_AES_CTR) 
+        saInfo.cipherMode = NWAL_SA_EALG_AES_CTR;
+    else if (sa_info->enc.algo == SA_EALG_AES_CBC)
+        saInfo.cipherMode = NWAL_SA_EALG_AES_CBC;
+    else if (sa_info->enc.algo == SA_EALG_3DES_CBC) 
+        saInfo.cipherMode = NWAL_SA_EALG_3DES_CBC;
+    else if (sa_info->enc.algo == SA_EALG_DES_CBC) 
+        saInfo.cipherMode = NWAL_SA_EALG_DES_CBC;
+    else
+    {
+        ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
+            "netapilib_ifAddSA: Encryption algorithm (%d) is invalid\n", sa_info->enc.algo);
+        return -1;
+    }
+    /* Validate the key lengths. */
+    if ((keyParams.macKeySize = sa_info->auth_key_len) > 32)
+    {
+        ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
+            "netapilib_ifAddSA: Authentication key size (%d) is invalid.\n", sa_info->auth_key_len);
+        return -1;
+    }
+    if ((keyParams.encKeySize = sa_info->enc_key_len) > 32)
+    {
+        ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
+            "netapilib_ifAddSA: Encryption key size (%d) is invalid.\n", sa_info->enc_key_len);
+        return -1;
+    }
+
+    /* Get the authentication/encryption keys. */
+    keyParams.pAuthKey = &sa_info->auth_key[0];
+    keyParams.pEncKey = &sa_info->enc_key[0];
+
+    if (saInfo.dir == NWAL_SA_DIR_INBOUND)
+    {
+        /* Inbound == RX */
+        globalDB.rx_sa[slot].saAppId =  netapi_secAddSA(netapi_handle,
+                        NETCP_CFG_NO_INTERFACE,
+                        &saInfo,
+                        &keyParams,
+                        NETAPI_SEC_SA_INFLOW,
+                        (NETCP_CFG_ROUTE_HANDLE_T)&route,
+                        &p_rx_inflow_mode_handle,
+                        &p_tx_inflow_mode_handle,
+                        NULL, &error);
+
+        if (error == NETAPI_ERR_OK)
+        {
+            *sa_handle = globalDB.rx_sa[slot].saAppId;
+        }
+        else
+        {
+            ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
+                                "netapilib_ifAddSA: netapi_secAddSA returned error: %d.\n",
+                                 error);
+            return -1;
+        }
+    }
+    else
+    {
+        /* OUTBOUND == TX */
+        globalDB.tx_sa[slot].saAppId = netapi_secAddSA(netapi_handle,
+                        NETCP_CFG_NO_INTERFACE,
+                        &saInfo,
+                        &keyParams,
+                        NETAPI_SEC_SA_INFLOW,
+                        (NETCP_CFG_ROUTE_HANDLE_T)NULL,
+                        &p_rx_inflow_mode_handle,
+                        &p_tx_inflow_mode_handle,
+                        NULL, &error);
+        if (error == NETAPI_ERR_OK)
+        {
+            *sa_handle = globalDB.tx_sa[slot].saAppId;
+        }
+        else
+        {
+            ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
+                                "netapilib_ifAddSA: netapi_secAddSA returned error: %d.\n",
+                                 error);
+            return -1;
+        }
+    }
+    
+    ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
+    "netapilib_ifAddSA: Translation of SA successful, app_id: 0x%x\n", *sa_handle);
+
+    /* SA was created successfully. */
+    return 0;
+}
+
+
+#if 0
+/**************************************************************************
+ * FUNCTION PURPOSE: The function is used to translate the SA configuration
+ * parameters received from the IPSec Snopper and call the NETAPI function
+ * to create a security association
+ ********************************************************************/
+int netapilib_ifAddSA
+(
+    ipsecmgr_af_t               af,
+    ipsecmgr_sa_id_t            *sa_id,
+    ipsecmgr_sa_info_t          *sa_info,
+    ipsecmgr_sa_dscp_map_cfg_t  *dscp_map_cfg,
+    ipsecmgr_ifname_t           *if_name,
+    ipsecmgr_sa_encap_tmpl_t    *encap,
+    ipsecmgr_fp_handle_t        *sa_handle
+)
+{
+    int i;
+    uint8_t                 auth_key[36];
+    uint8_t                 encr_key[36];
+    int error, index,slot;
+    NETAPI_SEC_SA_INFO_T saInfo;
+    nwalSecKeyParams_t  keyParams;
+    void * p_rx_inflow_mode_handle;
+    void * p_tx_inflow_mode_handle;
+    NETCP_CFG_ROUTE_T  route;
+    NETCP_CFG_FLOW_T flow;
+    NETCP_CFG_SA_HANDLE_T pSaHandle;
+    char* pTok = NULL;
+    int iface;
+    cpu_set_t cpu_set;
+    ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
+                "netapilib_ifAddSA:, DEBUG: Translating SA\n");
+
+
+    /* assign main net_test thread to run on core 0 */
+    CPU_ZERO( &cpu_set);
+    CPU_SET( 0, &cpu_set);
+    hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
+
     memset((void *)&saInfo, 0, sizeof (NETAPI_SEC_SA_INFO_T));
     memset((void *)&keyParams, 0, sizeof (nwalSecKeyParams_t));
     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
@@ -205,6 +472,7 @@ int netapilib_ifAddSA
         /* need to check which interface this SA will be attached to */
         for (i=0;i<16;i++)
         {
+#if 1
             /* get interface for destination ip address */
             if (compareIPAddr(&ipConfigList[i].ip[0], 
                               saInfo.ipType == nwal_IPV4 ?
@@ -232,6 +500,7 @@ int netapilib_ifAddSA
                         return -1;
                     }
                 }
+#endif
                 globalDB.rx_sa[slot].iface = iface;
                 flow.dma_engine= 1;
                 flow.flowid = globalDB.flowId[iface];
@@ -241,8 +510,13 @@ int netapilib_ifAddSA
 
                 route.p_flow = &flow;
                 route.p_dest_q = globalDB.pktio_channel[iface];
+
                 printf("add_sa: p_dest_q: 0x%x, flowId: 0x%x\n",
-                route.p_dest_q, route.p_flow->flowid);
+                route.p_dest_q, 
+                route.p_flow->flowid);
+
+                route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
+                route.routeType = NETCP_CFG_ROUTE_RX_INTF_W_FLOW;
                 printf("add_sa: pktio_handle: 0x%x\n", globalDB.pktio_channel[iface]);
                 break;
             }
@@ -399,6 +673,9 @@ int netapilib_ifAddSA
     /* SA was created successfully. */
     return 0;
 }
+
+#endif
+
 /**************************************************************************
  * FUNCTION PURPOSE: The function is used to translate the SA configuration
  * parameters received from the IPSec Snopper and call the NETAPI function
@@ -407,7 +684,12 @@ int netapilib_ifAddSA
 int netapilib_ifDeleteSA (ipsecmgr_fp_handle_t sa_handle)
 {
     int error, slot;
+    cpu_set_t cpu_set;
     
+    /* assign main net_test thread to run on core 0 */
+    CPU_ZERO( &cpu_set);
+    CPU_SET( 0, &cpu_set);
+    hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
     slot = findAppIdSlot(&globalDB.rx_sa[0],sa_handle, 1);
 
     /* Determine if rx_sa or tx_sa is being deleted */
@@ -491,6 +773,12 @@ int32_t netapilib_ifAddSP
     NETCP_CFG_PA_HANDLE_T pPaHandleOuterIP;
     NETCP_CFG_PA_HANDLE_T pPaHandleInnerIP;
     NETCP_CFG_SA_HANDLE_T pSaHandle;
+
+    cpu_set_t cpu_set;
+    /* assign main net_test thread to run on core 0 */
+    CPU_ZERO( &cpu_set);
+    CPU_SET( 0, &cpu_set);
+    hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"netapilib_ifAddSP: called\n");
 
 
@@ -584,6 +872,11 @@ int32_t netapilib_ifDeleteSP
     ipsecmgr_dir_t          dir
 )
 {
+    cpu_set_t cpu_set;
+    /* assign main net_test thread to run on core 0 */
+    CPU_ZERO( &cpu_set);
+    CPU_SET( 0, &cpu_set);
+    hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
     /* Security Policy is deleted as part of deleting SA */
     return 0;
 #if 0
index 80ef727604c7e0098259841d9c663203dc26d4a8..b6e06bd8e03d059b2a4cec29776fa6aeda1cc954 100755 (executable)
@@ -64,7 +64,7 @@ all: .executables install installbin
 .executables: lib tests examples
 
 # Make rule to create $(ARMV7LIBDIR)/libnetapi.a library
-lib: $(ARMV7LIBDIR)/libnetapi.a libnetapi.so
+lib: $(ARMV7LIBDIR)/libnetapi.a
 
 $(ARMV7LIBDIR)/libnetapi.a:
        -@echo Building library...
index ff63191307027a1af874186b190ae4701f2c8d09..d4decbcda461facd93ad3bcefd969b903026a103 100755 (executable)
@@ -131,25 +131,97 @@ typedef NETCP_CFG_FLOW_T* NETCP_CFG_FLOW_HANDLE_T;
 
 
 /**
+ * @ingroup cfg_constants
  * @def NETCP_DEFAULT_ROUTE
- * This defines the NETCP default route.  This route has NETCP send received packets to the default NETCP 
+ * @brief This defines the NETCP default route.  This route has NETCP send received packets to the default NETCP 
  * pktio channel using descriptors and buffers from the default flow. The default route is created by netapi_init
  */
 #define NETCP_DEFAULT_ROUTE (NETCP_CFG_ROUTE_HANDLE_T) NULL
 
 
+#if 0
+/**
+ * @ingroup cfg_constants
+ * @def  NETCP_CFG_ROUTE_VLAN_PRIORITY
+* @brief Route by using VLAN bits as priority
+ */
+#define NETCP_CFG_ROUTE_VLAN_PRIORITY        0x1
+
+/**
+ * @ingroup cfg_constants
+ * @def  NETCP_CFG_ROUTE_DSCP_PRIORITY
+* @brief Route by using DSCP value as priority
+ */
+#define NETCP_CFG_ROUTE_DSCP_PRIORITY        0x2
+
+/**
+ * @ingroup cfg_constants
+ * @def  NETCP_CFG_ROUTE_RX_INTF
+* @brief Route by using EMAC port (interface) number as destination queue offset
+ */
+#define NETCP_CFG_ROUTE_RX_INTF              0x4
+
+/**
+ * @ingroup cfg_constants
+ * @def  NETCP_CFG_ROUTE_RX_INTF_W_FLOW
+ * @brief Route by using EMAC port (interface) number as both
+ *        destination queue and CPPI flow offset
+ */
+#define NETCP_CFG_ROUTE_RX_INTF_W_FLOW       0x8
+#endif
+/**
+ *  @ingroup cfg_constants
+ *  @{
+ *
+ *  @name   Valid Parameter configuration for NETCP_CFG_ROUTE_T
+ *  @brief  Valid Parameter configuration
+ *
+ *  @details Valid Parameter to configure optional parameters.
+ */
+/* @{ */
+/**
+ *  @def  NETCP_CFG_VALID_PARAM_ROUTE_TYPE
+ *        Valid Route Type configuration
+ *
+ */
+
+#define NETCP_CFG_VALID_PARAM_ROUTE_TYPE        0x01
+/*  @}  */
+/** @} */
+
+
+
 /**
  *  @ingroup cfg_structures
  *  @brief NETCP application defined route information.
  *  @details This structure is used to define a packet receive route.  A route consists of a 
  *           flow where to get free descriptors and buffers to hold the packet, and a destination 
- *           queue where to place the packet.
+ *           queue where to place the packet. Priority routing based on VLAN priority bits,
+ *           DSCP/TOS, and received input port is supported. In the case
+ *           of priority based routing, the PASS will forward the matchd packeed to the desired
+ *           queue which is equal to the base queue plus an offset. This offset is sepcififed
+ *           by the VLAN prioirty or DSCP/TOS value, or received input port.
  *
  */
 typedef struct NETCP_CFG_ROUTE_Tag
 {
-   NETCP_CFG_FLOW_T* p_flow;   /**< NULL or NETCP_DEFAULT_FLOW for default flow, @ref NETCP_CFG_FLOW_T */
-   PKTIO_HANDLE_T*   p_dest_q;   /**<NULL for default destination queue */
+    uint32_t            valid_params;       /**< Specifies which route config params
+                                                 are valid */
+    NETCP_CFG_FLOW_T    *p_flow;            /**< NULL or NETCP_DEFAULT_FLOW for default
+                                              *flow,@ref NETCP_CFG_FLOW_T
+                                              */
+    PKTIO_HANDLE_T      *p_dest_q;          /**< NULL for default destination queue */
+
+    nwalRouteType_t     routeType;          /**< Optional: Routing priority,
+                                              *  @see nwal.h for nwalRouteType_t
+                                              */
+    nwal_enetPort_t     tx_emac_port;       /**< Optional: TX Enet Port 1 based.Eg:
+                                              *  For transmitting through
+                                              *  first port configure as 1
+                                              *  @see nwal_enetPort_t in nwal.h.
+                                              *  Configuring to NWAL_ENET_PORT_UNKNOWN
+                                              *  will let CPSW decide on outgoing port.
+                                              */
 } NETCP_CFG_ROUTE_T;
 
 
@@ -506,12 +578,14 @@ void netapi_netcpCfgDelFlow(NETAPI_T h ,
  *  @param[in]  h    NETAPI instance handle, @ref NETAPI_T
  *  @param[in]  iface_no    interface number (0,1,..)
  *  @param[in]  ipType  type of IP address (V4 for V6)
- *  @param[in]  ip_addr      ip_address
+ *  @param[in]  ip_addr local
  *  @param[in]  ip_qualifiers   ip_qualifiers (all 0 for no qualifiers). This can be used to apply special handling for
- *                  diffserv category for example.
+ *                              diffserv category for example.
  *  @param[in]  route       handle of a created route or NULL to use internal default route, @ref NETCP_CFG_ROUTE_HANDLE_T
  *  @param[in]  user_data     Optional: pointer to user provided data associated with IP
+ *  @param[in]  ip_addr remote
  *  @param[out] err     pointer to error return
  *  @retval     returned AppID for attached rule. This is returned in RX meta data for packets matching this rule and no other, @ref NETCP_CFG_IP_T
  *  @pre       @ref netapi_init
  */
@@ -522,6 +596,7 @@ NETCP_CFG_IP_T  netapi_netcpCfgAddIp(NETAPI_T                   h,
                                      nwalIpOpt_t*               ip_qualifiers,
                                      NETCP_CFG_ROUTE_HANDLE_T   route,
                                      void*                      user_data,
+                                     //nwalIpAddr_t*              ip_addr_remote,
                                      int*                       err);
 
 /**
@@ -562,12 +637,13 @@ void netapi_netcpCfgDelIp(NETAPI_T          h,
  *      Note: The internal SOC switch (if operating in full swithc mode) may need to  be "taught" that this mac
  *      address is present by transmitting a packet with destination mac = this interface mac address.
  *  @param[in]  h   NETAPI instance handle, @ref NETAPI_T
- *  @param[in]  p_mac   pointer to 6 byte MAC address for interface
+ *  @param[in]  p_mac   pointer to 6 byte MAC address for local interface
  *  @param[in]  iface_no    interface number (0,1,..) 
  *  @param[in]  switch_port     (0 don't care, 1 switch port 1, 1 switch port 2) [only 0 supported currenly] 
  *  @param[in]  route   handle of a created route or NULL to use internal default route, @ref NETCP_CFG_ROUTE_HANDLE_T
  *  @param[in]  vlan    [future[ vlan configuration . Set to NULL, @ref NETCP_CFG_VLAN_T
  *  @param[in]  state   [future] interface state (0=down, 1= up)
+  * @param[in]  p_mac_remote   pointer to 6 byte MAC address for remote interface
  *  @param[out] err     pointer to error return
  *  @retval     returns AppID for interface (this is returned in meta data for received packets matching this rule an no others, @ref NETCP_CFG_MACIF_T
  *  @pre       @ref netapi_init 
@@ -579,6 +655,7 @@ NETCP_CFG_MACIF_T  netapi_netcpCfgCreateMacInterface(NETAPI_T
                                                      NETCP_CFG_ROUTE_HANDLE_T   route,
                                                      NETCP_CFG_VLAN_T           vlan,
                                                      int                        state,
+                                                     //uint8_t*                   p_mac_remote,
                                                      int *                      err);
 
 /**
index 548d5bd729642580b489343858a90f49bf9db87e..b379104d3a677d3c8e8f9635f2931077bc0c1f73 100755 (executable)
@@ -183,7 +183,7 @@ int netapip_startQm(void)
 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE     3400
 uint8_t nwalInstMem[NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_HANDLE]ALIGN(CACHE_LINESZ);
 
-#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC                    128
+#define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_MAC                    256
 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_IPSEC_HANDLE_PER_CHAN      256
 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_IP                     128
 #define NETAPI_NWAL_CONFIG_BUFSIZE_NWAL_PER_PORT                   128
@@ -281,7 +281,7 @@ int netapip_initNwal(
         }
         if(hplib_shmAddEntry(pBase, sizeof(NETAPI_SA_SHM_T), SA_ENTRY) == hplib_OK)
         {
-            saEntry = (NETAPI_PA_SHM_T*)hplib_shmGetEntry(pBase,SA_ENTRY);
+            saEntry = (NETAPI_SA_SHM_T*)hplib_shmGetEntry(pBase,SA_ENTRY);
             nwalGlobCfg.instPoolSaBaseAddr = (void*) saEntry;
         }
         else
@@ -345,6 +345,7 @@ int netapip_initNwal(
     nwalGlobCfg.paPowerOn = nwal_TRUE;
     nwalGlobCfg.saPowerOn = nwal_TRUE;
     nwalGlobCfg.paFwActive = nwal_TRUE;
+    nwalGlobCfg.paFwActive = nwal_FALSE;
     nwalGlobCfg.saFwActive = nwal_FALSE;
 
     /* Pick Default Physical Address */
@@ -384,6 +385,8 @@ int netapip_initNwal(
     bases[nwal_BUF_INDEX_INT_HANDLES] = (uint32_t *)Osal_nwalLocToGlobAddr((uint32_t)nwalHandleMem);
     if(NWAL_CHAN_HANDLE_SIZE  < sizes[nwal_BUF_INDEX_INT_HANDLES])
     {
+        printf("NWAL_CHAN_HANDLE_SIZE: %d, sizes: %d\n", NWAL_CHAN_HANDLE_SIZE,
+            sizes[nwal_BUF_INDEX_INT_HANDLES]);
         /* Resize Memory */
         while(1);
     }
index 7ba66535692ad9c2979ea4f28866434721f5feb0..71a307b0e1bc801a1c9eb90219649598ec950cf8 100755 (executable)
@@ -39,6 +39,7 @@ typedef struct NETCP_INTERFACE_IP_Tag
         nwalIpAddr_t  ip_addr;
         nwalIpOpt_t ip_qualifiers;
         void * user_data;
+        int ref_count;
 } NETCP_INTERFACE_IP_T;
 
 /* to hold a classifier */
@@ -389,7 +390,10 @@ return ((NETAPI_GLOBAL_T *)(pp->global))->nwal_context.nwalInstHandle;
 
 //utility to clear out a queue
 void netapip_zapQ(int queueNum);
-void netapip_netcpCfgBuildRoute(NETCP_CFG_ROUTE_T * p_route, int16_t * p_flow,  Qmss_QueueHnd * p_q);
+void netapip_netcpCfgBuildRoute(NETCP_CFG_ROUTE_T * p_route,
+                                int16_t * p_flow,
+                                Qmss_QueueHnd * p_q,
+                                nwalRouteType_t *p_type);
 
 //database utilities
 void netapip_netcpCfgDeleteSa(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int sa_slot);
index 3ebfebaa2376c0255be89d5760ade2359fe51f07..f4c456036a26d1e4798e59a4245643df2745a0c4 100755 (executable)
@@ -91,7 +91,8 @@ NETCP_CFG_SA_T netapi_secAddSA(NETAPI_T h,
                 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,/* Continue parsing to next route for match */
                 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,/* For next route fail action by default is route to host */
                 CPPI_PARAM_NOT_SPECIFIED,         /* Use default flow configured to NWAL  if packet is routed to host */
-                QMSS_PARAM_NOT_SPECIFIED          /* Use default queue configured to NWAL if packet is routed to host */
+                QMSS_PARAM_NOT_SPECIFIED,         /* Use default queue configured to NWAL if packet is routed to host */
+                0                                 /* route type */
            },
            /* nwalSaIpSecKeyParams_t */
            {0}
@@ -172,8 +173,16 @@ NETCP_CFG_SA_T netapi_secAddSA(NETAPI_T h,
 
         if (route != NULL)
         {
-            netapip_netcpCfgBuildRoute(route,&createParam.saIpSecParam.appRxPktFlowId, 
-                                         &createParam.saIpSecParam.appRxPktQueue);
+            if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+                NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+            {
+               createParam.saIpSecParam.validParams |= 
+                        NWAL_SA_INFO_VALID_PARAM_ROUTE_TYPE;
+            }
+            netapip_netcpCfgBuildRoute(route,
+                                       &createParam.saIpSecParam.appRxPktFlowId,
+                                       &createParam.saIpSecParam.appRxPktQueue,
+                                       &createParam.saIpSecParam.routeType);
         }
 
         /* fire off config message */
@@ -464,6 +473,7 @@ NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h,
     nwalSecPolParams_t createParam =
     {
         0,  /* handle */
+        0,  /* valid params */
         NWAL_SA_DIR_INBOUND,
         4,      /* IP Type */
         {0},  /* dst */
@@ -472,7 +482,8 @@ NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h,
         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
-        QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
+        QMSS_PARAM_NOT_SPECIFIED,                    /* Use default queue configured to NWAL if packet is routed to host */
+        0                                            /* Optional: route type */
     };
 
     void * sa_handle = NULL;
@@ -511,8 +522,16 @@ NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h,
     if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
     if (route != NULL)
     {
-        netapip_netcpCfgBuildRoute(route,&createParam.appRxPktFlowId,
-                                     &createParam.appRxPktQueue);
+        if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+            NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+        {
+           createParam.validParams |= 
+                    NWAL_SET_SEC_POLICY_VALID_PARAM_ROUTE_TYPE;
+        }
+        netapip_netcpCfgBuildRoute(route,
+                                   &createParam.appRxPktFlowId,
+                                   &createParam.appRxPktQueue,
+                                   &createParam.routeType);
     }
     /* reserve a slot */
     policyId = netapip_netcpCfgFindPolicySlot(n,
index a342bb02cef2f20db36c9afc70392afdb7eadc7c..4207166a75829bb5fb5358950f8f60b9229f3c57 100755 (executable)
@@ -99,14 +99,18 @@ void netapip_freeTransInfo(NetapiNwalTransInfo_t *pTransInfo)
  * DESCRIPTION:  Netapi internal function to build a route
  ********************************************************************/
 void netapip_netcpCfgBuildRoute(NETCP_CFG_ROUTE_T * p_route,
-                                int16_t * p_flow,  
-                                Qmss_QueueHnd * p_q)
+                                int16_t *p_flow,
+                                Qmss_QueueHnd *p_q,
+                                nwalRouteType_t *p_type)
 {
     if (!p_route) return;
     if (p_route->p_flow)  *p_flow= p_route->p_flow->flowid;
     else *p_flow = CPPI_PARAM_NOT_SPECIFIED;
+
     if (p_route->p_dest_q) *p_q = netapi_pktioGetQ(p_route->p_dest_q);
     else *p_q=QMSS_PARAM_NOT_SPECIFIED;
+
+    *p_type = p_route->routeType;
 }
 
 
@@ -475,6 +479,7 @@ static void netapip_netcpCfgInsertIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
     p->ips[ip_slot].ip_type = ipType;
     p->ips[ip_slot].nwal_handle = handle;
     p->ips[ip_slot].user_data = user_data;
+    p->ips[ip_slot].ref_count++;
     
 }
 
@@ -490,9 +495,38 @@ static void netapip_netcpCfgDeleteIp(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
     if ((ip_slot >=0) &&(ip_slot <=TUNE_NETAPI_MAX_NUM_IP))
     {
         p->ips[ip_slot].in_use=0;
+        p->ips[ip_slot].ref_count = 0;
     }
 }
 
+/***************************************************************************
+ * FUNCTION PURPOSE:  Netapi internal function to see if this IP is associated
+ *                    with any classifiers and if so, can only be deleted when
+                      its associated with only 1 classifier.
+ ***************************************************************************
+ * DESCRIPTION:Netapi internal function to check reference count of IP
+ ***************************************************************************/
+static Bool netapip_netcpCfgCheckIpRefCount(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,
+                                       int ip_slot)
+{
+
+#if 0
+    if ((ip_slot >=0) &&(ip_slot <=TUNE_NETAPI_MAX_NUM_IP))
+    {
+            /* IS IP is associated with alteast 2 rules, if yes, then dont delete IP */
+            if(p>ips[ip_slot].ref_count)
+                p->ips[ip_slot].ref_count--;
+            if (p>ips[ip_slot].ref_count)
+                return FALSE;
+            else
+                return TRUE;
+    }
+    else
+        return FALSE;
+#endif
+    return TRUE;
+}
+
 /***************************************************************************
  * FUNCTION PURPOSE:  Netapi internal function to get IP handle associated with IP address
  ***************************************************************************
@@ -748,7 +782,8 @@ NETCP_CFG_MACIF_T  netapi_netcpCfgCreateMacInterface(NETAPI_T  h,
         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
-        QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
+        QMSS_PARAM_NOT_SPECIFIED,                     /* Use default queue configured to NWAL if packet is routed to host */
+        0
     };
 
     nwal_RetValue       retValue;
@@ -782,7 +817,16 @@ NETCP_CFG_MACIF_T  netapi_netcpCfgCreateMacInterface(NETAPI_T  h,
 
     if (route != NULL)
     {
-        netapip_netcpCfgBuildRoute(route,&macInfo.appRxPktFlowId, &macInfo.appRxPktQueue);
+        if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+            NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+        {
+           macInfo.validParams |= 
+                    NWAL_SET_MAC_VALID_PARAM_ROUTE_TYPE;
+        }
+        netapip_netcpCfgBuildRoute(route,
+                                   &macInfo.appRxPktFlowId,
+                                   &macInfo.appRxPktQueue,
+                                   &macInfo.routeType);
     }
     retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
                                   trans_id,
@@ -927,13 +971,16 @@ static NETCP_CFG_IP_T  netapip_netcpCfgAddIpInternal(NETAPI_T  h,
     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
     void * n_handle=NULL;
     nwalIpParam_t    nwalIpParam= {
+    0,
     pa_IPV4,      /* IP Type */
     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
     { 0x0,0,0,0},/* IP Options */
     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
+    0,
     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
-    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
+    QMSS_PARAM_NOT_SPECIFIED,                     /* Use default queue configured to NWAL if packet is routed to host */
+    0
 };
     nwal_RetValue       retValue;
     NetapiNwalTransInfo_t *pTransInfo;
@@ -1000,7 +1047,16 @@ static NETCP_CFG_IP_T  netapip_netcpCfgAddIpInternal(NETAPI_T  h,
     nwalIpParam.ipType=ipType;
     if(route)
     {
-        netapip_netcpCfgBuildRoute(route,&nwalIpParam.appRxPktFlowId, &nwalIpParam.appRxPktQueue);
+        if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+            NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+        {
+           nwalIpParam.validParams |= 
+                    NWAL_SET_IP_VALID_PARAM_ROUTE_TYPE;
+        }
+        netapip_netcpCfgBuildRoute(route,
+                                   &nwalIpParam.appRxPktFlowId,
+                                   &nwalIpParam.appRxPktQueue,
+                                   &nwalIpParam.routeType);
     }
     else{} //use nwal defaults
 
@@ -1114,7 +1170,6 @@ static void netapip_netcpCfgDelIpInternal(NETAPI_T h,
     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
     void * ifHandle;
     int ip_slot = netapi_cfgGetMatchId(ip_rule_id);
-
     //get the nwal handle assoicated with this ip   
     if (flag)
     {
@@ -1133,6 +1188,15 @@ static void netapip_netcpCfgDelIpInternal(NETAPI_T h,
     }
     *err =0;
 
+    /* need to check to see if this IP is attached to a classifier(s)
+       and only delete if this is last classifier */
+    /* need to check to see if this IP is attached to  classifier
+       if referernce count is 1, this is only instance IP exists*/
+     if (!netapip_netcpCfgCheckIpRefCount(&netapi_get_global()->nwal_context, ip_slot))
+     {
+        return;
+     }
+    
     //get a transaction id
     pTransInfo = netapip_getFreeTransInfo(n,
                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
@@ -1235,11 +1299,13 @@ NETCP_CFG_CLASS_T netapi_netcpCfgAddClass(NETAPI_T                  h,
     nwalRxConnCfg_t tempCfg=
     {
         0,  //nwal_handle: to be filled in
-        {0}, // l4 ports: to be filled in
+        0, // l4 ports: to be filled in
         0,  //core id (NA)
         0, //action
         CPPI_PARAM_NOT_SPECIFIED, //flow id
         QMSS_PARAM_NOT_SPECIFIED, //dest queue
+        0,
+        0, // l4 ports: to be filled in
     };
 
     *err = NETAPI_ERR_OK;
@@ -1284,13 +1350,15 @@ NETCP_CFG_CLASS_T netapi_netcpCfgAddClass(NETAPI_T                  h,
             {
                 nwalIpParam_t tempParam=
                 {
+                    0,
                     pa_IPV4,      /* IP Type */
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  /* Dest IP */
                     { 0x0,0,0,0},/* IP Options */
                     NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
                     NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
                     CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
-                    QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
+                    QMSS_PARAM_NOT_SPECIFIED,                    /* Use default queue configured to NWAL if packet is routed to host */
+                    0
                 };
                 //build nwalIpParam
                 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));
@@ -1356,7 +1424,16 @@ NETCP_CFG_CLASS_T netapi_netcpCfgAddClass(NETAPI_T                  h,
             tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW)  ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;
             if (route)
             {
-                netapip_netcpCfgBuildRoute(route,&tempCfg.appRxPktFlowId, &tempCfg.appRxPktQueue);
+                if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+                    NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+                {
+                    tempCfg.validParams |= 
+                        NWAL_SET_CONN_VALID_PARAM_ROUTE_TYPE;
+                }
+                netapip_netcpCfgBuildRoute(route,
+                                           &tempCfg.appRxPktFlowId,
+                                           &tempCfg.appRxPktQueue,
+                                           &tempCfg.routeType);
             }
 
 
@@ -1707,7 +1784,18 @@ NETCP_CFG_EXCEPTION_PKT_T netapi_netcpCfgExceptions(NETAPI_T
 
     if (p_route != NULL)
     {
-        netapip_netcpCfgBuildRoute(p_route, &ctrl.appRxPktFlowId,& ctrl.appRxPktQueue);
+#if 0
+        if((p_route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
+            NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
+        {
+           ctrl.validParams |= 
+                    NWAL_SET_MAC_VALID_PARAM_ROUTE_TYPE;
+        }
+#endif
+        netapip_netcpCfgBuildRoute(p_route,
+                                   &ctrl.appRxPktFlowId,
+                                   &ctrl.appRxPktQueue,
+                                   &ctrl.routeType);
     }
     else
     {