Jonathan Khoo wrote: > > Hi guys, > > I hacked part of the route.c under /net/ipv6. I made modifications to > ip6_route_output, trying to change the destination address, so that a > different interface will be chosen. This will then affect the hash_val > that will be calculated under neigh_lookup (ndisc.c) used for neighbour > discovery. > > I tested the codes listed below in the user-land and everything is okay. > However, when I merged it into the kernel and it always goes into kernel > panic at the memcpy statement. I must apologize as I am not well versed > with c and always made silly mistakes over pointers. I would appreciate > it if anyone can help point out my errors. > > Thanks in advance. > Jon. > > The codes are basically: > > struct in6_addr *daddr; > > my_function(daddr); > > .... > > (in another file) > void my_function(struct in6_addr *addr) > { > struct in6_addr *newaddr; > .... > memcpy(&(*addr), &(*newaddr), sizeof(struct in6_addr)); This is equivalent to memcpy(addr, newaddr, sizeof(struct in6_addr)); Note that with memcpy, the first argument is the *destination* address. So you are copying the contents of a random memory block (whatever is pointed to by the uninitialized "newaddr") over the address passed in "addr". This is certainly not what you want :-) First, if you want to make a copy of the struct pointed to by "addr", you need a place to put it, so you must either declare a struct in6_addr on the stack, or else declare a pointer (as you've done) and malloc() storage for it to point to. I'll do both: void my_function(struct in6_addr *addr) { struct in6_addr newstruct; struct in6_addr *newaddr; /* Local copy... */ memcpy(&newstruct, addr, sizeof(struct in6_addr)); /* Heap copy... */ newaddr = (struct in6_addr*)malloc(sizeof(struct in6_addr)); memcpy(newaddr,addr,sizeof(struct in6_addr)); /*...*/ /* return &newstruct; WRONG! Don't do this. */ return newaddr; /* And don't forget to free(newaddr) when you're done. */ } Note that you cannot successfully return &newstruct from my_function(), since its storage is allocated in the stack frame in which my_function() executes, and will therefore be destroyed (logically) when my_function() returns to its caller (you might get such code to *appear* to work under a limited set of circumstances, but it's wrong: as soon as some function call needs to re-use the stack space on which newstruct was allocated, it will be destroyed). You *can* return newaddr, the address of an in6_addr allocated on the heap -- but you must be sure to free the malloc'd memory when you are done with it, or else you have a memory leak. A thorough understanding of exactly how functions are called, stack frames constructed, and free storage managed is absolutely critical to successful coding in C, especially at the kernel level. Don't leave home without it. HTH, -- Joe -- "I should like to close this book by sticking out any part of my neck which is not yet exposed, and making a few predictions about how the problem of quantum gravity will in the end be solved." --- Physicist Lee Smolin, "Three Roads to Quantum Gravity" -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ IRC Channel: irc.openprojects.net / #kernelnewbies Web Page: http://www.kernelnewbies.org/