Exemple #1
0
static int
sal_config_get_rvalue(char *str, sc_t *sc)
{
    char *begin;
    char *end;

    if ((begin = strchr(str, '=')) == NULL) {
        return FALSE;
    }

    begin++;             /* Move past '=' */
    while (isspace((unsigned)*begin)) {
        begin++;         /* Trim leading whitespace */
    }

    for (end = begin + strlen(begin) - 1; isspace((unsigned)*end); end--)
        *end = '\0';     /* Trim trailing whitespace */

    sc->sc_value = sal_alloc(end - begin + 2, "config value");
    if (sc->sc_value == NULL) {
        sal_printf("sal_config_parse: Memory allocation failed\n");
        FREE_SC(sc);
        return FALSE;
    }

    sal_strncpy(sc->sc_value, begin, end - begin + 1);
    sc->sc_value[end - begin + 1] = '\0';

    return TRUE;
}
Exemple #2
0
/*
 * Function:
 *  sal_config_find
 * Purpose:
 *  Find a config entry for the specified name.
 * Parameters:
 *  name - name of variable to recover
 * Returns:
 *  NULL - not found
 *  !NULL - pointer to value
 */

static sc_t *
sal_config_find(const char *name)
{
    sc_t  *sc;
    sc_hash_t hash;
    SC_HASH(name, hash);
    sc = sal_config_list[hash];
    while (sc != NULL) {
        if (sal_strcmp(sc->sc_name, name) == 0) {
            break;
        }
        sc = sc->sc_next;
    }
    return sc;
}

#ifndef SAL_CONFIG_FILE_DISABLE /* Only used by fileio functions */
static int
sal_config_get_lvalue(char *str, sc_t *sc)
{
    char *equals_loc;

    if ((equals_loc = strchr(str, '=')) == NULL) {
        return FALSE;
    }

    while (isspace((unsigned)*str)) {
        str++;              /* skip leading whitespace */
    }

    if (str == equals_loc) {
        return FALSE;           /* lvalue is empty or only whitespace */
    }

    while (isspace((unsigned)*(equals_loc - 1)) && equals_loc > str) {
        equals_loc--;       /* trim trailing whitespace */
    }

    sc->sc_name = sal_alloc(equals_loc - str + 1, "config name");
    sal_strncpy(sc->sc_name, str, equals_loc - str);

    sc->sc_name[equals_loc - str] = '\0';

    SC_HASH(sc->sc_name, sc->sc_hash);
    return TRUE;
}
Exemple #3
0
int
_ct_echo_pkt_create(_echo_payload_t *ep,
                    char *str, int mode, int cte_flags, int minlen)
{
    int payload_len, len, len_str;
    uint32 pkt_flags = 0;
    uint8 *pkt_buf, *payload_buf;
    int alloc_hdr_here = cte_flags & CTE_FLAGS_ALLOC_HDR_HERE;

    sal_memset(ep, 0, sizeof(*ep));

    if (str == NULL) {
        cli_out("Null string\n");
        return 0;
    }

    pkt_flags = mode;
    len_str = sal_strlen(str);
    len = len_str + 1;
    len += ECHO_STR_OFFSET;      /* To store depth, flags */
    len += sizeof(uint32);       /* CRC at end of payload */
    
    if (cte_flags & CTE_FLAGS_CRC_REGEN) {
        pkt_flags |= CTE_FLAGS_CRC_REGEN;
        len += sizeof(uint32);       /* CRC at end of Ethernet frame */
    }
    
    len = minlen > len ? minlen : len;  /* Take min length if set */
    payload_len = len;
    if (alloc_hdr_here) {
        len += CPUTRANS_HEADER_BYTES;
        pkt_flags |= CTE_FLAGS_ALLOC_HDR_HERE;
    }

    /* Create packet */
    pkt_buf = sal_dma_alloc(len, "ct_echo");
    if (pkt_buf == NULL) {
        cli_out("Could not alloc packet buffer\n");
        return 0;
    }

    /* Pack the string into the payload past depth, flags */
    payload_buf = pkt_buf;
    if (alloc_hdr_here) {
        payload_buf += CPUTRANS_HEADER_BYTES;
    }

    sal_strncpy((char *)&payload_buf[ECHO_STR_OFFSET], str, len_str);
    if (len_str)
        *(char*)&payload_buf[ECHO_STR_OFFSET+len_str] = '\0';

    ep->pkt_buf = pkt_buf;
    ep->pkt_flags = pkt_flags;
    ep->payload_buf = payload_buf;
    ep->payload_len = payload_len;

    return 1;
}
Exemple #4
0
/*
 * Function:
 *   sal_config_prop_is_known
 * Purpose:
 *   Determine if a given property is valid or not
 * Returns:
 *   TRUE if property exists in property.h, FALSE if it does not
 */
