<< | Thread Index | >> ]    [ << | Date Index | >> ]

To: cipe-l,AT,inka,DOT,de
Subject: Bridge Mode
From: Ravi Kumar <ravivsn,AT,rocsys,DOT,com>
Date: Mon, 28 Jun 2004 18:37:14 +0530

Hi,
Did any one using cipe in bridge mode?
I have a question for cipe developers. I took cipe ethernet device creation as reference, but I could not make it work. I am attaching the code.
Does ethernet interface created takes IP address?
I am not getting xmit function called!! Please help.


Thanks,
-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");
}

<< | Thread Index | >> ]    [ << | Date Index | >> ]