The following is my code to allocate new socket buffer with new 'skb->truesize'.
/* skbhandle.h
*
* C header file - Socket buffer handling module added on by blusjune.
*
* Last modified:
* A.D. 2000. 06. 22. THU.
*
* Author:
* | blusjune@nirva | ^_^ | stoneroses |
*/
#ifndef _SKBHANDLE_H_
#define _SKBHANDLE_H_
#include <linux/skbuff.h>
int skb_replace_with_newsize(
struct sk_buff *nskb,
struct sk_buff *oldskb,
unsigned int nskb_truesize
);
struct sk_buff *skb_copy_with_newsize(
struct sk_buff *skb,
int gfp_mask,
unsigned int nskb_truesize
);
#endif /* _SKBHANDLE_H_ */
/* skbhandle.c
*
* C source file - Socket buffer handling module added on by blusjune.
*
* Last modified:
* A.D. 2000. 06. 22. THU.
*
* Author:
* | blusjune@nirva | ^_^ | stoneroses |
*/
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/dst.h>
#include <net/skbhandle.h>
__inline__ int skb_replace_with_newsize(
struct sk_buff *nskb,
struct sk_buff *oldskb,
unsigned int nskb_truesize
)
{
// nskb = skb_copy_with_newsize(oldskb, GFP_ATOMIC, nskb_truesize);
nskb = skb;
if (!nskb)
{
printk("\nError: NULL skb poiner returned!.");
return -1;
}
return 0;
}
struct sk_buff *skb_copy_with_newsize(
struct sk_buff *skb,
int gfp_mask,
unsigned int nskb_truesize
)
{
struct sk_buff *n;
unsigned long offset;
unsigned int skb_truesize = skb->end - skb->head;
/*
* Allocate the copy buffer
*/
n = alloc_skb(nskb_truesize, gfp_mask);
if (n == NULL)
{
printk("\nalloc_skb(): returns a NULL pointer.");
return NULL;
}
/*
* Shift between the two data areas in bytes
*/
offset = n->head - skb->head;
/* Set the data pointer */
skb_reserve(n, skb->data - skb->head);
/* Set the tail pointer and length */
skb_put(n, skb->len + nskb_truesize - skb_truesize);
/* Copy the bytes */
if (nskb_truesize > skb_truesize)
memcpy(n->head, skb->head, skb_truesize);
else
memcpy(n->head, skb->head, nskb_truesize);
/* explicit skb->len substitution */
n->len = skb->len + nskb_truesize - skb_truesize;
/* explicit skb->truesize substitution */
n->truesize = nskb_truesize;
n->csum = skb->csum;
n->list = NULL;
n->sk = NULL;
n->dev = skb->dev;
n->priority = skb->priority;
n->protocol = skb->protocol;
n->dst = dst_clone(skb->dst);
n->h.raw = skb->h.raw + offset;
n->nh.raw = skb->nh.raw + offset;
n->mac.raw = skb->mac.raw + offset;
memcpy(n->cb, skb->cb, sizeof(skb->cb));
n->used = skb->used;
n->is_clone = 0;
atomic_set(&n->users, 1);
n->pkt_type = skb->pkt_type;
n->stamp = skb->stamp;
n->destructor = NULL;
n->security = skb->security;
#ifdef CONFIG_IP_FIREWALL
n->fwmark = skb->fwmark;
#endif
return n;
}
The objectives of the code above are
to allocate new socket buffer with new skb->truesize,
to have the same contents with the original socket buffer (i.e., carbon copy except socket buffer size).
After finishing kernel compile(no warning, no error), I reboot the computer as the newly created kernel image.
After some boot strapping messages are scrolled,
kernel panic has occurred with the following message:
<1>Unable to handle kernel NULL pointer dereference at virtual address 00000004
current->tss.cr3 = 00101000, %cr3 = 00101000
*pde = 00000000
Oops: 0002
CPU: 0
EIP: 0010: [<c016fe8e>]
EFLAGS: 00010296
eax: .............. /* register values */ .................
esi: .............. /* register values */ .................
ds: 0018 es: 0018 ss: 0018
Process swapper (pid: 0, process nr: 0, stackpage = c01fb000)
Stack: .............. /* Stack values */ ..................
Call Trace: ............
Code: 89 4d 04 89 0f 89 71 08 ff 46 08 5b 5e 5f 5d 83 c4 08 c3 90
Aiee, killing interrupt handler
Kernel panic: Attempted to kill the idle task!
In swapper task - not syncing
So I analized my code included in kernel(ip_output.c, ip_input.c).
After a few minutes, I've got found out the fact that the return value of skb_copy_with_newsize() is 'NULL'.
But... I can't understand why 'NULL' pointer should be returned whenever kernel uses it.
Would you mind teaching me why?
Thank you.
-- | blusjune@nirva | ^_^ | stoneroses | Blusjune Jung Email: blusjune@yahoo.com- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Fri Jun 23 2000 - 21:00:25 EST