From patchwork Thu Jun 30 08:41:10 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asias He X-Patchwork-Id: 932352 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5U8jSuP014473 for ; Thu, 30 Jun 2011 08:45:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758910Ab1F3Ip0 (ORCPT ); Thu, 30 Jun 2011 04:45:26 -0400 Received: from mail-iw0-f174.google.com ([209.85.214.174]:43568 "EHLO mail-iw0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757363Ab1F3IpZ (ORCPT ); Thu, 30 Jun 2011 04:45:25 -0400 Received: by mail-iw0-f174.google.com with SMTP id 6so1718423iwn.19 for ; Thu, 30 Jun 2011 01:45:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=bOh+5iWxxaKBc8btxzYS+1PiDzj0er9/1mYptnWcJys=; b=Qsd+e6Dssvw8g8k+fVGcbkD+S3PqvIXS+xC1eNths37nWqB0wCBsn+qkXPAuEAjyLv ucoBUhlcN9rnQ3zFNXEOYNGid7DpEX34dsRmhfzqUvP9oX7hHe1Yol9b2cV1LHSUrhMA 6NjH6vQFp+Jy5VWqKiJpYF3N3nB8mIRJMKoPg= Received: by 10.42.155.74 with SMTP id t10mr1680858icw.527.1309423524132; Thu, 30 Jun 2011 01:45:24 -0700 (PDT) Received: from localhost.localdomain ([219.224.169.130]) by mx.google.com with ESMTPS id d6sm1967338icx.1.2011.06.30.01.45.20 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 30 Jun 2011 01:45:23 -0700 (PDT) From: Asias He To: Pekka Enberg Cc: Cyrill Gorcunov , Ingo Molnar , Sasha Levin , Prasad Joshi , kvm@vger.kernel.org, Asias He Subject: [PATCH v2 22/31] kvm tools: Introduce uip_tx() for uip Date: Thu, 30 Jun 2011 16:41:10 +0800 Message-Id: <1309423279-3093-23-git-send-email-asias.hejun@gmail.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1309423279-3093-1-git-send-email-asias.hejun@gmail.com> References: <1309423279-3093-1-git-send-email-asias.hejun@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 30 Jun 2011 08:45:29 +0000 (UTC) This patch implement tx interface for uip. uip_tx() can be called in virtio_net_tx_thread(). It dispatches ethernet frame to ARP or IP handling code. Signed-off-by: Asias He --- tools/kvm/include/kvm/uip.h | 2 + tools/kvm/uip/core.c | 69 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 0 deletions(-) diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h index c300de0..38ad386 100644 --- a/tools/kvm/include/kvm/uip.h +++ b/tools/kvm/include/kvm/uip.h @@ -12,6 +12,7 @@ #define UIP_BUF_STATUS_USED 2 #define UIP_ETH_P_IP 0X0800 +#define UIP_ETH_P_ARP 0X0806 #define UIP_IP_VER_4 0X40 #define UIP_IP_HDR_LEN 0X05 @@ -267,6 +268,7 @@ static inline u16 uip_eth_hdrlen(struct uip_eth *eth) return sizeof(*eth); } +int uip_tx(struct iovec *iov, u16 out, struct uip_info *info); int uip_init(struct uip_info *info); int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg); diff --git a/tools/kvm/uip/core.c b/tools/kvm/uip/core.c index 58eba6b..3a37546 100644 --- a/tools/kvm/uip/core.c +++ b/tools/kvm/uip/core.c @@ -5,6 +5,75 @@ #include #include +int uip_tx(struct iovec *iov, u16 out, struct uip_info *info) +{ + struct virtio_net_hdr *vnet; + struct uip_tx_arg arg; + int eth_len, vnet_len; + struct uip_eth *eth; + u8 *buf = NULL; + u16 proto; + int i; + + /* + * Buffer from guest to device + */ + vnet_len = iov[0].iov_len; + vnet = iov[0].iov_base; + + eth_len = iov[1].iov_len; + eth = iov[1].iov_base; + + /* + * In case, ethernet frame is in more than one iov entry. + * Copy iov buffer into one linear buffer. + */ + if (out > 2) { + eth_len = 0; + for (i = 1; i < out; i++) + eth_len += iov[i].iov_len; + + buf = malloc(eth_len); + if (!buf) + return -1; + + eth = (struct uip_eth *)buf; + for (i = 1; i < out; i++) { + memcpy(buf, iov[i].iov_base, iov[i].iov_len); + buf += iov[i].iov_len; + } + } + + memset(&arg, 0, sizeof(arg)); + + arg.vnet_len = vnet_len; + arg.eth_len = eth_len; + arg.info = info; + arg.vnet = vnet; + arg.eth = eth; + + /* + * Check package type + */ + proto = ntohs(eth->type); + + switch (proto) { + case UIP_ETH_P_ARP: + uip_tx_do_arp(&arg); + break; + case UIP_ETH_P_IP: + uip_tx_do_ipv4(&arg); + break; + default: + break; + } + + if (out > 2 && buf) + free(eth); + + return vnet_len + eth_len; +} + int uip_init(struct uip_info *info) { struct list_head *udp_socket_head;