API: Traffic Metering and Policing

Link-Inline™ Software User Guide

Platform
Napatech SmartNIC
Content Type
User Guide
Capture Software Version
Link-Inline™ Software 3.2

This DPDK API examples illustrates how to set up a meter to perform traffic policing and how to apply the meter in a flow rule as well as how to read the statistics.

Setting up a meter object

This example creates a meter profile, meter policy and meter instance.
struct rte_flow_action action[] = {
  [0] = { .type = RTE_FLOW_ACTION_TYPE_END }};
struct rte_flow_action drop_action[] = {
  [0] = { .type = RTE_FLOW_ACTION_TYPE_DROP },
  [1] = { .type = RTE_FLOW_ACTION_TYPE_END }};

struct rte_mtr_meter_profile profile = {
  .alg = RTE_MTR_TRTCM_RFC2698,
  .trtcm_rfc2698 = { .cir = MAX_RATE, .cbs = BUCKET_SIZE, .pir = MAX_RATE, .pbs = BUCKET_SIZE },
  .packet_mode = 1 };
struct rte_mtr_meter_policy_params policy = { .actions = {
  [RTE_COLOR_GREEN] = action,
  [RTE_COLOR_YELLOW] = drop_action,
  [RTE_COLOR_RED] = drop_action }};
struct rte_mtr_params params = {
  .meter_profile_id = PROFILE_ID,
  .meter_enable = 1,
  .stats_mask = RTE_MTR_STATS_N_PKTS_GREEN | RTE_MTR_STATS_N_BYTES_GREEN,
  .meter_policy_id = POLICY_ID };

struct rte_mtr_error error;
if (rte_mtr_meter_profile_add(PORT_ID, PROFILE_ID, &profile, &error)) {
  /* Error handling */
}
if (rte_mtr_meter_policy_add(PORT_ID, POLICY_ID, &policy, &error)) {
  /* Error handling */
}
if (rte_mtr_create(PORT_ID, METER_ID, &params, 1, &error)) {
  /* Error handling */
}

Two actions are defined: one contains only an end action, indicating no action should be taken, and another that drops the frame. These actions are used in the meter policy definition.

The metering profile specifies how to meter the traffic. It uses two-rate three-color marker algorithm (as defined in RFC 2698) with specified committed information rate (CIR) / peak information rate (PIR) and committed burst size (CBS) / peak burst size (PBS) values.

The meter policy specifies how to handle the traffic based on its metering results. In this example, the policy maps the three possible colors (green, yellow and red) to different actions. Green traffic is mapped to the action array, which indicates that no action should be applied. Yellow and red traffic is mapped to the drop_action array, which indicates that the frame should be dropped.

The meter object combines the meter profile and policy to perform traffic policing on the specified port. The meter_enable flag enables the metering functionality on the port, and the stats_mask parameter specifies which statistics to collect.

Applying a meter in a flow rule

After creating a meter object, it can be applied in a flow rule. This example creates a flow rule to apply a meter and transmit matching traffic on a specific port.
/* Create group 1 exact match 5-tuple to retransmit offloaded IPv4 UDP packets. */
struct rte_flow_attr attr = { .group = 1, .ingress = 1 };

struct rte_flow_item_ipv4 ipv4 = { .hdr = {
  .src_addr = RTE_BE32(RTE_IPV4(20, 10, 10, 2)),
  .dst_addr = RTE_BE32(RTE_IPV4(20, 10, 11, 23)) }};
struct rte_flow_item_udp udp = { .hdr = {
  .src_port = RTE_BE16(0x1000),
  .dst_port = RTE_BE16(0x1001) }};
struct rte_flow_item pattern[] = {
  [0] = { .type = RTE_FLOW_ITEM_TYPE_IPV4, .spec = &ipv4, .mask = &rte_flow_item_ipv4_mask },
  [1] = { .type = RTE_FLOW_ITEM_TYPE_UDP, .spec = &udp, .mask = &rte_flow_item_udp_mask }};

struct rte_flow_action_meter meter = { .mtr_id = METER_ID };
struct rte_flow_action_port_id port_id = { .id = 1 };
struct rte_flow_action action[] = {
  [0] = { .type = RTE_FLOW_ACTION_TYPE_METER, .conf = &meter },
  [1] = { .type = RTE_FLOW_ACTION_TYPE_PORT_ID, .conf = &port_id },
  [2] = { .type = RTE_FLOW_ACTION_TYPE_END }};

struct rte_flow_error error;
struct rte_flow *flow = rte_flow_create(PORT_ID, &attr, pattern, action, &error);
if (!flow) {
  /* Error handling */
}
The flow rule is defined with a group ID of 1. It matches IPv4 frames with specific source and destination IP addresses, as well as with specific source and destination UDP port numbers. The flow rule applies a meter with the specified meter ID and forwards matching traffic to a specific port.
Note: A flow rule with group 0 must be created before the flow rule in this API example is created. This step has been omitted in this example for brevity.

Reading usage counters

This examples shows how to read the statistics of a meter associated with a specific port.
uint64_t stats_mask = 0;
struct rte_mtr_stats stats = {};

struct rte_mtr_error error;
if (rte_mtr_stats_read(PORT_ID, METER_ID, &stats, &stats_mask, 0, &error)) {
  /* ERROR */
}

/* Result in stats.n_pkts[RTE_COLOR_GREEN] */
/* Result in stats.n_bytes[RTE_COLOR_GREEN] */

The rte_mtr_stats_read function is called with the specified port ID and meter object ID, as well as a pointer to a rte_mtr_stats structure and a mask indicating which statistics should be read.

If the statistics are successfully read, the resulting values of the n_pkts and n_bytes fields of the rte_mtr_stats structure for the RTE_COLOR_GREEN packet color are retrieved. These fields contain the number of packets and bytes that have been processed by the meter and classified as green.

Running a user application with the DPDK virtio PMD

The following error message may be generated when flow rules with meter objects are applied in a user application, which is connected to the DPDK virtio PMD with the Napatech patch.
NTCONNECT: ERR: Error: Meter ID 655999 out of range. Max value is 559240.
This error message occurs because the meter object ID has exceeded the limit. This issue can be resolved by compiling the application with the -Dmax_ethports option.
Unique meter object IDs are assigned using the following formulas.
max_id = flow_mtr_meter_policy_n_max() / (RTE_MAX_ETHPORTS - 2);
id = ((vport - 4) * max_id) + id;
To increase the maximum meter object ID, the simplest approach is to reduce RTE_MAX_ETHPORTS, which represents the maximum number of physical ports that DPDK can support on a system. By default, RTE_MAX_ETHPORTS is set to 32. RTE_MAX_ETHPORTS can be modified using the -Dmax_ethports parameter during compilation.
Note: When RTE_MAX_ETHPORTS is adjusted, it must be evaluated and tested as it can impact system performance and resource utilization. It can also limit the maximum number of virtual functions. See RX queues for virtual functions in DN-1355.