mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-31 22:11:53 -06:00
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:
parent
1a0ca1e1f6
commit
1ab74cea06
5 changed files with 69 additions and 37 deletions
28
slirp/if.c
28
slirp/if.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue