summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Simonart <xavier.simonart@intel.com>2018-11-27 15:03:21 +0100
committerXavier Simonart <xavier.simonart@intel.com>2018-12-13 16:21:20 +0100
commit4da0effed52e73e23f73884af771d2aff1332efc (patch)
treea63de3deba812868608233b4f500c82d35c0e2d1
parent6923c9623fd958b183741b4d4f8d2cbe4325a144 (diff)
Fix issue in l3 mode when no arp reply was received
When no arp reply was received in l3 mode, the requesting core continuously sends ARP requests every seconds (which is correct). But master core was keeping a list of all requests, while all those requests are the same, resulting in potential table overflow. Change-Id: I13aa1ec4ea88404a690a25678fb6ec72df19a9b9 Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
-rw-r--r--VNFs/DPPD-PROX/handle_master.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/VNFs/DPPD-PROX/handle_master.c b/VNFs/DPPD-PROX/handle_master.c
index 853df428..22527413 100644
--- a/VNFs/DPPD-PROX/handle_master.c
+++ b/VNFs/DPPD-PROX/handle_master.c
@@ -118,7 +118,7 @@ void register_ip_to_ctrl_plane(struct task_base *tbase, uint32_t ip, uint8_t por
plogx_dbg("\tregistering IP %d.%d.%d.%d with port %d core %d and task %d\n", IP4(ip), port_id, core_id, task_id);
if (port_id >= PROX_MAX_PORTS) {
- plog_err("Unable to register ip %x, port %d\n", ip, port_id);
+ plog_err("Unable to register ip %d.%d.%d.%d, port %d\n", IP4(ip), port_id);
return;
}
@@ -138,7 +138,7 @@ void register_ip_to_ctrl_plane(struct task_base *tbase, uint32_t ip, uint8_t por
key.port = port_id;
int ret = rte_hash_add_key(task->internal_ip_hash, (const void *)&key);
if (unlikely(ret < 0)) {
- plog_err("Unable to register ip %x\n", ip);
+ plog_err("Unable to register ip %d.%d.%d.%d\n", IP4(ip));
return;
}
memcpy(&task->internal_ip_table[ret].mac, &prox_port_cfg[port_id].eth_addr, 6);
@@ -216,7 +216,7 @@ static inline void handle_unknown_ip(struct task_base *tbase, struct rte_mbuf *m
struct ether_hdr_arp *hdr_arp = rte_pktmbuf_mtod(mbuf, struct ether_hdr_arp *);
uint8_t port = get_port(mbuf);
uint32_t ip_dst = get_ip(mbuf);
- int ret1, ret2;
+ int ret1, ret2, i;
plogx_dbg("\tMaster handling unknown ip %d.%d.%d.%d for port %d\n", IP4(ip_dst), port);
if (unlikely(port >= PROX_MAX_PORTS)) {
@@ -236,13 +236,32 @@ static inline void handle_unknown_ip(struct task_base *tbase, struct rte_mbuf *m
ret2 = rte_hash_add_key(task->external_ip_hash, (const void *)&ip_dst);
if (unlikely(ret2 < 0)) {
// entry not found for this IP: delete the reply
- plogx_dbg("Unable to add IP %x in external_ip_hash\n", rte_be_to_cpu_32(hdr_arp->arp.data.tpa));
+ plogx_dbg("Unable to add IP %d.%d.%d.%d in external_ip_hash\n", IP4(ip_dst));
tx_drop(mbuf);
return;
}
- 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);
+
+ // If multiple tasks requesting the same info, we will need to send a reply to all of them
+ // However if one task sends multiple requests to the same IP (e.g. because it is not answering)
+ // then we should not send multiple replies to the same task
+ if (task->external_ip_table[ret2].nb_requests >= PROX_MAX_ARP_REQUESTS) {
+ // This can only happen if really many tasks requests the same IP
+ plogx_dbg("Unable to add request for IP %d.%d.%d.%d in external_ip_table\n", IP4(ip_dst));
+ tx_drop(mbuf);
+ return;
+ }
+ for (i = 0; i < task->external_ip_table[ret2].nb_requests; i++) {
+ if (task->external_ip_table[ret2].rings[i] == ring)
+ break;
+ }
+ if (i >= task->external_ip_table[ret2].nb_requests) {
+ // If this is a new request i.e. a new task requesting a new IP
+ task->external_ip_table[ret2].rings[task->external_ip_table[ret2].nb_requests] = ring;
+ task->external_ip_table[ret2].nb_requests++;
+ // Only needed for first request - but avoid test and copy the same 6 bytes
+ // In most cases we will only have one request per IP.
+ 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);