Pregunta

Quiero usar netlink para comunicarme entre una aplicación y el espacio del kernel. La versión de mi kernel de Linux es 2.6.28, y el siguiente es mi código incorrecto:

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

El mensaje de error abreviado es:

error: too few arguments to function 'netlink_kernel_create'

En el archivo < linux / netlink.h > , la función netlink_kernel_create () se define como

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)

No entiendo qué usar para el primer argumento, net . ¿Alguien puede explicar qué debo usar aquí?

¿Fue útil?

Solución

Un struct net contiene información sobre el espacio de nombres de la red, un conjunto de recursos de red disponibles para los procesos. Tenga en cuenta que podría haber múltiples espacios de nombres de red (es decir, varias instancias de la pila de red), pero la mayoría de los controladores usan el espacio de nombres init_net.

Su llamada probablemente debería verse como la siguiente

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

donde nl_rcv_func es una función que toma struct sk_buff * skb como el único argumento y procesa el mensaje de enlace de red recibido.

Otros consejos

Parece que has estado siguiendo una guía como esta , que ( siendo de 2005) bien podría haber sido superado por el desarrollo del núcleo. Parece que la API interna para crear un enlace de red desde el lado del kernel ha cambiado.

Revise la Documentación / carpeta en su árbol del kernel local para obtener documentación (ojalá sea más reciente), o lea el código en sí. También puede trawl los archivos de la lista de correo del Kernel de Linux por cualquier mención de los cambios que Parece que ha sucedido.

Aquí es la implementación real a partir de 2.6.29, si prefieres descifrarlo al revés (y no lo hayas comprobado en tu propio árbol, por supuesto).

Sí, struct net es de hecho para el espacio de nombres de red, pero no es correcto usar siempre init_net, debe registrar sus propias pernet_operations, como esta:

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;
}

y finalmente:

register_pernet_subsys(&fib_net_ops);

Sugeriría ioctl para la comunicación del kernel / usuario. La interfaz ioctl es estándar y la posibilidad de actualización entre los kernels es pequeña.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top