diff options
author | Avik Sil <aviksil@linux.vnet.ibm.com> | 2013-11-17 16:22:03 +0530 |
---|---|---|
committer | Avik Sil <aviksil@linux.vnet.ibm.com> | 2013-11-17 16:22:03 +0530 |
commit | 345a00a3d7df54ff03c0bd49dfc095e13c0d777d (patch) | |
tree | d06a60b5981ab13de3e03d83fb7cc7eb288c4808 | |
parent | 69d32fe332662829d16c7130935d38c220c81d9b (diff) | |
download | SLOF-345a00a3d7df54ff03c0bd49dfc095e13c0d777d.zip SLOF-345a00a3d7df54ff03c0bd49dfc095e13c0d777d.tar.gz SLOF-345a00a3d7df54ff03c0bd49dfc095e13c0d777d.tar.bz2 |
ipv4: fix frame overwriting following arp_send_request
Sometimes before ARP request frame is written to the line by qemu, the data gets overwritten
by next outgoing frame (typically tftp request) since both use the same ARP table index for
the frame buffer. This is fixed by copying the next outgoing packet data to a different
buffer instead of writing it to same ARP table index's frame buffer.
Signed-off-by: Avik Sil <aviksil@linux.vnet.ibm.com>
-rw-r--r-- | clients/net-snk/app/netlib/ipv4.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/clients/net-snk/app/netlib/ipv4.c b/clients/net-snk/app/netlib/ipv4.c index e55b582..f6752ec 100644 --- a/clients/net-snk/app/netlib/ipv4.c +++ b/clients/net-snk/app/netlib/ipv4.c @@ -17,6 +17,7 @@ #include <udp.h> #include <tcp.h> #include <ethernet.h> +#include <time.h> #include <sys/socket.h> #include <string.h> @@ -49,6 +50,7 @@ struct arp_entry { uint8_t mac_addr[6]; uint8_t eth_frame[ETH_MTU_SIZE]; int eth_len; + int pkt_pending; }; /** \struct icmphdr @@ -124,6 +126,7 @@ static uint8_t multicast_mac[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; static unsigned int arp_consumer = 0; static unsigned int arp_producer = 0; static arp_entry_t arp_table[ARP_ENTRIES]; +static arp_entry_t pending_pkt; /* Function pointer send_ip. Points either to send_ipv4() or send_ipv6() */ int (*send_ip) (void *, int); @@ -147,6 +150,7 @@ ipv4_init(void) arp_table[i].ipv4_addr = 0; memset(arp_table[i].mac_addr, 0, 6); arp_table[i].eth_len = 0; + arp_table[i].pkt_pending = 0; } /* Set IP send function to send_ipv4() */ @@ -419,7 +423,7 @@ handle_ipv4(uint8_t * ip_packet, int32_t packetsize) int send_ipv4(void* buffer, int len) { - arp_entry_t *arp_entry; + arp_entry_t *arp_entry = 0; struct iphdr *ip; const uint8_t *mac_addr = 0; @@ -493,13 +497,23 @@ send_ipv4(void* buffer, int len) arp_consumer = (arp_consumer+1)%ARP_ENTRIES; // store the packet to be send if the ARP reply is received + arp_entry->pkt_pending = 1; arp_entry->ipv4_addr = ip->ip_dst; memset(arp_entry->mac_addr, 0, 6); - fill_ethhdr (arp_entry->eth_frame, htons(ETHERTYPE_IP), + pending_pkt.ipv4_addr = ip->ip_dst; + memset(pending_pkt.mac_addr, 0, 6); + fill_ethhdr (pending_pkt.eth_frame, htons(ETHERTYPE_IP), get_mac_address(), null_mac_addr); - memcpy(&arp_entry->eth_frame[sizeof(struct ethhdr)], + memcpy(&pending_pkt.eth_frame[sizeof(struct ethhdr)], buffer, len); - arp_entry->eth_len = len + sizeof(struct ethhdr); + pending_pkt.eth_len = len + sizeof(struct ethhdr); + + set_timer(TICKS_SEC); + do { + receive_ether(); + if (!arp_entry->eth_len) + break; + } while (get_timer() > 0); return 0; } @@ -723,11 +737,12 @@ handle_arp(uint8_t * packet, int32_t packetsize) memcpy(arp_table[i].mac_addr, arph->src_mac, 6); // do we have something to send - if(arp_table[i].eth_len > 0) { - struct ethhdr * ethh = (struct ethhdr *) arp_table[i].eth_frame; + if (arp_table[i].pkt_pending) { + struct ethhdr * ethh = (struct ethhdr *) pending_pkt.eth_frame; memcpy(ethh -> dest_mac, arp_table[i].mac_addr, 6); - send_ether(arp_table[i].eth_frame, arp_table[i].eth_len); + send_ether(pending_pkt.eth_frame, pending_pkt.eth_len); + pending_pkt.pkt_pending = 0; arp_table[i].eth_len = 0; } return 0; // no error |