Compiling virtual network adapter driver problem (net_device struct)

Hi,
I found on Writing a Network device driver - Part 1 LG #93 page very useful sample of virtual driver (not connected to real hardware).
I try to compile it with no effect.
So:
I got fresh Ubuntu 9.10 (kernel 2.6.31-14)
My source is saved in networkAdapter.c file in /usr/src/myModules directory.
I created Makefile too with: obj-m = networkAdapter.o content in /usr/src/myModules directory.
I try to compile with:

make -C /usr/src/linux-headers-2.6.31-14-generic/ M=$(pwd) modules
cc -I /usr/src/linux-headers-2.6.31-14-generic/include/ -c networkAdapter.c

being in /usr/src/myModules directory.

Make -c ... output contains 3 errors:

'struct net_device' has no member named 'open'
'struct net_device' has no member named 'stop'
'struct net_device' has no member named 'hard_start_xmit'

cc -I ... output is very long and contains lots of errors.

Could you give me some hints how to compile it?

Regards.

#define MODULE             
    #define __KERNEL__     
    
    #include < linux/module.h >  
    #include < linux/config.h >  

     #include < linux/netdevice.h > 
    
    int rtl8139_open (struct net_device *dev)
    {
        printk("rtl8139_open called\n");
        netif_start_queue (dev);
        return 0;
    }

    int rtl8139_release (struct net_device *dev)
    {
        printk ("rtl8139_release called\n");
        netif_stop_queue(dev);
        return 0;
    }

    static int rtl8139_xmit (struct sk_buff *skb, 
                    struct net_device *dev)
    {
        printk ("dummy xmit function called....\n");
        dev_kfree_skb(skb);
        return 0;
    }

    int rtl8139_init (struct net_device *dev)
    {
        dev->open = rtl8139_open;
        dev->stop = rtl8139_release;
        dev->hard_start_xmit = rtl8139_xmit;
        printk ("8139 device initialized\n");
        return 0;
    }

    struct net_device rtl8139 = {init: rtl8139_init};

    int rtl8139_init_module (void)
    {
        int result;

        strcpy (rtl8139.name, "rtl8139");
        if ((result = register_netdev (&rtl8139))) {
            printk ("rtl8139: Error %d  initializing card rtl8139 card",result);
            return result;
        }
    return 0;
    }
    
     void rtl8139_cleanup (void)
    {
        printk ("<0> Cleaning Up the Module\n");
        unregister_netdev (&rtl8139);
        return;
    }
    
    module_init (rtl8139_init_module);
    module_exit (rtl8139_cleanup);

This is very old code in terms of Linux. Kernel network structures have changed significantly since 2003.

Yes, I have made a little research and found that net_device struct is a little bit different since 2009. I am trying to fit this code to new net_device struct that is no so easy.
Have you got any samples of network drivers basic source code?

I got now:

#include <linux/module.h>
#include <linux/config.h>
#include <linux/netdevice.h>


int virtualNIC_open(struct net_device *dev) {
 printk("virtualNIC_open called\n");
 netif_start_queue(dev);
 return 0;
}

int virtualNIC_release(struct net_device *dev) {
 printk("virtualNIC_release called\n");
 netif_stop_queue(dev);
 return 0;
}

static int virtualNIC_xmit(struct sk_buff *skb, struct net_device *dev) {
 printk("dummy xmit function called...\n");
 dev_kfree_skb(skb);
 return 0;
}

int virtualNIC_init(struct net_device *dev);


static const struct net_device_ops my_netdev_ops = {
 .ndo_init = virtualNIC_init,
 .ndo_open = virtualNIC_open,
 .ndo_stop = virtualNIC_release,
 .ndo_start_xmit = virtualNIC_xmit,
};

int virtualNIC_init(struct net_device *dev) {
 dev->netdev_ops = &my_netdev_ops;
 printk("virtualNIC device initialized\n");

struct net_device virtualNIC = {
 .netdev_ops = &my_netdev_ops
/* .netdev_ops.ndo_init: virtualNIC_init*/
};

int virtualNIC_init_module(void) {
 int result;
 strcpy(virtualNIC.name, "virtual network adapter");
 if((result = register_netdev(&virtualNIC))) {
  printk("virtualNIC: Error %d initalizing card ...", result);
  return result;
 }
 return 0;
}

I can compile it, but if I type 'insmod mymodule' then segmentation fault occurs. Don't know solution.

How about using new code instead of fitting old code to new code?

I have no idea how to make brand new code. What is more - I haven't found any tutorials containing writing network drivers based on new net_structure. All of them are old. That is the purpose to searching on unix.com forum for help.

This looks like a decent tutorial: Writing Network Device Drivers for Linux

God bless you. I am going to check this out this evening.

As suggested before, you can find better source code inside the linux kernel itself than by browsing the internet for random code to try and hope it works.

Tell me exactly where I can find it.

If you have kernel source installed, /usr/src/linux or something similar.

If you go to The Linux Home Page at Linux Online you can download full kernel sources from there. They also have a free ebook, Linux Device Drivers, available here: Linux Device Drivers, 2nd Edition: Online Book, which has a chapter on network drivers.

HTH,

Rob.

That version of LDD is out-of-date. Many of the examples do not work on the 2.6.* kernel. LDD 3rd edition is available online here.

1 Like

Thanks for the update and the link. Appreciated.

This ebook (3rd edition) is also little bit outdated if we consider net_device structure (chapter 17 - network drivers).
At this moment that structure is different since 2009. However they say:

It is only mentioned that struct differ from old one, which all examples are based on.

I have not found on the internet any examples of network drivers written with new net_structure and believe me I am searching few days. Unfortunatelly link passed by fpmurphy is also describing driver based on old net_structure.

I got only "/usr/src/linux-headers-2.6.31-14" - headers. No *.c files.

You only have the headers installed, then. There's probably a way to install kernel source in your distro, but I don't know your distro.

You can get raw kernel source at kernel.org.

I found this:

Linux/arch/ppc/8260_io/enet.c

It is complete source of a network driver. I will try to get something from this and build my own simple driver.
Quick questions:

  • there is no 'module_init' and 'module_exit' functions. Is 'module_init' sort of replacement for '__init' ?
  • what is more - there is no 'module_exit' nor '__exit'. Isn't it necessary?

Well... it is also based on old net_structure :confused:

I don't think that's a generic network driver. It's for PowerPC only, it seems, and may be some kind of odd builtin.

Install some kernel source already(It's free) so you can use the files I suggested. Preferably the same version as the kernel you have, which you can get with 'cat /proc/verson'. If you can't find a way to install source in your distro you can still download tarballs from kernel.org

You seem to be having great difficulty getting going on building a simple network module. Let me try and help you. It is not difficult but can be a bit daunting the first time around.

  1. Install the Ubuntu kernel sources for your current kernel See Kernel/Compile - Community Help Wiki and elsewhere for how to do this. Follow the instructions to the letter. Do not try and take any shortcuts.

  2. Copy the following source file from your kernel source tree to your work area: .../drivers/net/dummy.c. Read the comments at the top of this file for an explanation of the dummy network driver. This driver is about as simple as a 2.6 kernel network driver gets.

  3. Create the following Makefile in your work area:

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
        obj-m := dummy.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
        KERNELDIR ?= /lib/modules/$(shell uname -r)/build
        PWD := $(shell pwd)
default:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
  1. Type 'make'. dummy.ko should be built.

  2. Install the dummy network driver using "inmod ./dummy.ko"

  3. Possible operations:
    To list this driver: ifconfig -a. It will show up as dummy0
    To remove the driver: rmmod dummy0
    To config the driver: ifconfig dummy0 192.168.0.100 netmask 255.255.255.0

Note you can have more than one dummy interface.

2 Likes

Thank you man. You made my day. I got working virtual driver at this moment. Now I add new features and work on makefile (that one you posted does not work for me: "nothing to do in 'default'").
Great job.

There is probably something wrong with your development/build environment if the Makefile did not work. It is basically the standard default build-a-module-outside-of-kernel-build-tree Makefile.