meter: initial import

Signed-off-by: Intel
This commit is contained in:
Intel 2013-06-03 00:00:00 +00:00 committed by Thomas Monjalon
parent d7937e2e3d
commit e6541fdec8
20 changed files with 1814 additions and 0 deletions

View File

@ -85,6 +85,7 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_cmdline_ipaddr.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_cmdline_cirbuf.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_cmdline_string.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_cmdline_lib.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_meter.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_pmac_pm.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_pmac_acl.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_power.c

View File

@ -77,6 +77,12 @@ parallel_test_group_list = [
"Func" : default_autotest,
"Report" : None,
},
{
"Name" : "Meter autotest",
"Command" : "meter_autotest",
"Func" : default_autotest,
"Report" : None,
},
{
"Name" : "Dump log history",
"Command" : "dump_log_history",

View File

@ -167,6 +167,8 @@ static void cmd_autotest_parsed(void *parsed_result,
ret |= test_memcpy_perf();
if (all || !strcmp(res->autotest, "func_reentrancy_autotest"))
ret |= test_func_reentrancy();
if (all || !strcmp(res->autotest, "meter_autotest"))
ret |= test_meter();
if (all || !strcmp(res->autotest, "pm_autotest"))
ret |= test_pmac_pm();
if (all || !strcmp(res->autotest, "acl_autotest"))
@ -201,6 +203,7 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
"version_autotest#eal_fs_autotest#"
"cmdline_autotest#func_reentrancy_autotest#"
"mempool_perf_autotest#hash_perf_autotest#"
"meter_autotest#"
"memcpy_perf_autotest#pm_autotest#"
"acl_autotest#power_autotest#"
"all_autotests");

View File

@ -84,6 +84,7 @@ int test_version(void);
int test_eal_fs(void);
int test_cmdline(void);
int test_func_reentrancy(void);
int test_meter(void);
int test_pmac_pm(void);
int test_pmac_acl(void);
int test_power(void);

510
app/test/test_meter.c Normal file
View File

@ -0,0 +1,510 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <cmdline_parse.h>
#include "test.h"
#ifdef RTE_LIBRTE_METER
#include <rte_cycles.h>
#include <rte_meter.h>
#define mlog(format, ...) do{\
printf("Line %d:",__LINE__);\
printf(format, ##__VA_ARGS__);\
printf("\n");\
}while(0);
#define melog(format, ...) do{\
printf("Line %d:",__LINE__);\
printf(format, ##__VA_ARGS__);\
printf(" failed!\n");\
return -1;\
}while(0);
#define TM_TEST_SRTCM_CIR_DF 46000000
#define TM_TEST_SRTCM_CBS_DF 2048
#define TM_TEST_SRTCM_EBS_DF 4096
#define TM_TEST_TRTCM_CIR_DF 46000000
#define TM_TEST_TRTCM_PIR_DF 69000000
#define TM_TEST_TRTCM_CBS_DF 2048
#define TM_TEST_TRTCM_PBS_DF 4096
static struct rte_meter_srtcm_params sparams =
{.cir = TM_TEST_SRTCM_CIR_DF,
.cbs = TM_TEST_SRTCM_CBS_DF,
.ebs = TM_TEST_SRTCM_EBS_DF,};
static struct rte_meter_trtcm_params tparams=
{.cir = TM_TEST_TRTCM_CIR_DF,
.pir = TM_TEST_TRTCM_PIR_DF,
.cbs = TM_TEST_TRTCM_CBS_DF,
.pbs = TM_TEST_TRTCM_PBS_DF,};
/**
* functional test for rte_meter_srtcm_config
*/
static inline int
tm_test_srtcm_config(void)
{
#define SRTCM_CFG_MSG "srtcm_config"
struct rte_meter_srtcm sm;
struct rte_meter_srtcm_params sparams1;
/* invalid parameter test */
if(rte_meter_srtcm_config(NULL, NULL) == 0)
melog(SRTCM_CFG_MSG);
if(rte_meter_srtcm_config(&sm, NULL) == 0)
melog(SRTCM_CFG_MSG);
if(rte_meter_srtcm_config(NULL, &sparams) == 0)
melog(SRTCM_CFG_MSG);
/* cbs and ebs can't both be zero */
sparams1 = sparams;
sparams1.cbs = 0;
sparams1.ebs = 0;
if(rte_meter_srtcm_config(&sm, &sparams1) == 0)
melog(SRTCM_CFG_MSG);
/* cir should never be 0 */
sparams1 = sparams;
sparams1.cir = 0;
if(rte_meter_srtcm_config(&sm, &sparams1) == 0)
melog(SRTCM_CFG_MSG);
/* one of ebs and cbs can be zero, should be successful */
sparams1 = sparams;
sparams1.ebs = 0;
if(rte_meter_srtcm_config(&sm, &sparams1) != 0)
melog(SRTCM_CFG_MSG);
sparams1 = sparams;
sparams1.cbs = 0;
if(rte_meter_srtcm_config(&sm, &sparams1) != 0)
melog(SRTCM_CFG_MSG);
/* usual parameter, should be successful */
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_CFG_MSG);
return 0;
}
/**
* functional test for rte_meter_trtcm_config
*/
static inline int
tm_test_trtcm_config(void)
{
struct rte_meter_trtcm tm;
struct rte_meter_trtcm_params tparams1;
#define TRTCM_CFG_MSG "trtcm_config"
/* invalid parameter test */
if(rte_meter_trtcm_config(NULL, NULL) == 0)
melog(TRTCM_CFG_MSG);
if(rte_meter_trtcm_config(&tm, NULL) == 0)
melog(TRTCM_CFG_MSG);
if(rte_meter_trtcm_config(NULL, &tparams) == 0)
melog(TRTCM_CFG_MSG);
/* cir, cbs, pir and pbs never be zero */
tparams1 = tparams;
tparams1.cir = 0;
if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.cbs = 0;
if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.pbs = 0;
if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.pir = 0;
if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
/* pir should be greater or equal to cir */
tparams1 = tparams;
tparams1.pir = tparams1.cir - 1;
if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
melog(TRTCM_CFG_MSG" pir < cir test");
/* usual parameter, should be successful */
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_CFG_MSG);
return 0;
}
/**
* functional test for rte_meter_srtcm_color_blind_check
*/
static inline int
tm_test_srtcm_color_blind_check(void)
{
#define SRTCM_BLIND_CHECK_MSG "srtcm_blind_check"
struct rte_meter_srtcm sm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
/* Test green */
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_blind_check(
&sm, time, TM_TEST_SRTCM_CBS_DF - 1)
!= e_RTE_METER_GREEN)
melog(SRTCM_BLIND_CHECK_MSG" GREEN");
/* Test yellow */
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_blind_check(
&sm, time, TM_TEST_SRTCM_CBS_DF + 1)
!= e_RTE_METER_YELLOW)
melog(SRTCM_BLIND_CHECK_MSG" YELLOW");
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_blind_check(
&sm, time, (uint32_t)sm.ebs - 1) != e_RTE_METER_YELLOW)
melog(SRTCM_BLIND_CHECK_MSG" YELLOW");
/* Test red */
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_blind_check(
&sm, time, TM_TEST_SRTCM_EBS_DF + 1)
!= e_RTE_METER_RED)
melog(SRTCM_BLIND_CHECK_MSG" RED");
return 0;
}
/**
* functional test for rte_meter_trtcm_color_blind_check
*/
static inline int
tm_test_trtcm_color_blind_check(void)
{
#define TRTCM_BLIND_CHECK_MSG "trtcm_blind_check"
uint64_t time;
struct rte_meter_trtcm tm;
uint64_t hz = rte_get_tsc_hz();
/* Test green */
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_blind_check(
&tm, time, TM_TEST_TRTCM_CBS_DF - 1)
!= e_RTE_METER_GREEN)
melog(TRTCM_BLIND_CHECK_MSG" GREEN");
/* Test yellow */
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_blind_check(
&tm, time, TM_TEST_TRTCM_CBS_DF + 1)
!= e_RTE_METER_YELLOW)
melog(TRTCM_BLIND_CHECK_MSG" YELLOW");
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_blind_check(
&tm, time, TM_TEST_TRTCM_PBS_DF - 1)
!= e_RTE_METER_YELLOW)
melog(TRTCM_BLIND_CHECK_MSG" YELLOW");
/* Test red */
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_blind_check(
&tm, time, TM_TEST_TRTCM_PBS_DF + 1)
!= e_RTE_METER_RED)
melog(TRTCM_BLIND_CHECK_MSG" RED");
return 0;
}
/**
* @in[4] : the flags packets carries.
* @in[4] : the flags function expect to return.
* It will do blind check at the time of 1 second from beginning.
* At the time, it will use packets length of cbs -1, cbs + 1,
* ebs -1 and ebs +1 with flag in[0], in[1], in[2] and in[3] to do
* aware check, expect flag out[0], out[1], out[2] and out[3]
*/
static inline int
tm_test_srtcm_aware_check
(enum rte_meter_color in[4], enum rte_meter_color out[4])
{
#define SRTCM_AWARE_CHECK_MSG "srtcm_aware_check"
struct rte_meter_srtcm sm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_aware_check(
&sm, time, TM_TEST_SRTCM_CBS_DF - 1, in[0]) != out[0])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]);
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_aware_check(
&sm, time, TM_TEST_SRTCM_CBS_DF + 1, in[1]) != out[1])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]);
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_aware_check(
&sm, time, TM_TEST_SRTCM_EBS_DF - 1, in[2]) != out[2])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]);
if(rte_meter_srtcm_config(&sm, &sparams) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_srtcm_color_aware_check(
&sm, time, TM_TEST_SRTCM_EBS_DF + 1, in[3]) != out[3])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]);
return 0;
}
/**
* functional test for rte_meter_srtcm_color_aware_check
*/
static inline int
tm_test_srtcm_color_aware_check(void)
{
enum rte_meter_color in[4], out[4];
/**
* test 4 points that will produce green, yellow, yellow, red flag
* if using blind check
*/
/* previouly have a green, test points should keep unchanged */
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_GREEN;
out[0] = e_RTE_METER_GREEN;
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
if(tm_test_srtcm_aware_check(in, out) != 0)
return -1;
/**
* previously have a yellow, green & yellow = yellow
* yellow & red = red
*/
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW;
out[0] = e_RTE_METER_YELLOW;
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
if(tm_test_srtcm_aware_check(in, out) != 0)
return -1;
/**
* previously have a red, red & green = red
* red & yellow = red
*/
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED;
out[0] = e_RTE_METER_RED;
out[1] = e_RTE_METER_RED;
out[2] = e_RTE_METER_RED;
out[3] = e_RTE_METER_RED;
if(tm_test_srtcm_aware_check(in, out) != 0)
return -1;
return 0;
}
/**
* @in[4] : the flags packets carries.
* @in[4] : the flags function expect to return.
* It will do blind check at the time of 1 second from beginning.
* At the time, it will use packets length of cbs -1, cbs + 1,
* ebs -1 and ebs +1 with flag in[0], in[1], in[2] and in[3] to do
* aware check, expect flag out[0], out[1], out[2] and out[3]
*/
static inline int
tm_test_trtcm_aware_check
(enum rte_meter_color in[4], enum rte_meter_color out[4])
{
#define TRTCM_AWARE_CHECK_MSG "trtcm_aware_check"
struct rte_meter_trtcm tm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_aware_check(
&tm, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]);
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_aware_check(
&tm, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]);
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_aware_check(
&tm, time, TM_TEST_TRTCM_PBS_DF - 1, in[2]) != out[2])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]);
if(rte_meter_trtcm_config(&tm, &tparams) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
if(rte_meter_trtcm_color_aware_check(
&tm, time, TM_TEST_TRTCM_PBS_DF + 1, in[3]) != out[3])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]);
return 0;
}
/**
* functional test for rte_meter_trtcm_color_aware_check
*/
static inline int
tm_test_trtcm_color_aware_check(void)
{
enum rte_meter_color in[4], out[4];
/**
* test 4 points that will produce green, yellow, yellow, red flag
* if using blind check
*/
/* previouly have a green, test points should keep unchanged */
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_GREEN;
out[0] = e_RTE_METER_GREEN;
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
if(tm_test_trtcm_aware_check(in, out) != 0)
return -1;
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW;
out[0] = e_RTE_METER_YELLOW;
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
if(tm_test_trtcm_aware_check(in, out) != 0)
return -1;
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED;
out[0] = e_RTE_METER_RED;
out[1] = e_RTE_METER_RED;
out[2] = e_RTE_METER_RED;
out[3] = e_RTE_METER_RED;
if(tm_test_trtcm_aware_check(in, out) != 0)
return -1;
return 0;
}
/**
* test main entrance for library meter
*/
int
test_meter(void)
{
if(tm_test_srtcm_config() != 0 )
return -1;
if(tm_test_trtcm_config() != 0 )
return -1;
if(tm_test_srtcm_color_blind_check() != 0)
return -1;
if(tm_test_trtcm_color_blind_check()!= 0)
return -1;
if(tm_test_srtcm_color_aware_check()!= 0)
return -1;
if(tm_test_trtcm_color_aware_check()!= 0)
return -1;
return 0;
}
#else /* RTE_LIBRTE_METER */
int
test_meter(void)
{
printf("The meter library is not included in this build\n");
return 0;
}
#endif /* RTE_LIBRTE_METER */

