ip_output.c (ip_finish_output2( ))
hello all ,
i faced some probs after recompiling the kernel...
i wrote a module to collect the skbs , which is below ...
i called a function in the module from the ip_finish_output2() function in ip_output.c
exactly inside the if(hh) , i placed the function ptr ,which calls my function in the module...
initially , i used the read_lock_bh() and read_unlock_bh() inside my kernel module ... the things worked ...
PROBLEM started when i recompiled the kernel ...
Now if i try to insmod the same prg , sys is crashing...
what would br the reason ...
mymodule & diff of ip_output.c is here ....
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/netdevice.h>
#include <net/dst.h>
#include <linux/string.h>
#include <linux/timer.h>
struct timer_list my_timer;
extern int (*check_ptr)(struct sk_buff *skb);
struct sk_buff *skb_tmp[10],*skb_gp = NULL;
int k=0;
void release()
{
printk("<0> TIMER EXP\n");
int n=0,size=0;
struct dst_entry *dst = skb_tmp[n]->dst;
struct hh_cache *hh = dst->hh;
char *c;
/*
* To find out total size of all skbs
*/
while(n<k)
size += skb_tmp[n++]->nh.iph->tot_len;
/*
* allocate the new skb
*/
skb_gp = alloc_skb((size + hh->hh_len) , GFP_ATOMIC);
skb_reserve(skb_gp , hh->hh_len);
read_lock_bh(&hh->hh_lock);
c = skb_push(skb_gp, hh->hh_len);
memcpy(c, hh->hh_data, 16);
read_unlock_bh(&hh->hh_lock);
printk("<0> THE SIZE: %d \n",size);
n=0;
/*
* grouping all the skbs into the newskb....
*/
while( n<k){
c = skb_put(skb_gp , skb_tmp[n]->nh.iph->tot_len);
memcpy(c,(const void *)skb_tmp[n],skb_tmp[n]->nh.iph->tot_len);
kfree_skb(skb_tmp[n++]);
skb_tmp[n-1] = NULL;
printk("<0>FREEING:%d \n",n-1);
}
k=0;
c = NULL;
printk("<0> FREEING GROUPED SKB \n");
/*
* The function below is the one used to forward the pkts..
* Based on some tests i found this out...
*/
// hh->hh_output(skb_gp);
kfree_skb(skb_gp);
skb_gp = NULL;
}
int check(struct sk_buff *skb)
{
static int i=0;
if(k==0)
i=0;
if(i >= 10){
printk("<0> ERROR : No Space on Array\n");
kfree_skb(skb);
return 0;
}
skb_tmp[i] = skb;
i++;
k++;
printk("<0> %d \n",i);
/*
* Timer will run for 3 seconds .....
*/
if(i==1){
init_timer(&my_timer);
my_timer.expires = jiffies + 3*HZ;
my_timer.data = 0;
my_timer.function= release;
add_timer(&my_timer);
}
return 0;
}
static int hello_init(void)
{
check_ptr = check;
return 0;
}
static void hello_exit(void)
{
check_ptr=NULL;
printk("out \n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SHRI");
DIFF OF IP_OUTPUT.C
2006-04-28 11:01 diff -lbt ip_output.c ip_output_old.c Page 1
53d52
< #include <linux/module.h>
82,85d80
< int test=1;
< int (*check_ptr)(struct sk_buff *skb)=NULL;
< EXPORT_SYMBOL(check_ptr);
<
186,192d169
< if(test){
< if(check_ptr){
< return (*check_ptr)(skb);
< }
< }
|