RTE_TARGET ?= x86_64-native-linuxapp-gcc
rte_version_h := $(RTE_SDK)/$(RTE_TARGET)/include/rte_version.h
+rte_config_h := $(RTE_SDK)/$(RTE_TARGET)/include/rte_config.h
rte_ver_part = $(shell sed -n -e 's/^\#define\s*$1\s*\(.*\)$$/\1/p' $(rte_version_h))
+rte_config_part = $(shell sed -n -e 's/^\#define\s*$1\s*\(.*\)$$/\1/p' $(rte_config_h))
rte_ver_eval = $(shell printf '%u' $$(printf '0x%02x%02x%02x%02x' $1 $2 $3 $4))
rte_ver_MMLR = $(call rte_ver_eval,$(call \
rte_ver_part,RTE_VER_MAJOR),$(call \
rte_ver_part,RTE_VER_MINOR),$(call \
rte_ver_part,RTE_VER_PATCH_LEVEL),$(call \
rte_ver_part,RTE_VER_PATCH_RELEASE))
-rte_ver_YMMR = $(call rte_ver_eval,$(call \
+rte_version_YMMR = $(call rte_ver_eval,$(call \
rte_ver_part,RTE_VER_YEAR),$(call \
rte_ver_part,RTE_VER_MONTH),$(call \
rte_ver_part,RTE_VER_MINOR),$(call \
rte_ver_part,RTE_VER_RELEASE))
+rte_config_YMMR = $(call rte_ver_eval,$(call \
+ rte_config_part,RTE_VER_YEAR),$(call \
+ rte_config_part,RTE_VER_MONTH),$(call \
+ rte_config_part,RTE_VER_MINOR),$(call \
+ rte_config_part,RTE_VER_RELEASE))
+rte_ver_YMMR = $(if $(shell test $(rte_config_YMMR) -gt 0 && echo 'y'),$(rte_config_YMMR),$(rte_version_YMMR))
rte_ver_dpdk := $(if $(call rte_ver_part,RTE_VER_MAJOR),$(rte_ver_MMLR),$(rte_ver_YMMR))
rte_ver_comp = $(shell test $(rte_ver_dpdk) $5 $(call rte_ver_eval,$1,$2,$3,$4) && echo 'y')
rte_ver_EQ = $(call rte_ver_comp,$1,$2,$3,$4,-eq)
#include <rte_cycles.h>
#include <rte_ether.h>
+#include <rte_ethdev.h> // required by rte_eth_ctrl.h in 19.05
#include <rte_eth_ctrl.h>
#include "log.h"
#include "lconf.h"
#include "prefetch.h"
#include "etypes.h"
+#include "prox_compat.h"
+#include "handle_sched.h"
struct task_acl {
struct task_base base;
void *field_defs;
size_t field_defs_size;
uint32_t n_field_defs;
+ struct rte_sched_port *sched_port;
};
-static void set_tc(struct rte_mbuf *mbuf, uint32_t tc)
+static void set_tc(struct task_base *tbase, struct rte_mbuf *mbuf, uint32_t tc)
{
+ struct task_acl *task = (struct task_acl *)tbase;
#if RTE_VERSION >= RTE_VERSION_NUM(1,8,0,0)
uint32_t subport, pipe, traffic_class, queue;
- enum rte_meter_color color;
+ enum prox_rte_color color;
- rte_sched_port_pkt_read_tree_path(mbuf, &subport, &pipe, &traffic_class, &queue);
+ prox_rte_sched_port_pkt_read_tree_path(task->sched_port, mbuf, &subport, &pipe, &traffic_class, &queue);
color = rte_sched_port_pkt_read_color(mbuf);
- rte_sched_port_pkt_write(mbuf, subport, pipe, tc, queue, color);
+ prox_rte_sched_port_pkt_write(task->sched_port, mbuf, subport, pipe, tc, queue, color);
#else
struct rte_sched_port_hierarchy *sched =
(struct rte_sched_port_hierarchy *) &mbuf->pkt.hash.sched;
out[i] = 0;
// __attribute__ ((fallthrough));
case ACL_RATE_LIMIT:
- set_tc(mbufs[i], 3);
+ set_tc(tbase, mbufs[i], 3);
break;
};
}
targ->lconf->ctrl_timeout = freq_to_tsc(targ->ctrl_freq);
targ->lconf->ctrl_func_m[targ->task] = acl_msg;
+
+ // If rate limiting is used tc will be set, sched_port must be initialized, and tc will be used by a following policing or qos task
+ int rc = init_port_sched(&task->sched_port, targ);
+
+ // ACL can be used to accept/drop packets and/or to set rate limiting. If using rate limiting, then sched_port must be defined
+ // TODO: check whether rate limiting is configured, and, if yes, check that QoS or policing task configures the qos_conf.params.
+ if (rc)
+ plog_info("Did not find any QoS or Policing task to transmit to => setting tc will not work\n");
}
int str_to_rule(struct acl4_rule *rule, char** fields, int n_rules, int use_qinq)
#include "log.h"
#include "quit.h"
#include "prox_shared.h"
+#include "handle_sched.h"
+#include "prox_compat.h"
struct task_classify {
struct task_base base;
uint16_t *user_table;
uint8_t *dscp;
+ struct rte_sched_port *sched_port;
};
static inline void handle_classify(struct task_classify *task, struct rte_mbuf *mbuf)
uint32_t prev_tc;
#if RTE_VERSION >= RTE_VERSION_NUM(1,8,0,0)
uint32_t dummy;
- rte_sched_port_pkt_read_tree_path(mbuf, &dummy, &dummy, &prev_tc, &dummy);
+ prox_rte_sched_port_pkt_read_tree_path(task->sched_port, mbuf, &dummy, &dummy, &prev_tc, &dummy);
#else
struct rte_sched_port_hierarchy *sched = (struct rte_sched_port_hierarchy *) &mbuf->pkt.hash.sched;
prev_tc = sched->traffic_class;
uint8_t queue = dscp & 0x3;
uint8_t tc = prev_tc? prev_tc : dscp >> 2;
- rte_sched_port_pkt_write(mbuf, 0, task->user_table[qinq], tc, queue, 0);
+ prox_rte_sched_port_pkt_write(task->sched_port, mbuf, 0, task->user_table[qinq], tc, queue, 0);
}
static int handle_classify_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts)
PROX_PANIC(ret, "Failed to create dscp table from config\n");
prox_sh_add_socket(socket_id, targ->dscp, task->dscp);
}
+ int rc = init_port_sched(&task->sched_port, targ);
+ PROX_PANIC(rc, "Did not find any QoS task to transmit to => undefined sched_port parameters\n");
}
static struct task_init task_init_classify = {
#include <rte_tcp.h>
#include <rte_cycles.h>
#include <rte_ether.h>
+#include <rte_ethdev.h> // required by rte_eth_ctrl.h in 19.05
#include <rte_eth_ctrl.h>
#include "log.h"
#include "qinq.h"
#include "prox_cfg.h"
#include "prox_shared.h"
+#include "prox_compat.h"
#if RTE_VERSION < RTE_VERSION_NUM(1,8,0,0)
#define RTE_CACHE_LINE_SIZE CACHE_LINE_SIZE
enum police_action police_act[3][3];
uint16_t overhead;
uint8_t runtime_flags;
+ struct rte_sched_port *sched_port;
};
typedef uint8_t (*hp) (struct task_police *task, struct rte_mbuf *mbuf, uint64_t tsc, uint32_t user);
static uint8_t handle_police(struct task_police *task, struct rte_mbuf *mbuf, uint64_t tsc, uint32_t user)
{
- enum rte_meter_color in_color = e_RTE_METER_GREEN;
- enum rte_meter_color out_color;
+ enum prox_rte_color in_color = RTE_COLOR_GREEN;
+ enum prox_rte_color out_color;
uint32_t pkt_len = rte_pktmbuf_pkt_len(mbuf) + task->overhead;
#if RTE_VERSION < RTE_VERSION_NUM(18,5,0,0)
static uint8_t handle_police_tr(struct task_police *task, struct rte_mbuf *mbuf, uint64_t tsc, uint32_t user)
{
- enum rte_meter_color in_color = e_RTE_METER_GREEN;
- enum rte_meter_color out_color;
+ enum prox_rte_color in_color = RTE_COLOR_GREEN;
+ enum prox_rte_color out_color;
uint32_t pkt_len = rte_pktmbuf_pkt_len(mbuf) + task->overhead;
#if RTE_VERSION < RTE_VERSION_NUM(18,5,0,0)
out_color = rte_meter_trtcm_color_aware_check(&task->tr_flows[user], tsc, pkt_len, in_color);
if (task->runtime_flags & TASK_MARK) {
#if RTE_VERSION >= RTE_VERSION_NUM(1,8,0,0)
uint32_t subport, pipe, traffic_class, queue;
- enum rte_meter_color color;
+ enum prox_rte_color color;
- rte_sched_port_pkt_read_tree_path(mbuf, &subport, &pipe, &traffic_class, &queue);
+ prox_rte_sched_port_pkt_read_tree_path(task->sched_port, mbuf, &subport, &pipe, &traffic_class, &queue);
color = task->police_act[in_color][out_color];
- rte_sched_port_pkt_write(mbuf, subport, pipe, traffic_class, queue, color);
+ prox_rte_sched_port_pkt_write(task->sched_port, mbuf, subport, pipe, traffic_class, queue, color);
#else
struct rte_sched_port_hierarchy *sched =
(struct rte_sched_port_hierarchy *) &mbuf->pkt.hash.sched;
uint32_t dummy;
uint32_t pipe;
- rte_sched_port_pkt_read_tree_path(mbuf, &dummy, &pipe, &dummy, &dummy);
+ prox_rte_sched_port_pkt_read_tree_path(task->sched_port, mbuf, &dummy, &pipe, &dummy, &dummy);
return pipe;
#else
struct rte_sched_port_hierarchy *sched =
prox_sh_add_socket(socket_id, "user_table", task->user_table);
}
+ task->sched_port = rte_sched_port_config(&targ->qos_conf.port_params);
+
if (strcmp(targ->task_init->sub_mode_str, "trtcm")) {
task->sr_flows = prox_zmalloc(targ->n_flows * sizeof(*task->sr_flows), socket_id);
PROX_PANIC(task->sr_flows == NULL, "Failed to allocate flow contexts\n");
}
static struct task_init task_init_police = {
+ .mode = POLICE,
.mode_str = "police",
.init = init_task_police,
.handle = handle_police_bulk,
};
static struct task_init task_init_police2 = {
+ .mode = POLICE,
.mode_str = "police",
.sub_mode_str = "trtcm",
.init = init_task_police,
}
/* task->src_mac[entry->port_idx] = *(uint64_t*)&prox_port_cfg[entry->port_idx].eth_addr; */
+ if (targ->runtime_flags & TASK_CLASSIFY) {
+ int rc = init_port_sched(&task->sched_port, targ);
+ PROX_PANIC(rc, "Did not find any QoS task to transmit to => undefined sched_port parameters\n");
+ }
}
static void arp_msg(struct task_base *tbase, void **data, uint16_t n_msgs)
uint8_t queue = task->dscp[cpe_pkt->ipv4_hdr.type_of_service >> 2] & 0x3;
uint8_t tc = task->dscp[cpe_pkt->ipv4_hdr.type_of_service >> 2] >> 2;
- rte_sched_port_pkt_write(mbuf, 0, entry->user, tc, queue, 0);
+ prox_rte_sched_port_pkt_write(task->sched_port, mbuf, 0, entry->user, tc, queue, 0);
}
#ifdef ENABLE_EXTRA_USER_STATISTICS
task->stats_per_user[entry->user]++;
#include "etypes.h"
#include "mpls.h"
#include "task_init.h"
+#include "handle_sched.h"
struct task_qinq_encap4 {
struct task_base base;
uint32_t *stats_per_user;
uint32_t n_users;
#endif
+ struct rte_sched_port *sched_port;
};
struct qinq_gre_entry {
#include "hash_utils.h"
#include "quit.h"
#include "prox_compat.h"
+#include "handle_sched.h"
struct task_qinq_encap6 {
struct task_base base;
uint8_t tx_portid;
uint8_t runtime_flags;
struct rte_table_hash *cpe_table;
+ struct rte_sched_port *sched_port;
};
static void init_task_qinq_encap6(struct task_base *tbase, struct task_args *targ)
task->qinq_tag = targ->qinq_tag;
task->cpe_table = targ->cpe_table;
task->runtime_flags = targ->runtime_flags;
+ if (task->runtime_flags & TASK_CLASSIFY) {
+ int rc = init_port_sched(&task->sched_port, targ);
+ PROX_PANIC(rc, "Did not find any QoS task to transmit to => undefined sched_port parameters\n");
+ }
}
/* Encapsulate IPv6 packet in QinQ where the QinQ is derived from the IPv6 address */
/* classification can only be done from this point */
if (task->runtime_flags & TASK_CLASSIFY) {
- rte_sched_port_pkt_write(mbuf, 0, entries[0]->user, 0, 0, 0);
+ prox_rte_sched_port_pkt_write(task->sched_port, mbuf, 0, entries[0]->user, 0, 0, 0);
}
return 0;
}
#include "qinq.h"
#include "prox_cfg.h"
#include "prox_shared.h"
+#include "prox_compat.h"
struct task_qos {
struct task_base base;
queue = 0;
tc = 0;
}
-
- rte_sched_port_pkt_write(mbufs[j], 0, task->user_table[qinq], tc, queue, 0);
+ prox_rte_sched_port_pkt_write(task->sched_port, mbufs[j], 0, task->user_table[qinq], tc, queue, 0);
}
#ifdef PROX_PREFETCH_OFFSET
prefetch_nta(rte_pktmbuf_mtod(mbufs[n_pkts - 1], void *));
tc = 0;
}
- rte_sched_port_pkt_write(mbufs[j], 0, task->user_table[qinq], tc, queue, 0);
+ prox_rte_sched_port_pkt_write(task->sched_port, mbufs[j], 0, task->user_table[qinq], tc, queue, 0);
}
#endif
}
}
static struct task_init task_init_qos = {
+ .mode = QOS,
.mode_str = "qos",
.init = init_task_qos,
.handle = handle_qos_bulk,
#include "prox_shared.h"
#include "prox_cksum.h"
#include "mbuf_utils.h"
+#include "prox_compat.h"
struct task_routing {
struct task_base base;
struct mpls_hdr *mpls = (struct mpls_hdr *)(peth + 1);
if (task->runtime_flags & TASK_MARK) {
- enum rte_meter_color color = rte_sched_port_pkt_read_color(mbuf);
-
+ enum prox_rte_color color = rte_sched_port_pkt_read_color(mbuf);
*(uint32_t *)mpls = task->next_hops[nh_idx].mpls | task->marking[color] | 0x00010000; // Set BoS to 1
}
else {
--- /dev/null
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#ifndef _PROX_SCHED_H
+#define _PROX_SCHED_H
+
+#include "task_init.h"
+#include "lconf.h"
+
+static int init_port_sched(struct rte_sched_port **sched_port, struct task_args *targ)
+{
+ *sched_port = NULL;
+#if RTE_VERSION >= RTE_VERSION_NUM(19,2,0,0)
+ for (uint8_t idx = 0; idx < MAX_PROTOCOLS; ++idx) {
+ for (uint8_t ring_idx = 0; ring_idx < targ->core_task_set[idx].n_elems; ++ring_idx) {
+ struct core_task ct = targ->core_task_set[idx].core_task[ring_idx];
+ struct task_args *dtarg = core_targ_get(ct.core, ct.task);
+ enum task_mode dmode = dtarg->mode;
+ if ((dmode == QOS) || (dmode == POLICE)) {
+ // Next task is QOS or POLICE
+ // We use the same configuration as the QoS we are transmitting to
+ *sched_port = rte_sched_port_config(&dtarg->qos_conf.port_params);
+ plog_info("\tInitializing sched_port based on QoS config of core %d task %d\n", ct.core, ct.task);
+ return 0;
+ }
+ }
+ }
+ return -1;
+#endif
+ return 0;
+}
+#endif
// See the License for the specific language governing permissions and
// limitations under the License.
*/
+
+#ifndef _PROX_COMPAT_H_
+#define _PROX_COMPAT_H_
#include <rte_common.h>
#include <rte_table_hash.h>
#include <rte_hash_crc.h>
#define DEV_RX_OFFLOAD_JUMBO_FRAME 0x00000800
#endif
+#if RTE_VERSION < RTE_VERSION_NUM(19,2,0,0)
+#define RTE_COLOR_GREEN e_RTE_METER_GREEN
+#define RTE_COLOR_YELLOW e_RTE_METER_YELLOW
+#define RTE_COLOR_RED e_RTE_METER_RED
+#define prox_rte_color rte_meter_color
+#define prox_rte_sched_port_pkt_read_tree_path(A,B,C,D,E,F) rte_sched_port_pkt_read_tree_path(B,C,D,E,F)
+#define prox_rte_sched_port_pkt_write(A,B,C,D,E,F,G) rte_sched_port_pkt_write(B,C,D,E,F,G);
+#else
+#define prox_rte_color rte_color
+#define prox_rte_sched_port_pkt_read_tree_path(A,B,C,D,E,F) rte_sched_port_pkt_read_tree_path(A,B,C,D,E,F)
+#define prox_rte_sched_port_pkt_write(A,B,C,D,E,F,G) rte_sched_port_pkt_write(A,B,C,D,E,F,G);
+#endif
+
static inline char *prox_strncpy(char * dest, const char * src, size_t count)
{
#pragma GCC diagnostic push
PROX_PANIC(dest[count - 1] != 0, "\t\tError in strncpy: buffer overrun (%lu bytes)", count);
return dest;
}
+#endif // _PROX_COMPAT_H
#include "ip6_addr.h"
#include "flow_iter.h"
#include "parse_utils.h"
+#include "prox_compat.h"
struct rte_mbuf;
struct lcore_cfg;
};
enum task_mode {NOT_SET, MASTER, QINQ_DECAP4, QINQ_DECAP6,
- QINQ_ENCAP4, QINQ_ENCAP6, GRE_DECAP, GRE_ENCAP,CGNAT, ESP_ENC, ESP_DEC,
+ QINQ_ENCAP4, QINQ_ENCAP6, GRE_DECAP, GRE_ENCAP,CGNAT, ESP_ENC, ESP_DEC, QOS, POLICE
};
struct task_args;
}
enum police_action {
- ACT_GREEN = e_RTE_METER_GREEN,
- ACT_YELLOW = e_RTE_METER_YELLOW,
- ACT_RED = e_RTE_METER_RED,
+ ACT_GREEN = RTE_COLOR_GREEN,
+ ACT_YELLOW = RTE_COLOR_YELLOW,
+ ACT_RED = RTE_COLOR_RED,
ACT_DROP = 3,
ACT_INVALID = 4
};