Question

I want to use netlink to communicate between an application and kernel space. My Linux kernel version is 2.6.28, and the following is my wrong code:

nf_sock=netlink_kernel_create(NL_PROTO,0,nl_user_skb,THIS_MODULE);

The abbreviated error message is:

error: too few arguments to function 'netlink_kernel_create'

In the file <linux/netlink.h>, the function netlink_kernel_create() is defined as

extern struct sock *netlink_kernel_create(struct net *net,int unit,unsigned int groups,void (*input)(struct sk_buff *skb),struct mutex *cb_mutex,struct module *module)

I don't understand what to use for the first argument, net. Can someone explain what I should use here?

Was it helpful?

Solution

A struct net contains information about the network namespace, a set of network resources available to processes. Note that there could be multiple network namespaces (i.e. multiple instances of the networking stack), but most drivers use the init_net namespace.

Your call should probably look something like the following

nf_sock = netlink_kernel_create(&init_net,
                                NETLINK_USERSOCK,
                                0,
                                nl_rcv_func,
                                NULL,
                                THIS_MODULE);

where nl_rcv_func is a function taking struct sk_buff *skb as the only argument and processes the received netlink message.

OTHER TIPS

You seem to have been following a guide such as this one, which (being from 2005) might well have been outpaced by the development of the kernel. It seems the internal API to create a netlink from the kernel side has changed.

Either check the Documentation/ folder in your local kernel tree for some (hopefully fresher) documentation, or read the code itself. You could also trawl the Linux Kernel mailing list archives for any mention of the changes that seem to have happened.

Here is the actual implemntation as of 2.6.29, if you'd rather puzzle it out backwards (and haven't already checked this in your own tree, of course).

Yes, struct net is indeed for net namespace, but it is not proper to always use init_net, you should register your own pernet_operations, like this:

static struct pernet_operations fib_net_ops = {
        .init = fib_net_init,
        .exit = fib_net_exit,
};

static int __net_init fib_net_init(struct net *net)
{
        int error;

#ifdef CONFIG_IP_ROUTE_CLASSID
        net->ipv4.fib_num_tclassid_users = 0;
#endif
        error = ip_fib_net_init(net);
        if (error < 0)
                goto out;
        error = nl_fib_lookup_init(net);
        if (error < 0)
                goto out_nlfl;
        error = fib_proc_init(net);
        if (error < 0)
                goto out_proc;
out:
        return error;

out_proc:
        nl_fib_lookup_exit(net);
out_nlfl:
        ip_fib_net_exit(net);
        goto out;
}

static int __net_init nl_fib_lookup_init(struct net *net)
{
        struct sock *sk;
        struct netlink_kernel_cfg cfg = {
                .input  = nl_fib_input,
        };

        sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, &cfg);
        if (sk == NULL)
                return -EAFNOSUPPORT;
        net->ipv4.fibnl = sk;
        return 0;
}

and finally:

register_pernet_subsys(&fib_net_ops);

I would suggest ioctl for kernel/user communication. The ioctl interface is standard and the chance of been updated between kernels is small.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top