From 444db750d138693b550fee928bc3d4af2954f700 Mon Sep 17 00:00:00 2001 From: Asias He Date: Wed, 29 Jun 2011 16:47:10 +0800 Subject: [PATCH] kvm tools: Add ICMP support for uip - 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 Signed-off-by: Pekka Enberg --- tools/kvm/Makefile | 1 + tools/kvm/include/kvm/uip.h | 11 +++++++++++ tools/kvm/uip/csum.c | 8 ++++++++ tools/kvm/uip/icmp.c | 29 +++++++++++++++++++++++++++++ tools/kvm/uip/ipv4.c | 8 ++++++++ 5 files changed, 57 insertions(+) create mode 100644 tools/kvm/uip/icmp.c diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index ece542c0a20e..9ad09a43b296 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -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 diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h index 00100e18a467..b9fa932401ff 100644 --- a/tools/kvm/include/kvm/uip.h +++ b/tools/kvm/include/kvm/uip.h @@ -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); diff --git a/tools/kvm/uip/csum.c b/tools/kvm/uip/csum.c index 8023ddbc71aa..c86bfdf74f9a 100644 --- a/tools/kvm/uip/csum.c +++ b/tools/kvm/uip/csum.c @@ -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 index 000000000000..233297caf44b --- /dev/null +++ b/tools/kvm/uip/icmp.c @@ -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; +} diff --git a/tools/kvm/uip/ipv4.c b/tools/kvm/uip/ipv4.c index da53fecdec6b..6175992f4d5e 100644 --- a/tools/kvm/uip/ipv4.c +++ b/tools/kvm/uip/ipv4.c @@ -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; } -- 2.39.5