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/