/******************************************************************************
 *
 *  <:copyright-BRCM:2016:DUAL/GPL:standard
 *  
 *     Copyright (c) 2016 Broadcom
 *     All Rights Reserved
 *  
 *  Unless you and Broadcom execute a separate written software license
 *  agreement governing use of this software, this software is licensed
 *  to you under the terms of the GNU General Public License version 2
 *  (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
 *  with the following added to such license:
 *  
 *     As a special exception, the copyright holders of this software give
 *     you permission to link this software with independent modules, and
 *     to copy and distribute the resulting executable under terms of your
 *     choice, provided that you also meet, for each linked independent
 *     module, the terms and conditions of the license of that module.
 *     An independent module is a module which is not derived from this
 *     software.  The special exception does not apply to any modifications
 *     of the software.
 *  
 *  Not withstanding the above, under no circumstances may you combine
 *  this software in any way with any other Broadcom software provided
 *  under a license other than the GPL, without Broadcom's express prior
 *  written consent.
 *  
 *  :>
 *
 *****************************************************************************/
 
/**
 * @file bal_dpp_flow.c
 * @brief BAL Switch util functions that handle flow requests
 * @addtogroup sw_util
 */
 
 /*@{*/
#include <bal_common.h>
#include <bcm_dev_log.h>
#include <bal_msg.h>
#include <bal_utils_msg.h>
#include "bal_switch_flow.h"
#include "flow_fsm.h"
#include "bcmos_errno.h"
#include "bal_switch_util.h"
#include "bal_dpp_qos_map.h"

#ifndef TEST_SW_UTIL_LOOPBACK
#define _SHR_PBMP_WIDTH 567  
                             /* match the WIDTH size of bcm_field_group_config_t in bcm/field.h with ARAD */
                             /* we build swich_util without #define created by the sdk make/Make.local */  
#include <bcm/types.h>
#include <sal/core/libc.h>
#ifndef sal_memset
#define sal_memset memset
#endif
#include <bcm/port.h>
#include <bcm/vlan.h>
#include <bcm/field.h>
#include <bcm/error.h>
#include <bcm/vswitch.h>
#include <bcm/qos.h>
#include <bcm/l2.h>

#include "bal_switch_acc_term.h"
#include "bal_dpp_flow.h"
#include "bal_dpp_qos.h"
#include "bal_dpp_vswitch.h"
#include "bal_dpp_group.h"

/** Local routines declarations */
static bcmos_errno bal_sw_util_reverse_flow_create(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_flow_rev);
static bcmos_bool bal_sw_util_is_symmetry_flows(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_ref_flow);

/* perform initialization before any dpp flow function calls */
void bal_sw_util_dpp_flow_init(void)
{
   /* nothing to do here yet, place holder */ 
   return;
}

/**
 * @brief The create trap gport function create a trap port that allow TRAP action to
 *        associate with and perform packet trapping to the CPU port.
 * 
 * @param unit          the switch unit this trap port to be created
 * @param p_trap_gport  a pointer that the created gport will be return  
 * @param p_trap_code   a pointer that the created trap code will be return  
 * @return bcm error code
 */
static int bal_sw_util_create_trap_gport(int unit, bcm_gport_t *p_trap_gport, uint32_t *p_trap_code)
{
    int ret, trap_id;
    bcm_rx_trap_config_t trap_config;
    
    ret = bcm_rx_trap_type_create(unit, 0, bcmRxTrapUserDefine, &trap_id);
    if(ret != BCM_E_NONE)
    {
        BCM_LOG(ERROR, log_id_sw_util, "create trap type return %d\n", ret);
        return ret;
    }
    
    bcm_rx_trap_config_t_init(&trap_config);
    trap_config.flags = (BCM_RX_TRAP_UPDATE_DEST | BCM_RX_TRAP_TRAP | BCM_RX_TRAP_REPLACE);
    trap_config.trap_strength = 0;
    trap_config.dest_port = BCM_GPORT_LOCAL_CPU;
    ret = bcm_rx_trap_set(unit, trap_id, &trap_config);
    if(ret != BCM_E_NONE)
    {
        BCM_LOG(ERROR, log_id_sw_util, "set rx trap return %d\n", ret);
        return ret;
    }
    BCM_GPORT_TRAP_SET(*p_trap_gport, trap_id, 7 /* trap_strength */, 0); 
    *p_trap_code = trap_id;    
    return ret;    
}
/* disable the field group (FG) source ip support to restrict the FG size */ 
#define BAL_ACL_FG_SRC_IP_ENABLE 0
/* create a default field group that used by all default ACL. 
   When a FLOW is created,a LIF is created to direct the packets to a VSwitch.
   The LIF can only match packet with ingress port and VID.
   If a FLOW needs to be classified with more attributes, an ACL is created to override the LIF.
   A default ACL has the same packet classification as the LIF but has lower priority than the overlapped ACL.
   The default ACL dropped packets that match the LIF but do not match the ACL. This enforce the FLOW
   to only forward packets with exact match */
static bcm_field_group_t dpp_dft_group_id = 1;
/* create a field group that used by all ACL */
static bcm_field_group_t dpp_group_id = 0;
/**
 * @brief Create a field group in the switch ICAP, 
 *        The field group allow flow classifier to create ACL rules
 * 
 * @param unit    the switch unit this rule is to be added
 * @param p_group_id  a pointer to a variable that return the created group id  
 * @return error code
 */
 static bcmos_errno bal_sw_util_dpp_fg_create(int unit, bcm_field_group_t *p_group_id)
 {
    bcm_field_group_status_t fg_status;    
    bcm_field_group_config_t grp; 
    int32_t ret = 0;
    
    /* VCAP - bcmFieldQualifyStageLookup, ICAP - bcmFieldQualifyStageIngress, ECAP - bcmFieldQualifyStageEgress */
    /* The DPP resources allow only limit number of qset - indexed by dpp_group_id, create qset when necessary */
    /* create one if not exist */
    if (BCM_E_NOT_FOUND == bcm_field_group_status_get(unit, *p_group_id, &fg_status))
    {      
        bcm_field_group_config_t_init(&grp);
        
        BCM_FIELD_QSET_INIT(grp.qset);   
                                                                      /* TCAM entry limit to 80 bits per slice, but up to 4 slices for a group
                                                                         use ModeAuto to automatically adjust it */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInPort);          /* 32 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyDstMac);          /* 48 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifySrcMac);          /* 48 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyDstIp);           /* 32 bits */
#if (BAL_ACL_FG_SRC_IP_ENABLE == 1)       
        /* save source IP space for other classifier, try to keep total size under 4 slices */ 
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifySrcIp);           /* 32 bits */
#endif        
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyEtherType);       /* 16 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyIpProtocol);      /*  8 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyL4DstPort);       /* 16 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyL4SrcPort);       /* 16 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyOuterVlanId);     /* 16 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyOuterVlanPri);    /*  8 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInnerVlanId);     /* 16 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInnerVlanPri);    /*  8 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInVPort);         /* 32 bits */
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyPacketRes);             
        
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyStageIngress);
        
        BCM_FIELD_ASET_INIT(grp.aset);
        BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionTrap);
        BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionDrop);
        BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionRedirect);
        BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionVportNew);
        
        grp.priority = 12; /* the higher the number the higher the priority */
        grp.flags = (BCM_FIELD_GROUP_CREATE_WITH_MODE | BCM_FIELD_GROUP_CREATE_WITH_ASET);
        grp.mode = bcmFieldGroupModeAuto;
        
        ret = bcm_field_group_config_create(unit, &grp);
        
        if (ret != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, 
                              " flow fail to create field - %d\n", ret );
             return BCM_ERR_INTERNAL;
        }
                  
        *p_group_id = grp.group;
        BCM_LOG(INFO, log_id_sw_util, "Field Group %d created\n", *p_group_id);
        return BCM_ERR_OK;
    }
    return BCM_ERR_ALREADY; 
 }

/**
 * @brief Create a default field group in the switch ICAP, 
 *        This field group allow flow classifier to create default ACL rules
 * 
 * @param unit    the switch unit this rule is to be added
 * @param p_group_id  a pointer to a variable that return the created group id  
 * @return error code
 */
 static bcmos_errno bal_sw_util_dpp_dft_fg_create(int unit, bcm_field_group_t *p_group_id)
 {
    bcm_field_group_status_t fg_status;    
    bcm_field_group_config_t grp; 
    int32_t ret = 0;
    
    /* VCAP - bcmFieldQualifyStageLookup, ICAP - bcmFieldQualifyStageIngress, ECAP - bcmFieldQualifyStageEgress */
    /* The DPP resources allow only limit number of qset - indexed by dpp_group_id, create qset when necessary */
    /* create one if not exist */
    if (BCM_E_NOT_FOUND == bcm_field_group_status_get(unit, *p_group_id, &fg_status))
    {      
        bcm_field_group_config_t_init(&grp);
        
        BCM_FIELD_QSET_INIT(grp.qset);   
                                                                      /* TCAM entry limit to 80 bits per slice, but up to 4 slices for a group
                                                                         use ModeAuto to automatically adjust it */
   
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyInVPort);         /* 32 bits */            		 
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyPacketRes); 
        
        BCM_FIELD_QSET_ADD(grp.qset, bcmFieldQualifyStageIngress); 
        
        BCM_FIELD_ASET_INIT(grp.aset);
        BCM_FIELD_ASET_ADD(grp.aset, bcmFieldActionDrop);
       
        grp.priority = 10; /* the higher the number the higher the priority */
        grp.flags = (BCM_FIELD_GROUP_CREATE_WITH_MODE | BCM_FIELD_GROUP_CREATE_WITH_ASET);
        grp.mode = bcmFieldGroupModeAuto;
        
        ret = bcm_field_group_config_create(unit, &grp);
        
        if (ret != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, 
                              " flow fail to create default field - %d\n", ret );
             return BCM_ERR_INTERNAL;
        }
                  
        *p_group_id = grp.group;
        BCM_LOG(INFO, log_id_sw_util, "Default Field Group %d created\n", *p_group_id);
        return BCM_ERR_OK;
    }
    return BCM_ERR_ALREADY; 
 } 
 
/**
 * @brief The acl add function add an Access Control Rule in the switch  VCAP/ICAP/ECAP
 *        to perform action based on flow classifier
 * 
 * @param unit    the switch unit this rule is to be added
 * @param p_flow  a pointer to the flow definition the created rule will be based on 
 * @param p_flow_elm  a pointer to the switch internal flow list  
 * @param in_gport  ingress virtual port (LIF) this acl applied 
 * @param out_gport egress virtual port (LIF) this acl applied 
 * @return error code
 */
static bcmos_errno bal_sw_util_dpp_acl_add(int unit, bcmbal_flow_cfg *p_flow, bal_sw_flow *p_flow_elm, uint32_t in_gport, uint32_t out_gport)
{
     int32_t ret = 0;
     uint16_t udp_port, flow_pri;
     bcm_field_entry_t eid;
     bcm_gport_t trap_gport;            
     bcm_mac_t dst_mac, src_mac;
     bcm_mac_t mac_mask =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};    
     uint32_t trap_code = 0;
     bcmos_errno err;
      
    BCM_LOG(INFO, log_id_sw_util,
                  " Add an ACL to a flow w type = %d\n", p_flow->key.flow_type);                  
 
    if(p_flow_elm->num_eid >= MAX_FIELD_EID)
    {
        BCM_LOG(ERROR, log_id_sw_util, "Too many ACL rules in flow id %d\n", p_flow_elm->id);
        return BCM_ERR_NORES;
    } 
	
    err = bal_sw_util_dpp_fg_create(unit, &dpp_group_id);
 
    if (BCM_ERR_ALREADY != err && BCM_ERR_OK != err)
    {
        BCM_LOG(ERROR, log_id_sw_util, "Field Group %d create failed\n", dpp_group_id);
        return err;
    }

    /* fill in the match fields */
    do
    { 
        ret = bcm_field_entry_create(unit, dpp_group_id, &eid);
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field_entry_create failed - %d\n", ret);
            break;
        }
        /* if upstream, match ingress port */
        if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM &&  BCMBAL_CFG_PROP_IS_SET(p_flow, flow, access_int_id))
        {            
            ret = bcm_field_qualify_InPort(unit, eid, bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id), 0xffffffff);
            if (BCM_E_NONE != ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InPort failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add InPort %d to qualifier\n", bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id));
            }
 
        }
        /* if downstream, match ingress nni port */
        if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM && BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id))
        {            
            ret = bcm_field_qualify_InPort(unit, eid, bal_bcm_net_inf_pbm_get(p_flow->data.network_int_id), 0xffffffff);
            if (BCM_E_NONE != ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InPort failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add network port %d to qualifier\n", bal_bcm_net_inf_pbm_get(p_flow->data.network_int_id));
            }                
        }
        /* match ether type */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ether_type))
        {
            ret = bcm_field_qualify_EtherType(unit, eid, p_flow->data.classifier.ether_type, 0xffff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_EtherType failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add ether type 0x%x to qualifier\n", p_flow->data.classifier.ether_type );
            }
        }
        /* add IP protocol to match rule */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, ip_proto))
        {
            ret = bcm_field_qualify_IpProtocol(unit, eid, p_flow->data.classifier.ip_proto, 0xff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_IpProtocol failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add ip protocol 0x%x to qualifier\n", p_flow->data.classifier.ip_proto );
            }
        }
        /* add L3 source port to match rule - Don't be confused by the API name */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_port))
        {
            udp_port = p_flow->data.classifier.src_port;
            ret = bcm_field_qualify_L4SrcPort(unit, eid, udp_port, 0xffff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_L4SrcPort failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add src port %d to qualifier\n", udp_port );
            }
        }
        /* add L3 destination port to match rule */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_port))
        {
            udp_port = p_flow->data.classifier.dst_port;
            ret = bcm_field_qualify_L4DstPort(unit, eid, udp_port, 0xffff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_L4DstPort failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add dst port %d to qualifier\n", udp_port );
            }
        }
        /* add Outer vid to match rule */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid))
        {
            ret = bcm_field_qualify_OuterVlanId(unit, eid, p_flow->data.classifier.o_vid, 0x0fff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_OuterVlanId failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add outer vid 0x%x to qualifier\n", p_flow->data.classifier.o_vid );
            }
        }
        /* add Inner vid to match rule */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid))
        {
            ret = bcm_field_qualify_InnerVlanId(unit, eid, p_flow->data.classifier.i_vid, 0x0fff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InnerVlanId failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add Inner vid 0x%x to qualifier\n", p_flow->data.classifier.i_vid );
            }
        }
        /* add Outer priority to match rule  - only accept 3 bits */
        /* use ACL for downstream, upstream pbit classification will be done through PON LIF */
        if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
           BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_pbits))
        {
            ret = bcm_field_qualify_OuterVlanPri(unit, eid, p_flow->data.classifier.o_pbits, 0x7);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_OuterVlanPri failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add outer pri 0x%x to qualifier\n", p_flow->data.classifier.o_pbits );
            }
        }
        /* add Inner priority to match rule  - only accept 3 bits */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_pbits))
        {
            ret = bcm_field_qualify_InnerVlanPri(unit, eid, p_flow->data.classifier.i_pbits, 0x7);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InnerVlanPri failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add inner pri 0x%x to qualifier\n", p_flow->data.classifier.i_pbits );
            }
        }
        /* add Dst Mac to match rule */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac))
        {
            memcpy(&dst_mac, &(p_flow->data.classifier.dst_mac), sizeof(bcm_mac_t));
            ret = bcm_field_qualify_DstMac(unit, eid, dst_mac, mac_mask);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_DstMac failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add DstMac %x:%x:%x:%x:%x:%x to qualifier\n",
                                p_flow->data.classifier.dst_mac.u8[0],
                                p_flow->data.classifier.dst_mac.u8[1],
                                p_flow->data.classifier.dst_mac.u8[2],
                                p_flow->data.classifier.dst_mac.u8[3],
                                p_flow->data.classifier.dst_mac.u8[4],                              
                                p_flow->data.classifier.dst_mac.u8[5] );
            }
        }
        /* add Src Mac to match rule */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_mac))
        {
            memcpy(&src_mac, &(p_flow->data.classifier.src_mac), sizeof(bcm_mac_t));
            ret = bcm_field_qualify_SrcMac(unit, eid, src_mac, mac_mask);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_SrcMac failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add SrcMac[5] 0x%x to qualifier\n", p_flow->data.classifier.src_mac.u8[5] );
            }
        }
        /* add Dst IP to match rule */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_ip))
        {           
            ret = bcm_field_qualify_DstIp(unit, eid, p_flow->data.classifier.dst_ip.u32, 0xffffffff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_DstIp failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add DstIp 0x%x to qualifier\n", p_flow->data.classifier.dst_ip.u32 );
            }
        }
      
        /* add Src IP to match rule */        
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_ip))
        {           
            ret = bcm_field_qualify_SrcIp(unit, eid, p_flow->data.classifier.src_ip.u32, 0xffffffff);
            if (ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, "field_qualify_SrcIp failed - %d\n", ret);
                break;
            }
            else
            {
                BCM_LOG(INFO, log_id_sw_util, "Add SrcIp 0x%x to qualifier\n", p_flow->data.classifier.src_ip.u32 );
            }
        }        
        /* set ACL priority */
        if(BCMBAL_CFG_PROP_IS_SET(p_flow, flow, priority))
        {
            flow_pri = p_flow->data.priority;
        }
        else /* default to 10, valid range 0 - 65535 */
        {
            flow_pri = BAL_FLOW_DEFAULT_PRIORITY;
            /* set the presence of priority bit in the flow to reflect insertion of DEFAULT_PRIORITY */
            BCMBAL_CFG_PROP_SET(p_flow, flow, priority, flow_pri);                    
        }
        ret = bcm_field_entry_prio_set(unit, eid, flow_pri);
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field entry priority failed - %d\n", ret);
            break;
        }
        else
        {
            BCM_LOG(INFO, log_id_sw_util, "field entry priority set to - %d\n", flow_pri);
        }
     
    }while(0);
        
    if (BCM_E_NONE == ret) /* make sure the field qualifier settings are good */
    {
        if( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)  &&
            BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST)    )                
        {
            BCM_LOG(INFO, log_id_sw_util,
                  " Got a flow action cmd=0x%x \n", p_flow->data.action.cmds_bitmask);    
            do
            {      
                ret = bal_sw_util_create_trap_gport(unit, &trap_gport, &trap_code);
                if (ret)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "create_trap_gport failed - %d\n", ret);
                    break;
                }
                /* qualify with in LIF */
                if(in_gport)
                {
                    /* add vPort to match rule */
                    ret = bcm_field_qualify_InVPort32(unit, eid, in_gport, 0xffff);               
                    if (ret)
                    {
                        BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InVPort failed - %d\n", ret);
                        break;
                    } 
                }
                ret = bcm_field_action_add(unit, eid, bcmFieldActionTrap, trap_gport, 0);
                if (ret)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "field action add failed - %d\n", ret);
                    break;
                };
                ret = bcm_field_entry_install(unit, eid);
                if (ret)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "field_entry_install %d failed - %d\n", eid, ret);
                    break;
                } 
                else
                {
                    BCM_LOG(INFO, log_id_sw_util, "Add rule %d Success\n", eid);
                }
                
            }while(0);
        }
        /* regular forwarding ACL */
        else 
        {     
            do
            {
                /* redirect to the egress LIF */
                ret = bcm_field_action_add(unit, eid, bcmFieldActionRedirect,  0,  out_gport);
                if (ret)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "field action add failed - %d\n", ret);
                    break;
                };
                /* trigger vlan translation at the egress LIF */
                ret = bcm_field_action_add(unit, eid, bcmFieldActionVportNew,  out_gport, 0);
                if (ret)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "field action add new vport failed - %d\n", ret);
                    break;
                };

                ret = bcm_field_entry_install(unit, eid);
                if (ret)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "field_entry_install %d failed - %d\n", eid, ret);
                    break;
                } 
                else
                {
                    BCM_LOG(INFO, log_id_sw_util, "Add rule %d to gport 0x%x Success\n", eid, out_gport);
                }              
            }while(0);
        }
    }  
    
    if (ret != BCM_E_NONE)
    {
         /* TBD - release the eid and trap port resource */
         return BCM_ERR_INTERNAL;
    }
    else
    {
        /* add flow info into the internal link list */
        p_flow_elm->trap_code = trap_code;
        p_flow_elm->trap_port = trap_gport;
        p_flow_elm->field_entry_id[p_flow_elm->num_eid] = eid; 
        p_flow_elm->num_eid += 1;        
        p_flow_elm->valid = 1;
        return BCM_ERR_OK;
    }
}

/**
 * @brief The default acl add function add a DROP Access Control Rule on the ingress LIF
 * 
 * @param unit    the switch unit this rule is to be added
 * @param p_flow  a pointer to the flow definition the created rule will be based on 
 * @param p_flow_elm  a pointer to the switch internal flow list  
 * @param in_gport  ingress virtual port (LIF) this acl applied  
 * @return error code
 */
static bcmos_errno bal_sw_util_dpp_dft_acl_add(int unit, bcmbal_flow_cfg *p_flow, bal_sw_flow *p_flow_elm, uint32_t in_gport)
{
    bcmos_errno err;
    bcm_field_entry_t dft_eid = 0;
    int32_t ret = 0;
  
    if(p_flow_elm->num_eid >= MAX_FIELD_EID)
    {
        BCM_LOG(ERROR, log_id_sw_util, "Too many dft ACL rules in flow id %d\n", p_flow_elm->id);
        return BCM_ERR_NORES;
    }
	
    err = bal_sw_util_dpp_dft_fg_create(unit, &dpp_group_id);
 
    if (BCM_ERR_ALREADY != err && BCM_ERR_OK != err)
    {
        BCM_LOG(ERROR, log_id_sw_util, "Field Default Group %d create failed\n", dpp_dft_group_id);
        return err;
    }
    do
    {
         /* Install a default drop ACL at lowest priority(0). 
           This will drop unmatch packets received on the same ingress LIF 
         */   
        
        ret = bcm_field_entry_create(unit, dpp_group_id, &dft_eid);
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field_entry_create failed - %d\n", ret);
            break;
        }
   
        /* add vPort to match rule */
        ret = bcm_field_qualify_InVPort32(unit, dft_eid, in_gport, 0xffff);               
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field_qualify_InVPort failed - %d\n", ret);
            break;
        } 

		/* add Packet type to match rule, drop only unicast */
        ret = bcm_field_qualify_PacketRes(unit, dft_eid, BCM_FIELD_PKT_RES_L2UC, 0);                        
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field_qualify_PacketRes failed - %d\n", ret);
            break;
        } 
		
        
        /* set to lowest priority 0 */ 
        ret = bcm_field_entry_prio_set(unit, dft_eid, 0);                
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field entry priority failed - %d\n", ret);
            break;
        };

        /* Drop the packet */
        ret = bcm_field_action_add(unit, dft_eid, bcmFieldActionDrop,  0,  0);
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field action add failed - %d\n", ret);
            break;
        };
        ret = bcm_field_entry_install(unit, dft_eid);
        if (ret)
        {
            BCM_LOG(ERROR, log_id_sw_util, "field_entry_install %d failed - %d\n", dft_eid, ret);
            break;
        } 
        else
        {
            BCM_LOG(INFO, log_id_sw_util, "Add default rule %d Success\n", dft_eid);
        }  
    }while(0);  
    if (ret != BCM_E_NONE)
    {
        return BCM_ERR_INTERNAL;
    }
    else
    {
        p_flow_elm->field_entry_id[p_flow_elm->num_eid] = dft_eid; 
        p_flow_elm->num_eid += 1; 
        return BCM_ERR_OK;
    }    
}

/**
 * @brief The ingress vlan translation function modified the packet VLAN tag 
 *        before sending it out 
 * 
 * @param unit    the switch unit this rule is to be added
 * @param p_flow  a pointer to the flow definition the created rule will be based on 
 * @param ingport  the gport the translation will be applied 
 * @return error code
 */
