Re: ethernet device xmit function is not gettting called

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks Bhaskar,
That helped me. Now the bridge is calling xmit function.
-Ravi


Bhaskar-ROCSYS wrote:

Hi,
The only place where u can get kernel panic is in the xmit function. Check if the oldhdr value is NULL.


Regards
bhaskar
On Mon, 2004-06-28 at 18:48, Ravi Kumar wrote:


Hi,
I wrote a module to create dummy ethernet device, the intention is to add it to a bridge and transmit modified packets. I get ethernet device created but its xmit function is not called when the bridge receives a packet.


I feel I have missed some information to register netdevice.

To add to bridge I did the following:
brctl addbr br0
brctl addif bro eth0
brctl addif br0 firsteth0
ifconfig etho 0.0.0.0
ifconfig bro 172.16.2.100 up

When I try to add IP address to firsteth0, I get a kernel panic!!
Can we give IP to dummy ethernet device?

Please help, I am given little time to complete this :( I am attaching the code for the dummy ethernet device.
-Ravi
----







#ifndef __KERNEL__
#   define __KERNEL__
#endif

#ifndef MODULE
#  define MODULE
#endif

#define DEVNAME "firsteth"

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/slab.h>

#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>

/* netfilters related */
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

#include <linux/in.h>
#include <linux/udp.h>
#include <net/ip.h>

int test_open(struct inode *,struct file *);
int test_release(struct inode *,struct file*);


struct test_struct{ struct net_device *dev; char name[IFNAMSIZ]; };

struct file_operations test_fop={
llseek:  	NULL,
read:   	NULL,
write:  	NULL,
ioctl:  	NULL,
open:   	test_open,
release: 	test_release,
};


struct test_struct pTestStruct;


static int testdev_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct iphdr *oldiph;
unsigned char tos=0;
unsigned short df =0;
unsigned char ttl;

printk(KERN_INFO " In xmit function\n");
oldiph = (skb->protocol==htons(ETH_P_IP))
? (struct iphdr*)(skb->data+ETH_HLEN)
: NULL;

tos = oldiph->tos;
df = oldiph->frag_off;
ttl = oldiph->ttl;
printk(KERN_INFO"src IP: %x dst IP: %x , protocol %d \n",ntohl(oldiph->saddr), ntohl(oldiph->daddr),oldiph->protocol);
return 0;
}


int test_open(struct inode *inode, struct file *filep)
{
	MOD_INC_USE_COUNT;
	return 0;
}

int test_release(struct inode *inode, struct file *filep)
{
	MOD_DEC_USE_COUNT;
	return 0;
}

int testdev_open(struct net_device *dev)
{
	MOD_INC_USE_COUNT;
	return 0;
}

int testdev_close(struct net_device *dev)
{
unregister_netdev(dev);
MOD_DEC_USE_COUNT;
return 0;
}
//t test_ioctl(struct inode *inode, static int test_init_dev(struct net_device *dev)
{
struct test_struct *c;


	printk(KERN_INFO "in test_init_dev\n");
	
	c = (struct test_struct *)dev->priv;
	if(!c)
		return -ENODEV;

	memset(c,0,sizeof(struct test_struct));
       c->dev = dev;			

      // ether_setup(dev);	
	dev->open  = testdev_open;
	dev->stop  = testdev_close;
	dev->hard_start_xmit        = testdev_xmit;
	dev->mtu   = ETH_DATA_LEN - sizeof(struct udphdr) - sizeof(struct iphdr) ;
       dev_init_buffers(dev);

	printk(KERN_INFO "completed test_init_dev\n");
	return 0;
}
			

int init_module(void)
{
	int result,i;
       struct net_device *tempDev;
	struct test_struct *temp_struct;
       char devname[25]; // Remove the hardcode


for(i=0;i<99;i++)
{
sprintf(devname,"firseth%d",i);
if(__dev_get_by_name(devname) == NULL)
break;
}
if(i==100)
return -ENFILE;
printk(KERN_INFO "********MACOUDP TUNNEL******\n");
temp_struct = (struct test_struct *)kmalloc(sizeof(struct test_struct),GFP_KERNEL);
if(!temp_struct)
{
printk(KERN_ERR "error in allocating memory\n");
return -ENOMEM;
}
result = register_chrdev(244,"testdrv",&test_fop);
if( result != 0 ){
printk(KERN_WARNING "test: cant get major\n");
return result;
}
i=0;
memset(temp_struct,0,sizeof(struct test_struct));
//sprintf(temp_struct->name, DEVNAME "%d",i);
tempDev = (struct net_device *)kmalloc(sizeof(struct net_device),GFP_KERNEL);
if( !tempDev)
{
printk(KERN_ERR "kmalloc faied\n");
return -ENOMEM;
}
memset(tempDev,0,sizeof(struct net_device));
temp_struct->dev = tempDev;
temp_struct->dev->priv = &pTestStruct;
temp_struct->dev->next = NULL;
temp_struct->dev->base_addr=0;
temp_struct->dev->init = test_init_dev;
temp_struct->dev->dev_addr[0]=0xFC;
temp_struct->dev->dev_addr[1]=0xFC;
temp_struct->dev->dev_addr[2]=0xA;
temp_struct->dev->dev_addr[3]=0xB;
temp_struct->dev->dev_addr[4]=0xC;
temp_struct->dev->addr_len = ETH_ALEN;
i = dev_alloc_name(temp_struct->dev,"firsteth%d");
if(i < 0 )
{
printk(KERN_ERR "cant allocate device\n");
return -ENODEV;
}
ether_setup(temp_struct->dev);
rtnl_lock();
printk(KERN_INFO "Before calling register_netdevice\n");
i = register_netdevice((temp_struct->dev));
rtnl_unlock();
memcpy(&pTestStruct,temp_struct,sizeof(struct test_struct));
if( i < 0 ){
printk(KERN_ERR "register netdevice failed\n");
return -1;
}
return 0;
}


void cleanup_module(void)
{
       rtnl_lock();
	unregister_netdevice(pTestStruct.dev);
	rtnl_unlock();
	unregister_chrdev(244,"testdrv");
}
















--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux