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

mbufs holding a reference to conntrack should be part of ref counting #623

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/dp_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ extern "C" {
#include <assert.h>
#include <rte_errno.h>

#define DP_RETURN_REF_COUNT_REDUCE_DROP(var, X) \
do { dp_ref_dec(&(var)->ref_count); return X; } while (0)

#define DP_OK 0
#define DP_ERROR (-RTE_MAX_ERRNO)
#define _DP_GRPC_ERRCODES (DP_ERROR-1)
Expand Down
1 change: 1 addition & 0 deletions src/dp_cntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ int dp_cntrack_handle(struct rte_mbuf *m, struct dp_flow *df)
return DP_ERROR;

df->conntrack = flow_val;
dp_ref_inc(&flow_val->ref_count);
dp_cntrack_set_pkt_offload_decision(df);

return DP_OK;
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/conntrack_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
case DP_VNF_TYPE_ALIAS_PFX:
return CONNTRACK_NEXT_FIREWALL;
case DP_VNF_TYPE_UNDEFINED:
return CONNTRACK_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, CONNTRACK_NEXT_DROP);
}

return CONNTRACK_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, CONNTRACK_NEXT_DROP);
}

static uint16_t conntrack_node_process(struct rte_graph *graph,
Expand Down
14 changes: 7 additions & 7 deletions src/nodes/dnat_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
// then it is a premature dnat pkt for network nat (sent before any outgoing traffic from VM,
// and it cannot be a standalone new incoming flow for network NAT),
// silently drop it now.
return DNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(cntrack, DNAT_NEXT_DROP);
}

ipv4_hdr = dp_get_ipv4_hdr(m);
Expand All @@ -84,7 +84,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
dp_delete_flow(&cntrack->flow_key[DP_FLOW_DIR_REPLY], cntrack);
dp_set_ipaddr4(&cntrack->flow_key[DP_FLOW_DIR_REPLY].l3_src, ntohl(ipv4_hdr->dst_addr));
if (DP_FAILED(dp_add_flow(&cntrack->flow_key[DP_FLOW_DIR_REPLY], cntrack)))
return DNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(cntrack, DNAT_NEXT_DROP);
dp_ref_inc(&cntrack->ref_count);
}
return DNAT_NEXT_IPV4_LOOKUP;
Expand All @@ -102,7 +102,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod

if (DP_FLOW_HAS_FLAG_DST_NAT(cntrack->flow_flags) && df->flow_dir == DP_FLOW_DIR_ORG) {
if (cntrack->flow_key[DP_FLOW_DIR_REPLY].l3_src.is_v6)
return DNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(cntrack, DNAT_NEXT_DROP);
ipv4_hdr = dp_get_ipv4_hdr(m);
ipv4_hdr->dst_addr = htonl(cntrack->flow_key[DP_FLOW_DIR_REPLY].l3_src.ipv4);
df->nat_type = DP_NAT_CHG_DST_IP;
Expand All @@ -114,7 +114,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
/* We already know what to do */
if (DP_FLOW_HAS_FLAG_SRC_NAT(cntrack->flow_flags) && df->flow_dir == DP_FLOW_DIR_REPLY) {
if (cntrack->flow_key[DP_FLOW_DIR_ORG].l3_src.is_v6)
return DNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(cntrack, DNAT_NEXT_DROP);
ipv4_hdr = dp_get_ipv4_hdr(m);
ipv4_hdr->dst_addr = htonl(cntrack->flow_key[DP_FLOW_DIR_ORG].l3_src.ipv4);
if (cntrack->nf_info.nat_type == DP_FLOW_NAT_TYPE_NETWORK_LOCAL) {
Expand All @@ -125,7 +125,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
memset(&icmp_err_ip_info, 0, sizeof(icmp_err_ip_info));
dp_get_icmp_err_ip_hdr(m, &icmp_err_ip_info);
if (!icmp_err_ip_info.err_ipv4_hdr || !icmp_err_ip_info.l4_src_port || !icmp_err_ip_info.l4_dst_port)
return DNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(cntrack, DNAT_NEXT_DROP);
icmp_err_ip_info.err_ipv4_hdr->src_addr = htonl(cntrack->flow_key[DP_FLOW_DIR_ORG].l3_src.ipv4);
icmp_err_ip_info.err_ipv4_hdr->hdr_checksum = cntrack->nf_info.icmp_err_ip_cksum;
dp_change_icmp_err_l4_src_port(m, &icmp_err_ip_info, cntrack->flow_key[DP_FLOW_DIR_ORG].src.port_src);
Expand Down Expand Up @@ -155,7 +155,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
}
if (DP_FAILED(dp_ipv6_from_ipaddr(&nat_ipv6, &cntrack->flow_key[DP_FLOW_DIR_ORG].l3_src))
|| DP_FAILED(dp_nat_chg_ipv4_to_ipv6_hdr(df, m, &nat_ipv6)))
return DNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(cntrack, DNAT_NEXT_DROP);

return DNAT_NEXT_IPV6_LOOKUP;
}
Expand All @@ -166,7 +166,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
else if (df->l3_type == RTE_ETHER_TYPE_IPV6)
return DNAT_NEXT_IPV6_LOOKUP;
else
return DNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(cntrack, DNAT_NEXT_DROP);
}