static bcmos_errno bal_sw_util_dpp_invlanx(int unit, bcmbal_flow_cfg *p_flow, uint32_t ingport)
{
    int rv = 0;
    bcm_vlan_action_set_t action;
    bcm_vlan_action_set_t_init(&action);
    bcmos_errno ret;
    
    if(BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMARK_PBITS))       
    {  
        int qos_map_id, i_pri, o_pri;
       
        do
        {
            switch(p_flow->data.classifier.pkt_tag_type)
            {
                case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG: 
                    /* should be                                           
                       action.dt_outer_pkt_prio = bcmVlanActionReplace;
                       action.new_outer_vlan = p_flow->data.classifier.o_vid;;
                       action.dt_outer = bcmVlanActionReplace;
                       but it does not seems to work. Using ot_outer seems to also work for double tagged packets 
                    */   
                    action.ot_outer_pkt_prio = bcmVlanActionReplace; 
                    action.new_outer_vlan = p_flow->data.classifier.o_vid;
                    action.ot_outer = bcmVlanActionReplace;                      
                break;
                case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                    action.ot_outer_pkt_prio = bcmVlanActionReplace; 
                    action.new_outer_vlan = p_flow->data.classifier.o_vid;
                    action.ot_outer = bcmVlanActionReplace;  
                                                      
                break;
                default:
                    BCM_LOG(ERROR, log_id_sw_util,
                            "Error, pbits translation on untagged packets\n"); 
                    return BCM_ERR_NOT_SUPPORTED;                        
                break;
            }   
             
                 
            /* perform o_pbits translation */
            if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_pbits))
            {
                i_pri = p_flow->data.classifier.o_pbits;
            }
            else
            {
                /* mark the source pcp DONTCARE */
                i_pri = -1;
            }
            /* flow validation already make sure the action.o_pbits is set for REMARK_PBITS */
            o_pri = p_flow->data.action.o_pbits;        
            
            ret = bal_sw_dpp_pcp_remark_map_get(i_pri, o_pri, &qos_map_id);
       
            if (ret != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, log_id_sw_util,
                        "Error, faile to obtain pcp map id, ret = %d\n", ret);
                rv = BCM_E_UNAVAIL;        
                break;                        
            }
            
            rv = bcm_qos_port_map_set(unit, ingport, qos_map_id, -1);     
            if (rv != BCM_E_NONE)
            {
                BCM_LOG(ERROR, log_id_sw_util,
                        "Error, pbits translation bcm_qos_port_map_set ret = %d\n", rv);
                break;                        
            }
                        
            /* set the action priority profile */
            action.priority = qos_map_id;
            action.new_inner_pkt_prio = qos_map_id;            
        }while(0);
    }
    else
    {
        /* nothing to do, return OK */
        return BCM_ERR_OK;
    }
    if(rv != BCM_E_NONE)
    {
        return BCM_ERR_INTERNAL;
    }
    
    rv = bcm_vlan_translate_action_create(unit, ingport, bcmVlanTranslateKeyPortOuter, BCM_VLAN_INVALID, BCM_VLAN_NONE, &action);
    if( rv )
    {
        return BCM_ERR_INTERNAL;
    }
    else
    {
        BCM_LOG(INFO, log_id_sw_util, "Perform ingress vlan translation w %s action on gport 0x%x\n",
                (p_flow->data.classifier.pkt_tag_type == BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG)? "DT": "ST",
                ingport);
        return BCM_ERR_OK;
    }
}
/**
 * @brief The egress vlan translation function modified the packet VLAN tag 
 *        before sending it out 
 * 
 * @param unit    the switch unit this rule is to be added
 * @param p_flow  a pointer to the flow definition the created rule will be based on 
 * @param egport  the gport the translation will be applied 
 * @return error code
 */
static bcmos_errno bal_sw_util_dpp_evlanx(int unit, bcmbal_flow_cfg *p_flow, uint32_t egport)
{
    int rv = 0;
    bcm_vlan_action_set_t action;
    bcm_vlan_action_set_t_init(&action);

    if(BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG))   
    {
        action.new_outer_vlan = p_flow->data.action.o_vid;
        action.priority = 0;
        switch(p_flow->data.classifier.pkt_tag_type)
        {
            case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
                action.ut_outer = bcmVlanActionAdd;
                action.ut_outer_pkt_prio = bcmVlanActionAdd;
            break;
            case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                action.ot_outer = bcmVlanActionAdd;
                action.ot_outer_pkt_prio = bcmVlanActionAdd;
            break;
            default:
                action.new_outer_vlan = 0;
                action.ot_outer = bcmVlanActionNone;
            break;
        }        
        
        if( p_flow->data.action.o_tpid )
        {
            action.outer_tpid_action = bcmVlanTpidActionModify;
            action.outer_tpid = p_flow->data.action.o_tpid;
        }
		
    }
    else if(BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG))
    {   
        switch(p_flow->data.classifier.pkt_tag_type)
        {
            case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
                /* should be action.dt_outer = bcmVlanActionDelete, 
                   but it does not seems to work. Using ot_outer seems to also work for double tagged packets */ 
                action.ot_outer = bcmVlanActionDelete;                        
            break;
            case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                action.ot_outer = bcmVlanActionDelete;               
            break;
            default:
                action.ut_outer = bcmVlanActionNone;
            break;
        }               
    }
    else if (BCMBAL_ACTION_CMD_ID_IS_SET( &(p_flow->data.action), BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG))
    {
        action.new_outer_vlan = p_flow->data.action.o_vid;
        switch(p_flow->data.classifier.pkt_tag_type)
        {
            case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
                /* should be action.dt_outer = bcmVlanActionReplace, 
                   but it does not seems to work. Using ot_outer seems to also work for double tagged packets */ 
                action.ot_outer = bcmVlanActionReplace;                  
            break;
            case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                action.ot_outer = bcmVlanActionReplace;               
            break;
            default:
                action.ut_outer = bcmVlanActionNone;
            break;
        }       

        /** @todo tpid is not translated for now */
        /** @note the vid translated from is passed as a parameter to the api call */
       
    }
    else
    {
        /* nothing to do, return OK */
        return BCM_ERR_OK;
    }

    rv = bcm_vlan_translate_egress_action_add(unit, egport, BCM_VLAN_NONE, BCM_VLAN_NONE, &action);
    if( rv )
    {
        BCM_LOG(ERROR, log_id_sw_util, "bcm_vlan_translate_egress_action_add failed %d on gport 0x%x\n", rv, egport);
        return BCM_ERR_INTERNAL;
    }
    else
    {
        BCM_LOG(INFO, log_id_sw_util, "Perform egress vlan translation on gport 0x%x\n", egport);
        return BCM_ERR_OK;
    }
}
/**
 * @brief Multicast flow add function forward the specified multicast packets to a multicast group.
 *        The multicast group has to be created prio to the mc_flow add operation
 * 
 * @param p_flow  a pointer to the flow definition the created rule will be based on 
 * @param service_type id this multicast flow is for multicast or downstream N:1 service
 * @return error code
 */
static bcmos_errno bal_sw_util_dpp_mc_flow_add(bcmbal_flow_cfg *p_flow, uint32_t service_type)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcm_gport_t nni_gport;
    int ii, unit, rv;      
    int nni; 
    bcm_vlan_t vsi;
    bal_sw_flow *p_flow_elm;   
    bal_sw_flow flow_elm;  
    bal_sw_vsi_service *p_vsi_svc;
    bal_sw_group_list *p_group_list;
    uint32_t svc_tag_indx;
    
    /* get a pointer to the specified group instance */
    p_group_list = bal_sw_util_dpp_group_list_get_by_id(p_flow->data.group_id);
 
    if ( p_group_list == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util,
                " ERROR: group %d not found\n", p_flow->data.group_id);
        return BCM_ERR_INTERNAL;   
    }
    
    unit = p_group_list->device; 

    /* make sure this flow id does not already exist */
    p_flow_elm = bal_sw_util_flow_list_get_by_id(p_flow->key.flow_id);
    if (p_flow_elm)
    {
        BCM_LOG(ERROR, log_id_sw_util,
                " ERROR: flow id %d type %d already exist\n",p_flow->key.flow_id, p_flow->key.flow_type); 
        return BCM_ERR_INTERNAL;
    }
        
    do 
    {        
        /* initialize link list flow element */         
        memset(&flow_elm, 0, sizeof (bal_sw_flow));
        /* fill in the basic info */
        flow_elm.id = p_flow->key.flow_id;
        flow_elm.device = unit;
        flow_elm.group_id = p_flow->data.group_id;
        flow_elm.flow_cookie = p_flow->data.cookie;        
  
        /* packet tag type are required fields when create NNI LIF */
        /* Here make sure it is the supported type */        
        if(p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_UNTAGGED &&
           p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_SINGLE_TAG &&
           p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG)
        {
            BCM_LOG(ERROR, log_id_sw_util,
                    " ERROR: MC classifier packet tag type 0x%x is invalid\n", p_flow->data.classifier.pkt_tag_type);
            ret = BCM_ERR_PARM;
            break;
        }        
 
        /* retrieve the vswitch instance */
        p_vsi_svc = p_group_list->p_vsi;
        if(p_vsi_svc == NULL)
        {   
            BCM_LOG(ERROR, log_id_sw_util, "Error, MC: vsi not created\n");         
            ret = BCM_ERR_INTERNAL;
            break;      
        }
        vsi = p_vsi_svc->vswitch;
        
        /* add flow to the vsi service tag list */
        ret = bal_sw_util_dpp_vsi_service_tag_add(unit, p_vsi_svc, p_flow, &svc_tag_indx);
        if (ret != BCM_ERR_OK)
        {
            BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add flow to vsi service tag list\n");
            break;                    
        }
        
        ii = 0;  /* Start with the first NNI logical interface */
        /* loop through all nni port, add them to vswitch, -1 indicate end of table */
        /* Configure the switch nni LIF based on classifier in the flow. */           
        while(-1 != (nni = bal_bcm_net_inf_pbm_get(ii)))
        {
            /* skip nni port that is not in the same device or not valid */
            if ( bal_bcm_net_inf_dev_get(ii) != unit   ||
                 BCMOS_FALSE == bcm_topo_nni_is_valid(ii))
            {
                ii++;
                continue; 
            }
          
            /* if nni port is specified in the flow, skip the other nni ports */
            if ( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id) &&
                 ii != p_flow->data.network_int_id
               )
            {
                ii++;
                continue;
            }
                
            /* create gport based on nni physical port number */
            ret = bal_sw_util_dpp_vsi_service_port_add(unit, p_vsi_svc, svc_tag_indx, nni, &nni_gport);
            if (ret != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add nni %d to vsi\n", nni);
                break;                    
            }
            
            /* if DMAC is set, create a L2 entry, otherwise flood unknown to the group */
            if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac))
            {
                /* add static MC 01:00:5E:00:00:start_mc to the dowstream MC group */
                bcm_l2_addr_t l2addr;
                bcm_mac_t mc_mac;

                /* Add mc mac address */
                memcpy(&mc_mac, &(p_flow->data.classifier.dst_mac), sizeof(bcm_mac_t));
               
                bcm_l2_addr_t_init(&l2addr, mc_mac, vsi); 
                l2addr.flags = BCM_L2_STATIC | BCM_L2_MCAST;
                /* direct output to the MC group */
                l2addr.l2mc_group = p_group_list->l2_grp_id; 

                rv = bcm_l2_addr_add(unit, &l2addr);
                if (rv != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util,"Error: bcm_l2_addr_add MC returned %s \n",
                           bcm_errmsg(rv));
                    ret = BCM_ERR_INTERNAL;
                    break;
                }  
            }
            else
            {
                rv = bcm_port_control_set(unit, nni_gport, bcmPortControlFloodUnknownMcastGroup, BAL_DPP_MC_OFFSET);
                if (rv != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, MC: bcm_port_control_set for nni failed %d\n", rv);         
                    ret = BCM_ERR_INTERNAL;
                    break;
                }
            }
            
            flow_elm.num_net++;
            flow_elm.net_port[ii] = nni_gport;
           
            ii++; /* Next NNI */            
        } 
        /* skip the rest if anything goes wrong */        
        if( ret != BCM_ERR_OK)
        {
            break;
        }
               /* perform vlan translation on nni port */ 
        if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)) 
        { 
            BCM_LOG(WARNING, log_id_sw_util, "Warning, action for multicast flow not supported\n");
        }
        
    } while(0);

    if( ret == BCM_ERR_OK)
    {
        /* increase the group reference count */
        p_group_list->use_count++;
        /* increase the vsi reference count */
        p_vsi_svc->use_count++;
        /* add the flow info to the flow link list */         
        flow_elm.p_vsi_svc = p_vsi_svc;
        flow_elm.num_pon = 0;
        flow_elm.type = service_type;
        /* nni ports are done in the nni loop */
        flow_elm.valid = 1;
        bal_sw_util_flow_list_insert(flow_elm);   
       
        BCM_LOG(INFO, log_id_sw_util, "Add flow_elm %d  type %d, vswitch 0x%x, group_id %d Success\n", flow_elm.id, flow_elm.type, p_vsi_svc->vswitch, flow_elm.group_id);        
    }        
    return ret;
}

