diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-01-28 23:28:48 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-01-28 23:28:48 +0100 |
commit | 3f7ad298fd5dd80c0dc017fdd77be23e7861e547 (patch) | |
tree | bed3a33609f64e6977675de2ebb73aad9790228e | |
parent | 3496138ca428a7b2b69fe08e69fb544006a9a2cc (diff) | |
parent | a12a10679017d89194c0dd873f44804b64f71102 (diff) |
Merge branch 'master' into master-slab
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | i386/intel/pmap.c | 2 | ||||
-rw-r--r-- | kern/sched_prim.c | 2 | ||||
-rw-r--r-- | kern/strings.c | 19 | ||||
-rw-r--r-- | xen/net.c | 74 |
5 files changed, 96 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am index 0c98bfd..319b7e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -156,7 +156,7 @@ noinst_PROGRAMS += \ gnumach.o # This is the list of routines we decide is OK to steal from the C library. -clib_routines := memcmp memcpy memmove memset \ +clib_routines := memcmp memcpy memmove \ strchr strstr strsep strtok \ htonl htons ntohl ntohs \ udivdi3 __udivdi3 \ diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c index 94d2e9c..d6e18e5 100644 --- a/i386/intel/pmap.c +++ b/i386/intel/pmap.c @@ -1587,7 +1587,7 @@ void pmap_page_protect(phys, prot) do { #ifdef MACH_XEN if (!hyp_mmu_update_pte(kv_to_ma(pte), *pte & ~INTEL_PTE_WRITE)) - panic("%s:%d could not enable write on pte %p\n",__FILE__,__LINE__,pte); + panic("%s:%d could not disable write on pte %p\n",__FILE__,__LINE__,pte); #else /* MACH_XEN */ *pte &= ~INTEL_PTE_WRITE; #endif /* MACH_XEN */ diff --git a/kern/sched_prim.c b/kern/sched_prim.c index ff942ae..9d4e8af 100644 --- a/kern/sched_prim.c +++ b/kern/sched_prim.c @@ -139,7 +139,7 @@ void thread_check(thread_t, run_queue_t); * The wait event hash table declarations are as follows: */ -#define NUMQUEUES 59 +#define NUMQUEUES 1031 queue_head_t wait_queue[NUMQUEUES]; decl_simple_lock_data(, wait_lock[NUMQUEUES]) diff --git a/kern/strings.c b/kern/strings.c index 80e410e..3676f98 100644 --- a/kern/strings.c +++ b/kern/strings.c @@ -172,3 +172,22 @@ strlen( return string - 1 - ret; } + +/* + * Abstract: + * memset writes value "c" in the "n" bytes starting at address "s". + * The return value is a pointer to the "s" string. + */ + +void * +memset( + void *_s, int c, size_t n) +{ + char *s = _s; + int i; + + for (i = 0; i < n ; i++) + s[i] = c; + + return _s; +} @@ -118,6 +118,61 @@ static void enqueue_rx_buf(struct net_data *nd, int number) { req->gref = nd->rx_buf_gnt[number] = gref; } +static int recompute_checksum(void *data, int len) { + unsigned16_t *header16 = data; + unsigned8_t *header8 = data; + unsigned length, i; + unsigned32_t checksum = 0; + + /* IPv4 header length */ + length = (header8[0] & 0xf) * 4; + if (length < 20) + /* Too small for an IP header16 */ + return -1; + if (length > len) + /* Does not fit in the ethernet frame */ + return -1; + + /* Compute IP header checksum */ + header16[5] = 0; + for (i = 0; i < length/2; i++) + checksum += ntohs(header16[i]); + + while (checksum >> 16) + checksum = (checksum & 0xffff) + (checksum >> 16); + + header16[5] = htons(~checksum); + + if (header8[9] == 6) { + /* Need to fix TCP checksum as well */ + unsigned16_t *tcp_header16 = header16 + length/2; + unsigned8_t *tcp_header8 = header8 + length; + unsigned tcp_length = ntohs(header16[1]) - length; + + /* Pseudo IP header */ + checksum = ntohs(header16[6]) + ntohs(header16[7]) + + ntohs(header16[8]) + ntohs(header16[9]) + + header8[9] + tcp_length; + + tcp_header16[8] = 0; + for (i = 0; i < tcp_length / 2; i++) + checksum += ntohs(tcp_header16[i]); + if (tcp_length & 1) + checksum += tcp_header8[tcp_length-1] << 8; + + while (checksum >> 16) + checksum = (checksum & 0xffff) + (checksum >> 16); + + tcp_header16[8] = htons(~checksum); + } else if (header8[9] == 17) { + /* Drop any bogus checksum */ + unsigned16_t *udp_header16 = header16 + length/2; + udp_header16[3] = 0; + } + + return 0; +} + static void hyp_net_intr(int unit) { ipc_kmsg_t kmsg; struct ether_header *eh; @@ -173,6 +228,25 @@ static void hyp_net_intr(int unit) { data = nd->rx_buf[number] + rx_rsp->offset; len = rx_rsp->status; + if (rx_rsp->flags & NETRXF_csum_blank) { + struct ether_header *ether = data; + + if (!(rx_rsp->flags & NETRXF_data_validated)) { + printf("packet with no checksum and not validated, dropping it\n"); + goto drop_kmsg; + } + + /* TODO: rather tell pfinet to ignore checksums */ + + if (ntohs(ether->ether_type) != 0x0800) { + printf("packet with no checksum and not IPv4, dropping it\n"); + goto drop_kmsg; + } + + if (recompute_checksum(data + sizeof(*ether), len - sizeof(*ether))) + goto drop_kmsg; + } + eh = (void*) (net_kmsg(kmsg)->header); ph = (void*) (net_kmsg(kmsg)->packet); memcpy(eh, data, sizeof (struct ether_header)); |