2062 lines
70 KiB
C
2062 lines
70 KiB
C
/*
|
|
* Copyright (C) 2013 Realtek Semiconductor Corp.
|
|
* All Rights Reserved.
|
|
*
|
|
* Unless you and Realtek 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,
|
|
* available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
|
*
|
|
* $Revision: 76306 $
|
|
* $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $
|
|
*
|
|
* Purpose : RTK switch high-level API for RTL8367/RTL8367C
|
|
* Feature : Here is a list of all functions and variables in ACL module.
|
|
*
|
|
*/
|
|
|
|
#include <rtk_switch.h>
|
|
#include <rtk_error.h>
|
|
#include <acl.h>
|
|
#include <vlan.h>
|
|
#include <svlan.h>
|
|
#include <rate.h>
|
|
#include <string.h>
|
|
|
|
#include <rtl8367c_asicdrv.h>
|
|
#include <rtl8367c_asicdrv_acl.h>
|
|
#include <rtl8367c_asicdrv_hsb.h>
|
|
#include <rtl8367c_asicdrv_vlan.h>
|
|
#include <rtl8367c_asicdrv_svlan.h>
|
|
#include <rtl8367c_asicdrv_cputag.h>
|
|
#include <rtl8367c_asicdrv_mib.h>
|
|
|
|
CONST_T rtk_uint8 filter_templateField[RTL8367C_ACLTEMPLATENO][RTL8367C_ACLRULEFIELDNO] = {
|
|
{ACL_DMAC0, ACL_DMAC1, ACL_DMAC2, ACL_SMAC0, ACL_SMAC1, ACL_SMAC2, ACL_ETHERTYPE, ACL_FIELD_SELECT15},
|
|
{ACL_IP4SIP0, ACL_IP4SIP1, ACL_IP4DIP0, ACL_IP4DIP1, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT02, ACL_FIELD_SELECT15},
|
|
{ACL_IP6SIP0WITHIPV4, ACL_IP6SIP1WITHIPV4,ACL_FIELD_SELECT03, ACL_FIELD_SELECT04, ACL_FIELD_SELECT05, ACL_FIELD_SELECT06, ACL_FIELD_SELECT07, ACL_FIELD_SELECT08},
|
|
{ACL_IP6DIP0WITHIPV4, ACL_IP6DIP1WITHIPV4,ACL_FIELD_SELECT09, ACL_FIELD_SELECT10, ACL_FIELD_SELECT11, ACL_FIELD_SELECT12, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14},
|
|
{ACL_VIDRANGE, ACL_IPRANGE, ACL_PORTRANGE, ACL_CTAG, ACL_STAG, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT15}
|
|
};
|
|
|
|
CONST_T rtk_uint8 filter_advanceCaretagField[RTL8367C_ACLTEMPLATENO][2] = {
|
|
{TRUE, 7},
|
|
{TRUE, 7},
|
|
{FALSE, 0},
|
|
{FALSE, 0},
|
|
{TRUE, 7},
|
|
};
|
|
|
|
|
|
CONST_T rtk_uint8 filter_fieldTemplateIndex[FILTER_FIELD_END][RTK_FILTER_FIELD_USED_MAX] = {
|
|
{0x00, 0x01,0x02},
|
|
{0x03, 0x04,0x05},
|
|
{0x06},
|
|
{0x43},
|
|
{0x44},
|
|
{0x10, 0x11},
|
|
{0x12, 0x13},
|
|
{0x24},
|
|
{0x25},
|
|
{0x35},
|
|
{0x35},
|
|
{0x20, 0x21,0x22,0x23},
|
|
{0x30, 0x31,0x32,0x33},
|
|
{0x26},
|
|
{0x27},
|
|
{0x14},
|
|
{0x15},
|
|
{0x16},
|
|
{0x14},
|
|
{0x15},
|
|
{0x14},
|
|
{0x14},
|
|
{0x14},
|
|
|
|
{0x40},
|
|
{0x41},
|
|
{0x42},
|
|
|
|
{0x14},
|
|
{0x15},
|
|
{0x16},
|
|
{0x22},
|
|
{0x23},
|
|
{0x24},
|
|
{0x25},
|
|
{0x26},
|
|
{0x27},
|
|
{0x32},
|
|
{0x33},
|
|
{0x34},
|
|
{0x35},
|
|
{0x36},
|
|
{0x37},
|
|
{0x47},
|
|
|
|
{0xFF} /* Pattern Match */
|
|
};
|
|
|
|
CONST_T rtk_uint8 filter_fieldSize[FILTER_FIELD_END] = {
|
|
3, 3, 1, 1, 1,
|
|
2, 2, 1, 1, 1, 1, 4, 4, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
8
|
|
};
|
|
|
|
CONST_T rtk_uint16 field_selector[RTL8367C_FIELDSEL_FORMAT_NUMBER][2] =
|
|
{
|
|
{FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 0 */
|
|
{FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 1 */
|
|
{FIELDSEL_FORMAT_IPPAYLOAD, 12}, /* Field Selector 2 */
|
|
{FIELDSEL_FORMAT_IPV6, 10}, /* Field Selector 3 */
|
|
{FIELDSEL_FORMAT_IPV6, 8}, /* Field Selector 4 */
|
|
{FIELDSEL_FORMAT_IPV4, 0}, /* Field Selector 5 */
|
|
{FIELDSEL_FORMAT_IPV4, 8}, /* Field Selector 6 */
|
|
{FIELDSEL_FORMAT_IPV6, 0}, /* Field Selector 7 */
|
|
{FIELDSEL_FORMAT_IPV6, 6}, /* Field Selector 8 */
|
|
{FIELDSEL_FORMAT_IPV6, 26}, /* Field Selector 9 */
|
|
{FIELDSEL_FORMAT_IPV6, 24}, /* Field Selector 10 */
|
|
{FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 11 */
|
|
{FIELDSEL_FORMAT_IPV4, 6}, /* Field Selector 12 */
|
|
{FIELDSEL_FORMAT_IPPAYLOAD, 0}, /* Field Selector 13 */
|
|
{FIELDSEL_FORMAT_IPPAYLOAD, 2}, /* Field Selector 14 */
|
|
{FIELDSEL_FORMAT_DEFAULT, 0} /* Field Selector 15 */
|
|
};
|
|
|
|
|
|
static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr);
|
|
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_init
|
|
* Description:
|
|
* ACL initialization function
|
|
* Input:
|
|
* None
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
|
|
* Note:
|
|
* This function enable and initialize ACL function
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_init(void)
|
|
{
|
|
rtl8367c_acltemplate_t aclTemp;
|
|
rtk_uint32 i, j;
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if ((ret = rtk_filter_igrAcl_cfg_delAll()) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
|
|
{
|
|
for(j = 0; j < RTL8367C_ACLRULEFIELDNO;j++)
|
|
aclTemp.field[j] = filter_templateField[i][j];
|
|
|
|
if ((ret = rtl8367c_setAsicAclTemplate(i, &aclTemp)) != RT_ERR_OK)
|
|
return ret;
|
|
}
|
|
|
|
for(i = 0; i < RTL8367C_FIELDSEL_FORMAT_NUMBER; i++)
|
|
{
|
|
if ((ret = rtl8367c_setAsicFieldSelector(i, field_selector[i][0], field_selector[i][1])) != RT_ERR_OK)
|
|
return ret;
|
|
}
|
|
|
|
RTK_SCAN_ALL_PHY_PORTMASK(i)
|
|
{
|
|
if ((ret = rtl8367c_setAsicAcl(i, TRUE)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
if ((ret = rtl8367c_setAsicAclUnmatchedPermit(i, TRUE)) != RT_ERR_OK)
|
|
return ret;
|
|
}
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_field_add
|
|
* Description:
|
|
* Add comparison rule to an ACL configuration
|
|
* Input:
|
|
* pFilter_cfg - The ACL configuration that this function will add comparison rule
|
|
* pFilter_field - The comparison rule that will be added.
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
|
|
* RT_ERR_INPUT - Invalid input parameters.
|
|
* Note:
|
|
* This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg).
|
|
* Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL
|
|
* comparison rules by means of linked list. Pointer pFilter_field will be added to linked
|
|
* list kept by structure that pFilter_cfg points to.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t* pFilter_cfg, rtk_filter_field_t* pFilter_field)
|
|
{
|
|
rtk_uint32 i;
|
|
rtk_filter_field_t *tailPtr;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(NULL == pFilter_cfg || NULL == pFilter_field)
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
if(pFilter_field->fieldType >= FILTER_FIELD_END)
|
|
return RT_ERR_ENTRY_INDEX;
|
|
|
|
|
|
if(0 == pFilter_field->fieldTemplateNo)
|
|
{
|
|
pFilter_field->fieldTemplateNo = filter_fieldSize[pFilter_field->fieldType];
|
|
|
|
for(i = 0; i < pFilter_field->fieldTemplateNo; i++)
|
|
{
|
|
pFilter_field->fieldTemplateIdx[i] = filter_fieldTemplateIndex[pFilter_field->fieldType][i];
|
|
}
|
|
}
|
|
|
|
if(NULL == pFilter_cfg->fieldHead)
|
|
{
|
|
pFilter_cfg->fieldHead = pFilter_field;
|
|
}
|
|
else
|
|
{
|
|
if (pFilter_cfg->fieldHead->next == NULL)
|
|
{
|
|
pFilter_cfg->fieldHead->next = pFilter_field;
|
|
}
|
|
else
|
|
{
|
|
tailPtr = pFilter_cfg->fieldHead->next;
|
|
while( tailPtr->next != NULL)
|
|
{
|
|
tailPtr = tailPtr->next;
|
|
}
|
|
tailPtr->next = pFilter_field;
|
|
}
|
|
}
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr)
|
|
{
|
|
rtk_uint32 i, tempIdx,fieldIdx, ipValue, ipMask;
|
|
rtk_uint32 ip6addr[RTK_IPV6_ADDR_WORD_LENGTH];
|
|
rtk_uint32 ip6mask[RTK_IPV6_ADDR_WORD_LENGTH];
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
|
|
aclRule[tempIdx].valid = TRUE;
|
|
}
|
|
|
|
switch (fieldPtr->fieldType)
|
|
{
|
|
/* use DMAC structure as representative for mac structure */
|
|
case FILTER_FIELD_DMAC:
|
|
case FILTER_FIELD_SMAC:
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.value.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.value.octet[5 - (i*2 + 1)] << 8);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.mask.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.mask.octet[5 - (i*2 + 1)] << 8);
|
|
}
|
|
break;
|
|
case FILTER_FIELD_ETHERTYPE:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_IPV4_SIP:
|
|
case FILTER_FIELD_IPV4_DIP:
|
|
|
|
ipValue = fieldPtr->filter_pattern_union.sip.value;
|
|
ipMask = fieldPtr->filter_pattern_union.sip.mask;
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = (0xFFFF & (ipValue >> (i*16)));
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = (0xFFFF & (ipMask >> (i*16)));
|
|
}
|
|
break;
|
|
case FILTER_FIELD_IPV4_TOS:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.value & 0xFF;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.mask & 0xFF;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_IPV4_PROTOCOL:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.value & 0xFF;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.mask & 0xFF;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_IPV6_SIPV6:
|
|
case FILTER_FIELD_IPV6_DIPV6:
|
|
for(i = 0; i < RTK_IPV6_ADDR_WORD_LENGTH; i++)
|
|
{
|
|
ip6addr[i] = fieldPtr->filter_pattern_union.sipv6.value.addr[i];
|
|
ip6mask[i] = fieldPtr->filter_pattern_union.sipv6.mask.addr[i];
|
|
}
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
if(i < 2)
|
|
{
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[0] & (0xFFFF << (i * 16))) >> (i * 16));
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[0] & (0xFFFF << (i * 16))) >> (i * 16));
|
|
}
|
|
else
|
|
{
|
|
/*default ACL template for ipv6 address supports MSB 32-bits and LSB 32-bits only*/
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16));
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16));
|
|
}
|
|
}
|
|
|
|
break;
|
|
case FILTER_FIELD_CTAG:
|
|
case FILTER_FIELD_STAG:
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.value << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.value << 12) | fieldPtr->filter_pattern_union.l2tag.vid.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.mask << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.mask << 12) | fieldPtr->filter_pattern_union.l2tag.vid.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_IPV4_FLAG:
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x1FFF;
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.value << 15);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.value << 14);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.value << 13);
|
|
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x1FFF;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.mask << 15);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.mask << 14);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.mask << 13);
|
|
}
|
|
|
|
break;
|
|
case FILTER_FIELD_IPV4_OFFSET:
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xE000;
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.value;
|
|
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xE000;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.mask;
|
|
}
|
|
|
|
break;
|
|
|
|
case FILTER_FIELD_IPV6_TRAFFIC_CLASS:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.value << 4)&0x0FF0;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.mask << 4)&0x0FF0;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_IPV6_NEXT_HEADER:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value << 8;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask << 8;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_TCP_SPORT:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_TCP_DPORT:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_TCP_FLAG:
|
|
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.value << 7);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.value << 6);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.value << 5);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.value << 4);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.value << 3);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.value << 2);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.value << 1);
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.value;
|
|
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.mask << 7);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.mask << 6);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.mask << 5);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.mask << 4);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.mask << 3);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.mask << 2);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.mask << 1);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_UDP_SPORT:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_UDP_DPORT:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_ICMP_CODE:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xFF00;
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xFF00;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.mask;
|
|
}
|
|
break;
|
|
case FILTER_FIELD_ICMP_TYPE:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x00FF;
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.value << 8);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x00FF;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.mask << 8);
|
|
}
|
|
break;
|
|
case FILTER_FIELD_IGMP_TYPE:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.value << 8);
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.mask << 8);
|
|
}
|
|
break;
|
|
case FILTER_FIELD_PATTERN_MATCH:
|
|
for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
|
|
{
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.value[i/2] >> (16 * (i%2))) & 0x0000FFFF );
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.mask[i/2] >> (16 * (i%2))) & 0x0000FFFF );
|
|
}
|
|
break;
|
|
case FILTER_FIELD_VID_RANGE:
|
|
case FILTER_FIELD_IP_RANGE:
|
|
case FILTER_FIELD_PORT_RANGE:
|
|
default:
|
|
tempIdx = (fieldPtr->fieldTemplateIdx[0] & 0xF0) >> 4;
|
|
fieldIdx = fieldPtr->fieldTemplateIdx[0] & 0x0F;
|
|
|
|
aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value;
|
|
aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask;
|
|
break;
|
|
}
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_cfg_add
|
|
* Description:
|
|
* Add an ACL configuration to ASIC
|
|
* Input:
|
|
* filter_id - Start index of ACL configuration.
|
|
* pFilter_cfg - The ACL configuration that this function will add comparison rule
|
|
* pFilter_action - Action(s) of ACL configuration.
|
|
* Output:
|
|
* ruleNum - number of rules written in ACL table
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
|
|
* RT_ERR_INPUT - Invalid input parameters.
|
|
* RT_ERR_ENTRY_INDEX - Invalid filter_id .
|
|
* RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
|
|
* RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip.
|
|
* RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported.
|
|
* Note:
|
|
* This function store pFilter_cfg, pFilter_action into ASIC. The starting
|
|
* index(es) is filter_id.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t* pFilter_cfg, rtk_filter_action_t* pFilter_action, rtk_filter_number_t *ruleNum)
|
|
{
|
|
rtk_api_ret_t retVal;
|
|
rtk_uint32 careTagData, careTagMask;
|
|
rtk_uint32 i,vidx, svidx, actType, ruleId;
|
|
rtk_uint32 aclActCtrl;
|
|
rtk_uint32 cpuPort;
|
|
rtk_filter_field_t* fieldPtr;
|
|
rtl8367c_aclrule aclRule[RTL8367C_ACLTEMPLATENO];
|
|
rtl8367c_aclrule tempRule;
|
|
rtl8367c_acl_act_t aclAct;
|
|
rtk_uint32 noRulesAdd;
|
|
rtk_uint32 portmask;
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(filter_id > RTL8367C_ACLRULEMAX )
|
|
return RT_ERR_ENTRY_INDEX;
|
|
|
|
if((NULL == pFilter_cfg) || (NULL == pFilter_action) || (NULL == ruleNum))
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
fieldPtr = pFilter_cfg->fieldHead;
|
|
|
|
/* init RULE */
|
|
for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
|
|
{
|
|
memset(&aclRule[i], 0, sizeof(rtl8367c_aclrule));
|
|
|
|
aclRule[i].data_bits.type= i;
|
|
aclRule[i].care_bits.type= 0x7;
|
|
}
|
|
|
|
while(NULL != fieldPtr)
|
|
{
|
|
_rtk_filter_igrAcl_writeDataField(aclRule, fieldPtr);
|
|
|
|
fieldPtr = fieldPtr->next;
|
|
}
|
|
|
|
/*set care tag mask in User Defined Field 15*/
|
|
/*Follow care tag should not be used while ACL template and User defined fields are fully control by system designer*/
|
|
/*those advanced packet type care tag is used in default template design structure only*/
|
|
careTagData = 0;
|
|
careTagMask = 0;
|
|
|
|
for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++)
|
|
{
|
|
if(pFilter_cfg->careTag.tagType[i].mask)
|
|
careTagMask = careTagMask | (1 << (i-CARE_TAG_TCP));
|
|
|
|
if(pFilter_cfg->careTag.tagType[i].value)
|
|
careTagData = careTagData | (1 << (i-CARE_TAG_TCP));
|
|
}
|
|
|
|
if(careTagData || careTagMask)
|
|
{
|
|
i = 0;
|
|
while(i < RTL8367C_ACLTEMPLATENO)
|
|
{
|
|
if(aclRule[i].valid == 1 && filter_advanceCaretagField[i][0] == TRUE)
|
|
{
|
|
|
|
aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF;
|
|
aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
/*none of previous used template containing field 15*/
|
|
if(i == RTL8367C_ACLTEMPLATENO)
|
|
{
|
|
i = 0;
|
|
while(i < RTL8367C_ACLTEMPLATENO)
|
|
{
|
|
if(filter_advanceCaretagField[i][0] == TRUE)
|
|
{
|
|
aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF;
|
|
aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF;
|
|
aclRule[i].valid = 1;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*Check rule number*/
|
|
noRulesAdd = 0;
|
|
for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
|
|
{
|
|
if(1 == aclRule[i].valid)
|
|
{
|
|
noRulesAdd ++;
|
|
}
|
|
}
|
|
|
|
*ruleNum = noRulesAdd;
|
|
|
|
if((filter_id + noRulesAdd - 1) > RTL8367C_ACLRULEMAX)
|
|
{
|
|
return RT_ERR_ENTRY_INDEX;
|
|
}
|
|
|
|
/*set care tag mask in TAG Indicator*/
|
|
careTagData = 0;
|
|
careTagMask = 0;
|
|
|
|
for(i = 0; i <= CARE_TAG_IPV6;i++)
|
|
{
|
|
if(0 == pFilter_cfg->careTag.tagType[i].mask )
|
|
{
|
|
careTagMask &= ~(1 << i);
|
|
}
|
|
else
|
|
{
|
|
careTagMask |= (1 << i);
|
|
if(0 == pFilter_cfg->careTag.tagType[i].value )
|
|
careTagData &= ~(1 << i);
|
|
else
|
|
careTagData |= (1 << i);
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
|
|
{
|
|
aclRule[i].data_bits.tag_exist = (careTagData) & ACL_RULE_CARETAG_MASK;
|
|
aclRule[i].care_bits.tag_exist = (careTagMask) & ACL_RULE_CARETAG_MASK;
|
|
}
|
|
|
|
RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.value);
|
|
RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.mask);
|
|
|
|
for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
|
|
{
|
|
if(TRUE == aclRule[i].valid)
|
|
{
|
|
if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.value, &portmask) != RT_ERR_OK)
|
|
return RT_ERR_PORT_MASK;
|
|
|
|
aclRule[i].data_bits.active_portmsk = portmask;
|
|
|
|
if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.mask, &portmask) != RT_ERR_OK)
|
|
return RT_ERR_PORT_MASK;
|
|
|
|
aclRule[i].care_bits.active_portmsk = portmask;
|
|
}
|
|
}
|
|
|
|
if(pFilter_cfg->invert >= FILTER_INVERT_END )
|
|
return RT_ERR_INPUT;
|
|
|
|
|
|
/*Last action gets high priority if actions are the same*/
|
|
memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t));
|
|
aclActCtrl = 0;
|
|
for(actType = 0; actType < FILTER_ENACT_END; actType ++)
|
|
{
|
|
if(pFilter_action->actEnable[actType])
|
|
{
|
|
switch (actType)
|
|
{
|
|
case FILTER_ENACT_CVLAN_INGRESS:
|
|
if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX)
|
|
return RT_ERR_INPUT;
|
|
|
|
if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK)
|
|
{
|
|
return retVal;
|
|
}
|
|
aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
|
|
aclAct.cvidx_cact = vidx;
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
|
|
}
|
|
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_CVLAN_EGRESS:
|
|
if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX)
|
|
return RT_ERR_INPUT;
|
|
|
|
if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
|
|
aclAct.cvidx_cact = vidx;
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
|
|
}
|
|
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_CVLAN_SVID:
|
|
|
|
aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
|
|
}
|
|
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_POLICING_1:
|
|
if(pFilter_action->filterPolicingIdx[1] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
|
|
return RT_ERR_INPUT;
|
|
|
|
aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
|
|
aclAct.cvidx_cact = pFilter_action->filterPolicingIdx[1];
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
|
|
}
|
|
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
|
|
case FILTER_ENACT_SVLAN_INGRESS:
|
|
case FILTER_ENACT_SVLAN_EGRESS:
|
|
|
|
if((retVal = rtk_svlan_checkAndCreateMbr(pFilter_action->filterSvlanVid, &svidx)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
|
|
aclAct.svidx_sact = svidx;
|
|
aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_SVLAN_CVID:
|
|
|
|
aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
|
|
aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_POLICING_2:
|
|
if(pFilter_action->filterPolicingIdx[2] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
|
|
return RT_ERR_INPUT;
|
|
|
|
aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
|
|
aclAct.svidx_sact = pFilter_action->filterPolicingIdx[2];
|
|
aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_POLICING_0:
|
|
if(pFilter_action->filterPolicingIdx[0] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
|
|
return RT_ERR_INPUT;
|
|
|
|
aclAct.aclmeteridx = pFilter_action->filterPolicingIdx[0];
|
|
aclActCtrl |= FILTER_ENACT_POLICING_MASK;
|
|
break;
|
|
case FILTER_ENACT_PRIORITY:
|
|
case FILTER_ENACT_1P_REMARK:
|
|
if(pFilter_action->filterPriority > RTL8367C_PRIMAX)
|
|
return RT_ERR_INPUT;
|
|
|
|
aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
|
|
aclAct.pridx = pFilter_action->filterPriority;
|
|
aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
|
|
break;
|
|
case FILTER_ENACT_DSCP_REMARK:
|
|
if(pFilter_action->filterPriority > RTL8367C_DSCPMAX)
|
|
return RT_ERR_INPUT;
|
|
|
|
aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
|
|
aclAct.pridx = pFilter_action->filterPriority;
|
|
aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
|
|
break;
|
|
case FILTER_ENACT_POLICING_3:
|
|
if(pFilter_action->filterPriority >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
|
|
return RT_ERR_INPUT;
|
|
|
|
aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
|
|
aclAct.pridx = pFilter_action->filterPolicingIdx[3];
|
|
aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
|
|
break;
|
|
case FILTER_ENACT_DROP:
|
|
|
|
aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_REDIRECT);
|
|
aclAct.fwdact_ext = FALSE;
|
|
|
|
aclAct.fwdpmask = 0;
|
|
aclActCtrl |= FILTER_ENACT_FWD_MASK;
|
|
break;
|
|
case FILTER_ENACT_REDIRECT:
|
|
RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
|
|
|
|
aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
|
|
aclAct.fwdact_ext = FALSE;
|
|
|
|
if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
|
|
return RT_ERR_PORT_MASK;
|
|
aclAct.fwdpmask = portmask;
|
|
|
|
aclActCtrl |= FILTER_ENACT_FWD_MASK;
|
|
break;
|
|
|
|
case FILTER_ENACT_ADD_DSTPORT:
|
|
RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
|
|
|
|
aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
|
|
aclAct.fwdact_ext = FALSE;
|
|
|
|
if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
|
|
return RT_ERR_PORT_MASK;
|
|
aclAct.fwdpmask = portmask;
|
|
|
|
aclActCtrl |= FILTER_ENACT_FWD_MASK;
|
|
break;
|
|
case FILTER_ENACT_MIRROR:
|
|
RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
|
|
|
|
aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
|
|
aclAct.cact_ext = FALSE;
|
|
|
|
if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
|
|
return RT_ERR_PORT_MASK;
|
|
aclAct.fwdpmask = portmask;
|
|
|
|
aclActCtrl |= FILTER_ENACT_FWD_MASK;
|
|
break;
|
|
case FILTER_ENACT_TRAP_CPU:
|
|
|
|
aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
|
|
aclAct.fwdact_ext = FALSE;
|
|
|
|
aclActCtrl |= FILTER_ENACT_FWD_MASK;
|
|
break;
|
|
case FILTER_ENACT_COPY_CPU:
|
|
if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_MIRROR);
|
|
aclAct.fwdact_ext = FALSE;
|
|
|
|
aclAct.fwdpmask = 1 << cpuPort;
|
|
aclActCtrl |= FILTER_ENACT_FWD_MASK;
|
|
break;
|
|
case FILTER_ENACT_ISOLATION:
|
|
RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
|
|
|
|
aclAct.fwdact_ext = TRUE;
|
|
|
|
if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
|
|
return RT_ERR_PORT_MASK;
|
|
aclAct.fwdpmask = portmask;
|
|
|
|
aclActCtrl |= FILTER_ENACT_FWD_MASK;
|
|
break;
|
|
|
|
case FILTER_ENACT_INTERRUPT:
|
|
|
|
aclAct.aclint = TRUE;
|
|
aclActCtrl |= FILTER_ENACT_INTGPIO_MASK;
|
|
break;
|
|
case FILTER_ENACT_GPO:
|
|
|
|
aclAct.gpio_en = TRUE;
|
|
aclAct.gpio_pin = pFilter_action->filterPin;
|
|
aclActCtrl |= FILTER_ENACT_INTGPIO_MASK;
|
|
break;
|
|
case FILTER_ENACT_EGRESSCTAG_TAG:
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
|
|
}
|
|
aclAct.tag_fmt = FILTER_CTAGFMT_TAG;
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_EGRESSCTAG_UNTAG:
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
|
|
}
|
|
aclAct.tag_fmt = FILTER_CTAGFMT_UNTAG;
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_EGRESSCTAG_KEEP:
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
|
|
}
|
|
aclAct.tag_fmt = FILTER_CTAGFMT_KEEP;
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
case FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK:
|
|
|
|
if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
|
|
{
|
|
if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
|
|
}
|
|
else
|
|
{
|
|
aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
|
|
}
|
|
aclAct.tag_fmt = FILTER_CTAGFMT_KEEP1PRMK;
|
|
aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
|
|
break;
|
|
default:
|
|
return RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*check if free ACL rules are enough*/
|
|
for(i = filter_id; i < (filter_id + noRulesAdd); i++)
|
|
{
|
|
if((retVal = rtl8367c_getAsicAclRule(i, &tempRule)) != RT_ERR_OK )
|
|
return retVal;
|
|
|
|
if(tempRule.valid == TRUE)
|
|
{
|
|
return RT_ERR_TBL_FULL;
|
|
}
|
|
}
|
|
|
|
ruleId = 0;
|
|
for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
|
|
{
|
|
if(aclRule[i].valid == TRUE)
|
|
{
|
|
/* write ACL action control */
|
|
if((retVal = rtl8367c_setAsicAclActCtrl(filter_id + ruleId, aclActCtrl)) != RT_ERR_OK )
|
|
return retVal;
|
|
/* write ACL action */
|
|
if((retVal = rtl8367c_setAsicAclAct(filter_id + ruleId, &aclAct)) != RT_ERR_OK )
|
|
return retVal;
|
|
|
|
/* write ACL not */
|
|
if((retVal = rtl8367c_setAsicAclNot(filter_id + ruleId, pFilter_cfg->invert)) != RT_ERR_OK )
|
|
return retVal;
|
|
/* write ACL rule */
|
|
if((retVal = rtl8367c_setAsicAclRule(filter_id + ruleId, &aclRule[i])) != RT_ERR_OK )
|
|
return retVal;
|
|
|
|
/* only the first rule will be written with input action control, aclActCtrl of other rules will be zero */
|
|
aclActCtrl = 0;
|
|
memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t));
|
|
|
|
ruleId ++;
|
|
}
|
|
}
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_cfg_del
|
|
* Description:
|
|
* Delete an ACL configuration from ASIC
|
|
* Input:
|
|
* filter_id - Start index of ACL configuration.
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_FILTER_ENTRYIDX - Invalid filter_id.
|
|
* Note:
|
|
* This function delete a group of ACL rules starting from filter_id.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id)
|
|
{
|
|
rtl8367c_aclrule initRule;
|
|
rtl8367c_acl_act_t initAct;
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(filter_id > RTL8367C_ACLRULEMAX )
|
|
return RT_ERR_FILTER_ENTRYIDX;
|
|
|
|
memset(&initRule, 0, sizeof(rtl8367c_aclrule));
|
|
memset(&initAct, 0, sizeof(rtl8367c_acl_act_t));
|
|
|
|
if((ret = rtl8367c_setAsicAclRule(filter_id, &initRule)) != RT_ERR_OK)
|
|
return ret;
|
|
if((ret = rtl8367c_setAsicAclActCtrl(filter_id, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK)
|
|
return ret;
|
|
if((ret = rtl8367c_setAsicAclAct(filter_id, &initAct)) != RT_ERR_OK)
|
|
return ret;
|
|
if((ret = rtl8367c_setAsicAclNot(filter_id, DISABLED)) != RT_ERR_OK )
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_cfg_delAll
|
|
* Description:
|
|
* Delete all ACL entries from ASIC
|
|
* Input:
|
|
* None
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* Note:
|
|
* This function delete all ACL configuration from ASIC.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void)
|
|
{
|
|
rtk_uint32 i;
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
for(i = 0; i < RTL8367C_ACLRULENO; i++)
|
|
{
|
|
if((ret = rtl8367c_setAsicAclActCtrl(i, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK)
|
|
return ret;
|
|
if((ret = rtl8367c_setAsicAclNot(i, DISABLED)) != RT_ERR_OK )
|
|
return ret;
|
|
}
|
|
|
|
return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_RESET_CFG, RTL8367C_ACL_RESET_CFG_OFFSET, TRUE);;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_cfg_get
|
|
* Description:
|
|
* Get one ingress ACL configuration from ASIC.
|
|
* Input:
|
|
* filter_id - Start index of ACL configuration.
|
|
* Output:
|
|
* pFilter_cfg - buffer pointer of ingress ACL data
|
|
* pFilter_action - buffer pointer of ingress ACL action
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
|
|
* RT_ERR_FILTER_ENTRYIDX - Invalid entry index.
|
|
* Note:
|
|
* This function get configuration from ASIC.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction)
|
|
{
|
|
rtk_api_ret_t retVal;
|
|
rtk_uint32 i, tmp;
|
|
rtl8367c_aclrule aclRule;
|
|
rtl8367c_acl_act_t aclAct;
|
|
rtk_uint32 cpuPort;
|
|
rtl8367c_acltemplate_t type;
|
|
rtl8367c_svlan_memconf_t svlan_cfg;
|
|
rtl8367c_vlanconfiguser vlanMC;
|
|
rtk_uint32 phyPmask;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(NULL == pFilter_cfg || NULL == pAction)
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
if(filter_id > RTL8367C_ACLRULEMAX)
|
|
return RT_ERR_ENTRY_INDEX;
|
|
|
|
if ((retVal = rtl8367c_getAsicAclRule(filter_id, &aclRule)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
/* Check valid */
|
|
if(aclRule.valid == 0)
|
|
{
|
|
pFilter_cfg->valid = DISABLED;
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
phyPmask = aclRule.data_bits.active_portmsk;
|
|
if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.value)) != RT_ERR_OK)
|
|
return RT_ERR_FAILED;
|
|
|
|
phyPmask = aclRule.care_bits.active_portmsk;
|
|
if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.mask)) != RT_ERR_OK)
|
|
return RT_ERR_FAILED;
|
|
|
|
for(i = 0; i <= CARE_TAG_IPV6; i++)
|
|
{
|
|
if(aclRule.data_bits.tag_exist & (1 << i))
|
|
pFilter_cfg->careTag.tagType[i].value = 1;
|
|
else
|
|
pFilter_cfg->careTag.tagType[i].value = 0;
|
|
|
|
if (aclRule.care_bits.tag_exist & (1 << i))
|
|
pFilter_cfg->careTag.tagType[i].mask = 1;
|
|
else
|
|
pFilter_cfg->careTag.tagType[i].mask = 0;
|
|
}
|
|
|
|
if(filter_advanceCaretagField[aclRule.data_bits.type][0] == TRUE)
|
|
{
|
|
/* Advanced Care tag setting */
|
|
for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++)
|
|
{
|
|
if(aclRule.data_bits.field[filter_advanceCaretagField[aclRule.data_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) )
|
|
pFilter_cfg->careTag.tagType[i].value = 1;
|
|
else
|
|
pFilter_cfg->careTag.tagType[i].value = 0;
|
|
|
|
if(aclRule.care_bits.field[filter_advanceCaretagField[aclRule.care_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) )
|
|
pFilter_cfg->careTag.tagType[i].mask = 1;
|
|
else
|
|
pFilter_cfg->careTag.tagType[i].mask = 0;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++)
|
|
{
|
|
pFilter_cfg->careFieldRaw[i] = aclRule.care_bits.field[i];
|
|
pFilter_cfg->dataFieldRaw[i] = aclRule.data_bits.field[i];
|
|
}
|
|
|
|
if ((retVal = rtl8367c_getAsicAclNot(filter_id, &tmp))!= RT_ERR_OK)
|
|
return retVal;
|
|
|
|
pFilter_cfg->invert = tmp;
|
|
|
|
pFilter_cfg->valid = aclRule.valid;
|
|
|
|
memset(pAction, 0, sizeof(rtk_filter_action_t));
|
|
|
|
if ((retVal = rtl8367c_getAsicAclActCtrl(filter_id, &tmp))!= RT_ERR_OK)
|
|
return retVal;
|
|
|
|
if ((retVal = rtl8367c_getAsicAclAct(filter_id, &aclAct)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
if(tmp & FILTER_ENACT_FWD_MASK)
|
|
{
|
|
if(TRUE == aclAct.fwdact_ext)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_ISOLATION] = TRUE;
|
|
|
|
phyPmask = aclAct.fwdpmask;
|
|
if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
|
|
return RT_ERR_FAILED;
|
|
}
|
|
else if(aclAct.fwdact == RTL8367C_ACL_FWD_TRAP)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_TRAP_CPU] = TRUE;
|
|
}
|
|
else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRRORFUNTION )
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_MIRROR] = TRUE;
|
|
|
|
phyPmask = aclAct.fwdpmask;
|
|
if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
|
|
return RT_ERR_FAILED;
|
|
}
|
|
else if (aclAct.fwdact == RTL8367C_ACL_FWD_REDIRECT)
|
|
{
|
|
if(aclAct.fwdpmask == 0 )
|
|
pAction->actEnable[FILTER_ENACT_DROP] = TRUE;
|
|
else
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_REDIRECT] = TRUE;
|
|
|
|
phyPmask = aclAct.fwdpmask;
|
|
if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
|
|
return RT_ERR_FAILED;
|
|
}
|
|
}
|
|
else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRROR)
|
|
{
|
|
if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK)
|
|
return retVal;
|
|
if (aclAct.fwdpmask == (1 << cpuPort))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_COPY_CPU] = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_ADD_DSTPORT] = TRUE;
|
|
|
|
phyPmask = aclAct.fwdpmask;
|
|
if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
|
|
return RT_ERR_FAILED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return RT_ERR_FAILED;
|
|
}
|
|
}
|
|
|
|
if(tmp & FILTER_ENACT_POLICING_MASK)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_POLICING_0] = TRUE;
|
|
pAction->filterPolicingIdx[0] = aclAct.aclmeteridx;
|
|
}
|
|
|
|
if(tmp & FILTER_ENACT_PRIORITY_MASK)
|
|
{
|
|
if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_PRIORITY))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_PRIORITY] = TRUE;
|
|
pAction->filterPriority = aclAct.pridx;
|
|
}
|
|
else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_1P_REMARK))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_1P_REMARK] = TRUE;
|
|
pAction->filterPriority = aclAct.pridx;
|
|
}
|
|
else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_DSCP_REMARK))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_DSCP_REMARK] = TRUE;
|
|
pAction->filterPriority = aclAct.pridx;
|
|
}
|
|
else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_POLICING_3))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_POLICING_3] = TRUE;
|
|
pAction->filterPolicingIdx[3] = aclAct.pridx;
|
|
}
|
|
}
|
|
|
|
if(tmp & FILTER_ENACT_SVLAN_MASK)
|
|
{
|
|
if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_INGRESS))
|
|
{
|
|
if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
pAction->actEnable[FILTER_ENACT_SVLAN_INGRESS] = TRUE;
|
|
pAction->filterSvlanIdx = aclAct.svidx_sact;
|
|
pAction->filterSvlanVid = svlan_cfg.vs_svid;
|
|
}
|
|
else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_EGRESS))
|
|
{
|
|
if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
pAction->actEnable[FILTER_ENACT_SVLAN_EGRESS] = TRUE;
|
|
pAction->filterSvlanIdx = aclAct.svidx_sact;
|
|
pAction->filterSvlanVid = svlan_cfg.vs_svid;
|
|
}
|
|
else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_CVID))
|
|
pAction->actEnable[FILTER_ENACT_SVLAN_CVID] = TRUE;
|
|
else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_POLICING_2))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_POLICING_2] = TRUE;
|
|
pAction->filterPolicingIdx[2] = aclAct.svidx_sact;
|
|
}
|
|
}
|
|
|
|
|
|
if(tmp & FILTER_ENACT_CVLAN_MASK)
|
|
{
|
|
if(FILTER_ENACT_CACTEXT_TAGONLY == aclAct.cact_ext ||
|
|
FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext )
|
|
{
|
|
if(FILTER_CTAGFMT_UNTAG == aclAct.tag_fmt)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_EGRESSCTAG_UNTAG] = TRUE;
|
|
}
|
|
else if(FILTER_CTAGFMT_TAG == aclAct.tag_fmt)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_EGRESSCTAG_TAG] = TRUE;
|
|
}
|
|
else if(FILTER_CTAGFMT_KEEP == aclAct.tag_fmt)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEP] = TRUE;
|
|
}
|
|
else if(FILTER_CTAGFMT_KEEP1PRMK== aclAct.tag_fmt)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK] = TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
if(FILTER_ENACT_CACTEXT_VLANONLY == aclAct.cact_ext ||
|
|
FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext )
|
|
{
|
|
if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_INGRESS))
|
|
{
|
|
if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
pAction->actEnable[FILTER_ENACT_CVLAN_INGRESS] = TRUE;
|
|
pAction->filterCvlanIdx = aclAct.cvidx_cact;
|
|
pAction->filterCvlanVid = vlanMC.evid;
|
|
}
|
|
else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_EGRESS))
|
|
{
|
|
if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
pAction->actEnable[FILTER_ENACT_CVLAN_EGRESS] = TRUE;
|
|
pAction->filterCvlanIdx = aclAct.cvidx_cact;
|
|
pAction->filterCvlanVid = vlanMC.evid;
|
|
}
|
|
else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_SVID))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_CVLAN_SVID] = TRUE;
|
|
}
|
|
else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_POLICING_1))
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_POLICING_1] = TRUE;
|
|
pAction->filterPolicingIdx[1] = aclAct.cvidx_cact;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(tmp & FILTER_ENACT_INTGPIO_MASK)
|
|
{
|
|
if(TRUE == aclAct.aclint)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_INTERRUPT] = TRUE;
|
|
}
|
|
|
|
if(TRUE == aclAct.gpio_en)
|
|
{
|
|
pAction->actEnable[FILTER_ENACT_GPO] = TRUE;
|
|
pAction->filterPin = aclAct.gpio_pin;
|
|
}
|
|
}
|
|
|
|
/* Get field type of RAW data */
|
|
if ((retVal = rtl8367c_getAsicAclTemplate(aclRule.data_bits.type, &type))!= RT_ERR_OK)
|
|
return retVal;
|
|
|
|
for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++)
|
|
{
|
|
pFilter_cfg->fieldRawType[i] = type.field[i];
|
|
}/* end of for(i...) */
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_unmatchAction_set
|
|
* Description:
|
|
* Set action to packets when no ACL configuration match
|
|
* Input:
|
|
* port - Port id.
|
|
* action - Action.
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_PORT_ID - Invalid port id.
|
|
* RT_ERR_INPUT - Invalid input parameters.
|
|
* Note:
|
|
* This function sets action of packets when no ACL configuration matches.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
/* Check port valid */
|
|
RTK_CHK_PORT_VALID(port);
|
|
|
|
if(action >= FILTER_UNMATCH_END)
|
|
return RT_ERR_INPUT;
|
|
|
|
if((ret = rtl8367c_setAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), action)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_unmatchAction_get
|
|
* Description:
|
|
* Get action to packets when no ACL configuration match
|
|
* Input:
|
|
* port - Port id.
|
|
* Output:
|
|
* pAction - Action.
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_PORT_ID - Invalid port id.
|
|
* RT_ERR_INPUT - Invalid input parameters.
|
|
* Note:
|
|
* This function gets action of packets when no ACL configruation matches.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* pAction)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(NULL == pAction)
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
/* Check port valid */
|
|
RTK_CHK_PORT_VALID(port);
|
|
|
|
if((ret = rtl8367c_getAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), pAction)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_state_set
|
|
* Description:
|
|
* Set state of ingress ACL.
|
|
* Input:
|
|
* port - Port id.
|
|
* state - Ingress ACL state.
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_PORT_ID - Invalid port id.
|
|
* RT_ERR_INPUT - Invalid input parameters.
|
|
* Note:
|
|
* This function gets action of packets when no ACL configuration matches.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
/* Check port valid */
|
|
RTK_CHK_PORT_VALID(port);
|
|
|
|
if(state >= RTK_ENABLE_END)
|
|
return RT_ERR_INPUT;
|
|
|
|
if((ret = rtl8367c_setAsicAcl(rtk_switch_port_L2P_get(port), state)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_state_get
|
|
* Description:
|
|
* Get state of ingress ACL.
|
|
* Input:
|
|
* port - Port id.
|
|
* Output:
|
|
* pState - Ingress ACL state.
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_PORT_ID - Invalid port id.
|
|
* RT_ERR_INPUT - Invalid input parameters.
|
|
* Note:
|
|
* This function gets action of packets when no ACL configuration matches.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* pState)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(NULL == pState)
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
/* Check port valid */
|
|
RTK_CHK_PORT_VALID(port);
|
|
|
|
if((ret = rtl8367c_getAsicAcl(rtk_switch_port_L2P_get(port), pState)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_template_set
|
|
* Description:
|
|
* Set template of ingress ACL.
|
|
* Input:
|
|
* template - Ingress ACL template
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_INPUT - Invalid input parameters.
|
|
* Note:
|
|
* This function set ACL template.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate)
|
|
{
|
|
rtk_api_ret_t retVal;
|
|
rtk_uint32 idxField;
|
|
rtl8367c_acltemplate_t aclType;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE)
|
|
return RT_ERR_INPUT;
|
|
|
|
for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++)
|
|
{
|
|
if(aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_DMAC_15_0 ||
|
|
(aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_CTAG && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV4_SIP_15_0 ) ||
|
|
(aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV4_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV6_SIP_15_0 ) ||
|
|
(aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV6_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_VIDRANGE ) ||
|
|
(aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_FIELD_VALID && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_FIELD_SELECT00 ) ||
|
|
aclTemplate->fieldType[idxField] >= FILTER_FIELD_RAW_END)
|
|
{
|
|
return RT_ERR_INPUT;
|
|
}
|
|
}
|
|
|
|
for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++)
|
|
{
|
|
aclType.field[idxField] = aclTemplate->fieldType[idxField];
|
|
}
|
|
|
|
if((retVal = rtl8367c_setAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK)
|
|
return retVal;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_template_get
|
|
* Description:
|
|
* Get template of ingress ACL.
|
|
* Input:
|
|
* template - Ingress ACL template
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* Note:
|
|
* This function gets template of ACL.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
rtk_uint32 idxField;
|
|
rtl8367c_acltemplate_t aclType;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(NULL == aclTemplate)
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE)
|
|
return RT_ERR_INPUT;
|
|
|
|
if((ret = rtl8367c_getAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField ++)
|
|
{
|
|
aclTemplate->fieldType[idxField] = aclType.field[idxField];
|
|
}
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_field_sel_set
|
|
* Description:
|
|
* Set user defined field selectors in HSB
|
|
* Input:
|
|
* index - index of field selector 0-15
|
|
* format - Format of field selector
|
|
* offset - Retrieving data offset
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* Note:
|
|
* System support 16 user defined field selectors.
|
|
* Each selector can be enabled or disable.
|
|
* User can defined retrieving 16-bits in many predefiend
|
|
* standard l2/l3/l4 payload.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(format >= FORMAT_END)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(offset > RTL8367C_FIELDSEL_MAX_OFFSET)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if((ret = rtl8367c_setAsicFieldSelector(index, (rtk_uint32)format, offset)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAcl_field_sel_get
|
|
* Description:
|
|
* Get user defined field selectors in HSB
|
|
* Input:
|
|
* index - index of field selector 0-15
|
|
* Output:
|
|
* pFormat - Format of field selector
|
|
* pOffset - Retrieving data offset
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* Note:
|
|
* None.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(NULL == pFormat || NULL == pOffset)
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if((ret = rtl8367c_getAsicFieldSelector(index, pFormat, pOffset)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_iprange_set
|
|
* Description:
|
|
* Set IP Range check
|
|
* Input:
|
|
* index - index of IP Range 0-15
|
|
* type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
|
|
* upperIp - The upper bound of IP range
|
|
* lowerIp - The lower Bound of IP range
|
|
* Output:
|
|
* None.
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
|
|
* RT_ERR_INPUT - Input error
|
|
* Note:
|
|
* upperIp must be larger or equal than lowerIp.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(index > RTL8367C_ACLRANGEMAX)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(type >= IPRANGE_END)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(lowerIp > upperIp)
|
|
return RT_ERR_INPUT;
|
|
|
|
if((ret = rtl8367c_setAsicAclIpRange(index, type, upperIp, lowerIp)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_iprange_get
|
|
* Description:
|
|
* Set IP Range check
|
|
* Input:
|
|
* index - index of IP Range 0-15
|
|
* Output:
|
|
* pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
|
|
* pUpperIp - The upper bound of IP range
|
|
* pLowerIp - The lower Bound of IP range
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
|
|
* Note:
|
|
* None.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if((NULL == pType) || (NULL == pUpperIp) || (NULL == pLowerIp))
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
if(index > RTL8367C_ACLRANGEMAX)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if((ret = rtl8367c_getAsicAclIpRange(index, pType, pUpperIp, pLowerIp)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_vidrange_set
|
|
* Description:
|
|
* Set VID Range check
|
|
* Input:
|
|
* index - index of VID Range 0-15
|
|
* type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID
|
|
* upperVid - The upper bound of VID range
|
|
* lowerVid - The lower Bound of VID range
|
|
* Output:
|
|
* None.
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
|
|
* RT_ERR_INPUT - Input error
|
|
* Note:
|
|
* upperVid must be larger or equal than lowerVid.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(index > RTL8367C_ACLRANGEMAX)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(type >= VIDRANGE_END)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(lowerVid > upperVid)
|
|
return RT_ERR_INPUT;
|
|
|
|
if( (upperVid > RTL8367C_VIDMAX) || (lowerVid > RTL8367C_VIDMAX))
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if((ret = rtl8367c_setAsicAclVidRange(index, type, upperVid, lowerVid)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_vidrange_get
|
|
* Description:
|
|
* Get VID Range check
|
|
* Input:
|
|
* index - index of VID Range 0-15
|
|
* Output:
|
|
* pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID
|
|
* pUpperVid - The upper bound of VID range
|
|
* pLowerVid - The lower Bound of VID range
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
|
|
* Note:
|
|
* None.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if((NULL == pType) || (NULL == pUpperVid) || (NULL == pLowerVid))
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
if(index > RTL8367C_ACLRANGEMAX)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if((ret = rtl8367c_getAsicAclVidRange(index, pType, pUpperVid, pLowerVid)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_portrange_set
|
|
* Description:
|
|
* Set Port Range check
|
|
* Input:
|
|
* index - index of Port Range 0-15
|
|
* type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destination Port
|
|
* upperPort - The upper bound of Port range
|
|
* lowerPort - The lower Bound of Port range
|
|
* Output:
|
|
* None.
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
|
|
* RT_ERR_INPUT - Input error
|
|
* Note:
|
|
* upperPort must be larger or equal than lowerPort.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(index > RTL8367C_ACLRANGEMAX)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(type >= PORTRANGE_END)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if(lowerPort > upperPort)
|
|
return RT_ERR_INPUT;
|
|
|
|
if(upperPort > RTL8367C_ACL_PORTRANGEMAX)
|
|
return RT_ERR_INPUT;
|
|
|
|
if(lowerPort > RTL8367C_ACL_PORTRANGEMAX)
|
|
return RT_ERR_INPUT;
|
|
|
|
if((ret = rtl8367c_setAsicAclPortRange(index, type, upperPort, lowerPort)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_portrange_get
|
|
* Description:
|
|
* Set Port Range check
|
|
* Input:
|
|
* index - index of Port Range 0-15
|
|
* Output:
|
|
* pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destination Port
|
|
* pUpperPort - The upper bound of Port range
|
|
* pLowerPort - The lower Bound of Port range
|
|
* Return:
|
|
* RT_ERR_OK - OK
|
|
* RT_ERR_FAILED - Failed
|
|
* RT_ERR_SMI - SMI access error
|
|
* RT_ERR_OUT_OF_RANGE - The parameter is out of range
|
|
* RT_ERR_INPUT - Input error
|
|
* Note:
|
|
* None.
|
|
*/
|
|
rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort)
|
|
{
|
|
rtk_api_ret_t ret;
|
|
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if((NULL == pType) || (NULL == pUpperPort) || (NULL == pLowerPort))
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
if(index > RTL8367C_ACLRANGEMAX)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
|
|
if((ret = rtl8367c_getAsicAclPortRange(index, pType, pUpperPort, pLowerPort)) != RT_ERR_OK)
|
|
return ret;
|
|
|
|
return RT_ERR_OK;
|
|
}
|
|
|
|
/* Function Name:
|
|
* rtk_filter_igrAclPolarity_set
|
|
* Description:
|
|
* Set ACL Goip control polarity
|
|
* Input:
|
|
* polarity - 1: High, 0: Low
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - Success
|
|
* RT_ERR_SMI - SMI access error
|
|
* Note:
|
|
* none
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity)
|
|
{
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(polarity > 1)
|
|
return RT_ERR_OUT_OF_RANGE;
|
|
return rtl8367c_setAsicAclGpioPolarity(polarity);
|
|
}
|
|
/* Function Name:
|
|
* rtk_filter_igrAclPolarity_get
|
|
* Description:
|
|
* Get ACL Goip control polarity
|
|
* Input:
|
|
* pPolarity - 1: High, 0: Low
|
|
* Output:
|
|
* None
|
|
* Return:
|
|
* RT_ERR_OK - Success
|
|
* RT_ERR_SMI - SMI access error
|
|
* Note:
|
|
* none
|
|
*/
|
|
rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity)
|
|
{
|
|
/* Check initialization state */
|
|
RTK_CHK_INIT_STATE();
|
|
|
|
if(NULL == pPolarity)
|
|
return RT_ERR_NULL_POINTER;
|
|
|
|
return rtl8367c_getAsicAclGpioPolarity(pPolarity);
|
|
}
|
|
|
|
|
|
|
|
|