View File

@ -228,6 +228,11 @@ CONFIG_RTE_MAX_LCORE_FREQS=64
#
CONFIG_RTE_LIBRTE_NET=y
#
# Compile librte_meter
#
CONFIG_RTE_LIBRTE_METER=y
#
# Compile librte_kni
#

View File

@ -229,6 +229,11 @@ CONFIG_RTE_MAX_LCORE_FREQS=64
#
CONFIG_RTE_LIBRTE_NET=y
#
# Compile librte_meter
#
CONFIG_RTE_LIBRTE_METER=y
#
# Compile librte_kni
#

View File

@ -229,6 +229,11 @@ CONFIG_RTE_MAX_LCORE_FREQS=64
#
CONFIG_RTE_LIBRTE_NET=y
#
# Compile librte_meter
#
CONFIG_RTE_LIBRTE_METER=y
#
# Compile librte_kni
#

View File

@ -229,6 +229,11 @@ CONFIG_RTE_MAX_LCORE_FREQS=64
#
CONFIG_RTE_LIBRTE_NET=y
#
# Compile librte_meter
#
CONFIG_RTE_LIBRTE_METER=y
#
# Compile librte_kni
#

View File

@ -0,0 +1,57 @@
# BSD LICENSE
#
# Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif
# Default target, can be overriden by command line or environment
RTE_TARGET ?= x86_64-default-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
# binary name
APP = qos_meter
# all source are stored in SRCS-y
SRCS-y := main.c rte_policer.c
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
# workaround for a gcc bug with noreturn attribute
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
CFLAGS_main.o += -Wno-return-type
endif
include $(RTE_SDK)/mk/rte.extapp.mk

