net: add queue for peer-to-peer packet forwarding
Now that we have re-factored the packet queue code, we can re-use it for peer-to-peer also. Patchworks-ID: 35520 Signed-off-by: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									f710584399
								
							
						
					
					
						commit
						9a6ecb308b
					
				
							
								
								
									
										113
									
								
								net.c
								
								
								
								
							
							
						
						
									
										113
									
								
								net.c
								
								
								
								
							| 
						 | 
					@ -301,6 +301,15 @@ static char *assign_name(VLANClientState *vc1, const char *model)
 | 
				
			||||||
    return qemu_strdup(buf);
 | 
					    return qemu_strdup(buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t qemu_deliver_packet(VLANClientState *sender,
 | 
				
			||||||
 | 
					                                   const uint8_t *data,
 | 
				
			||||||
 | 
					                                   size_t size,
 | 
				
			||||||
 | 
					                                   void *opaque);
 | 
				
			||||||
 | 
					static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
 | 
				
			||||||
 | 
					                                       const struct iovec *iov,
 | 
				
			||||||
 | 
					                                       int iovcnt,
 | 
				
			||||||
 | 
					                                       void *opaque);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VLANClientState *qemu_new_vlan_client(VLANState *vlan,
 | 
					VLANClientState *qemu_new_vlan_client(VLANState *vlan,
 | 
				
			||||||
                                      VLANClientState *peer,
 | 
					                                      VLANClientState *peer,
 | 
				
			||||||
                                      const char *model,
 | 
					                                      const char *model,
 | 
				
			||||||
| 
						 | 
					@ -336,6 +345,10 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
 | 
				
			||||||
            peer->peer = vc;
 | 
					            peer->peer = vc;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
 | 
					        QTAILQ_INSERT_TAIL(&non_vlan_clients, vc, next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vc->send_queue = qemu_new_net_queue(qemu_deliver_packet,
 | 
				
			||||||
 | 
					                                            qemu_deliver_packet_iov,
 | 
				
			||||||
 | 
					                                            vc);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return vc;
 | 
					    return vc;
 | 
				
			||||||
| 
						 | 
					@ -346,6 +359,9 @@ void qemu_del_vlan_client(VLANClientState *vc)
 | 
				
			||||||
    if (vc->vlan) {
 | 
					    if (vc->vlan) {
 | 
				
			||||||
        QTAILQ_REMOVE(&vc->vlan->clients, vc, next);
 | 
					        QTAILQ_REMOVE(&vc->vlan->clients, vc, next);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (vc->send_queue) {
 | 
				
			||||||
 | 
					            qemu_del_net_queue(vc->send_queue);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        QTAILQ_REMOVE(&non_vlan_clients, vc, next);
 | 
					        QTAILQ_REMOVE(&non_vlan_clients, vc, next);
 | 
				
			||||||
        if (vc->peer) {
 | 
					        if (vc->peer) {
 | 
				
			||||||
            vc->peer->peer = NULL;
 | 
					            vc->peer->peer = NULL;
 | 
				
			||||||
| 
						 | 
					@ -405,6 +421,15 @@ int qemu_can_send_packet(VLANClientState *sender)
 | 
				
			||||||
    VLANState *vlan = sender->vlan;
 | 
					    VLANState *vlan = sender->vlan;
 | 
				
			||||||
    VLANClientState *vc;
 | 
					    VLANClientState *vc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (sender->peer) {
 | 
				
			||||||
 | 
					        if (!sender->peer->can_receive ||
 | 
				
			||||||
 | 
					            sender->peer->can_receive(sender->peer)) {
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!sender->vlan) {
 | 
					    if (!sender->vlan) {
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -422,6 +447,20 @@ int qemu_can_send_packet(VLANClientState *sender)
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t qemu_deliver_packet(VLANClientState *sender,
 | 
				
			||||||
 | 
					                                   const uint8_t *data,
 | 
				
			||||||
 | 
					                                   size_t size,
 | 
				
			||||||
 | 
					                                   void *opaque)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    VLANClientState *vc = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vc->link_down) {
 | 
				
			||||||
 | 
					        return size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return vc->receive(vc, data, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
 | 
					static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
 | 
				
			||||||
                                        const uint8_t *buf,
 | 
					                                        const uint8_t *buf,
 | 
				
			||||||
                                        size_t size,
 | 
					                                        size_t size,
 | 
				
			||||||
| 
						 | 
					@ -453,35 +492,56 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void qemu_purge_queued_packets(VLANClientState *vc)
 | 
					void qemu_purge_queued_packets(VLANClientState *vc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!vc->vlan)
 | 
					    NetQueue *queue;
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_net_queue_purge(vc->vlan->send_queue, vc);
 | 
					    if (!vc->peer && !vc->vlan) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vc->peer) {
 | 
				
			||||||
 | 
					        queue = vc->peer->send_queue;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        queue = vc->vlan->send_queue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qemu_net_queue_purge(queue, vc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void qemu_flush_queued_packets(VLANClientState *vc)
 | 
					void qemu_flush_queued_packets(VLANClientState *vc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!vc->vlan)
 | 
					    NetQueue *queue;
 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_net_queue_flush(vc->vlan->send_queue);
 | 
					    if (vc->vlan) {
 | 
				
			||||||
 | 
					        queue = vc->vlan->send_queue;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        queue = vc->send_queue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qemu_net_queue_flush(queue);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ssize_t qemu_send_packet_async(VLANClientState *sender,
 | 
					ssize_t qemu_send_packet_async(VLANClientState *sender,
 | 
				
			||||||
                               const uint8_t *buf, int size,
 | 
					                               const uint8_t *buf, int size,
 | 
				
			||||||
                               NetPacketSent *sent_cb)
 | 
					                               NetPacketSent *sent_cb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (sender->link_down || !sender->vlan) {
 | 
					    NetQueue *queue;
 | 
				
			||||||
        return size;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef DEBUG_NET
 | 
					#ifdef DEBUG_NET
 | 
				
			||||||
    printf("qemu_send_packet_async:\n");
 | 
					    printf("qemu_send_packet_async:\n");
 | 
				
			||||||
    hex_dump(stdout, buf, size);
 | 
					    hex_dump(stdout, buf, size);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return qemu_net_queue_send(sender->vlan->send_queue,
 | 
					    if (sender->link_down || (!sender->peer && !sender->vlan)) {
 | 
				
			||||||
                               sender, buf, size, sent_cb);
 | 
					        return size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (sender->peer) {
 | 
				
			||||||
 | 
					        queue = sender->peer->send_queue;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        queue = sender->vlan->send_queue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return qemu_net_queue_send(queue, sender, 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)
 | 
				
			||||||
| 
						 | 
					@ -517,6 +577,24 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
 | 
				
			||||||
    return offset;
 | 
					    return offset;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
 | 
				
			||||||
 | 
					                                       const struct iovec *iov,
 | 
				
			||||||
 | 
					                                       int iovcnt,
 | 
				
			||||||
 | 
					                                       void *opaque)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    VLANClientState *vc = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vc->link_down) {
 | 
				
			||||||
 | 
					        return calc_iov_length(iov, iovcnt);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vc->receive_iov) {
 | 
				
			||||||
 | 
					        return vc->receive_iov(vc, iov, iovcnt);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return vc_sendv_compat(vc, iov, iovcnt);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
 | 
					static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
 | 
				
			||||||
                                            const struct iovec *iov,
 | 
					                                            const struct iovec *iov,
 | 
				
			||||||
                                            int iovcnt,
 | 
					                                            int iovcnt,
 | 
				
			||||||
| 
						 | 
					@ -554,12 +632,19 @@ ssize_t qemu_sendv_packet_async(VLANClientState *sender,
 | 
				
			||||||
                                const struct iovec *iov, int iovcnt,
 | 
					                                const struct iovec *iov, int iovcnt,
 | 
				
			||||||
                                NetPacketSent *sent_cb)
 | 
					                                NetPacketSent *sent_cb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (sender->link_down || !sender->vlan) {
 | 
					    NetQueue *queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (sender->link_down || (!sender->peer && !sender->vlan)) {
 | 
				
			||||||
        return calc_iov_length(iov, iovcnt);
 | 
					        return calc_iov_length(iov, iovcnt);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return qemu_net_queue_send_iov(sender->vlan->send_queue,
 | 
					    if (sender->peer) {
 | 
				
			||||||
                                   sender, iov, iovcnt, sent_cb);
 | 
					        queue = sender->peer->send_queue;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        queue = sender->vlan->send_queue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return qemu_net_queue_send_iov(queue, sender, iov, iovcnt, sent_cb);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ssize_t
 | 
					ssize_t
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								net.h
								
								
								
								
							
							
						
						
									
										1
									
								
								net.h
								
								
								
								
							| 
						 | 
					@ -28,6 +28,7 @@ struct VLANClientState {
 | 
				
			||||||
    QTAILQ_ENTRY(VLANClientState) next;
 | 
					    QTAILQ_ENTRY(VLANClientState) next;
 | 
				
			||||||
    struct VLANState *vlan;
 | 
					    struct VLANState *vlan;
 | 
				
			||||||
    VLANClientState *peer;
 | 
					    VLANClientState *peer;
 | 
				
			||||||
 | 
					    NetQueue *send_queue;
 | 
				
			||||||
    char *model;
 | 
					    char *model;
 | 
				
			||||||
    char *name;
 | 
					    char *name;
 | 
				
			||||||
    char info_str[256];
 | 
					    char info_str[256];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue