summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--VNFs/DPPD-PROX/handle_master.c29
-rw-r--r--VNFs/DPPD-PROX/main.c9
-rw-r--r--VNFs/DPPD-PROX/task_init.c4
3 files changed, 28 insertions, 14 deletions
diff --git a/VNFs/DPPD-PROX/handle_master.c b/VNFs/DPPD-PROX/handle_master.c
index 6bd4ea2c..0e039bdd 100644
--- a/VNFs/DPPD-PROX/handle_master.c
+++ b/VNFs/DPPD-PROX/handle_master.c
@@ -37,6 +37,7 @@
#include "tx_pkt.h"
#define IP4(x) x & 0xff, (x >> 8) & 0xff, (x >> 16) & 0xff, x >> 24
+#define PROX_MAX_ARP_REQUESTS 32 // Maximum number of tasks requesting the same MAC address
const char *actions_string[] = {"UPDATE_FROM_CTRL", "SEND_ARP_REQUEST_FROM_CTRL", "SEND_ARP_REPLY_FROM_CTRL", "HANDLE_ARP_TO_CTRL", "REQ_MAC_TO_CTRL"};
@@ -60,6 +61,12 @@ struct ip_table {
struct rte_ring *ring;
};
+struct external_ip_table {
+ struct ether_addr mac;
+ struct rte_ring *rings[PROX_MAX_ARP_REQUESTS];
+ uint16_t nb_requests;
+};
+
struct port_table {
struct ether_addr mac;
struct rte_ring *ring;
@@ -73,7 +80,7 @@ struct task_master {
struct rte_ring *ctrl_rx_ring;
struct rte_ring **ctrl_tx_rings;
struct ip_table *internal_ip_table;
- struct ip_table *external_ip_table;
+ struct external_ip_table *external_ip_table;
struct rte_hash *external_ip_hash;
struct rte_hash *internal_ip_hash;
struct port_table internal_port_table[PROX_MAX_PORTS];
@@ -154,9 +161,17 @@ static inline void handle_arp_reply(struct task_base *tbase, struct rte_mbuf *mb
tx_drop(mbuf);
} else {
// entry found for this IP
- struct rte_ring *ring = task->external_ip_table[ret].ring;
+ uint16_t nb_requests = task->external_ip_table[ret].nb_requests;
memcpy(&hdr_arp->ether_hdr.d_addr.addr_bytes, &task->external_ip_table[ret].mac, 6);
- tx_ring_ip(tbase, ring, UPDATE_FROM_CTRL, mbuf, key);
+ // If we receive a request from multiple task for the same IP, then we update all tasks
+ if (task->external_ip_table[ret].nb_requests) {
+ rte_mbuf_refcnt_set(mbuf, nb_requests);
+ for (int i = 0; i < nb_requests; i++) {
+ struct rte_ring *ring = task->external_ip_table[ret].rings[i];
+ tx_ring_ip(tbase, ring, UPDATE_FROM_CTRL, mbuf, key);
+ }
+ task->external_ip_table[ret].nb_requests = 0;
+ }
}
}
@@ -226,9 +241,11 @@ static inline void handle_unknown_ip(struct task_base *tbase, struct rte_mbuf *m
tx_drop(mbuf);
return;
}
- task->external_ip_table[ret2].ring = ring;
+ task->external_ip_table[ret2].rings[task->external_ip_table[ret2].nb_requests] = ring;
+ task->external_ip_table[ret2].nb_requests++;
memcpy(&task->external_ip_table[ret2].mac, &task->internal_port_table[port].mac, 6);
+ // We send an ARP request even if one was just sent (and not yet answered) by another task
mbuf->ol_flags &= ~(PKT_TX_IP_CKSUM|PKT_TX_UDP_CKSUM);
build_arp_request(mbuf, &task->internal_port_table[port].mac, ip_dst, ip_src);
tx_ring(tbase, ring, ARP_REQ_FROM_CTRL, mbuf);
@@ -290,9 +307,9 @@ void init_ctrl_plane(struct task_base *tbase)
task->external_ip_hash = rte_hash_create(&hash_params);
PROX_PANIC(task->external_ip_hash == NULL, "Failed to set up external ip hash\n");
plog_info("\texternal ip hash table allocated, with %d entries of size %d\n", hash_params.entries, hash_params.key_len);
- task->external_ip_table = (struct ip_table *)prox_zmalloc(n_entries * sizeof(struct ip_table), socket);
+ task->external_ip_table = (struct external_ip_table *)prox_zmalloc(n_entries * sizeof(struct external_ip_table), socket);
PROX_PANIC(task->external_ip_table == NULL, "Failed to allocate memory for %u entries in external ip table\n", n_entries);
- plog_info("\texternal ip table, with %d entries of size %ld\n", n_entries, sizeof(struct ip_table));
+ plog_info("\texternal ip table, with %d entries of size %ld\n", n_entries, sizeof(struct external_ip_table));
hash_name[0]++;
hash_params.key_len = sizeof(struct ip_port);
diff --git a/VNFs/DPPD-PROX/main.c b/VNFs/DPPD-PROX/main.c
index 2c362d6c..2c8517f0 100644
--- a/VNFs/DPPD-PROX/main.c
+++ b/VNFs/DPPD-PROX/main.c
@@ -148,6 +148,7 @@ static void check_missing_rx(void)
if (strcmp(targ->sub_mode_str, "l3") != 0)
continue;
+ PROX_PANIC((targ->nb_rxports == 0) && (targ->nb_txports == 0), "L3 task must have a RX or a TX port\n");
// If the L3 sub_mode receives from a port, check that there is at least one core/task
// transmitting to this port in L3 sub_mode
for (uint8_t i = 0; i < targ->nb_rxports; ++i) {
@@ -155,10 +156,8 @@ static void check_missing_rx(void)
ok = 0;
tx_lconf = NULL;
while (core_targ_next(&tx_lconf, &tx_targ, 0) == 0) {
- port = find_reachable_port(tx_targ);
- if (port == NULL)
+ if ((port_id = tx_targ->tx_port_queue[0].port) == OUT_DISCARD)
continue;
- port_id = port - prox_port_cfg;
if ((rx_port_id == port_id) && (tx_targ->flags & TASK_ARG_L3)){
ok = 1;
break;
@@ -169,10 +168,8 @@ static void check_missing_rx(void)
// If the L3 sub_mode transmits to a port, check that there is at least one core/task
// receiving from that port in L3 sub_mode.
- port = find_reachable_port(targ);
- if (port == NULL)
+ if ((port_id = targ->tx_port_queue[0].port) == OUT_DISCARD)
continue;
- port_id = port - prox_port_cfg;
rx_lconf = NULL;
ok = 0;
plog_info("\tCore %d task %d transmitting to port %d in L3 mode\n", lconf->id, targ->id, port_id);
diff --git a/VNFs/DPPD-PROX/task_init.c b/VNFs/DPPD-PROX/task_init.c
index 2bc83f39..2361d32c 100644
--- a/VNFs/DPPD-PROX/task_init.c
+++ b/VNFs/DPPD-PROX/task_init.c
@@ -350,7 +350,7 @@ struct task_base *init_task_struct(struct task_args *targ)
offset = init_rx_tx_rings_ports(targ, tbase, offset);
tbase->aux = (struct task_base_aux *)(((uint8_t *)tbase) + offset);
- if ((targ->nb_txrings != 0) || (targ->nb_txports != 0)) {
+ if (targ->nb_txports != 0) {
if (targ->flags & TASK_ARG_L3) {
tbase->aux->tx_pkt_l2 = tbase->tx_pkt;
tbase->tx_pkt = tx_pkt_l3;
@@ -373,7 +373,7 @@ struct task_base *init_task_struct(struct task_args *targ)
plog_info("\tTask configured in L3 mode\n");
tbase->l3.ctrl_plane_ring = targ->ctrl_plane_ring;
}
- if ((targ->nb_txrings != 0) || (targ->nb_txports != 0)) {
+ if (targ->nb_txports != 0) {
if (targ->flags & TASK_ARG_L3)
task_init_l3(tbase, targ);
}