Delayed IP packets

In the current implementation, if Slirp tries to send an IP packet to a client
with an unknown hardware address, the packet is simply dropped and an ARP
request is sent (if_encap in slirp/slirp.c).

With this patch, Slirp will send the ARP request, re-queue the packet and try
to send it later. The packet is dropped after one second if the ARP reply is
not received.

Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This commit is contained in:
Fabien Chouteau 2011-08-01 18:18:37 +02:00 committed by Jan Kiszka
parent 1a0ca1e1f6
commit 1ab74cea06
5 changed files with 69 additions and 37 deletions

View file

@ -6,6 +6,7 @@
*/
#include <slirp.h>
#include "qemu-timer.h"
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
@ -105,6 +106,9 @@ if_output(struct socket *so, struct mbuf *ifm)
ifs_init(ifm);
insque(ifm, ifq);
/* Expiration date = Now + 1 second */
ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL;
diddit:
slirp->if_queued++;
@ -153,6 +157,9 @@ diddit:
void
if_start(Slirp *slirp)
{
int requeued = 0;
uint64_t now;
struct mbuf *ifm, *ifqt;
DEBUG_CALL("if_start");
@ -165,6 +172,8 @@ if_start(Slirp *slirp)
if (!slirp_can_output(slirp->opaque))
return;
now = qemu_get_clock_ns(rt_clock);
/*
* See which queue to get next packet from
* If there's something in the fastq, select it immediately
@ -199,11 +208,22 @@ if_start(Slirp *slirp)
ifm->ifq_so->so_nqueued = 0;
}
/* Encapsulate the packet for sending */
if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len);
m_free(ifm);
if (ifm->expiration_date < now) {
/* Expired */
m_free(ifm);
} else {
/* Encapsulate the packet for sending */
if (if_encap(slirp, ifm)) {
m_free(ifm);
} else {
/* re-queue */
insque(ifm, ifqt);
requeued++;
}
}
if (slirp->if_queued)
goto again;
slirp->if_queued = requeued;
}