/* HW limitation on max burst rate - bps */
#define BAL_MAX_BURST_RATE (1 << 16)

/**
 * @brief The flow add function program DPP to forward packets that have
 * specified attributes to the designated ports.
 * The packets is modified before egress
 * In case IWF is in DIRECT MODE, 
 * On the downstream, a tunnel id (outer vlan tag) is added to the packets
 * On the upstream, outer vlan tag (tunnel id) is removed from the packets
 * In case IWF is in PER_FLOW_MODE, currently not supported
 *
 * @note a flow can be created which does VID translation between V & U (refer to TR156) interfaces.
 *
 * @note This routine adds flow for both upstream and downstream direction i.e. create PON & NNI LIFs
 * for both directions in a same call to this routine - and all this as part of a single call to this function 
 * from the application module or CLI. 
 * It also programs the egress vlan translation modules for both upstream and downstream. 
 *
 * @note  The general sequence is:
 *  \li create PON LIF with matching ingress tunnel id (and vlan id, if upstream pkts are vlan tagged)
 *  \li next, configure egress vlan translation on PON side (for downstream pkts)
 *  \li create NNI LIF with matching ingress vlan id (currently by default it assumes downstream packets are tagged)
 *  \li next, configure egress vlan translation on NNI side (for upstream pkts)
 *
 * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
 * @param p_flow A pointer to the requested add flow info
 * @return error code
 */
