net: add an API for 'raw' packets
In the case where a NIC and backend agree on a packet header format, this API allows injecting packets which lack the agreed upon header. We need this for sending our gratuitous ARP. Signed-off-by: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
c0b8e49c69
commit
ca77d17591
@ -44,6 +44,7 @@ typedef ssize_t (NetPacketDeliverIOV) (VLANClientState *sender,
|
|||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
#define QEMU_NET_PACKET_FLAG_NONE 0
|
#define QEMU_NET_PACKET_FLAG_NONE 0
|
||||||
|
#define QEMU_NET_PACKET_FLAG_RAW (1<<0)
|
||||||
|
|
||||||
NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
|
NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
|
||||||
NetPacketDeliverIOV *deliver_iov,
|
NetPacketDeliverIOV *deliver_iov,
|
||||||
|
37
net.c
37
net.c
@ -478,7 +478,10 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vc->receive(vc, data, size);
|
if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw)
|
||||||
|
return vc->receive_raw(vc, data, size);
|
||||||
|
else
|
||||||
|
return vc->receive(vc, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
|
static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
|
||||||
@ -503,7 +506,10 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = vc->receive(vc, buf, size);
|
if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw)
|
||||||
|
len = vc->receive_raw(vc, buf, size);
|
||||||
|
else
|
||||||
|
len = vc->receive(vc, buf, size);
|
||||||
|
|
||||||
ret = (ret >= 0) ? ret : len;
|
ret = (ret >= 0) ? ret : len;
|
||||||
}
|
}
|
||||||
@ -541,9 +547,10 @@ void qemu_flush_queued_packets(VLANClientState *vc)
|
|||||||
qemu_net_queue_flush(queue);
|
qemu_net_queue_flush(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t qemu_send_packet_async(VLANClientState *sender,
|
static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
|
||||||
const uint8_t *buf, int size,
|
unsigned flags,
|
||||||
NetPacketSent *sent_cb)
|
const uint8_t *buf, int size,
|
||||||
|
NetPacketSent *sent_cb)
|
||||||
{
|
{
|
||||||
NetQueue *queue;
|
NetQueue *queue;
|
||||||
|
|
||||||
@ -562,9 +569,15 @@ ssize_t qemu_send_packet_async(VLANClientState *sender,
|
|||||||
queue = sender->vlan->send_queue;
|
queue = sender->vlan->send_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return qemu_net_queue_send(queue, sender,
|
return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
|
||||||
QEMU_NET_PACKET_FLAG_NONE,
|
}
|
||||||
buf, size, sent_cb);
|
|
||||||
|
ssize_t qemu_send_packet_async(VLANClientState *sender,
|
||||||
|
const uint8_t *buf, int size,
|
||||||
|
NetPacketSent *sent_cb)
|
||||||
|
{
|
||||||
|
return qemu_send_packet_async_with_flags(sender, QEMU_NET_PACKET_FLAG_NONE,
|
||||||
|
buf, size, sent_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
|
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
|
||||||
@ -572,6 +585,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
|
|||||||
qemu_send_packet_async(vc, buf, size, NULL);
|
qemu_send_packet_async(vc, buf, size, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size)
|
||||||
|
{
|
||||||
|
return qemu_send_packet_async_with_flags(vc, QEMU_NET_PACKET_FLAG_RAW,
|
||||||
|
buf, size, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
|
static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
|
||||||
int iovcnt)
|
int iovcnt)
|
||||||
{
|
{
|
||||||
@ -641,6 +660,8 @@ static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
|
||||||
|
|
||||||
if (vc->receive_iov) {
|
if (vc->receive_iov) {
|
||||||
len = vc->receive_iov(vc, iov, iovcnt);
|
len = vc->receive_iov(vc, iov, iovcnt);
|
||||||
} else {
|
} else {
|
||||||
|
2
net.h
2
net.h
@ -45,6 +45,7 @@ typedef void (LinkStatusChanged)(VLANClientState *);
|
|||||||
struct VLANClientState {
|
struct VLANClientState {
|
||||||
net_client_type type;
|
net_client_type type;
|
||||||
NetReceive *receive;
|
NetReceive *receive;
|
||||||
|
NetReceive *receive_raw;
|
||||||
NetReceiveIOV *receive_iov;
|
NetReceiveIOV *receive_iov;
|
||||||
/* Packets may still be sent if this returns zero. It's used to
|
/* Packets may still be sent if this returns zero. It's used to
|
||||||
rate-limit the slirp code. */
|
rate-limit the slirp code. */
|
||||||
@ -89,6 +90,7 @@ ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov,
|
|||||||
ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov,
|
ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov,
|
||||||
int iovcnt, NetPacketSent *sent_cb);
|
int iovcnt, NetPacketSent *sent_cb);
|
||||||
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
|
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
|
||||||
|
ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size);
|
||||||
ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
|
ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
|
||||||
int size, NetPacketSent *sent_cb);
|
int size, NetPacketSent *sent_cb);
|
||||||
void qemu_purge_queued_packets(VLANClientState *vc);
|
void qemu_purge_queued_packets(VLANClientState *vc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user