26 #include <rte_cycles.h>
27 #include <rte_ethdev.h>
28 #include <rte_ether.h>
42 #define UPF_ACCEL_MAX_PKT_BURST 32
44 #define UPF_ACCEL_MAX_NUM_AGING (UPF_ACCEL_MAX_PKT_BURST * 2)
46 #define UPF_ACCEL_DOCA_FLOW_MAX_TIMEOUT_US (0)
61 "Can't process a burst larger than RTE bulk size limit");
120 struct doca_flow_pipe_entry *
entry,
166 *entry_status = status;
209 DOCA_LOG_ERR(
"UPF accel static entry cb - bad op %u", op);
342 node->
next = old_head;
386 uint64_t tsc = rte_rdtsc();
394 if (tsc - node->
timestamp < aging_period_tsc)
429 return ~((1ul << (32 - mask)) - 1);
500 DOCA_LOG_DBG(
"Only support GTPU encapsulation with UDP over IPv4 and GTPU-reserved destination port");
631 for (i = 0; i < pdrs->
num_pdrs; i++) {
657 struct rte_ether_hdr *
eth =
NULL;
659 rte_pktmbuf_adj(pkt, parse_ctx->
len - parse_ctx->
inner.
len -
sizeof(*
eth));
661 eth = rte_pktmbuf_mtod(pkt,
struct rte_ether_hdr *);
662 eth->ether_type = RTE_BE16(RTE_ETHER_TYPE_IPV4);
663 SET_MAC_ADDR(
eth->src_addr.addr_bytes, src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5]);
664 SET_MAC_ADDR(
eth->dst_addr.addr_bytes, dst_mac[0], dst_mac[1], dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]);
680 for (i = 0; i < pdrs->
num_pdrs; i++) {
712 struct doca_flow_pipe_entry **
entry)
719 struct doca_flow_pipe *pipe;
779 struct doca_flow_pipe_entry **
entry)
824 struct rte_mbuf *pkt,
828 uint8_t *data_beg = rte_pktmbuf_mtod(pkt, uint8_t *);
829 uint8_t *data_end = data_beg + rte_pktmbuf_data_len(pkt);
832 memset(match, 0,
sizeof(*match));
837 DOCA_LOG_DBG(
"Failed to parse RAN packet status %u", ret);
843 DOCA_LOG_DBG(
"Failed to parse WAN packet status %u", ret);
859 const uint32_t md = *RTE_FLOW_DYNF_METADATA(pkt);
880 burst_ctx->
matches[i] = &match_mem[i];
923 DOCA_LOG_DBG(
"Failed to lookup PDR for packet type %u", pkt_type);
958 conn_idx = rte_hash_add_key_with_hash(fp_data->
dyn_tbl, &match->
inner, hash);
961 DOCA_LOG_DBG(
"Couldn't create flow, No space available in the ht, err %d", conn_idx);
966 memset(conn, 0,
sizeof(*conn));
981 DOCA_LOG_DBG(
"Detected packet with same 5tuple as connection with different tunnel");
1015 int32_t conn_idxs[RTE_HASH_LOOKUP_BULK_MAX];
1023 err = rte_hash_lookup_bulk(fp_data->
dyn_tbl,
1024 (
const void **)burst_ctx->
matches,
1038 &burst_ctx->
conns[i]);
1096 DOCA_LOG_DBG(
"Failed to accelerate connection on port %u, type %u.", port_id, pkt_type);
1111 ctr->
bytes += rte_pktmbuf_pkt_len(pkt);
1127 struct rte_mbuf *pkt;
1135 conn = burst_ctx->
conns[i];
1141 DOCA_LOG_DBG(
"Got a sneaker packet on core %u, port %u, type %u.",
1165 rte_pktmbuf_free(pkt);
1177 *RTE_FLOW_DYNF_METADATA(pkt) = md;
1178 pkt->ol_flags |= RTE_MBUF_DYNFLAG_TX_METADATA;
1205 struct rte_mbuf *pkt;
1210 conn = burst_ctx->
conns[i];
1211 match = burst_ctx->
matches[i];
1220 "Core %u, type %u parsed 8t tun_ip=%x teid=%u qfi=%hhu ue_ip=%x extern_ip=%x ue_port=%hu extern_port=%hu ip_proto=%hhu pdr=%u ran_pkts=%lu ran_bytes=%lu, wan_pkts=%lu, wan_bytes=%lu",
1257 for (port_id = 0; port_id < fp_data->
ctx->
num_ports; port_id++)
1274 int num_aged_entries;
1278 DOCA_LOG_ERR(
"In core %d port %d: couldn't finish HW aging, continuing...",
1291 if (num_aged_entries == -1)
1294 DOCA_LOG_DBG(
"In core %d port %d: num of aged entries: %d",
1361 for (port_id = 0; port_id < fp_data->
ctx->
num_ports; port_id++)
1405 size_t cntrs_num = shared_counter_ids->
cntrs_num;
1414 for (port_id = 0; port_id < fp_data->
ctx->
num_ports; ++port_id) {
1416 shared_counter_ids->
ids[port_id],
1417 query_results_array,
1424 for (i = 0; i < cntrs_num; ++i) {
1425 pdr_id = shared_counter_ids->
cntr_0 + i;
#define SET_MAC_ADDR(addr, a, b, c, d, e, f)
static struct doca_flow_actions actions
static struct doca_flow_pipe_entry * entry[MAX_ENTRIES]
static volatile bool force_quit
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
@ DOCA_ERROR_INVALID_VALUE
@ DOCA_ERROR_NOT_SUPPORTED
@ DOCA_ERROR_ALREADY_EXIST
#define DOCA_FLOW_PROTO_UDP
#define DOCA_FLOW_PROTO_TCP
#define DOCA_FLOW_GTPU_DEFAULT_PORT
DOCA_STABLE doca_error_t doca_flow_entries_process(struct doca_flow_port *port, uint16_t pipe_queue, uint64_t timeout, uint32_t max_processed_entries)
Process entries in queue.
doca_flow_entry_op
doca flow entry operation
DOCA_STABLE int doca_flow_aging_handle(struct doca_flow_port *port, uint16_t queue, uint64_t quota, uint64_t max_entries)
Handle aging of entries.
DOCA_EXPERIMENTAL doca_error_t doca_flow_pipe_add_entry(uint16_t pipe_queue, struct doca_flow_pipe *pipe, const struct doca_flow_match *match, const struct doca_flow_actions *actions, const struct doca_flow_monitor *monitor, const struct doca_flow_fwd *fwd, uint32_t flags, void *usr_ctx, struct doca_flow_pipe_entry **entry)
Add one new entry to a pipe.
DOCA_STABLE doca_error_t doca_flow_pipe_remove_entry(uint16_t pipe_queue, uint32_t flags, struct doca_flow_pipe_entry *entry)
Free one pipe entry.
doca_flow_entry_status
doca flow entry status
DOCA_EXPERIMENTAL doca_error_t doca_flow_shared_resources_query(enum doca_flow_shared_resource_type type, uint32_t *res_array, struct doca_flow_resource_query *query_results_array, uint32_t array_len)
Extract information about shared counter.
@ DOCA_FLOW_SHARED_RESOURCE_COUNTER
@ DOCA_FLOW_ENTRY_OP_AGED
@ DOCA_FLOW_WAIT_FOR_BATCH
@ DOCA_FLOW_ENTRY_STATUS_SUCCESS
@ DOCA_FLOW_ENTRY_STATUS_ERROR
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
#define DOCA_LOG_WARN(format,...)
Generates a WARNING application log message.
#define DOCA_LOG_DBG(format,...)
Generates a DEBUG application log message.
doca_error_t tunnel_parse(uint8_t *data, uint8_t *data_end, struct tun_parser_ctx *ctx)
doca_error_t plain_parse(uint8_t *data, uint8_t *data_end, struct conn_parser_ctx *ctx)
@ PARSER_PKT_TYPE_TUNNELED
uint32_t * ids[UPF_ACCEL_PORTS_MAX]
struct network_parser_ctx network_ctx
struct transport_parser_ctx transport_ctx
doca flow actions information
doca flow matcher information
struct doca_flow_header_format inner
struct doca_flow_header_format outer
struct doca_flow_resource_query::@115::@117 counter
user context struct that will be used in entries process callback
struct rte_gtp_psc_type0_hdr * ext_hdr
struct rte_gtp_hdr * gtp_hdr
struct rte_ipv4_hdr * ipv4_hdr
struct rte_udp_hdr * udp_hdr
struct rte_tcp_hdr * tcp_hdr
struct link_parser_ctx link_ctx
struct transport_parser_ctx transport_ctx
struct conn_parser_ctx inner
struct network_parser_ctx network_ctx
struct gtp_parser_ctx gtp_ctx
struct upf_accel_pdrs * pdrs
uint32_t sw_aging_time_sec
struct upf_accel_urrs * urrs
upf_accel_get_forwarding_port get_fwd_port
struct doca_flow_pipe * pipes[UPF_ACCEL_PORTS_MAX][UPF_ACCEL_PIPE_NUM]
struct doca_flow_port * ports[UPF_ACCEL_PORTS_MAX]
const struct upf_accel_config * upf_accel_cfg
uint64_t cnt_pkts[PARSER_PKT_TYPE_NUM]
struct upf_accel_match_8t match
uint32_t pdr_id[PARSER_PKT_TYPE_NUM]
struct doca_flow_pipe_entry * entry
struct upf_accel_fp_data * fp_data
uint64_t cnt_bytes[PARSER_PKT_TYPE_NUM]
union upf_accel_dyn_entry_ctx::@47 entries[PARSER_PKT_TYPE_NUM]
enum doca_flow_entry_status status
struct upf_accel_sw_aging_ll_node sw_aging_node
enum upf_accel_flow_status flow_status[PARSER_PKT_TYPE_NUM]
struct upf_accel_dyn_entry_ctx dyn_ctx
enum parser_pkt_type pkts_type[UPF_ACCEL_MAX_PKT_BURST]
struct tun_parser_ctx parse_ctxs[UPF_ACCEL_MAX_PKT_BURST]
struct rte_mbuf * tx_pkts[UPF_ACCEL_MAX_PKT_BURST]
bool pkts_drop[UPF_ACCEL_MAX_PKT_BURST]
struct rte_mbuf * rx_pkts[UPF_ACCEL_MAX_PKT_BURST]
struct upf_accel_entry_ctx * conns[UPF_ACCEL_MAX_PKT_BURST]
struct upf_accel_match_8t * matches[UPF_ACCEL_MAX_PKT_BURST]
struct upf_accel_fp_accel_counters accel_failed_counters[PARSER_PKT_TYPE_NUM]
bool hw_aging_in_progress[UPF_ACCEL_PORTS_MAX]
struct upf_accel_entry_ctx * dyn_tbl_data
struct rte_hash * dyn_tbl
struct upf_accel_ctx * ctx
struct app_shared_counter_ids quota_cntrs
struct upf_accel_fp_sw_counters sw_counters
uint64_t last_hw_aging_tsc[UPF_ACCEL_PORTS_MAX]
struct upf_accel_sw_aging_ll sw_aging_ll[PARSER_PKT_TYPE_NUM]
struct upf_accel_fp_accel_counters accel_counters[PARSER_PKT_TYPE_NUM]
struct upf_accel_fp_accel_counters unaccel_counters[PARSER_PKT_TYPE_NUM]
struct upf_accel_packet_byte_counter new_conn
struct upf_accel_packet_byte_counter err
struct upf_accel_packet_byte_counter ex_conn
struct upf_accel_match_5t inner
struct upf_accel_match_tun outer
struct upf_accel_ip_addr pdi_sdf_to_ip
struct upf_accel_ip_addr pdi_local_teid_ip
struct upf_accel_ip_addr pdi_sdf_from_ip
uint32_t pdi_local_teid_start
uint32_t pdi_local_teid_end
struct upf_accel_ip_addr pdi_ueip
uint32_t urrids[UPF_ACCEL_PDR_URRIDS_LEN]
struct upf_accel_ip_port_range pdi_sdf_from_port_range
enum upf_accel_pdr_pdi_si pdi_si
struct upf_accel_ip_port_range pdi_sdf_to_port_range
struct upf_accel_pdr arr_pdrs[]
struct entries_status ctrl_status
uint64_t volume_quota_total_volume
struct upf_accel_urr arr_urrs[]
@ UPF_ACCEL_FLOW_STATUS_UNACCELERATED
@ UPF_ACCEL_FLOW_STATUS_FAILED_ACCELERATION
@ UPF_ACCEL_FLOW_STATUS_ACCELERATED
@ UPF_ACCEL_FLOW_STATUS_PENDING
@ UPF_ACCEL_FLOW_STATUS_NONE
#define UPF_ACCEL_SRC_MAC
#define UPF_ACCEL_HW_AGING_POLL_INTERVAL_SEC
#define UPF_ACCEL_META_PKT_DIR_UL
struct upf_accel_dyn_entry_ctx dyn_ctx
#define UPF_ACCEL_DST_MAC
#define UPF_ACCEL_MAX_NUM_PDR
#define UPF_ACCEL_META_PKT_DIR_DL
#define UPF_ACCEL_META_PKT_DIR_MASK
struct upf_accel_static_entry_ctx static_ctx
@ UPF_ACCEL_PDR_PDI_SI_DL
@ UPF_ACCEL_PDR_PDI_SI_UL
void upf_accel_sw_aging_ll_init(struct upf_accel_fp_data *fp_data, enum parser_pkt_type pkt_type)
static bool upf_accel_fp_tunnel_eq(struct upf_accel_match_tun *tunnel1, struct upf_accel_match_tun *tunnel2)
static doca_error_t handle_exceeds_quotas(struct upf_accel_fp_data *fp_data)
DOCA_LOG_REGISTER(UPF_ACCEL::FLOW_PROCESSING)
static void upf_accel_sw_aging_ll_node_insert(struct upf_accel_fp_data *fp_data, struct upf_accel_entry_ctx *conn, enum parser_pkt_type pkt_type)
static const struct upf_accel_pdr * upf_accel_wan_pdr_lookup(const struct upf_accel_pdrs *pdrs, const struct upf_accel_match_5t *match)
static void upf_accel_static_entry_cb(struct upf_accel_static_entry_ctx *static_ctx, enum doca_flow_entry_status status, enum doca_flow_entry_op op)
static void upf_accel_decap(struct rte_mbuf *pkt, struct tun_parser_ctx *parse_ctx)
static bool ipv4_masked_is_matching(const struct upf_accel_ip_addr *masked, uint32_t ipv4)
static doca_error_t upf_accel_fp_flow_accel(struct upf_accel_fp_data *fp_data, enum upf_accel_port port_id, enum parser_pkt_type pkt_type, struct upf_accel_match_8t *match, struct upf_accel_entry_ctx *conn)
static doca_error_t upf_accel_fp_pkt_match(enum parser_pkt_type pkt_type, struct rte_mbuf *pkt, struct upf_accel_match_8t *match, struct tun_parser_ctx *parse_ctx)
static const struct upf_accel_pdr * upf_accel_ran_pdr_lookup(const struct upf_accel_pdrs *pdrs, const struct upf_accel_match_8t *match)
static enum parser_pkt_type upf_accel_fp_fetch_pkt_type(const struct rte_mbuf *pkt)
static doca_error_t upf_accel_fp_delete_flow(struct upf_accel_fp_data *fp_data, struct upf_accel_dyn_entry_ctx *dyn_ctx, enum parser_pkt_type pkt_type)
static bool upf_accel_pdr_tunnel_is_matching(const struct upf_accel_pdr *pdr, const struct upf_accel_match_tun *match)
static void upf_accel_packet_byte_counter_inc(struct upf_accel_packet_byte_counter *ctr, struct rte_mbuf *pkt)
static void upf_accel_fp_pkt_err_drop(struct upf_accel_fp_data *fp_data, struct rte_mbuf *pkt)
static doca_error_t upf_accel_fp_conn_lookup(struct upf_accel_fp_data *fp_data, enum parser_pkt_type pkt_type, struct upf_accel_match_8t *match, int32_t conn_idx, struct upf_accel_entry_ctx **conn_out)
static void upf_accel_fp_conns_lookup(struct upf_accel_fp_data *fp_data, struct upf_accel_fp_burst_ctx *burst_ctx)
static void upf_accel_sw_aging_ll_scan(struct upf_accel_fp_data *fp_data, enum parser_pkt_type pkt_type)
struct upf_accel_fp_burst_ctx __rte_aligned(RTE_CACHE_LINE_SIZE)
static doca_error_t handle_exceeds_quota_for_pdr(struct upf_accel_ctx *ctx, uint16_t pdr_id, struct doca_flow_resource_query *query)
static void upf_accel_dyn_entry_cb(struct upf_accel_dyn_entry_ctx *dyn_ctx, struct doca_flow_pipe_entry *entry, uint16_t pipe_queue, enum doca_flow_entry_status status, enum doca_flow_entry_op op)
static bool upf_accel_pdr_tuple_is_matching(const struct upf_accel_pdr *pdr, const struct upf_accel_match_5t *match)
static bool upf_accel_sw_aging_ll_node_remove(struct upf_accel_fp_data *fp_data, struct upf_accel_entry_ctx *conn, enum parser_pkt_type pkt_type)
#define UPF_ACCEL_MAX_NUM_AGING
void upf_accel_check_for_valid_entry_aging(struct doca_flow_pipe_entry *entry, uint16_t pipe_queue, enum doca_flow_entry_status status, enum doca_flow_entry_op op, void *user_ctx)
static uint32_t ipv4_netmask_get(uint8_t mask)
static bool upf_accel_sw_aging_ll_node_is_valid(int32_t node_idx)
static bool upf_accel_sw_aging_ll_node_exist(struct upf_accel_fp_data *fp_data, struct upf_accel_entry_ctx *conn, enum parser_pkt_type pkt_type)
static void upf_accel_fp_run_port(struct upf_accel_fp_data *fp_data, enum upf_accel_port rx_port_id, enum upf_accel_port tx_port_id)
static doca_error_t upf_accel_pipe_8t_accel(struct upf_accel_ctx *ctx, enum upf_accel_port port_id, uint16_t queue_id, struct upf_accel_match_8t *match, uint32_t pdr_id, struct upf_accel_entry_ctx *entry_ctx, struct doca_flow_pipe_entry **entry)
#define UPF_ACCEL_MAX_PKT_BURST
static void upf_accel_fp_pkts_match(struct upf_accel_fp_burst_ctx *burst_ctx, struct upf_accel_match_8t match_mem[])
static doca_error_t upf_accel_ran_match(uint8_t *data, uint8_t *data_end, struct tun_parser_ctx *parse_ctx, struct upf_accel_match_8t *match)
void upf_accel_fp_loop(struct upf_accel_fp_data *fp_data)
static void upf_accel_fp_run(struct upf_accel_fp_data *fp_data)
static void upf_accel_fp_flows_accel(struct upf_accel_fp_data *fp_data, enum upf_accel_port rx_port_id, struct upf_accel_fp_burst_ctx *burst_ctx)
static void upf_accel_sw_aging_ll_node_move_to_head(struct upf_accel_fp_data *fp_data, struct upf_accel_entry_ctx *conn, enum parser_pkt_type pkt_type)
static void upf_accel_sw_aging_ll_node_init(struct upf_accel_entry_ctx *conn, enum parser_pkt_type pkt_type)
static doca_error_t upf_accel_wan_match(uint8_t *data, uint8_t *data_end, struct conn_parser_ctx *parse_ctx, struct upf_accel_match_5t *match)
static doca_error_t upf_accel_hw_aging_poll(struct upf_accel_fp_data *fp_data, enum upf_accel_port port_id)
static doca_error_t upf_accel_fp_pdr_lookup(struct upf_accel_fp_data *fp_data, enum parser_pkt_type pkt_type, struct upf_accel_match_8t *match, const struct upf_accel_pdr **pdr_out)
static doca_error_t upf_accel_5t_match(struct conn_parser_ctx *parse_ctx, uint32_t *src_ip, uint32_t *dst_ip, uint16_t *src_port, uint16_t *dst_port, uint8_t *ip_proto)
static bool upf_accel_flow_is_alive(enum upf_accel_flow_status flow_status)
static void upf_accel_aging_init(struct upf_accel_fp_data *fp_data)
static doca_error_t upf_accel_gtpu_match(struct tun_parser_ctx *tun_parse_ctx, struct upf_accel_match_8t *match)
static bool is_flow_unaccelerated(enum parser_pkt_type pkt_type, struct upf_accel_entry_ctx *conn)
static enum parser_pkt_type upf_accel_fp_get_opposite_pkt_type(enum parser_pkt_type pkt_type)
static doca_error_t upf_accel_pipe_5t_accel(struct upf_accel_ctx *ctx, enum upf_accel_port port_id, uint16_t queue_id, struct upf_accel_match_5t *match, uint32_t pdr_id, struct upf_accel_entry_ctx *entry_ctx, struct doca_flow_pipe_entry **entry)
static void upf_accel_fp_burst_postprocess(struct upf_accel_fp_data *fp_data, struct upf_accel_fp_burst_ctx *burst_ctx)
static void upf_accel_md_set(struct rte_mbuf *pkt, uint32_t md)
#define UPF_ACCEL_DOCA_FLOW_MAX_TIMEOUT_US
struct upf_accel_ctx * ctx
#define UPF_ACCEL_SW_AGING_LL_INVALID_NODE
struct upf_accel_fp_accel_counters accel_counters[PARSER_PKT_TYPE_NUM]