]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Add ICMP support for uip
authorAsias He <asias.hejun@gmail.com>
Wed, 29 Jun 2011 08:47:10 +0000 (16:47 +0800)
committerPekka Enberg <penberg@kernel.org>
Thu, 30 Jun 2011 07:42:02 +0000 (10:42 +0300)
- Introduce struct uip_icmp to present ICMP package

- Implement uip_csum_icmp() to calculate ICMP checksum

- Current ICMP implementation in uip does not really send ICMP package
  to remote host in question, instead it just fake a ICMP reply to fool guest.

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/Makefile
tools/kvm/include/kvm/uip.h
tools/kvm/uip/csum.c
tools/kvm/uip/icmp.c [new file with mode: 0644]
tools/kvm/uip/ipv4.c

index ece542c0a20ef8fa2acfb3b89efa12abfbbb5824..9ad09a43b2968e8dac4ab029bc44946ad1f8de2d 100644 (file)
@@ -46,6 +46,7 @@ OBJS  += disk/raw.o
 OBJS   += ioeventfd.o
 OBJS   += irq.o
 OBJS   += uip/arp.o
+OBJS   += uip/icmp.o
 OBJS   += uip/ipv4.o
 OBJS   += uip/buf.o
 OBJS   += uip/csum.o
index 00100e18a4676c8188cb9d12966fdd523e6a2c53..b9fa932401ff43f6f094a37946835563fbff5274 100644 (file)
@@ -51,6 +51,15 @@ struct uip_ip {
        u32 dip;
 } __attribute__((packed));
 
+struct uip_icmp {
+       struct uip_ip ip;
+       u8 type;
+       u8 code;
+       u16 csum;
+       u16 id;
+       u16 seq;
+} __attribute__((packed));
+
 struct uip_info {
        struct list_head udp_socket_head;
        struct list_head tcp_socket_head;
@@ -100,9 +109,11 @@ static inline u16 uip_ip_len(struct uip_ip *ip)
        return htons(ip->len);
 }
 
+int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
 int uip_tx_do_arp(struct uip_tx_arg *arg);
 
+u16 uip_csum_icmp(struct uip_icmp *icmp);
 u16 uip_csum_ip(struct uip_ip *ip);
 
 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
index 8023ddbc71aab06f4d77f11347205a91637cf80d..c86bfdf74f9a010108c4cb9da7923a6ecfe23925 100644 (file)
@@ -23,3 +23,11 @@ u16 uip_csum_ip(struct uip_ip *ip)
 {
        return uip_csum(0, &ip->vhl, uip_ip_hdrlen(ip));
 }
+
+u16 uip_csum_icmp(struct uip_icmp *icmp)
+{
+       struct uip_ip *ip;
+
+       ip = &icmp->ip;
+       return icmp->csum = uip_csum(0, &icmp->type, htons(ip->len) - uip_ip_hdrlen(ip) - 8); /* icmp header len = 8 */
+}
diff --git a/tools/kvm/uip/icmp.c b/tools/kvm/uip/icmp.c
new file mode 100644 (file)
index 0000000..233297c
--- /dev/null
@@ -0,0 +1,29 @@
+#include "kvm/uip.h"
+
+int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg)
+{
+       struct uip_ip *ip, *ip2;
+       struct uip_icmp *icmp2;
+       struct uip_buf *buf;
+
+       buf             = uip_buf_clone(arg);
+
+       icmp2           = (struct uip_icmp *)(buf->eth);
+       ip2             = (struct uip_ip *)(buf->eth);
+       ip              = (struct uip_ip *)(arg->eth);
+
+       ip2->sip        = ip->dip;
+       ip2->dip        = ip->sip;
+       ip2->csum       = 0;
+       /*
+        * ICMP reply: 0
+        */
+       icmp2->type     = 0;
+       icmp2->csum     = 0;
+       ip2->csum       = uip_csum_ip(ip2);
+       icmp2->csum     = uip_csum_icmp(icmp2);
+
+       uip_buf_set_used(arg->info, buf);
+
+       return 0;
+}
index da53fecdec6bfb14fb3a974c415e5c6ddebf4412..6175992f4d5e51139aacc309e7d499526b191455 100644 (file)
@@ -11,5 +11,13 @@ int uip_tx_do_ipv4(struct uip_tx_arg *arg)
                return -1;
        }
 
+       switch (ip->proto) {
+       case 0x01: /* ICMP */
+               uip_tx_do_ipv4_icmp(arg);
+               break;
+       default:
+               break;
+       }
+
        return 0;
 }