src/dpdk/drivers/net/mvpp2/mrvl_flow.c
static int
mrvl_parse_raw(const struct rte_flow_item *item,
	       struct rte_flow *flow,
	       struct rte_flow_error *error)
{
	const struct rte_flow_item_raw *spec = NULL, *mask = NULL;
	struct pp2_cls_rule_key_field *key_field;
	struct mv_net_udf *udf_params;
	uint8_t length;
	int ret;

	ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
			      &rte_flow_item_raw_mask,
			      sizeof(struct rte_flow_item_raw), error);
	if (ret)
		return ret;

	if (!spec->pattern) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "pattern pointer MUST be given\n");
		return -rte_errno;
	}

	/* Only hex string is supported; so, it must start with '0x' */
	if (strncmp((const char *)spec->pattern, "0x", 2) != 0)  {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'pattern' string must start with '0x'\n");
		return -rte_errno;
	}

	if (mask->pattern &&
	    strncmp((const char *)mask->pattern, "0x", 2) != 0)  {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'mask-pattern' string must start with '0x'\n");
		return -rte_errno;
	}

	if (mask->search && spec->search) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'search' option must be '0'\n");
		return -rte_errno;
	}

	if (mask->offset && spec->offset != 0) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'offset' option must be '0'\n");
		return -rte_errno;
	}

	if (!mask->relative || !spec->relative) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'relative' option must be given and enabled\n");
		return -rte_errno;
	}

	length = spec->length & mask->length;
	if (!length) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'length' option must be given bigger than '0'\n");
		return -rte_errno;
	}

	key_field = &flow->rule.fields[flow->rule.num_fields];
	mrvl_alloc_key_mask(key_field);

	/* pattern and length refer to string bytes. we need to convert it to
	 * values.
	 */
	key_field->size = length;
	ret = mrvl_string_to_hex_values(spec->pattern, key_field->key,
					&key_field->size);
	if (ret) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL,
				   "can't convert pattern from string to hex\n");
		return -rte_errno;
	}
	if (mask->pattern) {
		ret = mrvl_string_to_hex_values(mask->pattern, key_field->mask,
						&length);
		if (ret) {
			rte_flow_error_set(error, EINVAL,
					   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
					   NULL,
					   "can't convert mask-pattern from string to hex\n");
			return -rte_errno;
		}
	} else {
		rte_free(key_field->mask);
		key_field->mask = NULL;
	}

	flow->table_key.proto_field[flow->rule.num_fields].proto =
		MV_NET_UDF;
	udf_params =
		&flow->table_key.proto_field[flow->rule.num_fields].field.udf;
	udf_params->id = flow->next_udf_id++;
	udf_params->size = key_field->size;
	flow->table_key.key_size += key_field->size;

	flow->rule.num_fields += 1;

	return 0;
}
/**
 * Parse raw flow item.
 *
 * @param item Pointer to the flow item.
 * @param flow Pointer to the flow.
 * @param error Pointer to the flow error.
 * @returns 0 on success, negative value otherwise.
 */