static uint16_t dnat_node_process(struct rte_graph *graph,
Expand Down
1 change: 1 addition & 0 deletions src/nodes/ipip_encap_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static __rte_always_inline rte_edge_t get_next_index(struct rte_node *node, stru
m->ol_flags |= RTE_MBUF_F_TX_TUNNEL_IP;

if (df->nat_type == DP_LB_RECIRC) {
dp_ref_dec(&df->conntrack->ref_count);
dp_get_pkt_mark(m)->flags.is_recirc = true;
return IPIP_ENCAP_NEXT_CLS;
}
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/ipv4_lookup_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod

out_port = dp_get_ip4_out_port(in_port, df->tun_info.dst_vni, df, &route, &ip);
if (!out_port)
return IPV4_LOOKUP_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, IPV4_LOOKUP_NEXT_DROP);

if (out_port->is_pf) {
if (in_port->is_pf)
return IPV4_LOOKUP_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, IPV4_LOOKUP_NEXT_DROP);
dp_copy_ipv6(&df->tun_info.ul_dst_addr6, &route.nh_ipv6);
out_port = dp_multipath_get_pf(df->dp_flow_hash);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/ipv6_lookup_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod

out_port = dp_get_ip6_out_port(in_port, t_vni, df, &route, &ip);
if (!out_port)
return IPV6_LOOKUP_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, IPV6_LOOKUP_NEXT_DROP);

if (out_port->is_pf) {
if (in_port->is_pf)
return IPV6_LOOKUP_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, IPV6_LOOKUP_NEXT_DROP);
dp_copy_ipv6(&df->tun_info.ul_dst_addr6, &route.nh_ipv6);
} else {
// next hop is known, fill in Ether header
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/lb_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
}
/* ICMP error types conntrack keys are built from original TCP/UDP header, so let them slip */
if (df->l4_info.icmp_field.icmp_type != DP_IP_ICMP_TYPE_ERROR)
return LB_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, LB_NEXT_DROP);
}

target_ip6 = dp_lb_get_backend_ip(&cntrack->flow_key[DP_FLOW_DIR_ORG], vni);
if (!target_ip6)
return LB_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, LB_NEXT_DROP);

dp_copy_ipv6(&df->tun_info.ul_src_addr6, &df->tun_info.ul_dst_addr6); // same trick as in packet_relay_node.c
dp_copy_ipv6(&df->tun_info.ul_dst_addr6, target_ip6);
Expand Down
6 changes: 3 additions & 3 deletions src/nodes/packet_relay_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static __rte_always_inline rte_edge_t lb_nnat_icmp_reply(struct dp_flow *df, str
uint32_t cksum;

if (icmp_hdr->icmp_type != RTE_IP_ICMP_ECHO_REQUEST)
return PACKET_RELAY_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, PACKET_RELAY_NEXT_DROP);

// rewrite the packet and send it back
icmp_hdr->icmp_type = RTE_IP_ICMP_ECHO_REPLY;
Expand Down Expand Up @@ -53,7 +53,7 @@ static __rte_always_inline rte_edge_t lb_nnat_icmpv6_reply(struct dp_flow *df, s
union dp_ipv6 temp_addr;

if (icmp6_hdr->icmp_type != DP_ICMPV6_ECHO_REQUEST)
return PACKET_RELAY_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, PACKET_RELAY_NEXT_DROP);

