Re: ethernet device xmit function is not gettting called

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

 



hi ravi,
  your net driver doesn't fit into a proper net driver reasons being:
1)what is the char driver doing in a net driver
2)dev->priv is being typecasted to test_struct and assigned to
test_struct c; which itself has net_device variable:
Please remember that dev->priv is used for holding private data like the
statistics etc.,
  Please go thru skeleton of a sample net driver in

/usr/src/linux-2.4.x/drivers/net/pci-skeleton.c
/usr/src/linux-2.4.x/drivers/net/loopback.c

Hope this helps
Regards
Syed

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