433
examples/qos_meter/main.c Executable file
View File

@ -0,0 +1,433 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdio.h>
#include <getopt.h>
#include <rte_common.h>
#include <rte_eal.h>
#include <rte_mempool.h>
#include <rte_ethdev.h>
#include <rte_cycles.h>
#include <rte_mbuf.h>
#include <rte_meter.h>
/*
* Traffic metering configuration
*
*/
#define APP_MODE_FWD 0
#define APP_MODE_SRTCM_COLOR_BLIND 1
#define APP_MODE_SRTCM_COLOR_AWARE 2
#define APP_MODE_TRTCM_COLOR_BLIND 3
#define APP_MODE_TRTCM_COLOR_AWARE 4
#define APP_MODE APP_MODE_SRTCM_COLOR_BLIND
#include "main.h"
#define APP_PKT_FLOW_POS 33
#define APP_PKT_COLOR_POS 5
#if APP_PKT_FLOW_POS > 64 || APP_PKT_COLOR_POS > 64
#error Byte offset needs to be less than 64
#endif
/*
* Buffer pool configuration
*
***/
#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
#define NB_MBUF 8192
#define MEMPOOL_CACHE_SIZE 256
static struct rte_mempool *pool = NULL;
/*
* NIC configuration
*
***/
static struct rte_eth_conf port_conf = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
.split_hdr_size = 0,
.header_split = 0,
.hw_ip_checksum = 1,
.hw_vlan_filter = 0,
.jumbo_frame = 0,
.hw_strip_crc = 0,
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = NULL,
.rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6,
},
},
.txmode = {
.mq_mode = ETH_DCB_NONE,
},
};
static const struct rte_eth_rxconf rx_conf = {
.rx_thresh = {
.pthresh = 8, /* RX prefetch threshold reg */
.hthresh = 8, /* RX host threshold reg */
.wthresh = 4, /* RX write-back threshold reg */
},
.rx_free_thresh = 32,
};
static const struct rte_eth_txconf tx_conf = {
.tx_thresh = {
.pthresh = 36, /* TX prefetch threshold reg */
.hthresh = 0, /* TX host threshold reg */
.wthresh = 0, /* TX write-back threshold reg */
},
.tx_free_thresh = 0,
.tx_rs_thresh = 0,
.txq_flags = 0x0,
};
#define NIC_RX_QUEUE_DESC 128
#define NIC_TX_QUEUE_DESC 512
#define NIC_RX_QUEUE 0
#define NIC_TX_QUEUE 0
/*
* Packet RX/TX
*
***/
#define PKT_RX_BURST_MAX 32
#define PKT_TX_BURST_MAX 32
#define TIME_TX_DRAIN 200000ULL
static uint8_t port_rx;
static uint8_t port_tx;
static struct rte_mbuf *pkts_rx[PKT_RX_BURST_MAX];
static struct rte_mbuf *pkts_tx[PKT_TX_BURST_MAX];
static uint16_t pkts_tx_len = 0;
struct rte_meter_srtcm_params app_srtcm_params[] = {
{.cir = 1000000 * 46, .cbs = 2048, .ebs = 2048},
};
struct rte_meter_trtcm_params app_trtcm_params[] = {
{.cir = 1000000 * 46, .pir = 1500000 * 46, .cbs = 2048, .pbs = 2048},
};
#define DIM(a) (sizeof (a) / sizeof ((a)[0]))
#define APP_FLOWS_MAX 256
FLOW_METER app_flows[APP_FLOWS_MAX];
static void
app_configure_flow_table(void)
{
uint32_t i, j;
for (i = 0, j = 0; i < APP_FLOWS_MAX; i ++, j = (j + 1) % DIM(PARAMS)){
FUNC_CONFIG(&app_flows[i], &PARAMS[j]);
}
}
static inline void
app_pkt_handle(struct rte_mbuf *pkt, uint64_t time)
{
uint8_t color;
uint8_t *pkt_data = rte_pktmbuf_mtod(pkt, uint8_t *);
uint32_t pkt_len = rte_pktmbuf_pkt_len(pkt) - sizeof(struct ether_hdr);
uint8_t flow_id = (uint8_t)(pkt_data[APP_PKT_FLOW_POS] & (APP_FLOWS_MAX - 1));
color = pkt_data[APP_PKT_COLOR_POS];
/* color input is not used for blind modes */
color = (uint8_t) FUNC_METER(&app_flows[flow_id], time, pkt_len,
(enum rte_meter_color) color);
pkt_data[APP_PKT_COLOR_POS] = color;
}
static __attribute__((noreturn)) int
main_loop(__attribute__((unused)) void *dummy)
{
uint64_t current_time, last_time = rte_rdtsc();
uint32_t lcore_id = rte_lcore_id();
printf("Core %u: port RX = %d, port TX = %d\n", lcore_id, port_rx, port_tx);
while (1) {
uint64_t time_diff;
int i, nb_rx;
/* Mechanism to avoid stale packets in the output buffer */
current_time = rte_rdtsc();
time_diff = current_time - last_time;
if (unlikely(time_diff > TIME_TX_DRAIN)) {
int ret;
if (pkts_tx_len == 0) {
last_time = current_time;
continue;
}
/* Write packet burst to NIC TX */
ret = rte_eth_tx_burst(port_tx, NIC_TX_QUEUE, pkts_tx, pkts_tx_len);
/* Free buffers for any packets not written successfully */
if (unlikely(ret < pkts_tx_len)) {
for ( ; ret < pkts_tx_len; ret ++) {
rte_pktmbuf_free(pkts_tx[ret]);
}
}
/* Empty the output buffer */
pkts_tx_len = 0;
last_time = current_time;
}
/* Read packet burst from NIC RX */
nb_rx = rte_eth_rx_burst(port_rx, NIC_RX_QUEUE, pkts_rx, PKT_RX_BURST_MAX);
/* Handle packets */
for (i = 0; i < nb_rx; i ++) {
struct rte_mbuf *pkt = pkts_rx[i];
/* Handle current packet*/
app_pkt_handle(pkt, current_time);
/* Write current packet in the output buffer */
pkts_tx[pkts_tx_len] = pkt;
pkts_tx_len ++;
/* Write packets from output buffer to NIC TX when full burst is available */
if (unlikely(pkts_tx_len == PKT_TX_BURST_MAX)) {
/* Write packet burst to NIC TX */
int ret = rte_eth_tx_burst(port_tx, NIC_TX_QUEUE, pkts_tx, PKT_TX_BURST_MAX);
/* Free buffers for any packets not written successfully */
if (unlikely(ret < PKT_TX_BURST_MAX)) {
for ( ; ret < PKT_TX_BURST_MAX; ret ++) {
rte_pktmbuf_free(pkts_tx[ret]);
}
}
/* Empty the output buffer */
pkts_tx_len = 0;
}
}
}
}
static void
print_usage(const char *prgname)
{
printf ("%s [EAL options] -- -p PORTMASK\n"
" -p PORTMASK: hexadecimal bitmask of ports to configure\n",
prgname);
}
static int
parse_portmask(const char *portmask)
{
char *end = NULL;
unsigned long pm;
/* parse hexadecimal string */
pm = strtoul(portmask, &end, 16);
if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
return -1;
if (pm == 0)
return -1;
return pm;
}
/* Parse the argument given in the command line of the application */
static int
parse_args(int argc, char **argv)
{
int opt;
char **argvopt;
int option_index;
char *prgname = argv[0];
static struct option lgopts[] = {
{NULL, 0, 0, 0}
};
uint64_t port_mask, i, mask;
argvopt = argv;
while ((opt = getopt_long(argc, argvopt, "p:", lgopts, &option_index)) != EOF) {
switch (opt) {
case 'p':
port_mask = parse_portmask(optarg);
if (port_mask == 0) {
printf("invalid port mask (null port mask)\n");
print_usage(prgname);
return -1;
}
for (i = 0, mask = 1; i < 64; i ++, mask <<= 1){
if (mask & port_mask){
port_rx = i;
port_mask &= ~ mask;
break;
}
}
for (i = 0, mask = 1; i < 64; i ++, mask <<= 1){
if (mask & port_mask){
port_tx = i;
port_mask &= ~ mask;
break;
}
}
if (port_mask != 0) {
printf("invalid port mask (more than 2 ports)\n");
print_usage(prgname);
return -1;
}
break;
default:
print_usage(prgname);
return -1;
}
}
if (optind <= 1) {
print_usage(prgname);
return -1;
}
argv[optind-1] = prgname;
optind = 0; /* reset getopt lib */
return 0;
}
int
MAIN(int argc, char **argv)
{
uint32_t lcore_id;
int ret;
/* EAL init */
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n");
argc -= ret;
argv += ret;
if (rte_lcore_count() != 1) {
rte_exit(EXIT_FAILURE, "This application does not accept more than one core. "
"Please adjust the \"-c COREMASK\" parameter accordingly.\n");
}
/* Application non-EAL arguments parse */
ret = parse_args(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Invalid input arguments\n");
/* Buffer pool init */
pool = rte_mempool_create("pool", NB_MBUF, MBUF_SIZE, MEMPOOL_CACHE_SIZE,
sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL,
rte_pktmbuf_init, NULL, rte_socket_id(), 0);
if (pool == NULL)
rte_exit(EXIT_FAILURE, "Buffer pool creation error\n");
/* PMD init */
if (rte_pmd_init_all() < 0)
rte_exit(EXIT_FAILURE, "PMD init error\n");
if (rte_eal_pci_probe() < 0)
rte_exit(EXIT_FAILURE, "PCI probe error\n");
/* NIC init */
ret = rte_eth_dev_configure(port_rx, 1, 1, &port_conf);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_rx, ret);
ret = rte_eth_rx_queue_setup(port_rx, NIC_RX_QUEUE, NIC_RX_QUEUE_DESC, rte_eth_dev_socket_id(port_rx), &rx_conf, pool);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d RX queue setup error (%d)\n", port_rx, ret);
ret = rte_eth_tx_queue_setup(port_rx, NIC_TX_QUEUE, NIC_TX_QUEUE_DESC, rte_eth_dev_socket_id(port_rx), &tx_conf);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d TX queue setup error (%d)\n", port_rx, ret);
ret = rte_eth_dev_configure(port_tx, 1, 1, &port_conf);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d configuration error (%d)\n", port_tx, ret);
ret = rte_eth_rx_queue_setup(port_tx, NIC_RX_QUEUE, NIC_RX_QUEUE_DESC, rte_eth_dev_socket_id(port_tx), &rx_conf, pool);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d RX queue setup error (%d)\n", port_tx, ret);
ret = rte_eth_tx_queue_setup(port_tx, NIC_TX_QUEUE, NIC_TX_QUEUE_DESC, rte_eth_dev_socket_id(port_tx), &tx_conf);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d TX queue setup error (%d)\n", port_tx, ret);
ret = rte_eth_dev_start(port_rx);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d start error (%d)\n", port_rx, ret);
ret = rte_eth_dev_start(port_tx);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Port %d start error (%d)\n", port_tx, ret);
rte_eth_promiscuous_enable(port_rx);
rte_eth_promiscuous_enable(port_tx);
/* App configuration */
app_configure_flow_table();
/* Launch per-lcore init on every lcore */
rte_eal_mp_remote_launch(main_loop, NULL, CALL_MASTER);
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
return -1;
}
return 0;
}

