diff options
author | Xavier Simonart <xavier.simonart@intel.com> | 2018-11-27 15:03:21 +0100 |
---|---|---|
committer | Xavier Simonart <xavier.simonart@intel.com> | 2018-12-13 16:21:20 +0100 |
commit | 4da0effed52e73e23f73884af771d2aff1332efc (patch) | |
tree | a63de3deba812868608233b4f500c82d35c0e2d1 /VNFs | |
parent | 6923c9623fd958b183741b4d4f8d2cbe4325a144 (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>
Diffstat (limited to 'VNFs')
-rw-r--r-- | VNFs/DPPD-PROX/handle_master.c | 33 |
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); |