bcmos_errno bal_sw_util_dpp_flow_add(bcmbal_iwf_mode iwf_mode,  bcmbal_flow_cfg *p_flow)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcm_gport_t pon_gport, nni_gport;
    bcm_vlan_t tunnel_id;    
    int ii, unit, rv;      
    bcm_vlan_port_t vp;
    int pon, nni, sys_pon; 
    bcm_vlan_t vsi;
    int pon_encap_id;  
    bal_sw_flow *p_flow_elm;
    uint32_t flow_type, max_burst, svc_tag_indx;   
    bal_sw_flow flow_elm;  
    bal_sw_dpp_qos_service_cfg *p_service_cfg = NULL;   
    bcmbal_flow_cfg flow_rev;  /* used for configuration in opposite direction */
    bcmbal_flow_cfg *p_us_flow, *p_ds_flow;
    bal_sw_vsi_service *p_vsi_svc;
        
    BCM_LOG(INFO, log_id_sw_util,
            " Got an DPP flow request - iwf_mode=%d flow_id=%d flow_type=%d,  sub_port=%d svc_id=%d\n",
            iwf_mode, 
            p_flow->key.flow_id, p_flow->key.flow_type, p_flow->data.access_int_id, p_flow->data.svc_port_id);
    BCM_LOG(DEBUG, log_id_sw_util,
            " classifier - mask=0x%x otpid=%x itpid=%x ovid=%x ivid=%x\n",
            p_flow->data.classifier.presence_mask,
            p_flow->data.classifier.o_tpid, p_flow->data.classifier.i_tpid,
            p_flow->data.classifier.o_vid, p_flow->data.classifier.i_vid);
    
    
    if ( iwf_mode != BCMBAL_IWF_MODE_DIRECT_MAPPING)
    {
        BCM_LOG(ERROR, log_id_sw_util,
                    " ERROR: not supported IWF mode - %d\n", iwf_mode); 
        return BCM_ERR_NOT_SUPPORTED;
    }

    if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)) 
    {
        BCM_LOG(DEBUG, log_id_sw_util,
                " action.params: .cmds_bitmask=0x%x, .input_pkt_tag_type=0x%x\n", 
                    p_flow->data.action.cmds_bitmask, 
                    p_flow->data.classifier.pkt_tag_type);
    }

    if (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
        BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla) &&
        p_flow->data.sla.max_rate < p_flow->data.sla.min_rate)
    {
        BCM_LOG(ERROR, log_id_sw_util,
                    " ERROR: Max rate %d kbps is not >= Min rate %d kbps\n", p_flow->data.sla.max_rate, p_flow->data.sla.min_rate ); 
        return BCM_ERR_NOT_SUPPORTED;
    }
    
    switch(p_flow->key.flow_type)
    {
        case BCMBAL_FLOW_TYPE_DOWNSTREAM:
            flow_type = BAL_SW_FLOW_TYPE_DOWNSTREAM;
            /* for downstream N:1 service, same flood settings as multicast flow */
            if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id))
            {
                return  bal_sw_util_dpp_mc_flow_add(p_flow, BAL_SW_FLOW_TYPE_DOWNSTREAM); 
            }
            break;
        case BCMBAL_FLOW_TYPE_UPSTREAM:
            flow_type = BAL_SW_FLOW_TYPE_UPSTREAM;
            break;
        case BCMBAL_FLOW_TYPE_MULTICAST:
            return  bal_sw_util_dpp_mc_flow_add(p_flow, BCMBAL_FLOW_TYPE_MULTICAST);       
        default:
            return BCM_ERR_NOT_SUPPORTED;            
    }
    
    unit = bal_bcm_pon_inf_dev_get(p_flow->data.access_int_id); 
    /* We program a flow with 3 switch components, inLIF, vSwitch and outLIF. 
       LIF is always bi-directional operation, so for uni-directional flow we programmed an ingress or egress DROP
       on PON based on the BAL flow direction. Later, when the BAL flow from the other direction is SET, we
       remove the DROP from the PON.
       This imply that two BAL flows with same id must have symmetry vlan manipulation operations.
    */
    p_flow_elm = bal_sw_util_flow_list_get_by_id(p_flow->key.flow_id);
    if (p_flow_elm)
    {
        /* Check if flow with same id and type exist or not. 
           If downstream exist, remove the DISCARD_INGRESS from PON port by set it to DISCARD_NONE.
           If upstream exist,   remove the DISCARD_EGRESS from PON port by set it to DISCARD_NONE.            
           Asymmetry operations need two flows with different ID - each flow in uni-direction */        
        if(!(p_flow_elm->type & flow_type))
        {  
            bcmbal_flow_cfg *p_ref_flow = NULL;
            bcmbal_flow_key key;
            /* retrieve the classifier on the other flow direction */
            key.flow_id = p_flow->key.flow_id;
            key.flow_type = (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM)? BCMBAL_FLOW_TYPE_UPSTREAM : BCMBAL_FLOW_TYPE_DOWNSTREAM;
            p_ref_flow = flow_get_current_info_by_key(key);
            if(NULL == p_ref_flow)
            {
                BCM_LOG(ERROR, log_id_sw_util,
                        " ERROR: Can't locate flow %d type %d info from main DB\n", key.flow_id, key.flow_type);
                return BCM_ERR_INTERNAL;
            }                
            /* check the symmetrical properties between two flows */
            if (BCMOS_FALSE == bal_sw_util_is_symmetry_flows(p_flow, p_ref_flow))
            {
                BCM_LOG(ERROR, log_id_sw_util,
                        " ERROR: Flow %d does not have symmetry classifiers\n", key.flow_id);
                return BCM_ERR_INTERNAL;
            } 
            
            /* if there is SLA in downstream, remove the US flow ( LIFs & VSWITCH) and build a new bi-direction flow.
               This is because LIF is always bi-directional and when the US flow is created the PON LIF has no downstream VOQ.
               One needs to create a new PON LIF with VOQ for SLA. There is no easy way to add VOQ to an existing LIF. */
            if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM &&
                BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla)  )
            {
                /* remove the existing US flow */ 
                ret = bal_sw_util_dpp_flow_remove_int(p_flow_elm);
                if(ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util,
                            " ERROR: fail to remove flow %d from the list\n", p_flow->key.flow_id); 
                        
                    return BCM_ERR_INTERNAL;
                }           
                flow_type = BAL_SW_FLOW_TYPE_DOWNSTREAM | BAL_SW_FLOW_TYPE_UPSTREAM;
                /* goto regular path to create bi-directional flow */
            }                
             /* if no SLA and the classifier is more than just port + VLAN tags, add ACL rule to re-direct packet to egress port.
               This bypass the ingress LIF as LIF check VID only. 
               Upstream classification is expected to be done in ONU (onu add GEM based on classifiers for upstream), 
               return success after complete as there is no other changes needed for existing flow.
              */
            else 
            {
                int i;
                bcmos_bool is_nni_set = BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id);
                
                if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM  &&
                    bal_sw_util_flow_ds_acl_cls_chk(p_flow) == BCMOS_TRUE     )
                {   
                    for(i=0;  i < p_flow_elm->num_pon; i++)
                    {                        
                        for(ii=0; ii < p_flow_elm->num_net; ii++)
                        {
                            /*first get the ING logical port from gport */
                            bcm_vlan_port_t tmp_vp;
                            bcm_vlan_port_t_init(&tmp_vp);
                            tmp_vp.vlan_port_id = p_flow_elm->net_port[ii];
                            ret = bcm_vlan_port_find(unit, &tmp_vp);
                            if(ret != BCM_ERR_OK)
                            {
                                BCM_LOG(WARNING, log_id_sw_util,
                                " Warning: fail to retrieve logical port from gport 0x%x\n", p_flow_elm->net_port[ii]); 
                                continue;
                            }           
                            /* if nni port is specified in the flow, skip the other nni ports */
                            if ( BCMOS_TRUE == is_nni_set &&  tmp_vp.port != bal_bcm_net_inf_pbm_get(p_flow->data.network_int_id))                               
                            {
                                ii++;
                                /* if nni is set, it has to be in the nni list of the opposit FLOW */
                                /* set the return to BCM_ERR_INTERNAL, in case it reach the end of for-loop. */ 
                                ret = BCM_ERR_INTERNAL;
                                continue;
                            }
                            /* Rule need to match the ingress port, otherwise, it will apply to all ports - nni and pon */
                            if ( BCMOS_TRUE != is_nni_set)
                            { 
                                BCMBAL_CFG_PROP_SET(p_flow, flow, network_int_id, bal_bcm_net_inf_idx_get(tmp_vp.port));
                            }
                            ret = bal_sw_util_dpp_acl_add(unit, p_flow, p_flow_elm,  p_flow_elm->net_port[ii], p_flow_elm->pon_port[i]); 
                            if ( BCMOS_TRUE != is_nni_set)
                            {
                                BCMBAL_CFG_PROP_CLEAR(p_flow, flow, network_int_id);
                            }                    
                            if (ret != BCM_ERR_OK)
                            {
                                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on nni %d, ret = %d\n", ret, ii); 
                                break;                    
                            }
                            /* add a dft drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
                            ret = bal_sw_util_dpp_dft_acl_add(unit, p_flow, p_flow_elm, p_flow_elm->net_port[ii]);
                            if (ret != BCM_ERR_OK)
                            {
                                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on nni=0x%x, ret = %d\n", p_flow_elm->net_port[ii], ret); 
                                break;                    
                            }    
                        }
                        if (ret != BCM_ERR_OK)
                        {
                            break;
                        }
                    } 
                
                    if(ret != BCM_ERR_OK)
                    {
                        BCM_LOG(ERROR, log_id_sw_util,
                                " ERROR: fail to add DS ACL to nni_%d in flow id %d from the list\n", ii,p_flow->key.flow_id); 
                            
                        return BCM_ERR_INTERNAL;
                    } 
                } 
                /* If the US and DS has asymmetrical nature, we only program common part (VID) when create the LIF
                   We need an ACL rule to perform upstream specific classification and forwarding.
                   In addition, ACL allow upstream flows to be prioritized based on priority field.*/
                if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM  &&
                    bal_sw_util_flow_us_acl_cls_chk(p_flow) == BCMOS_TRUE  &&
                   /* there are issues using traditional API for PON application when egress vlan translation and ingress ACL are both active.
                       Enable the ACL only when there is no vlan action - TBD */
                    BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action))
                {   
                    if ( BCMOS_FALSE == is_nni_set)
                    {
                        BCM_LOG(ERROR, log_id_sw_util,
                                " ERROR: Upstream classifier in addition to VID without setting NNI is not supported\n");                             
                        return BCM_ERR_INTERNAL;
                    }
					
                    for(i=0;  i < p_flow_elm->num_pon; i++)
                    {                           
                        ret = bal_sw_util_dpp_acl_add(unit, p_flow, p_flow_elm,  p_flow_elm->pon_port[i], p_flow_elm->net_port[p_flow->data.network_int_id]); 
				
                        if (ret != BCM_ERR_OK)
                        {
                            BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on pon %d, ret = %d\n", ret, i); 
                            break;                    
                        }
                        /* add a default drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
                        ret = bal_sw_util_dpp_dft_acl_add(unit, p_flow, p_flow_elm, p_flow_elm->pon_port[i]);
                        if (ret != BCM_ERR_OK)
                        {
                            BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on pon=0x%x, ret = %d\n", p_flow_elm->pon_port[i], ret); 
                            break;                    
                        }    
                    } 
                
                    if(ret != BCM_ERR_OK)
                    {
                        BCM_LOG(ERROR, log_id_sw_util,
                                " ERROR: fail to add US ACL to pon_%d in flow id %d from the list\n", i, p_flow->key.flow_id);                             
                        return BCM_ERR_INTERNAL;
                    } 
                } 				
                      
                BCM_LOG(INFO, log_id_sw_util,
                        " remove packet discard function from PON in flow id %d \n",p_flow->key.flow_id);
                /* remove the PON ports from DISCARD_XXX mode  */
                for(ii=0; ii<p_flow_elm->num_pon; ii++)
                {
                    if(p_flow_elm->pon_port[ii] == 0)
                    {
                        /* if PON LIF is deleted, then continue to the next one */
                        continue;
                    }                    
                    ret = bcm_port_discard_set(p_flow_elm->device, p_flow_elm->pon_port[ii], BCM_PORT_DISCARD_NONE);
                    if (ret != BCM_ERR_OK)
                    {
                        break;
                    }
                }    
                if(ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util,
                            " ERROR: fail to remove packet discard from pon_%d in flow id %d from the list\n", ii,p_flow->key.flow_id); 
                        
                    ret = BCM_ERR_INTERNAL;
                }           
                else
                {  
                    /* add flow type to the exist list */
                    p_flow_elm->type |= flow_type;         
                    ret = BCM_ERR_OK;
                }
                return ret;
            }
        }
        else /* same id and type is an error  - we do not check if contents are the same or not */
        {
            BCM_LOG(ERROR, log_id_sw_util,
                    " ERROR: flow id %d type %d already exist\n",p_flow->key.flow_id, p_flow->key.flow_type); 
            return BCM_ERR_INTERNAL;
        }
    }
        
    /* 
     * First, validate that the specified PON has at least one NNI port on the same device.
     * If not, return an error, as this is not supported.
     */
    ii = 0;
    ret = BCM_ERR_NOT_SUPPORTED;
    /* walk through the entire mapping table */
    while(-1 != bal_bcm_net_inf_pbm_get(ii))
    {
        if(bal_bcm_net_inf_dev_get(ii) == unit)
        {
            ret = BCM_ERR_OK;
            break;
        }
        ii++; /* Next NNI */
    }

    do 
    {
        /*
         * Check return code from device check above.  Return if there was no local PON .
         */
        if(BCM_ERR_OK != ret)
        {
            BCM_LOG(ERROR, log_id_sw_util,
                    " ERROR: no network port is on the same device as access port %d\n", p_flow->data.access_int_id);
            break;
        }
        
        /* initialize link list flow element */         
        memset(&flow_elm, 0, sizeof (bal_sw_flow));
        /* fill in the basic info */
        flow_elm.id = p_flow->key.flow_id;
        flow_elm.device = unit;
        flow_elm.type = flow_type;
        flow_elm.svc_port = p_flow->data.svc_port_id;
        flow_elm.flow_cookie = p_flow->data.cookie;        
 
        tunnel_id = (bcm_vlan_t)p_flow->data.svc_port_id;
        pon = bal_bcm_pon_inf_pbm_get(p_flow->data.access_int_id);
        
        /* Map the tunnel ID to a PON channel OTM port */
        rv = bcm_port_pon_tunnel_map_set(unit,
                                         pon,
                                         tunnel_id,
                                         pon);
        if (rv != BCM_E_NONE)
        { 
            BCM_LOG(ERROR, log_id_sw_util,
                    "Error, bcm_port_pon_tunnel_map_set on pon %d failed %d"
                    " (have you chosen the correct intf_maptable?)\n", pon, rv);
            ret = BCM_ERR_INTERNAL;
            break;
        }        
        
        /* For TRAP to HOST action, it can be either upstream or downsteram,
           There is no packet manipulation, just insert an ACL and return.
           For flow action equal TRAP_TO_HOST, DS flow has to use different flow id even if the classifier is the same as the US.
           This is to simplify the REMOVE/DELETE operation in the switch.
        */   
        if ((BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action))  &&            
            (p_flow->data.action.cmds_bitmask & BCMBAL_ACTION_CMD_ID_TRAP_TO_HOST) 
           )
        {
            /* For US, create an in LIF for matching, this allow trapping of different tunnel_id on the same PON.
               Tunnel_id is stripped before packets are forwarding to the host */
            if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
            {
                if(BCMOS_FALSE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type))
                {
                    BCMBAL_ATTRIBUTE_PROP_SET(&p_flow->data.classifier, classifier, pkt_tag_type, BCMBAL_PKT_TAG_TYPE_UNTAGGED);
                    BCM_LOG(WARNING, log_id_sw_util, "Tag Type for Upstream Packet Trapping is not set, default to UNTAGGED\n");         
                }
                
                bcm_vlan_port_t_init(&vp);
                
                /* preserve any incoming packet vlan tags */
                vp.flags =  BCM_VLAN_PORT_OUTER_VLAN_PRESERVE  | BCM_VLAN_PORT_INNER_VLAN_PRESERVE | BCM_VLAN_PORT_FORWARD_GROUP;        
                                       
                switch(p_flow->data.classifier.pkt_tag_type)
                {
                    case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                        /* match both tunnel and outer tag on ingress PON  */
                        vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN;             
                        break; 
                    case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:                                    
                        /* match tunnel and both outer and inner tags on ingress PON  */
                        vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN_STACKED;                 
                        break;                             
                    case BCMBAL_PKT_TAG_TYPE_UNTAGGED: 
                    default: /* just to make compiler happy */                    
                        /* match tunnel tag on ingress PON  */
                        vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL;
                        break;             
                }                           
                                
                vp.port = pon;        
                vp.match_tunnel_value = tunnel_id;
                vp.egress_tunnel_value = tunnel_id;
                if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid))
                {
                    vp.match_vlan = p_flow->data.classifier.o_vid;       
                }
                if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid))
                {
                    vp.match_inner_vlan = p_flow->data.classifier.i_vid;  
                } 
                vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */
               
                /* Create the vlan port (i.e., PON LIF) */
                rv = bcm_vlan_port_create(unit, &vp);
                if (rv != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vlan_port_create pon %d failed %d\n", pon, rv);         
                    return BCM_ERR_INTERNAL;
                }
                ret = bal_sw_util_dpp_acl_add(unit, p_flow, &flow_elm, vp.vlan_port_id, 0);                
            }
            else
            {
                 ret = bal_sw_util_dpp_acl_add(unit, p_flow, &flow_elm, 0, 0);
            }
            
            if(BCM_ERR_OK != ret)
            {
                BCM_LOG(ERROR, log_id_sw_util, " ERROR: fail to add %s acl rule on trap\n", (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)? "US":"DS" );
            }
            else
            {
                ret = bal_sw_util_flow_list_insert(flow_elm);
                BCM_LOG(INFO, log_id_sw_util, "Add flow_elm %d  type %d, trap_code 0x%x, eid=%d Success\n", flow_elm.id, flow_elm.type, flow_elm.trap_code, flow_elm.field_entry_id[0]);
            }
            return ret;
        } /* endif TRAP_TO_HOST ACTION */         
  
        /* For TR-156 1:1, single tagged on V and R/S interface.
           The vswitch will push a tunnel tag on the down stream packets.
           The vswitch will pop the tunnel tag from the upstream packets.
       
           TBD For TR-156 1:1, double tagged on V interface and single tagged on R/S interface.           
           The vswitch will replace the outer tag with tunnel tag on the down stream packets.
           The vswitch will replace the tunnel tag with outer vid on upstream packets.           
           
           For TR-156 N:1, single tagged on V and R/S interface.
           The vswitch will learn the upstream source MAC for downstream forwarding
        */ 
  
        /* packet tag type and service port id are required fields when there is no action - checked in validation stage */
        /* Here make sure it is the supported type */        
        if(p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_UNTAGGED &&
           p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_SINGLE_TAG &&
           p_flow->data.classifier.pkt_tag_type != BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG)
        {
            BCM_LOG(ERROR, log_id_sw_util,
                    " ERROR: classifier packet tag type 0x%x is invalid\n", p_flow->data.classifier.pkt_tag_type);
            ret = BCM_ERR_PARM;
            break;
        }         

        /* create a local reverse flow for symmetry configurations */
        ret = bal_sw_util_reverse_flow_create(p_flow, &flow_rev);
        if (ret != BCM_ERR_OK)
        {
            BCM_LOG(ERROR, log_id_sw_util, "Error, (internal failure): fail to reverse flow\n"); 
            ret = BCM_ERR_INTERNAL;
            break;
        }
        
        if(p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
        {
            p_us_flow = p_flow;
            p_ds_flow = &flow_rev;            
        }
        else 
        {
            p_us_flow = &flow_rev;
            p_ds_flow = p_flow;
        }           
 
 
        /* create the vswitch */
        /* if flow is associated with a GROUP, use the vswitch from the GROUP */
        if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id))
        {
            bal_sw_group_list *p_group_list;
            /* get a pointer to the specified group instance */
            p_group_list = bal_sw_util_dpp_group_list_get_by_id(p_flow->data.group_id);
 
            if ( p_group_list == NULL)
            {
                BCM_LOG(ERROR, log_id_sw_util,
                        " ERROR: group %d not found\n", p_flow->data.group_id);
                ret = BCM_ERR_INTERNAL;
                break;   
            }
 
            /* retrieve the vswitch instance */
            p_vsi_svc = p_group_list->p_vsi;
            vsi = (p_group_list->p_vsi)->vswitch;
            /* add flow to the vsi service tag list */
            ret = bal_sw_util_dpp_vsi_service_tag_add(unit, p_vsi_svc, p_flow, &svc_tag_indx);
            if (ret != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, flow fail to add service to vsi service tag list\n");
                ret = BCM_ERR_INTERNAL;
                break;                    
            }
            
            /* set the mac learning distribution list */
            if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, resolve_mac) &&
               BCMOS_TRUE == p_flow->data.resolve_mac)
            {
                bcm_l2_addr_distribute_t dist;
    
                bcm_l2_addr_distribute_t_init(&dist);
                dist.vid = vsi;
                dist.flags  = BCM_L2_ADDR_DIST_SET_CPU_DMA_DISTRIBUTER | BCM_L2_ADDR_DIST_SET_LEARN_DISTRIBUTER;
                dist.flags |= BCM_L2_ADDR_DIST_LEARN_EVENT | BCM_L2_ADDR_DIST_AGED_OUT_EVENT | BCM_L2_ADDR_DIST_STATION_MOVE_EVENT;
                rv = bcm_l2_addr_msg_distribute_set(unit, &dist);
                if (rv != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_l2_addr_msg_distribute_set");         
                    ret = BCM_ERR_INTERNAL;
                    break;
                }
            }
        }
        else
        {
            /* vsi service needs down stream info for in LIF VLAN info */
            p_vsi_svc = bal_sw_util_dpp_vsi_service_create(unit, p_ds_flow, &svc_tag_indx);
            if(p_vsi_svc == NULL)
            {   
                BCM_LOG(ERROR, log_id_sw_util, "Error, vsi create failed\n");         
                ret = BCM_ERR_INTERNAL;
                break;      
            }
            vsi = p_vsi_svc->vswitch;
        }
        /* === create a PON LIF === */ 

        /* if DS SLA is set, create a VOQ id, otherwise use local port id */
        /** @note QoS from the Downstream flow config is taken to configure SLA in the switch. Upstream is done in MAC.
         */        
        if ((p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM) && (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla)))
        {
            p_service_cfg = bcmos_calloc(sizeof(bal_sw_dpp_qos_service_cfg));
            if (p_service_cfg == NULL)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to alloc a bal_sw_dpp_qos_service_cfg_t\n");         
                ret = BCM_ERR_INTERNAL;
                break;  
            }
            
            p_service_cfg->service_type = BAL_BCM_SVC_TYPE_IP;
            p_service_cfg->bal_flow_id = p_flow->key.flow_id;
            p_service_cfg->pon_port = p_flow->data.access_int_id; 
            p_service_cfg->tunnel_id = tunnel_id;
            /* TBD - channelize port config */
            p_service_cfg->ds_qos.pon_chan = 0;
            p_service_cfg->ds_qos.min.rate = p_flow->data.sla.min_rate;
            /* burst - set it to twice the rate */ 
            max_burst = ( (2*p_service_cfg->ds_qos.min.rate) < BAL_MAX_BURST_RATE )? (2*p_service_cfg->ds_qos.min.rate): BAL_MAX_BURST_RATE;
            p_service_cfg->ds_qos.min.burst = max_burst;
            /* TBD priority */
            p_service_cfg->ds_qos.min.traffic_priority = 2;
            
            p_service_cfg->ds_qos.max.rate = p_flow->data.sla.max_rate - p_flow->data.sla.min_rate;
            /* burst - set it to twice the rate */
            max_burst = ( (2*p_service_cfg->ds_qos.max.rate) < BAL_MAX_BURST_RATE )? (2*p_service_cfg->ds_qos.max.rate): BAL_MAX_BURST_RATE;            
            p_service_cfg->ds_qos.max.burst = max_burst;
            /* TBD priority */
            p_service_cfg->ds_qos.max.traffic_priority = 2;
            ret = bal_sw_dpp_llid_qos_config(unit, p_service_cfg);
               /* Check for errors */
            if (ret != BCM_ERR_OK)
            {
                /* Failure */
                BCM_LOG(WARNING, log_id_sw_util,
                            "Downstream QoS configuration failed for pon %u tid %u\n",
                            p_flow->data.access_int_id, tunnel_id);                
                break;                              
            }
            BCM_GPORT_UNICAST_QUEUE_GROUP_SET(pon, p_service_cfg->ds_qos.voq_flow_id);
            sys_pon = p_service_cfg->ds_qos.voq_gport;
            BCM_LOG(INFO, log_id_sw_util, " use voq_id 0x%x queue group 0x%x, voq_gport 0x%x to create PON LIFT\n", p_service_cfg->ds_qos.voq_flow_id, pon, sys_pon);
            
            /* clear the VOQ stats here */
            bal_sw_dpp_qos_clear_voq_stats(unit, sys_pon);
        }
        else
        {            
            sys_pon = pon;
            BCM_LOG(INFO, log_id_sw_util, " use pp port 0x%x to create PON LIFT\n", pon);
        }
         
         /* Configure the switch pon LIF based on classifier in the flow.
            The pon LIF filter the ingress packets from PON, so use the classifier in the US direction.
            This means, if the original flow configuration is for Downstream, use the reverse flow that locally created  */ 
        
        bcm_vlan_port_t_init(&vp);
        
        /* preserve any incoming packet vlan tags, if vlan actions are required, do it using egress translation */
        vp.flags =  BCM_VLAN_PORT_OUTER_VLAN_PRESERVE  | BCM_VLAN_PORT_INNER_VLAN_PRESERVE;        
        /* It is required to set the FEC flag so that the egress redirection action from the DS classification can 
           select the correct PON LIF to forward the packet */
        vp.flags |= BCM_VLAN_PORT_FORWARD_GROUP;        
      
               
        switch(p_us_flow->data.classifier.pkt_tag_type)
        {
            case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                /* match both tunnel and outer tag on ingress PON  */
                if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, o_pbits))
                {
                    vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_PCP_VLAN; 
                    vp.match_pcp = p_us_flow->data.classifier.o_pbits;                    
                }
                else
                {
                    vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN;
                }                    
                break; 
            case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:                                    
                /* Otherwise match both tunnel and both outer and inner tags on ingress PON  */
                if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, o_pbits))
                {
                    vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_PCP_VLAN_STACKED;
                    vp.match_pcp = p_us_flow->data.classifier.o_pbits;                    
                }
                else
                {
                    vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL_VLAN_STACKED;
                }                    
                break;                             
            case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
             /* Otherwise match tunnel tag on ingress PON  */
                {
                    vp.criteria = BCM_VLAN_PORT_MATCH_PORT_TUNNEL;
                }
               break; 
            default:
               /* should not reach here */
              BCM_LOG(ERROR, log_id_sw_util, "Error, Unsupported packet type %d for pon LIF\n",p_us_flow->data.classifier.pkt_tag_type );
              return BCM_ERR_INTERNAL;                    
        }                           
     
        
        vp.port = pon;        
        vp.match_tunnel_value = tunnel_id;
        vp.egress_tunnel_value = tunnel_id;
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, o_vid))
        {
            vp.match_vlan = p_us_flow->data.classifier.o_vid;       
        }
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_us_flow->data.classifier, classifier, i_vid))
        {
            vp.match_inner_vlan = p_us_flow->data.classifier.i_vid;  
        } 
        vp.vsi = 0; /* will be populated when the gport is added to service, using vswitch_port_add */
       
        /* Create the vlan port (i.e., PON LIF) */
        rv = bcm_vlan_port_create(unit, &vp);
        if (rv != BCM_E_NONE)
        {
            BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vlan_port_create pon %d failed %d\n", pon, rv);         
            ret = BCM_ERR_INTERNAL;
            break;  
        }
 
        pon_gport = vp.vlan_port_id;
        /* set pon gport to first element of the array */
        flow_elm.pon_port[0] = pon_gport;
        
        /* set PON port DISCARD mode to reflect the flow direction. When two BAL flows with same id  and different directions
           are configured, the DISCARD mode will be set back to NONE */
        if (flow_elm.type == BAL_SW_FLOW_TYPE_DOWNSTREAM)         
        {
            BCM_LOG(INFO, log_id_sw_util, "Info, bcm_port_discard_set pon 0x%x to DISCARD_INGRESS\n", pon_gport);  
            rv = bcm_port_discard_set(unit, pon_gport, BCM_PORT_DISCARD_INGRESS);
        }
        else if (flow_elm.type == BAL_SW_FLOW_TYPE_UPSTREAM)
        {
            /* allow bi-direction for N:1 service */
            if( BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, group_id) &&
                BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, resolve_mac) &&
                BCMOS_TRUE == p_us_flow->data.resolve_mac)
               {
                   rv = BCM_E_NONE;   
               }
               else
               {
                   BCM_LOG(INFO, log_id_sw_util, "Info, bcm_port_discard_set pon 0x%x to DISCARD_EGRESS\n", pon_gport); 
                   rv = bcm_port_discard_set(unit, pon_gport, BCM_PORT_DISCARD_EGRESS);
               }
        }
        else
        {
            rv = BCM_E_NONE;
        }
        
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_discard_set failed %d\n", rv);
             /* ARAD does not support the DISCARD function as of 6.5.4 */             