icmp6_hdr->icmp_type = DP_ICMPV6_ECHO_REPLY;

Expand Down Expand Up @@ -92,7 +92,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
if (df->l4_type == IPPROTO_ICMPV6)
return lb_nnat_icmpv6_reply(df, m);

return PACKET_RELAY_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, PACKET_RELAY_NEXT_DROP);
}

static uint16_t packet_relay_node_process(struct rte_graph *graph,
Expand Down
12 changes: 6 additions & 6 deletions src/nodes/snat_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
&& (df->l3_type == RTE_ETHER_TYPE_IPV4 || df->l3_type == RTE_ETHER_TYPE_IPV6)) {
color = rte_meter_srtcm_color_blind_check(&in_port->port_srtcm, &in_port->port_srtcm_profile, rte_rdtsc(), df->l3_payload_length);
if (color == RTE_COLOR_RED)
return SNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, SNAT_NEXT_DROP);
}

if (!cntrack)
Expand All @@ -173,7 +173,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
if (snat_data && (snat_data->vip_ip != 0 || snat_data->nat_ip != 0)
&& df->flow_type == DP_FLOW_SOUTH_NORTH) {
if (DP_FAILED(dp_process_ipv4_snat(m, df, cntrack, port, snat_data)))
return SNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, SNAT_NEXT_DROP);
}

if (df->l3_type == RTE_ETHER_TYPE_IPV6
Expand All @@ -182,7 +182,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
&& dp_is_ipv6_nat64(&df->dst.dst_addr6)
) {
if (DP_FAILED(dp_process_ipv6_nat64(m, df, cntrack, port)))
return SNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, SNAT_NEXT_DROP);

return SNAT_NEXT_FIREWALL;
}
Expand All @@ -191,7 +191,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
/* We already know what to do */
if (DP_FLOW_HAS_FLAG_SRC_NAT(cntrack->flow_flags) && df->flow_dir == DP_FLOW_DIR_ORG) {
if (cntrack->flow_key[DP_FLOW_DIR_REPLY].l3_dst.is_v6)
return SNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, SNAT_NEXT_DROP);
ipv4_hdr = dp_get_ipv4_hdr(m);
ipv4_hdr->src_addr = htonl(cntrack->flow_key[DP_FLOW_DIR_REPLY].l3_dst.ipv4);

Expand All @@ -212,7 +212,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
&& (df->flow_dir == DP_FLOW_DIR_REPLY)
) {
if (cntrack->flow_key[DP_FLOW_DIR_ORG].l3_dst.is_v6)
return SNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, SNAT_NEXT_DROP);
ipv4_hdr = dp_get_ipv4_hdr(m);
df->src.src_addr = ipv4_hdr->src_addr;
ipv4_hdr->src_addr = htonl(cntrack->flow_key[DP_FLOW_DIR_ORG].l3_dst.ipv4);
Expand All @@ -223,7 +223,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod

if (DP_FLOW_HAS_FLAG_SRC_NAT64(cntrack->flow_flags) && df->flow_dir == DP_FLOW_DIR_ORG) {
if (DP_FAILED(dp_nat_chg_ipv6_to_ipv4_hdr(df, m, port->iface.nat_ip, &dest_ip4)))
return SNAT_NEXT_DROP;
DP_RETURN_REF_COUNT_REDUCE_DROP(df->conntrack, SNAT_NEXT_DROP);

if (cntrack->nf_info.nat_type == DP_FLOW_NAT_TYPE_NETWORK_LOCAL) {
df->nat_port = cntrack->flow_key[DP_FLOW_DIR_REPLY].port_dst;
Expand Down
1 change: 1 addition & 0 deletions src/nodes/tx_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ static uint16_t tx_node_process(struct rte_graph *graph,
if (df->offload_state == DP_FLOW_OFFLOAD_INSTALL)
if (DP_FAILED(dp_offload_handler(m, df)))
DPNODE_LOG_WARNING(node, "Offloading handler failed");
dp_ref_dec(&df->conntrack->ref_count);
}
}

Expand Down
Loading