89
examples/qos_meter/main.h Executable file
View File

@ -0,0 +1,89 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _MAIN_H_
#define _MAIN_H_
#ifdef RTE_EXEC_ENV_BAREMETAL
#define MAIN _main
#else
#define MAIN main
#endif
int MAIN(int argc, char **argv);
#if APP_MODE == APP_MODE_FWD
#define FUNC_METER(a,b,c,d) color, flow_id=flow_id, pkt_len=pkt_len, time=time
#define FUNC_CONFIG(a,b)
#define PARAMS app_srtcm_params
#define FLOW_METER int
#elif APP_MODE == APP_MODE_SRTCM_COLOR_BLIND
#define FUNC_METER(a,b,c,d) rte_meter_srtcm_color_blind_check(a,b,c)
#define FUNC_CONFIG rte_meter_srtcm_config
#define PARAMS app_srtcm_params
#define FLOW_METER struct rte_meter_srtcm
#elif (APP_MODE == APP_MODE_SRTCM_COLOR_AWARE)
#define FUNC_METER rte_meter_srtcm_color_aware_check
#define FUNC_CONFIG rte_meter_srtcm_config
#define PARAMS app_srtcm_params
#define FLOW_METER struct rte_meter_srtcm
#elif (APP_MODE == APP_MODE_TRTCM_COLOR_BLIND)
#define FUNC_METER(a,b,c,d) rte_meter_trtcm_color_blind_check(a,b,c)
#define FUNC_CONFIG rte_meter_trtcm_config
#define PARAMS app_trtcm_params
#define FLOW_METER struct rte_meter_trtcm
#elif (APP_MODE == APP_MODE_TRTCM_COLOR_AWARE)
#define FUNC_METER rte_meter_trtcm_color_aware_check
#define FUNC_CONFIG rte_meter_trtcm_config
#define PARAMS app_trtcm_params
#define FLOW_METER struct rte_meter_trtcm
#else
#error Invalid value for APP_MODE
#endif
#endif /* _MAIN_H_ */