#ifdef QAX_SWITCH             
             ret = BCM_ERR_INTERNAL;
             break;
#endif             
        } 
        
        // add pon gport to vswitch
        rv = bcm_vswitch_port_add(unit, vsi, pon_gport);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_vswitch_port_add for pon 0x%x failed %d\n", pon, rv);         
             ret = BCM_ERR_INTERNAL;
             break;  
        }
        else
        {
            BCM_LOG(INFO, log_id_sw_util, "Info, bcm_vswitch_port_add for pon 0x%x, gport 0x%x\n", pon, pon_gport);   
        }
        
        if(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, group_id)    &&
           BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, resolve_mac) &&
           BCMOS_TRUE == p_flow->data.resolve_mac)
        {
            /* for flows that need to resolve mac, don't forward unknown traffics */
            BCM_LOG(DEBUG, log_id_sw_util, "pon %d:0x%x bypass downstream MC group join\n", pon, pon_gport); 
        }
        else
        {
            // obtain encapsulation ID for legacy reason, used in ADD API  */
            rv = bcm_multicast_vlan_encap_get(unit, p_vsi_svc->ds_flood_grp_id, sys_pon, pon_gport, &pon_encap_id);
            if (rv != BCM_E_NONE)
            {
                 BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_vlan_encap_get for pon failed %d\n", rv);         
                 ret = BCM_ERR_INTERNAL;
                 break; 
             }
            /* join the downstream multicast group as a member of replication list */ 
            rv = bcm_multicast_ingress_add(unit, p_vsi_svc->ds_flood_grp_id, sys_pon, pon_encap_id);
            if (rv != BCM_E_NONE)
            {
                 BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_multicast_ingress_add for pon failed %d\n", rv);         
                 ret = BCM_ERR_INTERNAL;
                 break;
            }
            /* now set the type of packets that goes to the upstream flooding group (offset 0) */        
            rv = bcm_port_control_set(unit, pon_gport, bcmPortControlFloodUnknownUcastGroup, BAL_DPP_US_FLOOD_OFFSET);
            if (rv != BCM_E_NONE)
            {
                 BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set ucast for pon failed %d\n", rv);                      
            }
        }
        rv = bcm_port_control_set(unit, pon_gport, bcmPortControlFloodUnknownMcastGroup, BAL_DPP_US_FLOOD_OFFSET);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set mcast for pon failed %d\n", rv);                      
             break;
        }
        rv = bcm_port_control_set(unit, pon_gport, bcmPortControlFloodBroadcastGroup, BAL_DPP_US_FLOOD_OFFSET);
        if (rv != BCM_E_NONE)
        {
             BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_control_set bcast for pon failed %d\n", rv); 
             break;             
        }
        /* perform vlan translation on pon port, pon egress info is in the Downstream configuration */ 
        if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_ds_flow, flow, action))
        {
            ret = bal_sw_util_dpp_invlanx(unit, p_us_flow, pon_gport); 
            if (ret != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform ingress vlan translation on pon %d\n", pon);
                break;                    
            }              
            ret = bal_sw_util_dpp_evlanx(unit, p_ds_flow, pon_gport); 
            if (ret != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform egress vlan translation on pon %d\n", pon);
                break;                    
            }  
        }    
        /* === PON LIF created === */
         
        ii = 0;  /* Start with the first NNI logical interface */
        /* loop through all nni port, add them to vswitch, -1 indicate end of table */
        /* Configure the switch nni LIF based on classifier in the flow.
           The nni LIF filter the ingress packets from Network, so use the classifier in the DS direction.
           This means, if the original flow configuration is for Upstream, use the reverse flow that locally created  */ 
        while(-1 != (nni = bal_bcm_net_inf_pbm_get(ii)))
        {
            /* skip nni port that is not in the same device or not valid */
            if ( bal_bcm_net_inf_dev_get(ii) != unit   ||
                 BCMOS_FALSE == bcm_topo_nni_is_valid(ii))
            {
                ii++;
                continue; 
            }
          
            /* if nni port is specified in the flow, skip the other nni ports */
            if ( BCMBAL_CFG_PROP_IS_SET(p_ds_flow, flow, network_int_id) &&
                 ii != p_ds_flow->data.network_int_id
               )
            {
                ii++;
                continue;
            }
                
            /* create gport based on nni physical port number */

            ret = bal_sw_util_dpp_vsi_service_port_add(unit, p_vsi_svc, svc_tag_indx, nni, &nni_gport);
            if (ret != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add nni %d to vsi\n", nni);
                break;                    
            }
            
            flow_elm.net_port[flow_elm.num_net] = nni_gport;
            flow_elm.num_net++;
			
            /* perform vlan translation on nni port, nni egress info is in the Upstream configuration */ 
            if (BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, action)) 
            { 
                rv = bcm_vlan_control_port_set(unit, nni_gport, bcmVlanPortTranslateKeyFirst, bcmVlanTranslateKeyPortOuter);      
                if (rv != BCM_E_NONE)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform vlan control port set on nni %d\n", nni);
                    break;
                }
                ret = bal_sw_util_dpp_invlanx(unit, p_ds_flow, nni_gport); 
                if (ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perform ingress vlan translation on nni %d\n", nni);
                    break;                    
                }        
        
                ret = bal_sw_util_dpp_evlanx(unit, p_us_flow, nni_gport); 
                if (ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perfrom egress vlan translation on nni %d\n", nni);
                    break;                    
                }
            }
            /* if classifier is more than just port + VLAN tags, add ACL rule to re-direct packet to egress port.
               This bypass the ingress LIF as LIF check VID only. 
               Upstream classification is expected to be done in ONU (onu add GEM based on classifiers for upstream) */
            if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM  &&
                bal_sw_util_flow_ds_acl_cls_chk(p_ds_flow) == BCMOS_TRUE )
            {  
                /* add re-direct rule */ 
                if( BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_ds_flow, flow, network_int_id))
                {                    
                    ret = bal_sw_util_dpp_acl_add(unit, p_ds_flow, &flow_elm,  nni_gport, pon_gport); 
                }
                else /* Rule need to match the network port, otherwise, it will apply to all ports - nni and pon */
                { 
                    BCMBAL_CFG_PROP_SET(p_ds_flow, flow, network_int_id, ii);
                    ret = bal_sw_util_dpp_acl_add(unit, p_ds_flow, &flow_elm,  nni_gport, pon_gport); 
                    BCMBAL_CFG_PROP_CLEAR(p_ds_flow, flow, network_int_id);
                }                    
                if (ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on nni %d, ret = %d\n", ret, ii); 
                    break;                    
                }
                /* add a dft drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
                ret = bal_sw_util_dpp_dft_acl_add(unit, p_ds_flow, &flow_elm, nni_gport);
                if (ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on nni=0x%x, ret = %d\n", nni_gport, ret); 
                    break;                    
                }                
            }
            /* If the user needs to perfrom upstream classification (in addition to VID),
               Add an ACL rule to re-direct packets. The ACL also allow upstream flows to be prioritized based on priority field */ 
            if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM  &&
                bal_sw_util_flow_us_acl_cls_chk(p_us_flow) == BCMOS_TRUE  &&
                /* there are issues using traditional API for PON application when egress vlan translation and ingress ACL are both active.
                   Enable the ACL only when there is no vlan action - TBD */
                BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action))
            {  
                /* ACL requires an action, currently support trap or re-direct the flow.
                   TRAP has been handle in other path, here we require user to specify which port to re-direct.
                   Other options will be adding multiple ACL to cover all possible egress ports - TBD */ 
                if( BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_us_flow, flow, network_int_id))
                {                    
                    BCM_LOG(ERROR, log_id_sw_util, "Error, Upstream classifier in addition to VID without NNI port set is not suppotred\n"); 
                    break; 
                }
                else 
                { 
                    ret = bal_sw_util_dpp_acl_add(unit, p_us_flow, &flow_elm,  pon_gport, nni_gport); 
                }                    
                if (ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add forwarding acl on pon %d, ret = %d\n", ret, pon); 
                    break;                    
                }
                /* add a default drop rule (priority 0) on the LIF to drop packets that match VID but no match for other fields */
                ret = bal_sw_util_dpp_dft_acl_add(unit, p_us_flow, &flow_elm, pon_gport);
                if (ret != BCM_ERR_OK)
                {
                    BCM_LOG(ERROR, log_id_sw_util, "Error, fail to add default acl on pon=0x%x, ret = %d\n", pon_gport, ret); 
                    break;                    
                }                
            }
           
            ii++; /* Next NNI */            
        } 
        /* skip the rest if anything goes wrong */        
        if( ret != BCM_ERR_OK)
        {
            break;
        }
        /* Configure PCP/Cos to Traffic Class mapping. This has to be done after the NNI LIFs are created */ 
        if (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM && BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, sla))
        {
            p_service_cfg->num_nni_gport = flow_elm.num_net;
            for( ii = 0; ii < p_service_cfg->num_nni_gport; ii++)
            {
                p_service_cfg->nni_gport[ii] = flow_elm.net_port[ii];
            }
            ret = bal_sw_dpp_llid_set_qos_port_map(unit, p_service_cfg);
            if (ret != BCM_ERR_OK)
            {
                BCM_LOG(ERROR, log_id_sw_util, "Error, fail to perfrom nni qos port map, ret = %d\n", ret);
                break;                
            }
        }
        
    } while(0);

    if( ret == BCM_ERR_OK)
    {
        /* add the flow info to the link list */         
        flow_elm.p_vsi_svc = p_vsi_svc;
        flow_elm.vsi_svc_indx = svc_tag_indx;
        flow_elm.num_pon = 1;
        flow_elm.p_service_cfg =  p_service_cfg;
  
        /* nni ports are done in the nni loop */
        flow_elm.valid = 1;
        bal_sw_util_flow_list_insert(flow_elm);   
       
        BCM_LOG(INFO, log_id_sw_util, "Add flow_elm %d  type %d, vswitch 0x%x, Success\n", flow_elm.id, flow_elm.type, p_vsi_svc->vswitch);        
    }        
    return ret;
}


