DPDK 25.03.0
examples/flow_filtering/snippets/snippet_match_ipv4.c
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2022 NVIDIA Corporation & Affiliates
*/
#include <stdlib.h>
#include <rte_errno.h>
#include <rte_flow.h>
#include "snippet_match_ipv4.h"
#include "../common.h"
void
snippet_ipv4_flow_create_actions(struct rte_flow_action *action)
{
/*
* create the action sequence.
* one action only, move packet to queue
*/
struct rte_flow_action_queue *queue = calloc(1, sizeof(struct rte_flow_action_queue));
if (queue == NULL)
fprintf(stderr, "Failed to allocate memory for queue\n");
queue->index = QUEUE_ID; /* The selected target queue.*/
action[0].conf = queue;
}
void
snippet_ipv4_flow_create_patterns(struct rte_flow_item *patterns)
{
struct rte_flow_item_ipv4 *ip_spec;
struct rte_flow_item_ipv4 *ip_mask;
/*
* set the first level of the pattern (ETH).
* since in this example we just want to get the
* IPV4 we set this level to allow all.
*/
/*
* setting the second level of the pattern (IP).
* in this example this is the level we care about
* so we set it according to the parameters.
*/
ip_spec = calloc(1, sizeof(struct rte_flow_item_ipv4));
if (ip_spec == NULL)
fprintf(stderr, "Failed to allocate memory for ip_spec\n");
ip_mask = calloc(1, sizeof(struct rte_flow_item_ipv4));
if (ip_mask == NULL)
fprintf(stderr, "Failed to allocate memory for ip_mask\n");
ip_spec->hdr.dst_addr = htonl(DEST_IP); /* The dest ip value to match the input packet. */
ip_mask->hdr.dst_addr = FULL_MASK; /* The mask to apply to the dest ip. */
ip_spec->hdr.src_addr = htonl(SRC_IP); /* The src ip value to match the input packet. */
ip_mask->hdr.src_addr = EMPTY_MASK; /* The mask to apply to the src ip. */
patterns[1].spec = ip_spec;
patterns[1].mask = ip_mask;
/* The final level must be always type end. */
}
/* creates a template that holds a list of action types without any specific values set. */
static struct rte_flow_actions_template *
snippet_ipv4_flow_create_actions_template(uint16_t port_id, struct rte_flow_error *error)
{
struct rte_flow_action tactions[MAX_ACTION_NUM] = {0};
struct rte_flow_action masks[MAX_ACTION_NUM] = {0};
struct rte_flow_actions_template_attr action_attr = {
.ingress = 1,
};
/* This sets the masks to match the actions, indicating that all fields of the actions
* should be considered as part of the template.
*/
memcpy(masks, tactions, sizeof(masks));
/* Create the flow actions template using the configured attributes, actions, and masks */
return rte_flow_actions_template_create(port_id, &action_attr,
tactions, masks, error);
}
static struct rte_flow_pattern_template *
snippet_ipv4_flow_create_pattern_template(uint16_t port_id, struct rte_flow_error *error)
{
struct rte_flow_item titems[MAX_PATTERN_NUM] = {0};
struct rte_flow_item_ipv4 ip_mask = {0};
.ingress = 1
};
ip_mask.hdr.src_addr = EMPTY_MASK;
ip_mask.hdr.dst_addr = FULL_MASK;
titems[1].mask = &ip_mask;
return rte_flow_pattern_template_create(port_id, &attr, titems, error);
}
struct rte_flow_template_table *
snippet_ipv4_flow_create_table(uint16_t port_id, struct rte_flow_error *error)
{
struct rte_flow_pattern_template *pt;
struct rte_flow_actions_template *at;
/* Set the rule attribute, only ingress packets will be checked. */
struct rte_flow_template_table_attr table_attr = {
.flow_attr = {
.group = 0,
.priority = 0,
.ingress = 1,
.egress = 0,
.transfer = 0,
.reserved = 0,
},
/* Maximum number of flow rules that this table holds. */
.nb_flows = 1,
};
/* The pattern template defines common matching fields without values.
* The number and order of items in the template must be the same at the rule creation.
*/
pt = snippet_ipv4_flow_create_pattern_template(port_id, error);
if (pt == NULL) {
printf("Failed to create pattern template: %s (%s)\n",
return NULL;
}
/* The actions template holds a list of action types without values.
* The number and order of actions in the template must be the same at the rule creation.
*/
at = snippet_ipv4_flow_create_actions_template(port_id, error);
if (at == NULL) {
printf("Failed to create actions template: %s (%s)\n",
return NULL;
}
return rte_flow_template_table_create(port_id, &table_attr, &pt, 1, &at, 1, error);
}
const char * rte_strerror(int errnum)
#define rte_errno
Definition: rte_errno.h:29
__rte_experimental struct rte_flow_actions_template * rte_flow_actions_template_create(uint16_t port_id, const struct rte_flow_actions_template_attr *template_attr, const struct rte_flow_action actions[], const struct rte_flow_action masks[], struct rte_flow_error *error)
__rte_experimental struct rte_flow_template_table * rte_flow_template_table_create(uint16_t port_id, const struct rte_flow_template_table_attr *table_attr, struct rte_flow_pattern_template *pattern_templates[], uint8_t nb_pattern_templates, struct rte_flow_actions_template *actions_templates[], uint8_t nb_actions_templates, struct rte_flow_error *error)
@ RTE_FLOW_ACTION_TYPE_QUEUE
Definition: rte_flow.h:2653
@ RTE_FLOW_ACTION_TYPE_END
Definition: rte_flow.h:2597
__rte_experimental struct rte_flow_pattern_template * rte_flow_pattern_template_create(uint16_t port_id, const struct rte_flow_pattern_template_attr *template_attr, const struct rte_flow_item pattern[], struct rte_flow_error *error)
@ RTE_FLOW_ITEM_TYPE_IPV4
Definition: rte_flow.h:232
@ RTE_FLOW_ITEM_TYPE_END
Definition: rte_flow.h:162
@ RTE_FLOW_ITEM_TYPE_ETH
Definition: rte_flow.h:218
const void * conf
Definition: rte_flow.h:4293
enum rte_flow_action_type type
Definition: rte_flow.h:4292
uint32_t group
Definition: rte_flow.h:100
const char * message
Definition: rte_flow.h:4381
struct rte_ipv4_hdr hdr
Definition: rte_flow.h:960
const void * spec
Definition: rte_flow.h:2129
const void * mask
Definition: rte_flow.h:2131
enum rte_flow_item_type type
Definition: rte_flow.h:2128
struct rte_flow_attr flow_attr
Definition: rte_flow.h:5957