View File

@ -0,0 +1,59 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include "rte_policer.h"
int
rte_phb_config(struct rte_phb *phb_table, uint32_t phb_table_index,
enum rte_meter_color pre_meter, enum rte_meter_color post_meter, enum rte_phb_action action)
{
struct rte_phb *phb = NULL;
/* User argument checking */
if (phb_table == NULL) {
return -1;
}
if ((pre_meter > e_RTE_METER_RED) || (post_meter > e_RTE_METER_RED) || (pre_meter > post_meter)) {
return -2;
}
/* Set action in PHB table entry */
phb = &phb_table[phb_table_index];
phb->actions[pre_meter][post_meter] = action;
return 0;
}

View File

@ -0,0 +1,65 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __INCLUDE_RTE_POLICER_H__
#define __INCLUDE_RTE_POLICER_H__
#include <stdint.h>
#include <rte_meter.h>
enum rte_phb_action {
e_RTE_PHB_ACTION_GREEN = e_RTE_METER_GREEN,
e_RTE_PHB_ACTION_YELLOW = e_RTE_METER_YELLOW,
e_RTE_PHB_ACTION_RED = e_RTE_METER_RED,
e_RTE_PHB_ACTION_DROP = 3,
};
struct rte_phb {
enum rte_phb_action actions[e_RTE_METER_COLORS][e_RTE_METER_COLORS];
};
int
rte_phb_config(struct rte_phb *phb_table, uint32_t phb_table_index,
enum rte_meter_color pre_meter, enum rte_meter_color post_meter, enum rte_phb_action action);
static inline enum rte_phb_action
policer_run(struct rte_phb *phb_table, uint32_t phb_table_index, enum rte_meter_color pre_meter, enum rte_meter_color post_meter)
{
struct rte_phb *phb = &phb_table[phb_table_index];
enum rte_phb_action action = phb->actions[pre_meter][post_meter];
return action;
}
#endif