/**
 * @brief The internal flow remove function program DPP to release resource that
 * were allocated during the ADD operation
 *
 * @param p_flow_elm  a pointer to the internal flow list
 *
 * @return error code
 */
bcmos_errno bal_sw_util_dpp_flow_remove_int(bal_sw_flow *p_flow_elm)
{
    bcmos_errno ret = BCM_ERR_OK;
    int rv, i, flow_id;
    bal_sw_vsi_service *p_vsi_svc;
    bal_sw_group_list *p_group_list;
    
    if(p_flow_elm == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, " invalid pointer to the internal flow list\n");
        return BCM_ERR_INTERNAL;
    }
    p_vsi_svc = (bal_sw_vsi_service *) p_flow_elm->p_vsi_svc;   
    /* if anything go wrong, log a warning and continue release resources */
    for(i = 0; i <p_flow_elm->num_pon; i++)
    {       
        rv = bcm_vswitch_port_delete(p_flow_elm->device, p_vsi_svc->vswitch, p_flow_elm->pon_port[i]);
        if(rv)
        {
            BCM_LOG(WARNING, log_id_sw_util, " vswitch pon port 0x%x delete failed %d\n", p_flow_elm->pon_port[i], rv);
        }
        rv = bcm_vlan_port_destroy(p_flow_elm->device, p_flow_elm->pon_port[i]); 
        if(rv)
        {
            BCM_LOG(WARNING, log_id_sw_util, " vswitch pon port 0x%x destroy failed %d\n", p_flow_elm->pon_port[i], rv);
        } 
        p_flow_elm->pon_port[i] = 0;        
    }
    p_flow_elm->num_pon = 0;
    
    for(i = 0; i <p_flow_elm->num_net; i++)
    {    
        ret = bal_sw_util_dpp_vsi_service_port_rem(p_flow_elm->device, p_flow_elm->p_vsi_svc, p_flow_elm->vsi_svc_indx, p_flow_elm->net_port[i]);
        if(ret != BCM_ERR_OK)
        {
            BCM_LOG(WARNING, log_id_sw_util, " vsi service port 0x%x remove failed %d\n", p_flow_elm->net_port[i], ret);
        }
         
        p_flow_elm->net_port[i] = 0;        
    }
    p_flow_elm->num_net = 0;
    
    /* release vswitch */
    if (p_vsi_svc)
    {
        /* remove the vsi if no more service, destroy function will do the counting */
        ret = bal_sw_util_dpp_vsi_service_destroy(p_flow_elm->device, p_vsi_svc);
        if(ret != BCM_ERR_OK)
        {
            BCM_LOG(WARNING, log_id_sw_util, " vsi service destroy failed %d\n", ret);
        }           
    }
        /* decrement the group reference counter in the group list */
    if (p_flow_elm->group_id)
    {
        p_group_list = bal_sw_util_dpp_group_list_get_by_id(p_flow_elm->group_id);
        if ( p_group_list == NULL)
        {
            BCM_LOG(WARNING, log_id_sw_util,
                    " WARNING: MC flow remove can't find the mc group %d in the list\n", p_flow_elm->group_id);            
        }   
        else
        {
            if(p_group_list->use_count)
            {
                p_group_list->use_count--;
            }
            else
            {
                BCM_LOG(WARNING, log_id_sw_util,
                    " WARNING: MC flow remove find the mc group %d in the list has no use_count\n", p_flow_elm->group_id);  
            }
        } 
    }
    
    /* relese trap */
    if (p_flow_elm->trap_code)
    {
        rv = bcm_rx_trap_type_destroy(p_flow_elm->device, p_flow_elm->trap_code);
        if(rv)
        {
            BCM_LOG(WARNING, log_id_sw_util, " rx trap %d destroy failed %d\n", p_flow_elm->trap_code, rv);
        }
        p_flow_elm->trap_code = 0;
        p_flow_elm->trap_port = 0;
    }
    
    /* release acl, if any */
    for(i = 0; i <p_flow_elm->num_eid; i++)
    {
        if (p_flow_elm->field_entry_id[i])
        {
            rv = bcm_field_entry_remove(p_flow_elm->device, p_flow_elm->field_entry_id[i]);
            if(rv)
            {
                BCM_LOG(WARNING, log_id_sw_util, " field entry %d remove failed %d\n", p_flow_elm->field_entry_id[i], rv);
            }
            rv = bcm_field_entry_destroy(p_flow_elm->device, p_flow_elm->field_entry_id[i]);
            if(rv)
            {
                BCM_LOG(WARNING, log_id_sw_util, " field entry %d destroy failed %d\n", p_flow_elm->field_entry_id[i], rv);
            }
            p_flow_elm->field_entry_id[i] = 0;
        }
    }
    p_flow_elm->num_eid = 0;
   
    /* release llid qos, if any */
    if (p_flow_elm->p_service_cfg)
    {
        /* any error during cleanup will be reported, but continue anyway */
        bal_sw_dpp_llid_qos_cleanup(p_flow_elm->device, (bal_sw_dpp_qos_service_cfg *)p_flow_elm->p_service_cfg); 
        bcmos_free(p_flow_elm->p_service_cfg);
        p_flow_elm->p_service_cfg = NULL;
    }
    
    /* remove from the internal link list */
    flow_id = p_flow_elm->id;
    ret = bal_sw_util_flow_list_remove(p_flow_elm);
    if(ret == BCM_ERR_OK)
    {
        BCM_LOG(INFO, log_id_sw_util, " flow %d is removed\n", flow_id);
        ret = BCM_ERR_OK;
    }
    else
    {
        BCM_LOG(WARNING, log_id_sw_util, " fail to remove flow %d w ret = %d\n", flow_id, ret);
        ret = BCM_ERR_INTERNAL;
    }
    return ret;
}

/**
 * @brief The flow remove function program DPP to release resource that
 * were allocated during the ADD operation
 *
 * @param iwf_mode The InterWorking Function mode - DIRECT or PER-FLOW
 * @param p_flow A pointer to the requested add flow info
 * @return error code
 */
bcmos_errno bal_sw_util_dpp_flow_remove(bcmbal_iwf_mode iwf_mode,  bcmbal_flow_cfg *p_flow)
{
    bcmos_errno ret = BCM_ERR_OK;
    bal_sw_flow *p_flow_elm;
    int ii, rv;
    bcm_port_discard_t discard_type = BCM_PORT_DISCARD_NONE;
 
    if(p_flow == NULL)
    {
        BCM_LOG(ERROR, log_id_sw_util, " invalid pointer to the bal flow\n");
        return BCM_ERR_INTERNAL;
    }   
    
    /* make sure the flow id is in the link list, if not return success anyway (probably clearing a DOWN flow) */
    p_flow_elm = bal_sw_util_flow_list_get_by_id (p_flow->key.flow_id);
    if(p_flow_elm == NULL)
    {
        BCM_LOG(WARNING, log_id_sw_util, " flow %d not exist the link list\n", p_flow->key.flow_id);
        return BCM_ERR_OK;
    }  

    /* if flow_elm has the requested direction, set switch to discard packets from the requested direction. */       
    if( (p_flow_elm->type & BAL_SW_FLOW_TYPE_DOWNSTREAM)        &&
        (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM)
      )        
    {
        discard_type = BCM_PORT_DISCARD_EGRESS;
    } 
    else if ((p_flow_elm->type & BAL_SW_FLOW_TYPE_UPSTREAM)      &&
             (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)   
            )
    {
        discard_type = BCM_PORT_DISCARD_INGRESS;
    }
    else if (p_flow_elm->type & BAL_SW_FLOW_TYPE_MULTICAST)
    {
        /* clear rhe type so that it can remove the flow below */
        p_flow_elm->type &= ~BAL_SW_FLOW_TYPE_MULTICAST;
    }        
    
    if (discard_type != BCM_PORT_DISCARD_NONE)
    {
        for(ii=0; ii<p_flow_elm->num_pon; ii++)
        {
            if(p_flow_elm->pon_port[ii] == 0)
            {
                /* if PON LIF is deleted, then continue to the next pon */
                continue;
            }
            rv = bcm_port_discard_set(p_flow_elm->device, p_flow_elm->pon_port[ii], discard_type);
            if (rv != BCM_E_NONE)
            {
                /* mark an error, but continue */
                BCM_LOG(ERROR, log_id_sw_util, "Error, bcm_port_discard_set failed %d on pon 0x%x\n", rv, p_flow_elm->pon_port[ii]);         
                ret = BCM_ERR_INTERNAL;                      
            }                 
        }
        if (BCM_ERR_OK == ret)
        {
            if( p_flow->key.flow_type == BCMBAL_FLOW_TYPE_DOWNSTREAM)
            {
                p_flow_elm->type &= ~BAL_SW_FLOW_TYPE_DOWNSTREAM;
            }  
            else if (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM)
            {  
                p_flow_elm->type &= ~BAL_SW_FLOW_TYPE_UPSTREAM;                    
            }
            BCM_LOG(INFO, log_id_sw_util, " Success remove flow %d with type %d\n", p_flow->key.flow_id, p_flow->key.flow_type);
        }
    }
    /* remove the flow from the list if everything is cleanup */
    if(BAL_SW_FLOW_TYPE_NONE == p_flow_elm->type) 
    {
        ret = bal_sw_util_dpp_flow_remove_int(p_flow_elm);
    }
   
    return ret;
}



