summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Provoost <luc.provoost@intel.com>2021-04-01 15:54:38 +0200
committerLuc Provoost <luc.provoost@intel.com>2021-04-06 13:34:36 +0000
commit6bffe8d5a58d62a377bbad0025b604f4be04a3b0 (patch)
tree1a3f2b9a082c9de3d2e0b518e3bfff47813bb50e
parentecec1b2f7c993d712e252a73c51736e4c9548533 (diff)
Avoid seg fault in rte_hash_lookup_bulk
In case we receive a NON-IPv4 packet, we discard the packet. However, this made the rte_hash_lookup_bulk crash. Hence the keys parameter has changed to avoid the crash. Change-Id: I093688a0b59d44667a42147fd67fbc7901d6dba4 Signed-off-by: Luc Provoost <luc.provoost@intel.com>
-rw-r--r--VNFs/DPPD-PROX/handle_cgnat.c161
1 files changed, 83 insertions, 78 deletions
diff --git a/VNFs/DPPD-PROX/handle_cgnat.c b/VNFs/DPPD-PROX/handle_cgnat.c
index 55a35c20..cc1eae28 100644
--- a/VNFs/DPPD-PROX/handle_cgnat.c
+++ b/VNFs/DPPD-PROX/handle_cgnat.c
@@ -148,7 +148,7 @@ static uint8_t route_ipv4(struct task_nat *task, struct rte_mbuf *mbuf)
break;
default:
/* Routing for other protocols is not implemented */
- plogx_info("Routing nit implemented for this protocol\n");
+ plogx_info("Routing not implemented for this protocol\n");
return OUT_DISCARD;
}
@@ -286,7 +286,7 @@ static int add_new_port_entry(struct task_nat *task, uint8_t proto, int public_i
task->private_flow_entries[ret].ip_addr = ip;
task->private_flow_entries[ret].l4_port = *port;
task->private_flow_entries[ret].flow_time = tsc;
- task->private_flow_entries[ret].private_ip_idx = private_ip_idx;
+ task->private_flow_entries[ret].private_ip_idx = private_ip_idx;
public_key.ip_addr = ip;
public_key.l4_port = *port;
@@ -303,15 +303,15 @@ static int add_new_port_entry(struct task_nat *task, uint8_t proto, int public_i
task->public_entries[ret].ip_addr = private_src_ip;
task->public_entries[ret].l4_port = private_udp_port;
task->public_entries[ret].dpdk_port = mbuf->port;
- task->public_entries[ret].private_ip_idx = private_ip_idx;
+ task->public_entries[ret].private_ip_idx = private_ip_idx;
return ret;
}
static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts)
{
- struct task_nat *task = (struct task_nat *)tbase;
- uint8_t out[MAX_PKT_BURST];
- uint16_t j;
+ struct task_nat *task = (struct task_nat *)tbase;
+ uint8_t out[MAX_PKT_BURST];
+ uint16_t j;
uint32_t *ip_addr, public_ip, private_ip;
uint16_t *udp_src_port, port, private_port, public_port;
struct pkt_eth_ipv4 *pkt[MAX_PKT_BURST];
@@ -322,6 +322,7 @@ static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
void *keys[MAX_PKT_BURST];
int32_t positions[MAX_PKT_BURST];
int map[MAX_PKT_BURST] = {0};
+ struct public_key null_key ={0};
if (unlikely(task->dump_public_hash)) {
const struct public_key *next_key;
@@ -348,24 +349,24 @@ static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
task->dump_private_hash = 0;
}
- for (j = 0; j < n_pkts; ++j) {
- PREFETCH0(mbufs[j]);
+ for (j = 0; j < n_pkts; ++j) {
+ PREFETCH0(mbufs[j]);
}
- for (j = 0; j < n_pkts; ++j) {
+ for (j = 0; j < n_pkts; ++j) {
pkt[j] = rte_pktmbuf_mtod(mbufs[j], struct pkt_eth_ipv4 *);
- PREFETCH0(pkt[j]);
+ PREFETCH0(pkt[j]);
}
if (task->private) {
- struct private_key key[MAX_PKT_BURST];
- for (j = 0; j < n_pkts; ++j) {
+ struct private_key key[MAX_PKT_BURST];
+ for (j = 0; j < n_pkts; ++j) {
/* Currently, only support eth/ipv4 packets */
if (pkt[j]->ether_hdr.ether_type != ETYPE_IPv4) {
plogx_info("Currently, only support eth/ipv4 packets\n");
out[j] = OUT_DISCARD;
- keys[j] = (void *)NULL;
+ keys[j] = (void *)&null_key;
continue;
}
- key[j].ip_addr = pkt[j]->ipv4_hdr.src_addr;
+ key[j].ip_addr = pkt[j]->ipv4_hdr.src_addr;
key[j].l4_port = pkt[j]->udp_hdr.src_port;
keys[j] = &key[j];
}
@@ -375,27 +376,29 @@ static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
return -1;
}
int n_new_mapping = 0;
- for (j = 0; j < n_pkts; ++j) {
+ for (j = 0; j < n_pkts; ++j) {
port_idx = positions[j];
- if (unlikely(port_idx < 0)) {
- plogx_dbg("ip %d.%d.%d.%d / port %x not found in private ip/port hash\n", IP4(pkt[j]->ipv4_hdr.src_addr), pkt[j]->udp_hdr.src_port);
- map[n_new_mapping] = j;
- keys[n_new_mapping++] = (void *)&(pkt[j]->ipv4_hdr.src_addr);
- } else {
- ip_addr = &(pkt[j]->ipv4_hdr.src_addr);
- udp_src_port = &(pkt[j]->udp_hdr.src_port);
- plogx_dbg("ip/port %d.%d.%d.%d / %x found in private ip/port hash\n", IP4(pkt[j]->ipv4_hdr.src_addr), pkt[j]->udp_hdr.src_port);
- *ip_addr = task->private_flow_entries[port_idx].ip_addr;
- *udp_src_port = task->private_flow_entries[port_idx].l4_port;
- uint64_t flow_time = task->private_flow_entries[port_idx].flow_time;
- if (flow_time + tsc_hz < tsc) {
- task->private_flow_entries[port_idx].flow_time = tsc;
+ if (out[j] != OUT_DISCARD) {
+ if (unlikely(port_idx < 0)) {
+ plogx_dbg("ip %d.%d.%d.%d / port %x not found in private ip/port hash\n", IP4(pkt[j]->ipv4_hdr.src_addr), pkt[j]->udp_hdr.src_port);
+ map[n_new_mapping] = j;
+ keys[n_new_mapping++] = (void *)&(pkt[j]->ipv4_hdr.src_addr);
+ } else {
+ ip_addr = &(pkt[j]->ipv4_hdr.src_addr);
+ udp_src_port = &(pkt[j]->udp_hdr.src_port);
+ plogx_dbg("ip/port %d.%d.%d.%d / %x found in private ip/port hash\n", IP4(pkt[j]->ipv4_hdr.src_addr), pkt[j]->udp_hdr.src_port);
+ *ip_addr = task->private_flow_entries[port_idx].ip_addr;
+ *udp_src_port = task->private_flow_entries[port_idx].l4_port;
+ uint64_t flow_time = task->private_flow_entries[port_idx].flow_time;
+ if (flow_time + tsc_hz < tsc) {
+ task->private_flow_entries[port_idx].flow_time = tsc;
+ }
+ private_ip_idx = task->private_flow_entries[port_idx].private_ip_idx;
+ if (task->private_ip_info[private_ip_idx].mac_aging_time + tsc_hz < tsc)
+ task->private_ip_info[private_ip_idx].mac_aging_time = tsc;
+ prox_ip_udp_cksum(mbufs[j], &pkt[j]->ipv4_hdr, sizeof(prox_rte_ether_hdr), sizeof(prox_rte_ipv4_hdr), task->offload_crc);
+ out[j] = route_ipv4(task, mbufs[j]);
}
- private_ip_idx = task->private_flow_entries[port_idx].private_ip_idx;
- if (task->private_ip_info[private_ip_idx].mac_aging_time + tsc_hz < tsc)
- task->private_ip_info[private_ip_idx].mac_aging_time = tsc;
- prox_ip_udp_cksum(mbufs[j], &pkt[j]->ipv4_hdr, sizeof(prox_rte_ether_hdr), sizeof(prox_rte_ipv4_hdr), task->offload_crc);
- out[j] = route_ipv4(task, mbufs[j]);
}
}
@@ -410,7 +413,7 @@ static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
}
n_new_mapping = 0;
}
- for (int k = 0; k < n_new_mapping; ++k) {
+ for (int k = 0; k < n_new_mapping; ++k) {
private_ip_idx = positions[k];
j = map[k];
ip_addr = &(pkt[j]->ipv4_hdr.src_addr);
@@ -476,10 +479,10 @@ static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
private_port = *udp_src_port;
plogx_info("Added new ip/port: private ip/port = %d.%d.%d.%d/%x public ip/port = %d.%d.%d.%d/%x, index = %d\n", IP4(private_ip), private_port, IP4(public_ip), public_port, port_idx);
}
- // task->private_flow_entries[port_idx].ip_addr = task->private_ip_info[private_ip_idx].public_ip;
+ // task->private_flow_entries[port_idx].ip_addr = task->private_ip_info[private_ip_idx].public_ip;
plogx_info("Added new port: private ip/port = %d.%d.%d.%d/%x, public ip/port = %d.%d.%d.%d/%x\n", IP4(private_ip), private_port, IP4(task->private_ip_info[private_ip_idx].public_ip), public_port);
- *ip_addr = public_ip ;
- *udp_src_port = public_port;
+ *ip_addr = public_ip ;
+ *udp_src_port = public_port;
uint64_t flow_time = task->private_flow_entries[port_idx].flow_time;
if (flow_time + tsc_hz < tsc) {
task->private_flow_entries[port_idx].flow_time = tsc;
@@ -495,18 +498,18 @@ static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
}
}
}
- return task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
+ return task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
} else {
struct public_key public_key[MAX_PKT_BURST];
- for (j = 0; j < n_pkts; ++j) {
+ for (j = 0; j < n_pkts; ++j) {
/* Currently, only support eth/ipv4 packets */
if (pkt[j]->ether_hdr.ether_type != ETYPE_IPv4) {
plogx_info("Currently, only support eth/ipv4 packets\n");
out[j] = OUT_DISCARD;
- keys[j] = (void *)NULL;
+ keys[j] = (void *)&null_key;
continue;
}
- public_key[j].ip_addr = pkt[j]->ipv4_hdr.dst_addr;
+ public_key[j].ip_addr = pkt[j]->ipv4_hdr.dst_addr;
public_key[j].l4_port = pkt[j]->udp_hdr.dst_port;
keys[j] = &public_key[j];
}
@@ -515,26 +518,28 @@ static int handle_nat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
plogx_err("Failed lookup bulk public_ip_port_hash\n");
return -1;
}
- for (j = 0; j < n_pkts; ++j) {
+ for (j = 0; j < n_pkts; ++j) {
port_idx = positions[j];
- ip_addr = &(pkt[j]->ipv4_hdr.dst_addr);
+ ip_addr = &(pkt[j]->ipv4_hdr.dst_addr);
udp_src_port = &(pkt[j]->udp_hdr.dst_port);
- if (port_idx < 0) {
- plogx_err("Failed to find ip/port %d.%d.%d.%d/%x in public_ip_port_hash\n", IP4(*ip_addr), *udp_src_port);
- out[j] = OUT_DISCARD;
- } else {
- plogx_dbg("Found ip/port %d.%d.%d.%d/%x in public_ip_port_hash\n", IP4(*ip_addr), *udp_src_port);
- *ip_addr = task->public_entries[port_idx].ip_addr;
- *udp_src_port = task->public_entries[port_idx].l4_port;
- private_ip_idx = task->public_entries[port_idx].private_ip_idx;
- plogx_dbg("Found private IP info for ip %d.%d.%d.%d\n", IP4(*ip_addr));
- rte_memcpy(((uint8_t *)(pkt[j])) + 0, &task->private_ip_info[private_ip_idx].private_mac, 6);
- rte_memcpy(((uint8_t *)(pkt[j])) + 6, &task->src_mac_from_dpdk_port[task->public_entries[port_idx].dpdk_port], 6);
- out[j] = task->public_entries[port_idx].dpdk_port;
+ if (out[j] != OUT_DISCARD) {
+ if (port_idx < 0) {
+ plogx_err("Failed to find ip/port %d.%d.%d.%d/%x in public_ip_port_hash\n", IP4(*ip_addr), *udp_src_port);
+ out[j] = OUT_DISCARD;
+ } else {
+ plogx_dbg("Found ip/port %d.%d.%d.%d/%x in public_ip_port_hash\n", IP4(*ip_addr), *udp_src_port);
+ *ip_addr = task->public_entries[port_idx].ip_addr;
+ *udp_src_port = task->public_entries[port_idx].l4_port;
+ private_ip_idx = task->public_entries[port_idx].private_ip_idx;
+ plogx_dbg("Found private IP info for ip %d.%d.%d.%d\n", IP4(*ip_addr));
+ rte_memcpy(((uint8_t *)(pkt[j])) + 0, &task->private_ip_info[private_ip_idx].private_mac, 6);
+ rte_memcpy(((uint8_t *)(pkt[j])) + 6, &task->src_mac_from_dpdk_port[task->public_entries[port_idx].dpdk_port], 6);
+ out[j] = task->public_entries[port_idx].dpdk_port;
+ }
}
prox_ip_udp_cksum(mbufs[j], &pkt[j]->ipv4_hdr, sizeof(prox_rte_ether_hdr), sizeof(prox_rte_ipv4_hdr), task->offload_crc);
}
- return task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
+ return task->base.tx_pkt(&task->base, mbufs, n_pkts, out);
}
}
@@ -562,9 +567,9 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
}
struct tmp_public_ip {
- uint32_t ip_beg;
+ uint32_t ip_beg;
uint32_t ip_end;
- uint16_t port_beg;
+ uint16_t port_beg;
uint16_t port_end;
};
struct tmp_static_ip {
@@ -595,10 +600,10 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
plogx_info("No dynamic table found\n");
} else {
uint64_t n_ip, n_port;
- if (!lua_istable(L, -1)) {
- plogx_err("Can't read cgnat since data is not a table\n");
- return -1;
- }
+ if (!lua_istable(L, -1)) {
+ plogx_err("Can't read cgnat since data is not a table\n");
+ return -1;
+ }
lua_len(L, -1);
n_public_groups = lua_tointeger(L, -1);
plogx_info("%d groups of public IP\n", n_public_groups);
@@ -609,9 +614,9 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
while (lua_next(L, -2)) {
if (lua_to_ip(L, TABLE, "public_ip_range_start", &dst_ip1) ||
- lua_to_ip(L, TABLE, "public_ip_range_stop", &dst_ip2) ||
- lua_to_val_range(L, TABLE, "public_port", &dst_port))
- return -1;
+ lua_to_ip(L, TABLE, "public_ip_range_stop", &dst_ip2) ||
+ lua_to_val_range(L, TABLE, "public_port", &dst_port))
+ return -1;
PROX_PANIC(dst_ip2 < dst_ip1, "public_ip_range error: %d.%d.%d.%d < %d.%d.%d.%d\n", (dst_ip2 >> 24), (dst_ip2 >> 16) & 0xFF, (dst_ip2 >> 8) & 0xFF, dst_ip2 & 0xFF, dst_ip1 >> 24, (dst_ip1 >> 16) & 0xFF, (dst_ip1 >> 8) & 0xFF, dst_ip1 & 0xFF);
PROX_PANIC(dst_port.end < dst_port.beg, "public_port error: %d < %d\n", dst_port.end, dst_port.beg);
n_ip = dst_ip2 - dst_ip1 + 1;
@@ -632,9 +637,9 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
if ((pop2 = lua_getfrom(L, TABLE, "static_ip")) < 0) {
plogx_info("No static ip table found\n");
} else {
- if (!lua_istable(L, -1)) {
- plogx_err("Can't read cgnat since data is not a table\n");
- return -1;
+ if (!lua_istable(L, -1)) {
+ plogx_err("Can't read cgnat since data is not a table\n");
+ return -1;
}
lua_len(L, -1);
@@ -646,7 +651,7 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
lua_pushnil(L);
while (lua_next(L, -2)) {
if (lua_to_ip(L, TABLE, "src_ip", &ip_from) ||
- lua_to_ip(L, TABLE, "dst_ip", &ip_to))
+ lua_to_ip(L, TABLE, "dst_ip", &ip_to))
return -1;
ip_from = rte_bswap32(ip_from);
ip_to = rte_bswap32(ip_to);
@@ -667,9 +672,9 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
if ((pop2 = lua_getfrom(L, TABLE, "static_ip_port")) < 0) {
plogx_info("No static table found\n");
} else {
- if (!lua_istable(L, -1)) {
- plogx_err("Can't read cgnat since data is not a table\n");
- return -1;
+ if (!lua_istable(L, -1)) {
+ plogx_err("Can't read cgnat since data is not a table\n");
+ return -1;
}
lua_len(L, -1);
@@ -682,10 +687,10 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
while (lua_next(L, -2)) {
if (lua_to_ip(L, TABLE, "src_ip", &ip_from) ||
- lua_to_ip(L, TABLE, "dst_ip", &ip_to) ||
- lua_to_port(L, TABLE, "src_port", &port_from) ||
- lua_to_port(L, TABLE, "dst_port", &port_to))
- return -1;
+ lua_to_ip(L, TABLE, "dst_ip", &ip_to) ||
+ lua_to_port(L, TABLE, "src_port", &port_from) ||
+ lua_to_port(L, TABLE, "dst_port", &port_to))
+ return -1;
ip_from = rte_bswap32(ip_from);
ip_to = rte_bswap32(ip_to);
@@ -740,7 +745,7 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
ip_info = &tmp_public_ip_config_info[ip_free_count];
ip_info->public_ip = rte_bswap32(ip);
ip_info->port_list = (uint16_t *)prox_zmalloc((dst_port.end - dst_port.beg) * sizeof(uint16_t), socket);
- PROX_PANIC(ip_info->port_list == NULL, "Failed to allocate list of ports for ip %x\n", ip);
+ PROX_PANIC(ip_info->port_list == NULL, "Failed to allocate list of ports for ip %x\n", ip);
for (uint32_t port = tmp_public_ip[i].port_beg; port <= tmp_public_ip[i].port_end; port++) {
ip_info->port_list[ip_info->port_free_count] = rte_bswap16(port);
ip_info->port_free_count++;
@@ -763,7 +768,7 @@ static int lua_to_hash_nat(struct task_args *targ, struct lua_State *L, enum lua
ip_info = &tmp_public_ip_config_info[ip_free_count];
ip_info->public_ip = tmp_static_ip_port[i].public_ip;
ip_info->port_list = (uint16_t *)prox_zmalloc(tmp_static_ip_port[i].n_ports * sizeof(uint16_t), socket);
- PROX_PANIC(ip_info->port_list == NULL, "Failed to allocate list of ports for ip %x\n", tmp_static_ip_port[i].public_ip);
+ PROX_PANIC(ip_info->port_list == NULL, "Failed to allocate list of ports for ip %x\n", tmp_static_ip_port[i].public_ip);
ip_info->port_list[ip_info->port_free_count] = tmp_static_ip_port[i].public_port;
ip_info->port_free_count++;
ip_info->max_port_count = ip_info->port_free_count;