View File

@ -47,6 +47,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net
DIRS-$(CONFIG_RTE_LIBRTE_POWER) += librte_power
DIRS-$(CONFIG_RTE_LIBRTE_METER) += librte_meter
DIRS-$(CONFIG_RTE_LIBRTE_PMAC) += librte_pmac
ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)

View File

@ -73,6 +73,7 @@ extern struct rte_logs rte_logs;
#define RTE_LOGTYPE_KNI 0X00000100 /**< Log related to KNI. */
#define RTE_LOGTYPE_PMAC 0x00000200 /**< Log related to PMAC. */
#define RTE_LOGTYPE_POWER 0x00000400 /**< Log related to power. */
#define RTE_LOGTYPE_METER 0x00000800 /**< Log related to QoS meter. */
/* these log types can be used in an application */
#define RTE_LOGTYPE_USER1 0x01000000 /**< User-defined log type 1. */

55
lib/librte_meter/Makefile Normal file
View File

@ -0,0 +1,55 @@
# BSD LICENSE
#
# Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
include $(RTE_SDK)/mk/rte.vars.mk
#
# library name
#
LIB = librte_meter.a
CFLAGS += -O3
CFLAGS += -g
CFLAGS += $(WERROR_FLAGS)
#
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_METER) := rte_meter.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_METER)-include := rte_meter.h
# this lib depends upon:
DEPDIRS-$(CONFIG_RTE_LIBRTE_METER) += lib/librte_eal
include $(RTE_SDK)/mk/rte.lib.mk

View File

