Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vf offload dump draft #371

Merged
merged 11 commits into from
Sep 22, 2023
2 changes: 2 additions & 0 deletions include/dp_cntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
extern "C" {
#endif

#define DP_IS_CAPTURED_HW_PKT 5

void dp_cntrack_init(void);

int dp_cntrack_handle(struct rte_node *node, struct rte_mbuf *m, struct dp_flow *df);
Expand Down
1 change: 1 addition & 0 deletions include/dp_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ extern "C" {
#define DP_LOG_SOCKID(VALUE) _DP_LOG_UINT("socket_id", VALUE)
#define DP_LOG_IFNAME(VALUE) _DP_LOG_STR("interface_name", VALUE)
#define DP_LOG_LCORE(VALUE) _DP_LOG_UINT("lcore_id", VALUE)
#define DP_LOG_RTE_GROUP(VALUE) _DP_LOG_UINT("rte_group", VALUE)
// networking stack
#define DP_LOG_IPV4(VALUE) _DP_LOG_IPV4("ipv4", VALUE)
#define DP_LOG_IPV6(VALUE) _DP_LOG_IPV6("ipv6", VALUE)
Expand Down
1 change: 1 addition & 0 deletions include/dp_mbuf_dyn.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct dp_flow {
uint16_t offload_ipv6 : 1; // tmp solution to set if we should offload ipv6 pkts
uint16_t dir : 2; // store the direction of each packet
uint16_t offload_decision: 2; // store the offload status of each packet
uint16_t offload_mark: 1; // store the offload mark of each packet
} flags;
uint16_t l3_type; //layer-3 for inner packets. it can be crafted or extracted from raw frames
union {
Expand Down
1 change: 1 addition & 0 deletions include/dp_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct dp_port {
uint8_t peer_pf_hairpin_tx_rx_queue_offset;
uint16_t peer_pf_port_id;
enum dp_vf_port_attach_status attach_status;
struct rte_flow *default_flow;
};

struct dp_ports {
Expand Down
5 changes: 5 additions & 0 deletions include/monitoring/dp_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ int dp_link_status_change_event_callback(uint16_t port_id,
void dp_process_event_link_msg(struct rte_mbuf *m);

int dp_send_event_flow_aging_msg(void);
int dp_send_event_hardware_capture_start_msg(void);
int dp_send_event_hardware_capture_stop_msg(void);

void dp_process_event_flow_aging_msg(struct rte_mbuf *m);
void dp_process_event_hardware_capture_start_msg(struct rte_mbuf *m);
void dp_process_event_hardware_capture_stop_msg(struct rte_mbuf *m);

#ifdef __cplusplus
}
Expand Down
18 changes: 14 additions & 4 deletions include/monitoring/dp_graphtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ enum dp_graphtrace_loglevel {
int dp_graphtrace_init(void);
void dp_graphtrace_free(void);

void _dp_graphtrace_send(struct rte_node *node, struct rte_node *next_node, void **objs, uint16_t nb_objs);
void _dp_graphtrace_send(enum dp_graphtrace_pkt_type type, struct rte_node *node, struct rte_node *next_node, void **objs, uint16_t nb_objs);

// Logging the trace for debugging
#ifdef ENABLE_PYTEST
Expand All @@ -45,25 +45,30 @@ extern bool _dp_graphtrace_enabled;
static __rte_always_inline void dp_graphtrace_next(struct rte_node *node, void *obj, rte_edge_t next_index)
{
if (_dp_graphtrace_enabled)
_dp_graphtrace_send(node, node->nodes[next_index], &obj, 1);
_dp_graphtrace_send(DP_GRAPHTRACE_PKT_TYPE_SOFTWARE, node, node->nodes[next_index], &obj, 1);
_dp_graphtrace_log_next(node, obj, next_index);
}

static __rte_always_inline void dp_graphtrace_next_burst(struct rte_node *node, void **objs, uint16_t nb_objs, rte_edge_t next_index)
{
if (_dp_graphtrace_enabled)
_dp_graphtrace_send(node, node->nodes[next_index], objs, nb_objs);
_dp_graphtrace_send(DP_GRAPHTRACE_PKT_TYPE_SOFTWARE, node, node->nodes[next_index], objs, nb_objs);
_dp_graphtrace_log_next_burst(node, objs, nb_objs, next_index);
}

static __rte_always_inline void dp_graphtrace_tx_burst(struct rte_node *node, void **objs, uint16_t nb_objs, uint16_t port_id)
{
if (_dp_graphtrace_enabled)
_dp_graphtrace_send(node, NULL, objs, nb_objs);
_dp_graphtrace_send(DP_GRAPHTRACE_PKT_TYPE_SOFTWARE, node, NULL, objs, nb_objs);
RTE_SET_USED(port_id);
_dp_graphtrace_log_tx_burst(node, objs, nb_objs, port_id);
}

static __rte_always_inline void dp_graphtrace_capture_offload_pkt(void *obj)
{
_dp_graphtrace_send(DP_GRAPHTRACE_PKT_TYPE_OFFLOAD, NULL, NULL, &obj, 1);
}

static __rte_always_inline void dp_graphtrace_enable(void)
{
_dp_graphtrace_enabled = true;
Expand All @@ -74,6 +79,11 @@ static __rte_always_inline void dp_graphtrace_disable(void)
_dp_graphtrace_enabled = false;
}

static __rte_always_inline bool dp_graphtrace_is_enabled(void)
{
return _dp_graphtrace_enabled;
}

#ifdef __cplusplus
}
#endif
Expand Down
17 changes: 15 additions & 2 deletions include/monitoring/dp_graphtrace_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,37 @@ extern "C" {
#endif

enum dp_graphtrace_action {
DP_GRAPHTRACE_ACTION_NULL,
DP_GRAPHTRACE_ACTION_START,
DP_GRAPHTRACE_ACTION_STOP,
};

enum dp_graphtrace_op_type {
DP_GRAPHTRACE_OP_TYPE_SOFTWARE,
DP_GRAPHTRACE_OP_TYPE_OFFLOAD,
};

enum dp_graphtrace_pkt_type {
DP_GRAPHTRACE_PKT_TYPE_SOFTWARE,
DP_GRAPHTRACE_PKT_TYPE_OFFLOAD,
};

struct dp_graphtrace {
struct rte_mempool *mempool;
struct rte_ring *ringbuf;
};

struct dp_graphtrace_pktinfo {
enum dp_graphtrace_pkt_type pkt_type;
uint32_t pktid;
struct rte_node *node;
struct rte_node *next_node;
};

struct dp_graphtrace_mp_request {
uint8_t action;
enum dp_graphtrace_action action;
union {
enum dp_graphtrace_op_type op_type;
} action_params;
};

struct dp_graphtrace_mp_reply {
Expand Down
18 changes: 7 additions & 11 deletions include/monitoring/dp_monitoring.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@
extern "C" {
#endif

enum dp_status_type {
DP_STATUS_TYPE_UNKNOWN,
DP_STATUS_TYPE_LINK,
DP_STATUS_TYPE_FLOW_AGING,
};

enum dp_status_scope {
DP_STATUS_SCOPE_LOCAL,
DP_STATUS_SCOPE_REMOTE,
enum dp_event_type {
DP_EVENT_TYPE_UNKNOWN,
DP_EVENT_TYPE_LINK_STATUS,
DP_EVENT_TYPE_FLOW_AGING,
DP_EVENT_TYPE_HARDWARE_CAPTURE_START,
DP_EVENT_TYPE_HARDWARE_CAPTURE_STOP,
};

struct dp_event_msg_head {
enum dp_status_type type;
enum dp_status_scope scope;
enum dp_event_type type;
};

struct dp_link_status {
Expand Down
6 changes: 6 additions & 0 deletions include/rte_flow/dp_rte_flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ extern "C"
#define DP_IP_ICMP_CODE_DST_PORT_UNREACHABLE 3
#define DP_IP_ICMP_CODE_FRAGMENT_NEEDED 4

enum {
DP_RTE_FLOW_DEFAULT_GROUP,
DP_RTE_FLOW_MONITORING_GROUP,
DP_RTE_FLOW_VNET_GROUP,
};

struct dp_icmp_err_ip_info {
struct rte_ipv4_hdr *err_ipv4_hdr;
rte_be16_t l4_src_port;
Expand Down
32 changes: 32 additions & 0 deletions include/rte_flow/dp_rte_flow_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ extern "C"
{
#endif

#define DP_PKT_OFFLOAD_MARK 1

#define DP_TCP_CONTROL_FLAGS \
(RTE_TCP_FIN_FLAG|RTE_TCP_SYN_FLAG|RTE_TCP_RST_FLAG)

Expand Down Expand Up @@ -91,6 +93,15 @@ static const struct rte_flow_item_icmp6 dp_flow_item_icmp6_mask = {
.type = 0xff,
};

static __rte_always_inline
void dp_set_eth_match_all_item(struct rte_flow_item *item)
{
item->type = RTE_FLOW_ITEM_TYPE_ETH;
item->spec = NULL;
item->mask = NULL;
item->last = NULL;
}

static __rte_always_inline
void dp_set_eth_flow_item(struct rte_flow_item *item,
struct rte_flow_item_eth *eth_spec,
Expand Down Expand Up @@ -533,6 +544,27 @@ void dp_set_set_meta_action(struct rte_flow_action *action,
action->conf = meta_action;
}

static __rte_always_inline
void dp_set_sample_action(struct rte_flow_action *action,
struct rte_flow_action_sample *sample_action,
uint32_t sample_ratio, struct rte_flow_action *sub_action)
{
sample_action->ratio = sample_ratio;
sample_action->actions = sub_action; // it seems that driver does not support null sub action
action->type = RTE_FLOW_ACTION_TYPE_SAMPLE;
action->conf = sample_action;
}

static __rte_always_inline
void dp_set_jump_group_action(struct rte_flow_action *action,
struct rte_flow_action_jump *jump_action,
uint32_t group_id)
{
jump_action->group = group_id;
action->type = RTE_FLOW_ACTION_TYPE_JUMP;
action->conf = jump_action;
}

static __rte_always_inline
void dp_set_end_action(struct rte_flow_action *action)
{
Expand Down
8 changes: 8 additions & 0 deletions include/rte_flow/dp_rte_flow_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ extern "C" {
#include <stdint.h>

int dp_install_isolated_mode_ipip(int port_id, uint8_t proto_id);

int dp_install_jump_rule_in_default_group(uint16_t port_id, uint32_t group_id);
int dp_install_default_rule_in_monitoring_group(uint16_t port_id);
int dp_install_default_capture_rule_in_vnet_group(uint16_t port_id);

int dp_turn_on_vf_offload_tracing(void);
int dp_turn_off_vf_offload_tracing(void);

#ifdef ENABLE_VIRTSVC
int dp_install_isolated_mode_virtsvc(int port_id, uint8_t proto_id, uint8_t svc_ipv6[16], uint16_t svc_port);
#endif
Expand Down
23 changes: 21 additions & 2 deletions src/dp_cntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "dp_log.h"
#include "dp_vnf.h"
#include "rte_flow/dp_rte_flow.h"
#include "rte_flow/dp_rte_flow_helpers.h"
#include "monitoring/dp_graphtrace.h"

static struct flow_key key_cache[2];
static int key_cache_index = 0;
Expand Down Expand Up @@ -75,6 +77,18 @@ static __rte_always_inline void dp_cntrack_tcp_state(struct flow_value *flow_val

}

static __rte_always_inline bool dp_capture_offloaded_pkts(struct rte_mbuf *m, struct flow_value *flow_val, struct dp_flow *df)
{
if (!offload_mode_enabled ||
flow_val->offload_flags.orig == DP_FLOW_NON_OFFLOAD || flow_val->offload_flags.reply == DP_FLOW_NON_OFFLOAD)
return false;

dp_graphtrace_capture_offload_pkt(m);
df->flags.offload_mark = DP_PKT_OFFLOAD_MARK;
return true;

}
byteocean marked this conversation as resolved.
Show resolved Hide resolved

static __rte_always_inline void dp_cntrack_init_flow_offload_flags(struct flow_value *flow_val, struct dp_flow *df)
{
if (!offload_mode_enabled)
Expand Down Expand Up @@ -247,6 +261,8 @@ static __rte_always_inline int dp_get_flow_val(struct rte_mbuf *m, struct dp_flo
) {
// flow is the same as it was for the previous packet
*p_flow_val = cached_flow_val;
if (dp_capture_offloaded_pkts(m, *p_flow_val, df))
return DP_IS_CAPTURED_HW_PKT;
dp_set_pkt_flow_direction(curr_key, cached_flow_val, df);
dp_set_flow_offload_flag(m, cached_flow_val, df);
return DP_OK;
Expand All @@ -269,6 +285,9 @@ static __rte_always_inline int dp_get_flow_val(struct rte_mbuf *m, struct dp_flo
return DP_OK;
}

if (dp_capture_offloaded_pkts(m, *p_flow_val, df))
return DP_IS_CAPTURED_HW_PKT;

byteocean marked this conversation as resolved.
Show resolved Hide resolved
// already established flow found
dp_set_pkt_flow_direction(curr_key, *p_flow_val, df);
dp_set_flow_offload_flag(m, *p_flow_val, df);
Expand All @@ -283,8 +302,8 @@ int dp_cntrack_handle(__rte_unused struct rte_node *node, struct rte_mbuf *m, st
int ret;

ret = dp_get_flow_val(m, df, &flow_val);
if (DP_FAILED(ret))
return ret;
if (DP_FAILED(ret) || ret == DP_IS_CAPTURED_HW_PKT)
return ret; // it is not really an error when ret == DP_IS_CAPTURED_HW_PKT, but we need to stop processing this pkt

flow_val->timestamp = rte_rdtsc();

Expand Down
65 changes: 65 additions & 0 deletions src/dp_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "monitoring/dp_event.h"
#include "nodes/rx_node.h"
#include "rte_flow/dp_rte_flow_init.h"
#include "rte_flow/dp_rte_flow.h"
#include "monitoring/dp_graphtrace.h"

static const struct rte_eth_conf port_conf_default = {
.rxmode = {
Expand Down Expand Up @@ -428,6 +430,62 @@ static int dp_port_bind_port_hairpins(struct dp_port *port)
return DP_OK;
}

static int dp_vf_init_monitoring_rule_rollback(uint32_t port_id)
{
struct dp_port *port = dp_port_get_vf(port_id);
struct rte_flow_error error;

if (DP_FAILED(rte_flow_destroy(port->port_id, port->default_flow, &error))) {
DPS_LOG_ERR("Failed to destroy default flow while rollback from vf init monitoring rule installation", \
DP_LOG_PORTID(port->port_id), DP_LOG_FLOW_ERROR(error.message));
return DP_ERROR;
}

if (DP_FAILED(dp_install_jump_rule_in_default_group(port->port_id, DP_RTE_FLOW_VNET_GROUP))) {
DPS_LOG_ERR("Failed to install default jump flow rule while rollback from vf init monitoring rule installation", \
DP_LOG_PORTID(port->port_id));
return DP_ERROR;
}

return DP_OK;
}

static int dp_install_vf_init_rte_rules(uint32_t port_id)
{
bool graphtrace_enabled = dp_graphtrace_is_enabled();
int ret;

// at least one rule must be there, otherwise new packets cannot be delivered to software path
// same as the isolation rule on pf
if (graphtrace_enabled)
ret = dp_install_jump_rule_in_default_group(port_id, DP_RTE_FLOW_MONITORING_GROUP);
else
ret = dp_install_jump_rule_in_default_group(port_id, DP_RTE_FLOW_VNET_GROUP);

if (DP_FAILED(ret)) {
DPS_LOG_ERR("Cannot install default jump rule", DP_LOG_PORTID(port_id), DP_LOG_RET(ret));
return DP_ERROR;
}

// this rule must be there, otherwise new packets cannot be delivered to software path, making communication failure
ret = dp_install_default_capture_rule_in_vnet_group(port_id);
if (DP_FAILED(ret)) {
DPS_LOG_ERR("Cannot install default capture rule in vnet group", DP_LOG_PORTID(port_id), DP_LOG_RET(ret));
return DP_ERROR;
}

ret = dp_install_default_rule_in_monitoring_group(port_id);
if (DP_FAILED(ret)) {
DPS_LOG_WARNING("Cannot install default rule in monitoring group", DP_LOG_PORTID(port_id), DP_LOG_RET(ret));
if (DP_FAILED(dp_vf_init_monitoring_rule_rollback(port_id))) {
DPS_LOG_ERR("Cannot rollback from the monitoring rule installation on vf", DP_LOG_PORTID(port_id));
return DP_ERROR;
}
}

return DP_OK;
}

int dp_port_start(uint16_t port_id)
{
struct dp_port *port;
Expand Down Expand Up @@ -462,6 +520,13 @@ int dp_port_start(uint16_t port_id)
if (DP_FAILED(dp_port_install_isolated_mode(port_id)))
return DP_ERROR;
}


if (port->port_type == DP_PORT_VF && dp_conf_is_offload_enabled()) {
ret = dp_install_vf_init_rte_rules(port_id);
byteocean marked this conversation as resolved.
Show resolved Hide resolved
if (DP_FAILED(ret))
assert(0); // if any flow rule failed, stop process running due to possible hw/driver failure
}
PlagueCZ marked this conversation as resolved.
Show resolved Hide resolved
}

return DP_OK;
Expand Down
Loading
Loading