/*******************************
 *  Helper routines below
 *******************************/
/**
 * @brief Helper routine to reverse a flow i.e. an upstream flow is made a downstream flow
 * and vice versa
 *
 * @param p_flow A pointer to the original flow
 * @param p_flow_rev A pointer to the reversed flow
 * @return error code
 *
 * @note for now it assumes an untagged or single tagged vlan flow with single vlan tag classificiation
 */
static bcmos_errno bal_sw_util_reverse_flow_create(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_flow_rev)
{
    bcmos_errno ret = BCM_ERR_OK;

    if ((p_flow == NULL) || (p_flow_rev == NULL))
    {
        return BCM_ERR_INTERNAL;
    }

    /* reverse parameters in flow */
    memcpy(p_flow_rev, p_flow, sizeof(bcmbal_flow_cfg));

    p_flow_rev->key.flow_type = (p_flow->key.flow_type == BCMBAL_FLOW_TYPE_UPSTREAM ?
        BCMBAL_FLOW_TYPE_DOWNSTREAM : BCMBAL_FLOW_TYPE_UPSTREAM);
    
    if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_mac))
    {
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, src_mac, p_flow->data.classifier.dst_mac);        
    }
    else /* clear the src_mac presence mask in the reverse flow */
    {
        BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, src_mac);
    }
    
    if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_mac))
    {
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, dst_mac, p_flow->data.classifier.src_mac);        
    }
    else /* clear the dst_mac presence mask in the reverse flow */
    {
        BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, dst_mac);
    }

    if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_port))
    {
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, src_port, p_flow->data.classifier.dst_port);        
    }
    else /* clear the src_port presence mask in the reverse flow */
    {
        BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, src_port);
    }
    
    if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_port))
    {
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, dst_port, p_flow->data.classifier.src_port);        
    } 
    else /* clear the dst_port presence mask in the reverse flow */
    {
        BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, dst_port);
    }
       
    if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, dst_ip))
    {
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, src_ip, p_flow->data.classifier.dst_ip);        
    }
    else /* clear the src_ip presence mask in the reverse flow */
    {
        BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, src_ip);
    }
    
    if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, src_ip))
    {
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, dst_ip, p_flow->data.classifier.src_ip);        
    }
    else /* clear the dst_ip presence mask in the reverse flow */
    {
        BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, dst_ip);
    }
        

    if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG))
    {
        BCMBAL_ACTION_CMD_ID_CLEAR(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG);
        BCMBAL_ACTION_CMD_ID_SET(&(p_flow_rev->data.action),  BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG);

        /* remove o_vid from action */       
        BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.action, action, o_vid);
        
        switch(p_flow->data.classifier.pkt_tag_type)
        {
            case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
                /* ADD on untagged packet result to single tagged on revert direction */
                p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_SINGLE_TAG;
                BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, o_vid, p_flow->data.action.o_vid);
                break;
            case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                /* ADD on single tagged packet result to double tagged on revert direction */
                p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG;
                p_flow_rev->data.classifier.o_vid = p_flow->data.action.o_vid;
                BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, i_vid, p_flow->data.classifier.o_vid);
                break;
            case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
            default:
                /* should not reach here */
            break;                    
        }                        
    }
    else if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action),  BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG)) 
    {
        BCMBAL_ACTION_CMD_ID_CLEAR(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG);
        BCMBAL_ACTION_CMD_ID_SET(&(p_flow_rev->data.action),  BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG);

        /* add o_vid to action */        
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.action, action, o_vid, p_flow->data.classifier.o_vid);
        switch(p_flow->data.classifier.pkt_tag_type)
        {
            case BCMBAL_PKT_TAG_TYPE_DOUBLE_TAG:
                /* REMOVE on double tagged packet result to single tagged on revert direction */
                p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_SINGLE_TAG;
                p_flow_rev->data.classifier.o_vid = p_flow->data.classifier.i_vid;
                BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, i_vid);                
                break;
            case BCMBAL_PKT_TAG_TYPE_SINGLE_TAG:
                /* REMOVE on single tagged packet result to untagged on revert direction */
                p_flow_rev->data.classifier.pkt_tag_type = BCMBAL_PKT_TAG_TYPE_UNTAGGED;
                BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, o_vid); 
                break;
            case BCMBAL_PKT_TAG_TYPE_UNTAGGED:
            default:
                /* should not reach here */
            break;                    
        }  
        /* if the remove classifier has tpid attribute, set it when ADD in reverse direction */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_tpid))
        {
              BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.action, action, o_tpid, p_flow->data.classifier.o_tpid);
              BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.classifier, classifier, o_tpid);
        }			
    }
    else if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action),  BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG)) 
    {
        /* swap output vid and classifier parameters */
        p_flow_rev->data.action.o_vid = p_flow->data.classifier.o_vid; 
        p_flow_rev->data.classifier.o_vid = p_flow->data.action.o_vid;
    }
    
    if (BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMARK_PBITS))
    {
        /* swap output pbits and classifier parameters */
        if(BCMOS_TRUE == BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_pbits))
        {             
            BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.action, action, o_pbits, p_flow->data.classifier.o_pbits);
        }
        else
        {
            /* if the pbits remark is for packets with any o_pibts, then there is no clear REVERSE operation.
               Set the reverse to NO pbits action. i.e pbits is a passthrough
             */           
            BCMBAL_ATTRIBUTE_PROP_CLEAR(&p_flow_rev->data.action, action, o_pbits); 
            BCMBAL_ACTION_CMD_ID_CLEAR(&(p_flow_rev->data.action), BCMBAL_ACTION_CMD_ID_REMARK_PBITS);            
        }
        
        BCMBAL_ATTRIBUTE_PROP_SET(&p_flow_rev->data.classifier, classifier, o_pbits, p_flow->data.action.o_pbits);        
    }
    //else tbd 


    return ret;
}

/**
 * @brief Helper routine to compare two flows for symmetry
 *
 * @param p_flow A pointer to the original flow
 * @param p_ref_flow A pointer to the reference flow
 * @return TRUE or FALSE 
 */
bcmos_bool bal_sw_util_is_symmetry_flows(bcmbal_flow_cfg *p_flow, bcmbal_flow_cfg *p_ref_flow)
{
    bcmos_bool ret = BCMOS_TRUE;
 
    /* compare the access interface */
    if( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, access_int_id) !=
        BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, access_int_id)  )
    { 
        BCM_LOG(INFO, log_id_sw_util, " access interface SET not the same for flow %d\n", p_flow->key.flow_id);                
        ret = BCMOS_FALSE;
    }
    else
    {
        if( (BCMBAL_CFG_PROP_IS_SET(p_flow, flow, access_int_id) || BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, access_int_id))  &&
            (p_flow->data.access_int_id != p_ref_flow->data.access_int_id)   )
        {
            BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream access interface %d != %d \n", 
                          p_flow->key.flow_id, p_flow->data.access_int_id, p_ref_flow->data.access_int_id );                
            ret = BCMOS_FALSE;
        }
    }
    /* compare the network interface */
    if( BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id) !=
        BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, network_int_id)  )
    { 
        BCM_LOG(INFO, log_id_sw_util, " network interface SET not the same for flow %d\n", p_flow->key.flow_id);                
        ret = BCMOS_FALSE;
    }
    else
    {
        if( (BCMBAL_CFG_PROP_IS_SET(p_flow, flow, network_int_id) ||BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, network_int_id))  &&
            (p_flow->data.network_int_id != p_ref_flow->data.network_int_id)   )
        {
            BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream access interface %d != %d \n", 
                          p_flow->key.flow_id, p_flow->data.network_int_id, p_ref_flow->data.network_int_id );                
            ret = BCMOS_FALSE;
        }
    } 
  
    /* if there is no action for the flow, packet type and VIDs should be the same */    
    /* compare the IPv4 addresses */
    if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_flow, flow, action)   &&
       BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(p_ref_flow, flow, action)) 
    {
        /* check packet type */
        if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type) !=
            BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_ref_flow->data.classifier, classifier, pkt_tag_type)  )
        { 
            BCM_LOG(INFO, log_id_sw_util, " packet type SET not the same for flow %d\n", p_flow->key.flow_id);                
            ret = BCMOS_FALSE;
        }
        else
        {
            if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, pkt_tag_type)   &&
                (p_flow->data.classifier.pkt_tag_type != p_ref_flow->data.classifier.pkt_tag_type)   )
            {
                BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream packet type %d != %d \n", 
                              p_flow->key.flow_id, p_flow->data.classifier.pkt_tag_type, p_ref_flow->data.classifier.pkt_tag_type );                
                ret = BCMOS_FALSE;
            }
        }
        
        /* check the outer VID */        
        if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid) !=
            BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_ref_flow->data.classifier, classifier, o_vid)  )
        { 
            BCM_LOG(INFO, log_id_sw_util, " outer vid SET not the same for flow %d\n", p_flow->key.flow_id);                
            ret = BCMOS_FALSE;
        }
        else
        {
            if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, o_vid)   &&
                (p_flow->data.classifier.o_vid != p_ref_flow->data.classifier.o_vid)   )
            {
                BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream outer vid %d != %d \n", 
                              p_flow->key.flow_id, p_flow->data.classifier.o_vid, p_ref_flow->data.classifier.o_vid );                
                ret = BCMOS_FALSE;
            }
        } 
        /* check the inner VID */        
        if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid) !=
            BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_ref_flow->data.classifier, classifier, i_vid)  )
        { 
            BCM_LOG(INFO, log_id_sw_util, " inner vid SET not the same for flow %d\n", p_flow->key.flow_id);                
            ret = BCMOS_FALSE;
        }
        else
        {
            if( BCMBAL_ATTRIBUTE_PROP_IS_SET(&p_flow->data.classifier, classifier, i_vid)   &&
                (p_flow->data.classifier.i_vid != p_ref_flow->data.classifier.i_vid)   )
            {
                BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream inner vid %d != %d \n", 
                              p_flow->key.flow_id, p_flow->data.classifier.i_vid, p_ref_flow->data.classifier.i_vid );                
                ret = BCMOS_FALSE;
            }
        }            
        
    }
    else  /* if there is an action - action for VID must be symmetrical */
    {
        if(BCMOS_TRUE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG) && 
           BCMOS_FALSE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_ref_flow->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG) )
        {
            BCM_LOG(INFO, log_id_sw_util, " flow %d downstream/upstream outer vlan action not symmetrical \n", p_flow->key.flow_id );                
            ret = BCMOS_FALSE; 
        }
        if(BCMOS_TRUE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_REMOVE_OUTER_TAG) && 
           BCMOS_FALSE == BCMBAL_ACTION_CMD_ID_IS_SET(&(p_ref_flow->data.action), BCMBAL_ACTION_CMD_ID_ADD_OUTER_TAG))
        {
            BCM_LOG(INFO, log_id_sw_util, " flow %d upstream/downstream outer vlan action not symmetrical \n", p_flow->key.flow_id );                
            ret = BCMOS_FALSE; 
        }
        if(BCMBAL_ACTION_CMD_ID_IS_SET(&(p_flow->data.action), BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG) != 
           BCMBAL_ACTION_CMD_ID_IS_SET(&(p_ref_flow->data.action), BCMBAL_ACTION_CMD_ID_XLATE_OUTER_TAG))
        {
            BCM_LOG(INFO, log_id_sw_util, " flow %d upstream/downstream outer vlan translation not symmetrical \n", p_flow->key.flow_id );                
            ret = BCMOS_FALSE; 
        }   
        
    }    
    
    return ret;
}
   
#endif /* #ifndef TEST_SW_UTIL_LOOPBACK */

/*@}*/