@ -0,0 +1,121 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <inttypes.h>
#include <stdio.h>
#include <math.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_cycles.h>
#include "rte_meter.h"
#ifndef RTE_METER_TB_PERIOD_MIN
#define RTE_METER_TB_PERIOD_MIN 100
#endif
static void
rte_meter_get_tb_params(uint64_t hz, uint64_t rate, uint64_t *tb_period, uint64_t *tb_bytes_per_period)
{
double period = ((double) hz) / ((double) rate);
if (period >= RTE_METER_TB_PERIOD_MIN) {
*tb_bytes_per_period = 1;
*tb_period = (uint64_t) period;
} else {
*tb_bytes_per_period = (uint64_t) ceil(RTE_METER_TB_PERIOD_MIN / period);
*tb_period = (hz * (*tb_bytes_per_period)) / rate;
}
}
int
rte_meter_srtcm_config(struct rte_meter_srtcm *m, struct rte_meter_srtcm_params *params)
{
uint64_t hz;
/* Check input parameters */
if ((m == NULL) || (params == NULL)) {
return -1;
}
if ((params->cir == 0) || ((params->cbs == 0) && (params->ebs == 0))) {
return -2;
}
/* Initialize srTCM run-time structure */
hz = rte_get_tsc_hz();
m->time = rte_get_tsc_cycles();
m->tc = m->cbs = params->cbs;
m->te = m->ebs = params->ebs;
rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
RTE_LOG(INFO, METER, "Low level srTCM config: \n"
"\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n",
m->cir_period, m->cir_bytes_per_period);
return 0;
}
int
rte_meter_trtcm_config(struct rte_meter_trtcm *m, struct rte_meter_trtcm_params *params)
{
uint64_t hz;
/* Check input parameters */
if ((m == NULL) || (params == NULL)) {
return -1;
}
if ((params->cir == 0) || (params->pir == 0) || (params->pir < params->cir) ||
(params->cbs == 0) || (params->pbs == 0)) {
return -2;
}
/* Initialize trTCM run-time structure */
hz = rte_get_tsc_hz();
m->time_tc = m->time_tp = rte_get_tsc_cycles();
m->tc = m->cbs = params->cbs;
m->tp = m->pbs = params->pbs;
rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
rte_meter_get_tb_params(hz, params->pir, &m->pir_period, &m->pir_bytes_per_period);
RTE_LOG(INFO, METER, "Low level trTCM config: \n"
"\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n"
"\tPIR period = %" PRIu64 ", PIR bytes per period = %" PRIu64 "\n",
m->cir_period, m->cir_bytes_per_period,
m->pir_period, m->pir_bytes_per_period);
return 0;
}

View File