int
sal_config_prop_is_known(sc_t *sc)
{
    static char name[256];
    char *loc;

    sal_strncpy(name, sc->sc_name, sizeof(name) - 1);
    name[sizeof(name) - 1] = '\0';
    if (sal_config_search_valid_prop(name)) {
        return TRUE;
    }

    /* try removing the . if there is one, for "prop.0" style */
    loc = sal_strrchr(name, '.');
    if (loc != NULL) {
        *loc = '\0';
        if (sal_config_search_valid_prop(name)) {
            return TRUE;
        }
    }

    /* try removing the . again if there is another one, 
       for "prop.port.0" style */
    loc = sal_strrchr(name, '.');
    if (loc != NULL) {
        *loc = '\0';
        if (sal_config_search_valid_prop(name)) {
            return TRUE;
        }
    }

    /* try removing the last underscore if it exists, for "prop_xe.0" style */
    loc = sal_strrchr(name, '_');
    if (loc != NULL) {
        *loc = '\0';
        if (sal_config_search_valid_prop(name)) {
            return TRUE;
        }
    }

    /* 
     * try removing one more underscore if it exists, for "prop_in_203.bcm88650" 
     * style 
     */
    loc = sal_strrchr(name, '_');
    if (loc != NULL) {
        *loc = '\0';
        if (sal_config_search_valid_prop(name)) {
            return TRUE;
        }
    }

    return FALSE;
}
Exemple #5
0
STATIC void
_tlv_msg_string_unpack(const void *buffer, void *value)
{
    int len_buffer = 0;
    
    len_buffer = sal_strlen((const char*)buffer);
    sal_strncpy((char *)value, (const char *)buffer, len_buffer);
    if (len_buffer)
        *((char*)value + len_buffer) = '\0';

    return;
}
Exemple #6
0
STATIC void
_tlv_msg_string_pack(void *buffer, const void *value)
{
    int len_value = 0;
    
    len_value = sal_strlen((const char*)value);
    sal_strncpy((char *)buffer, (const char *)value, len_value);
    if(len_value)
        *((char*)buffer+ len_value) = '\0';

    return;
}
Exemple #7
0
int
bslcons_init(void)
{
    static bslsink_sink_t console_sink;
    bslsink_sink_t *sink;

    /* Create console sink */
    sink = &console_sink;
    bslsink_sink_t_init(sink);
    sal_strncpy(sink->name, "console", sizeof(sink->name));
    sink->vfprintf = bslcons_vfprintf;
    sink->enable_range.min = bslSeverityOff+1;
    sink->enable_range.max = bslSeverityCount-1;
    bslsink_sink_add(sink);

    return 0;
}
Exemple #8
0
NDASUSER_API ndas_error_t    
ndas_get_string_error(ndas_error_t code, char* dest, int len)
{
    switch (code) {
    case NDAS_OK: 
        sal_strncpy(dest,"NDAS_OK",len); break;
    case NDAS_ERROR: 
        sal_strncpy(dest,"NDAS_ERROR",len); break;
    case NDAS_ERROR_DRIVER_NOT_LOADED: 
        sal_strncpy(dest,"DRIVER_NOT_LOADED",len); break;
    case NDAS_ERROR_DRIVER_ALREADY_LOADED: 
        sal_strncpy(dest,"DRIVER_ALREADY_LOADED",len); break;
    case NDAS_ERROR_LIBARARY_NOT_INITIALIZED: 
        sal_strncpy(dest,"LIBARARY_NOT_INITIALIZED",len); break;
    case NDAS_ERROR_INVALID_NDAS_ID: 
        sal_strncpy(dest,"INVALID_NDAS_ID",len); break;
    case NDAS_ERROR_INVALID_NDAS_KEY: 
        sal_strncpy(dest,"INVALID_NDAS_KEY",len); break;
    case NDAS_ERROR_NOT_IMPLEMENTED: 
        sal_strncpy(dest,"NOT_IMPLEMENTED",len); break;
    case NDAS_ERROR_INVALID_PARAMETER: 
        sal_strncpy(dest,"INVALID_PARAMETER",len); break;
    case NDAS_ERROR_INVALID_SLOT_NUMBER: 
        sal_strncpy(dest,"INVALID_SLOT_NUMBER",len); break;
    case NDAS_ERROR_INVALID_NAME: 
        sal_strncpy(dest,"invalid name",len); break;
    case NDAS_ERROR_NO_DEVICE: 
        sal_strncpy(dest,"NO_DEVICE",len); break;
    case NDAS_ERROR_ALREADY_REGISTERED_DEVICE: 
        sal_strncpy(dest,"ALREADY_REGISTERED_DEVICE",len); break;
    case NDAS_ERROR_ALREADY_ENABLED_DEVICE:
        sal_strncpy(dest,"ALREADY_ENABLED_DEVICE",len); break;
    case NDAS_ERROR_ALREADY_REGISTERED_NAME:
        sal_strncpy(dest,"ALREADY_REGISTERED_NAME",len); break;
    case NDAS_ERROR_ALREADY_DISABLED_DEVICE:
        sal_strncpy(dest,"ALREADY_DISABLED_DEVICE",len); break;
    case NDAS_ERROR_ALREADY_STARTED:
        sal_strncpy(dest,"ALREADY_STARTED",len); break;
    case NDAS_ERROR_ALREADY_STOPPED:
        sal_strncpy(dest,"ALREADY_STOPPED",len); break;
    case NDAS_ERROR_NOT_ONLINE    :
        sal_strncpy(dest,"the NDAS device is not online",len); break;
    case NDAS_ERROR_NOT_CONNECTED: 
        sal_strncpy(dest,"the NDAS device is not connected",len); break;
    case NDAS_ERROR_INVALID_HANDLE: 
        sal_strncpy(dest,"INVALID_HANDLE",len); break;
    case NDAS_ERROR_NO_WRITE_ACCESS_RIGHT: 
        sal_strncpy(dest,"no access right to write the data",len); break;
    case NDAS_ERROR_WRITE_BUSY: 
        sal_strncpy(dest,"WRITE_BUSY",len); break;        
    case NDAS_ERROR_UNSUPPORTED_HARDWARE_VERSION: 
        sal_strncpy(dest,"UNSUPPORTED_HARDWARE_VERSION",len); break;
    case NDAS_ERROR_UNSUPPORTED_SOFTWARE_VERSION: 
        sal_strncpy(dest,"UNSUPPORTED_SOFTWARE_VERSION",len); break;
    case NDAS_ERROR_UNSUPPORTED_DISK_MODE: 
        sal_strncpy(dest,"UNSUPPORTED_DISK_MODE",len); break;
    case NDAS_ERROR_UNSUPPORTED_FEATURE: 
        sal_strncpy(dest,"UNSUPPORTED_FEATURE",len); break;
    case NDAS_ERROR_BUFFER_OVERFLOW: 
        sal_strncpy(dest,"BUFFER_OVERFLOW",len); break;
    case NDAS_ERROR_NO_NETWORK_INTERFACE: 
        sal_strncpy(dest,"NO_NETWORK_INTERFACE",len); break;
    case NDAS_ERROR_INVALID_OPERATION: 
        sal_strncpy(dest,"INVALID_OPERATION",len); break;
    case NDAS_ERROR_NETWORK_DOWN: 
        sal_strncpy(dest,"NETWORK_DOWN",len); break;
    case NDAS_ERROR_MEDIA_CHANGED: 
        sal_strncpy(dest,"MEDIA_CHANGED",len); break;
    case NDAS_ERROR_TIME_OUT: 
        sal_strncpy(dest,"Timed out",len); break;
    case NDAS_ERROR_READONLY: 
        sal_strncpy(dest,"read-only",len); break;
    case NDAS_ERROR_OUT_OF_MEMORY: 
        sal_strncpy(dest,"out of memory",len); break;
    case NDAS_ERROR_EXIST: 
        sal_strncpy(dest,"EXIST",len); break;
    case NDAS_ERROR_SHUTDOWN: 
        sal_strncpy(dest,"SHUTDOWN",len); break;
    case NDAS_ERROR_PROTO_REGISTRATION_FAIL:         
        sal_strncpy(dest,"PROTO_REGISTRATION_FAIL",len); break;
    case NDAS_ERROR_SHUTDOWN_IN_PROGRESS:
        sal_strncpy(dest,"Shutdown is in progress", len); break;        
    case NDAS_ERROR_ADDRESS_NOT_AVAIABLE: 
        sal_strncpy(dest,"ADDRESS_NOT_AVAIABLE",len); break;
    case NDAS_ERROR_NOT_BOUND: 
        sal_strncpy(dest,"NOT_BOUND",len); break;
    case NDAS_ERROR_NETWORK_FAIL:
        sal_strncpy(dest,"NETWORK_FAIL",len); break;
    case NDAS_ERROR_HDD_DMA2_NOT_SUPPORTED:
        sal_strncpy(dest,"Hard Disk Device does not support DMA 2 mode",len); break;
    case NDAS_ERROR_IDE_REMOTE_INITIATOR_NOT_EXIST:
        sal_strncpy(dest,"Remote Initiator not exists",len); break;
    case NDAS_ERROR_IDE_REMOTE_INITIATOR_BAD_COMMAND:
        sal_strncpy(dest,"Remote Initiator bad command",len); break;
    case NDAS_ERROR_IDE_REMOTE_COMMAND_FAILED:
        sal_strncpy(dest,"Remote Initiator command failed",len); break;
    case NDAS_ERROR_IDE_REMOTE_AUTH_FAILED:
        sal_strncpy(dest,"Remote Authorization failed",len); break;
    case NDAS_ERROR_IDE_TARGET_NOT_EXIST:
        sal_strncpy(dest,"Target not exists",len); break;
    case NDAS_ERROR_HARDWARE_DEFECT:
        sal_strncpy(dest,"Hardware defect",len); break;
    case NDAS_ERROR_BAD_SECTOR:
        sal_strncpy(dest,"Bad sector",len); break;
    case NDAS_ERROR_IDE_TARGET_BROKEN_DATA:
        sal_strncpy(dest,"Target broken data",len); break;
    case NDAS_ERROR_IDE_VENDOR_SPECIFIC:    
        sal_strncpy(dest,"IDE vendor specific error",len); break;
    case NDAS_ERROR_INTERNAL:            
        sal_strncpy(dest,"The error is caused by the internal framework bug",len); break;
    case NDAS_ERROR_MAX_USER_ERR_NUM: 
        sal_strncpy(dest,"MAX_USER_ERR_NUM",len); break;
    case NDAS_ERROR_INVALID_RANGE_REQUEST:
        sal_strncpy(dest,"Invalid range of request",len); break;
    case NDAS_ERROR_INVALID_METADATA:
        sal_strncpy(dest,"Invalid metadata", len); break;
    case NDAS_ERROR_CONNECT_FAILED:
        sal_strncpy(dest,"Failed to connect", len); break;
    default: 
        sal_snprintf(dest,len,"UNKNOWN CODE(%d)",code); break;
    }
    return NDAS_OK;
}
Exemple #9
0
int
sal_config_set(char *name, char *value)
{
    sc_t  *sc, *psc;
    char  *newval;
    char    *wildcard = NULL;
    char    *sc_wildcard;
    int     length;
    sc_hash_t hash;

    if (name == NULL || *name == '\0') {
        return -1;
    }

    SC_HASH(name, hash);
    sc = sal_config_list[hash];
    psc = NULL;
    while (sc != NULL) {
        if (sal_strcmp(sc->sc_name, name) == 0) {
            break;
        }
        psc = sc;
        sc = sc->sc_next;
    }
    
    if (sc != NULL) {   /* found */
        if (value == NULL) {  /* delete */
            if (sal_config_list[hash] == sc)  {
                sal_config_list[hash] = sc->sc_next;
            } else {
                if (psc !=NULL) {
                    psc->sc_next = sc->sc_next;
                } 
            }
            FREE_SC(sc);
            return 0;
        } else {    /* replace */
            newval = sal_alloc(strlen(value) + 1, "config value");
            if (newval == NULL) {
                return -1;
            }
            sal_strncpy(newval, value, strlen(value));
            newval[strlen(value)] = '\0';
            sal_free(sc->sc_value);
            sc->sc_value = newval;
            return 0;
        }
    }

    /* not found, delete */
    if (value == NULL) {
        int i;
        wildcard = wildcard_search(name, wildcard, &length);
        if (wildcard != NULL) {
            sc_wildcard = sal_alloc((length + 1), "sc_wildcard");
            *(sc_wildcard+length) = 0;
            for (i = 0; i < MAX_CONFIG_HASH_COUNT; i++) {
                sc = sal_config_list[i];
                psc = NULL;
                while (sc != NULL){
                    sc_wildcard = sal_strncpy(sc_wildcard, sc->sc_name, length);
                    sc_wildcard[length] = '\0';
                    if (sal_strcmp(sc_wildcard, wildcard) == 0) {
                        if (sal_config_list[i] == sc) {
                            sal_config_list[i] = sc->sc_next;
                            FREE_SC(sc);
                            sc = sal_config_list[i]; 
                            psc = NULL;  
                        } else {
                            if (psc !=NULL) {
                                psc->sc_next = sc->sc_next;
                            } 
                            FREE_SC(sc);
                            if (psc !=NULL) {
                                sc = psc->sc_next;
                            }
                        }
                    } else {
                        psc = sc;
                        sc = sc->sc_next;
                    }
                }
            }
            sal_free(wildcard);
            sal_free(sc_wildcard);
            return 0;
        } else {
            return -1;
        }
    }

    

    /* not found, add */
    if ((sc = sal_alloc(sizeof(sc_t), "config set")) == NULL) {
        return -1;
    }

    sc->sc_name = sal_alloc(strlen(name) + 1, "config name");
    sc->sc_value = sal_alloc(strlen(value) + 1, "config value");

    if (sc->sc_name == NULL || sc->sc_value == NULL) {
        FREE_SC(sc);
        return -1;
    }

    sal_strncpy(sc->sc_name, name, strlen(name));
    sc->sc_name[strlen(name)] = '\0';
    sal_strncpy(sc->sc_value, value, strlen(value));
    sc->sc_value[strlen(value)] = '\0';
    sc->sc_hash = hash;

    sc->sc_next = sal_config_list[hash];
    sal_config_list[hash] = sc;

    return 0;
}
Exemple #10
0
cmd_result_t
cmd_knet_ctrl(int unit, args_t *args)
{
    parse_table_t  pt;
    char *subcmd;
    int rv;
    int idx, pdx, count;
    int if_id;
    int if_type;
    int if_vlan;
    int if_port;
    int if_addtag;
    int if_rcpu;
    char *if_name;
    int pf_id;
    int pf_prio;
    int pf_dest_type;
    int pf_dest_id;
    int pf_striptag;
    int pf_mirror;
    int pf_mirror_id;
    int pf_vlan;
    int pf_ingport;
    int pf_src_modport;
    int pf_src_modid;
    int pf_reason;
    int pf_fp_rule;
    char *pf_desc;
    uint32 pkt_offset;
    int pkt_data[8];
    bcm_knet_netif_t netif;
    bcm_knet_filter_t filter;
    int pf_dest_proto;
    int pf_mirror_proto;

    if ((subcmd = ARG_GET(args)) == NULL) {
        cli_out("Requires string argument\n");
        return CMD_USAGE;
    }
    if (sal_strcasecmp(subcmd, "netif") == 0) {
        if ((subcmd = ARG_GET(args)) == NULL) {
            cli_out("Requires additional string argument\n");
            return CMD_USAGE;
        }
        if (sal_strcasecmp(subcmd, "create") == 0) {
            if_type = BCM_KNET_NETIF_T_TX_CPU_INGRESS;
            if_vlan = 1;
            if_port = -1;
            if_addtag = 0;
            if_rcpu = 0;
            if_name = NULL;
            parse_table_init(unit, &pt);
            parse_table_add(&pt, "Type", PQ_DFL|PQ_MULTI, 0, &if_type, netif_type);
            parse_table_add(&pt, "Vlan", PQ_DFL|PQ_INT, 0, &if_vlan, 0);
            parse_table_add(&pt, "Port", PQ_DFL|PQ_PORT, 0, &if_port, 0);
            parse_table_add(&pt, "AddTag", PQ_DFL|PQ_BOOL, 0, &if_addtag, 0);
            parse_table_add(&pt, "RCPU", PQ_DFL|PQ_BOOL, 0, &if_rcpu, 0);
            parse_table_add(&pt, "IFName", PQ_DFL|PQ_STRING, 0, &if_name, 0);
            if (parse_arg_eq(args, &pt) < 0) {
                parse_arg_eq_done(&pt);
                return CMD_USAGE;
            }
            bcm_knet_netif_t_init(&netif);
            if (if_name) {
                sal_strncpy(netif.name, if_name, sizeof(netif.name) - 1);
            }
            parse_arg_eq_done(&pt);
            /* Force port mode if port was specified */
            if (if_port >= 0) {
                if_type = BCM_KNET_NETIF_T_TX_LOCAL_PORT;
            }
            /* Force meta mode if RCPU was specified */
            if (if_rcpu) {
                if_type = BCM_KNET_NETIF_T_TX_META_DATA;
            }
            netif.type = if_type;
            netif.vlan = if_vlan;
            if (if_port >= 0) {
                netif.port = if_port;
            }
            if (if_addtag) {
                netif.flags |= BCM_KNET_NETIF_F_ADD_TAG;
            }
            if (if_rcpu) {
                netif.flags |= BCM_KNET_NETIF_F_RCPU_ENCAP;
            }
            if ((rv = bcm_knet_netif_create(unit, &netif)) < 0) {
                cli_out("Error creating network interface: %s\n",
                        bcm_errmsg(rv));
                return CMD_FAIL;
            }
            _show_netif(unit, &netif);
        } else if (sal_strcasecmp(subcmd, "destroy") == 0) {
            if (!ARG_CNT(args) || !isint(ARG_CUR(args))) {
                return(CMD_USAGE);
            }
            if_id = parse_integer(ARG_GET(args));
            if ((rv = bcm_knet_netif_destroy(unit, if_id)) < 0) {
                cli_out("Error destroying network interface: %s\n",
                        bcm_errmsg(rv));
                return CMD_FAIL;
            }
        } else if (sal_strcasecmp(subcmd, "show") == 0) {
            count = 0;
            if (bcm_knet_netif_traverse(unit, _trav_netif, &count) < 0) {
                return CMD_FAIL;
            }
            if (count == 0) {
                cli_out("<no network interfaces>\n");
            }
        } else {
            cli_out("Subcommand not found: %s\n", subcmd);
            return CMD_USAGE;
        }
    } else if (sal_strcasecmp(subcmd, "filter") == 0) {
        if ((subcmd = ARG_GET(args)) == NULL) {
            cli_out("Requires string argument\n");
            return CMD_USAGE;
        }
        if (sal_strcasecmp(subcmd, "create") == 0) {
            pf_dest_type = -1;
            pf_dest_id = -1;
            pf_mirror = 0;
            pf_mirror_id = 0;
            pf_vlan = -1;
            pf_ingport = -1;
            pf_src_modport = -1;
            pf_src_modid = -1;
            pf_reason = -1;
            pf_fp_rule = -1;
            pkt_offset = 0;
            for (idx = 0; idx < COUNTOF(pkt_data); idx++) {
                pkt_data[idx] = -1;
            }
            pf_desc = NULL;
            pf_prio = 0;
            pf_striptag = 1;
            pf_dest_proto = 0;
            pf_mirror_proto = 0;
            parse_table_init(unit, &pt);
            parse_table_add(&pt, "DestType", PQ_DFL|PQ_MULTI, 0, &pf_dest_type,
                            filter_dest_type);
            parse_table_add(&pt, "DestID", PQ_DFL|PQ_INT, 0, &pf_dest_id, 0);
            parse_table_add(&pt, "PRIOrity", PQ_DFL|PQ_INT, 0, &pf_prio, 0);
            parse_table_add(&pt, "DESCription", PQ_DFL|PQ_STRING, 0, &pf_desc, 0);
            parse_table_add(&pt, "StripTag", PQ_DFL|PQ_BOOL, 0, &pf_striptag, 0);
            parse_table_add(&pt, "Mirror", PQ_DFL|PQ_BOOL, 0, &pf_mirror, 0);
            parse_table_add(&pt, "MirrorID", PQ_DFL|PQ_INT, 0, &pf_mirror_id, 0);
            parse_table_add(&pt, "Vlan", PQ_DFL|PQ_INT, 0, &pf_vlan, 0);
            parse_table_add(&pt, "IngPort", PQ_DFL|PQ_PORT, 0, &pf_ingport, 0);
            parse_table_add(&pt, "SrcPort", PQ_DFL|PQ_INT, 0, &pf_src_modport, 0);
            parse_table_add(&pt, "SrcModid", PQ_DFL|PQ_INT, 0, &pf_src_modid, 0);
            parse_table_add(&pt, "Reason", PQ_DFL|PQ_MULTI, 0, &pf_reason,
                            reason_str);
            parse_table_add(&pt, "FPRule", PQ_DFL|PQ_INT, 0, &pf_fp_rule, 0);
            parse_table_add(&pt, "PktOffset", PQ_DFL|PQ_HEX, 0, &pkt_offset, 0);
            parse_table_add(&pt, "PktByte0", PQ_DFL|PQ_INT, 0, &pkt_data[0], 0);
            parse_table_add(&pt, "PktByte1", PQ_DFL|PQ_INT, 0, &pkt_data[1], 0);
            parse_table_add(&pt, "PktByte2", PQ_DFL|PQ_INT, 0, &pkt_data[2], 0);
            parse_table_add(&pt, "PktByte3", PQ_DFL|PQ_INT, 0, &pkt_data[3], 0);
            parse_table_add(&pt, "PktByte4", PQ_DFL|PQ_INT, 0, &pkt_data[4], 0);
            parse_table_add(&pt, "PktByte5", PQ_DFL|PQ_INT, 0, &pkt_data[5], 0);
            parse_table_add(&pt, "PktByte6", PQ_DFL|PQ_INT, 0, &pkt_data[6], 0);
            parse_table_add(&pt, "PktByte7", PQ_DFL|PQ_INT, 0, &pkt_data[7], 0);
            parse_table_add(&pt, "DestProto", PQ_DFL|PQ_INT, 0, &pf_dest_proto, 0);
            parse_table_add(&pt, "MirrorProto", PQ_DFL|PQ_INT, 0, &pf_mirror_proto, 0);
            if (parse_arg_eq(args, &pt) < 0) {
                parse_arg_eq_done(&pt);
                return CMD_USAGE;
            }
            bcm_knet_filter_t_init(&filter);
            filter.type = BCM_KNET_FILTER_T_RX_PKT;
            if (pf_desc) {
                sal_strncpy(filter.desc, pf_desc, sizeof(filter.desc) - 1);
            }
            parse_arg_eq_done(&pt);
            if (pf_dest_type < 0) {
                cli_out("Missing destination\n");
                return CMD_USAGE;
            }
            filter.priority = pf_prio;
            filter.dest_type = pf_dest_type;
            filter.dest_id = pf_dest_id;
            filter.dest_proto = pf_dest_proto;
            /*
             * Specifying a mirror ID implies mirroring to another
             * netif.  Enabling mirroring while leaving mirror ID at
             * zero implies mirroring to the Rx API.
             */
            if (pf_mirror_id) {
                pf_mirror = 1;
            }
            if (pf_dest_type == BCM_KNET_DEST_T_NETIF && pf_mirror) {
                filter.mirror_type = BCM_KNET_DEST_T_BCM_RX_API;
                if (pf_mirror_id) {
                    filter.mirror_type = BCM_KNET_DEST_T_NETIF;
                    filter.mirror_id = pf_mirror_id;
                    filter.mirror_proto = pf_mirror_proto;
                }
            }
            if (pf_striptag) {
                filter.flags |= BCM_KNET_FILTER_F_STRIP_TAG;
            }
            if (pf_vlan >= 0) {
                filter.m_vlan = pf_vlan;
                filter.match_flags |= BCM_KNET_FILTER_M_VLAN;
            }
            if (pf_ingport >= 0) {
                filter.m_ingport = pf_ingport;
                filter.match_flags |= BCM_KNET_FILTER_M_INGPORT;
            }
            if (pf_src_modport >= 0) {
                filter.m_src_modport = pf_src_modport;
                filter.match_flags |= BCM_KNET_FILTER_M_SRC_MODPORT;
            }
            if (pf_src_modid >= 0) {
                filter.m_src_modid = pf_src_modid;
                filter.match_flags |= BCM_KNET_FILTER_M_SRC_MODID;
            }
            if (pf_reason >= 0) {
                BCM_RX_REASON_SET(filter.m_reason, pf_reason);
                filter.match_flags |= BCM_KNET_FILTER_M_REASON;
            }
            if (pf_fp_rule >= 0) {
                filter.m_fp_rule = pf_fp_rule;
                filter.match_flags |= BCM_KNET_FILTER_M_FP_RULE;
            }
            for (idx = 0; idx < COUNTOF(pkt_data); idx++) {
                pdx = pkt_offset + idx;
                if (pdx >= sizeof(filter.m_raw_data)) {
                    cli_out("PktOffset too large - max is %d\n",
                            (int)sizeof(filter.m_raw_data) - COUNTOF(pkt_data));
                    return CMD_USAGE;
                }
                if (pkt_data[idx] >= 0) {
                    filter.raw_size = pdx + 1;
                    filter.match_flags |= BCM_KNET_FILTER_M_RAW;
                    filter.m_raw_data[pdx] = (uint8)pkt_data[idx];
                    filter.m_raw_mask[pdx] = 0xff;
                }
            }
            if ((rv = bcm_knet_filter_create(unit, &filter)) < 0) {
                cli_out("Error creating packet filter: %s\n",
                        bcm_errmsg(rv));
                return CMD_FAIL;
            }
            _show_filter(unit, &filter);
        } else if (sal_strcasecmp(subcmd, "destroy") == 0) {
            if (!ARG_CNT(args) || !isint(ARG_CUR(args))) {
                return(CMD_USAGE);
            }
            pf_id = parse_integer(ARG_GET(args));
            if ((rv = bcm_knet_filter_destroy(unit, pf_id)) < 0) {
                cli_out("Error destroying packet filter: %s\n",
                        bcm_errmsg(rv));
                return CMD_FAIL;
            }
        } else if (sal_strcasecmp(subcmd, "show") == 0) {
            count = 0;
            if (bcm_knet_filter_traverse(unit, _trav_filter, &count) < 0) {
                return CMD_FAIL;
            }
            if (count == 0) {
                cli_out("<no filters>\n");
            }
        } else {
            cli_out("Subcommand not found: %s\n", subcmd);
            return CMD_USAGE;
        }
    } else {
        cli_out("Subcommand not found: %s\n", subcmd);
        return CMD_USAGE;
    }
    return CMD_OK;
}