Parse raw flow item.
@param item Pointer to the flow item.
@param flow Pointer to the flow.
@param error Pointer to the flow error.
@returns 0 on success, negative value otherwise.
Parse raw flow item . @param item Pointer to the flow item . @param flow Pointer to the flow . @param error Pointer to the flow error . @returns 0 on success negative value otherwise .
static int
mrvl_parse_raw(const struct rte_flow_item *item,
	       struct rte_flow *flow,
	       struct rte_flow_error *error)
{
	const struct rte_flow_item_raw *spec = NULL, *mask = NULL;
	struct pp2_cls_rule_key_field *key_field;
	struct mv_net_udf *udf_params;
	uint8_t length;
	int ret;
	ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
			      &rte_flow_item_raw_mask,
			      sizeof(struct rte_flow_item_raw), error);
	if (ret)
		return ret;
	if (!spec->pattern) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "pattern pointer MUST be given\n");
		return -rte_errno;
	}
	if (strncmp((const char *)spec->pattern, "0x", 2) != 0)  {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'pattern' string must start with '0x'\n");
		return -rte_errno;
	}
	if (mask->pattern &&
	    strncmp((const char *)mask->pattern, "0x", 2) != 0)  {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'mask-pattern' string must start with '0x'\n");
		return -rte_errno;
	}
	if (mask->search && spec->search) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'search' option must be '0'\n");
		return -rte_errno;
	}
	if (mask->offset && spec->offset != 0) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'offset' option must be '0'\n");
		return -rte_errno;
	}
	if (!mask->relative || !spec->relative) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'relative' option must be given and enabled\n");
		return -rte_errno;
	}
	length = spec->length & mask->length;
	if (!length) {
		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL, "'length' option must be given bigger than '0'\n");
		return -rte_errno;
	}
	key_field = &flow->rule.fields[flow->rule.num_fields];
	mrvl_alloc_key_mask(key_field);
	key_field->size = length;
	ret = mrvl_string_to_hex_values(spec->pattern, key_field->key,
					&key_field->size);
	if (ret) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
				   NULL,
				   "can't convert pattern from string to hex\n");
		return -rte_errno;
	}
	if (mask->pattern) {
		ret = mrvl_string_to_hex_values(mask->pattern, key_field->mask,
						&length);
		if (ret) {
			rte_flow_error_set(error, EINVAL,
					   RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
					   NULL,
					   "can't convert mask-pattern from string to hex\n");
			return -rte_errno;
		}
	} else {
		rte_free(key_field->mask);
		key_field->mask = NULL;
	}
	flow->table_key.proto_field[flow->rule.num_fields].proto =
		MV_NET_UDF;
	udf_params =
		&flow->table_key.proto_field[flow->rule.num_fields].field.udf;
	udf_params->id = flow->next_udf_id++;
	udf_params->size = key_field->size;
	flow->table_key.key_size += key_field->size;
	flow->rule.num_fields += 1;
	return 0;
}
static int mrvl_parse_raw ( const struct rte_flow_item * item , struct rte_flow * flow , struct rte_flow_error * error ) { const struct rte_flow_item_raw * spec = NULL , * mask = NULL ; struct pp2_cls_rule_key_field * key_field ; struct mv_net_udf * udf_params ; uint8_t length ; int ret ; ret = mrvl_parse_init ( item , ( const void * * ) & spec , ( const void * * ) & mask , & rte_flow_item_raw_mask , sizeof ( struct rte_flow_item_raw ) , error ) ; if ( ret ) return ret ; if ( ! spec -> pattern ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } if ( strncmp ( ( const char * ) spec -> pattern , " " , 2 ) != 0 ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } if ( mask -> pattern && strncmp ( ( const char * ) mask -> pattern , " " , 2 ) != 0 ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } if ( mask -> search && spec -> search ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } if ( mask -> offset && spec -> offset != 0 ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } if ( ! mask -> relative || ! spec -> relative ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } length = spec -> length & mask -> length ; if ( ! length ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } key_field = & flow -> rule . fields [ flow -> rule . num_fields ] ; mrvl_alloc_key_mask ( key_field ) ; key_field -> size = length ; ret = mrvl_string_to_hex_values ( spec -> pattern , key_field -> key , & key_field -> size ) ; if ( ret ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } if ( mask -> pattern ) { ret = mrvl_string_to_hex_values ( mask -> pattern , key_field -> mask , & length ) ; if ( ret ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ITEM_SPEC , NULL , " \n " ) ; return - rte_errno ; } } else { rte_free ( key_field -> mask ) ; key_field -> mask = NULL ; } flow -> table_key . proto_field [ flow -> rule . num_fields ] . proto = MV_NET_UDF ; udf_params = & flow -> table_key . proto_field [ flow -> rule . num_fields ] . field . udf ; udf_params -> id = flow -> next_udf_id ++ ; udf_params -> size = key_field -> size ; flow -> table_key . key_size += key_field -> size ; flow -> rule . num_fields += 1 ; return 0 ; }
Parse raw flow item.
Parse raw flow item .
/* Only hex string is supported; so, it must start with '0x' */ /* pattern and length refer to string bytes. we need to convert it to
	 * values.
	 */