@ -0,0 +1,388 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __INCLUDE_RTE_METER_H__
#define __INCLUDE_RTE_METER_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* RTE Traffic Metering
*
* Traffic metering algorithms:
* 1. Single Rate Three Color Marker (srTCM): defined by IETF RFC 2697
* 2. Two Rate Three Color Marker (trTCM): defined by IETF RFC 2698
*
***/
#include <stdint.h>
/*
* Application Programmer's Interface (API)
*
***/
/** Packet Color Set */
enum rte_meter_color {
e_RTE_METER_GREEN = 0, /**< Green */
e_RTE_METER_YELLOW, /**< Yellow */
e_RTE_METER_RED, /**< Red */
e_RTE_METER_COLORS /**< Number of available colors */
};
/** srTCM parameters per metered traffic flow. The CIR, CBS and EBS parameters only
count bytes of IP packets and do not include link specific headers. At least one of
the CBS or EBS parameters has to be greater than zero. */
struct rte_meter_srtcm_params {
uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
uint64_t cbs; /**< Committed Burst Size (CBS). Measured in bytes. */
uint64_t ebs; /**< Excess Burst Size (EBS). Measured in bytes. */
};
/** trTCM parameters per metered traffic flow. The CIR, PIR, CBS and PBS parameters
only count bytes of IP packets and do not include link specific headers. PIR has to
be greater than or equal to CIR. Both CBS or EBS have to be greater than zero. */
struct rte_meter_trtcm_params {
uint64_t cir; /**< Committed Information Rate (CIR). Measured in bytes per second. */
uint64_t pir; /**< Peak Information Rate (PIR). Measured in bytes per second. */
uint64_t cbs; /**< Committed Burst Size (CBS). Measured in byes. */
uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */
};
/** Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm;
/** Internal data structure storing the trTCM run-time context per metered traffic flow. */
struct rte_meter_trtcm;
/**
* srTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated srTCM data structure
* @param params
* User parameters per srTCM metered traffic flow
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_srtcm_config(struct rte_meter_srtcm *m,
struct rte_meter_srtcm_params *params);
/**
* trTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated trTCM data structure
* @param params
* User parameters per trTCM metered traffic flow
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_trtcm_config(struct rte_meter_trtcm *m,
struct rte_meter_trtcm_params *params);
/**
* srTCM color blind traffic metering
*
* @param m
* Handle to srTCM instance
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_length
* Length of the current IP packet (measured in bytes)
* @return
* Color assigned to the current IP packet
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
uint64_t time,
uint32_t pkt_len);
/**
* srTCM color aware traffic metering
*
* @param m
* Handle to srTCM instance
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_length
* Length of the current IP packet (measured in bytes)
* @param pkt_color
* Input color of the current IP packet
* @return
* Color assigned to the current IP packet
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
/**
* trTCM color blind traffic metering
*
* @param m
* Handle to trTCM instance
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_length
* Length of the current IP packet (measured in bytes)
* @return
* Color assigned to the current IP packet
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
uint64_t time,
uint32_t pkt_len);
/**
* trTCM color aware traffic metering
*
* @param m
* Handle to trTCM instance
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_length
* Length of the current IP packet (measured in bytes)
* @param pkt_color
* Input color of the current IP packet
* @return
* Color assigned to the current IP packet
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
/*
* Inline implementation of run-time methods
*
***/
/* Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm {
uint64_t time; /* Time of latest update of C and E token buckets */
uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
uint64_t te; /* Number of bytes currently available in the excess (E) token bucket */
uint64_t cbs; /* Upper limit for C token bucket */
uint64_t ebs; /* Upper limit for E token bucket */
uint64_t cir_period; /* Number of CPU cycles for one update of C and E token buckets */
uint64_t cir_bytes_per_period; /* Number of bytes to add to C and E token buckets on each update */
};
/* Internal data structure storing the trTCM run-time context per metered traffic flow. */
struct rte_meter_trtcm {
uint64_t time_tc; /* Time of latest update of C token bucket */
uint64_t time_tp; /* Time of latest update of E token bucket */
uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
uint64_t tp; /* Number of bytes currently available in the peak (P) token bucket */
uint64_t cbs; /* Upper limit for C token bucket */
uint64_t pbs; /* Upper limit for P token bucket */
uint64_t cir_period; /* Number of CPU cycles for one update of C token bucket */
uint64_t cir_bytes_per_period; /* Number of bytes to add to C token bucket on each update */
uint64_t pir_period; /* Number of CPU cycles for one update of P token bucket */
uint64_t pir_bytes_per_period; /* Number of bytes to add to P token bucket on each update */
};
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
uint64_t time,
uint32_t pkt_len)
{
uint64_t time_diff, n_periods, tc, te;
/* Bucket update */
time_diff = time - m->time;
n_periods = time_diff / m->cir_period;
m->time += n_periods * m->cir_period;
tc = m->tc + n_periods * m->cir_bytes_per_period;
if (tc > m->cbs)
tc = m->cbs;
te = m->te + n_periods * m->cir_bytes_per_period;
if (te > m->ebs)
te = m->ebs;
/* Color logic */
if (tc >= pkt_len) {
m->tc = tc - pkt_len;
m->te = te;
return e_RTE_METER_GREEN;
}
if (te >= pkt_len) {
m->tc = tc;
m->te = te - pkt_len;
return e_RTE_METER_YELLOW;
}
m->tc = tc;
m->te = te;
return e_RTE_METER_RED;
}
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
{
uint64_t time_diff, n_periods, tc, te;
/* Bucket update */
time_diff = time - m->time;
n_periods = time_diff / m->cir_period;
m->time += n_periods * m->cir_period;
tc = m->tc + n_periods * m->cir_bytes_per_period;
if (tc > m->cbs)
tc = m->cbs;
te = m->te + n_periods * m->cir_bytes_per_period;
if (te > m->ebs)
te = m->ebs;
/* Color logic */
if ((pkt_color == e_RTE_METER_GREEN) && (tc >= pkt_len)) {
m->tc = tc - pkt_len;
m->te = te;
return e_RTE_METER_GREEN;
}
if ((pkt_color != e_RTE_METER_RED) && (te >= pkt_len)) {
m->tc = tc;
m->te = te - pkt_len;
return e_RTE_METER_YELLOW;
}
m->tc = tc;
m->te = te;
return e_RTE_METER_RED;
}
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
uint64_t time,
uint32_t pkt_len)
{
uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
n_periods_tc = time_diff_tc / m->cir_period;
n_periods_tp = time_diff_tp / m->pir_period;
m->time_tc += n_periods_tc * m->cir_period;
m->time_tp += n_periods_tp * m->pir_period;
tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
if (tc > m->cbs)
tc = m->cbs;
tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
if (tp > m->pbs)
tp = m->pbs;
/* Color logic */
if (tp < pkt_len) {
m->tc = tc;
m->tp = tp;
return e_RTE_METER_RED;
}
if (tc < pkt_len) {
m->tc = tc;
m->tp = tp - pkt_len;
return e_RTE_METER_YELLOW;
}
m->tc = tc - pkt_len;
m->tp = tp - pkt_len;
return e_RTE_METER_GREEN;
}
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
{
uint64_t time_diff_tc, time_diff_tp, n_periods_tc, n_periods_tp, tc, tp;
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
n_periods_tc = time_diff_tc / m->cir_period;
n_periods_tp = time_diff_tp / m->pir_period;
m->time_tc += n_periods_tc * m->cir_period;
m->time_tp += n_periods_tp * m->pir_period;
tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
if (tc > m->cbs)
tc = m->cbs;
tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
if (tp > m->pbs)
tp = m->pbs;
/* Color logic */
if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
m->tc = tc;
m->tp = tp;
return e_RTE_METER_RED;
}
if ((pkt_color == e_RTE_METER_YELLOW) || (tc < pkt_len)) {
m->tc = tc;
m->tp = tp - pkt_len;
return e_RTE_METER_YELLOW;
}
m->tc = tc - pkt_len;
m->tp = tp - pkt_len;
return e_RTE_METER_GREEN;
}
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_RTE_METER_H__ */

View File

@ -101,6 +101,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMAC),y)
LDLIBS += -lrte_pmac
endif
ifeq ($(CONFIG_RTE_LIBRTE_METER),y)
LDLIBS += -lrte_meter
endif
LDLIBS += --start-group
ifeq ($(CONFIG_RTE_LIBRTE_ETHER),y)