2009-04-30 9 views
4

Ich möchte Netlink verwenden, um zwischen einer Anwendung und Kernel-Raum zu kommunizieren. Meine Linux-Kernel-Version ist 2.6.28, und die folgende ist mein Code falsch:Wie erstelle ich einen "netlink" zwischen Kernel und Userspace?

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

Die abgekürzte Fehlermeldung lautet:

error: too few arguments to function 'netlink_kernel_create' 

In der Datei <linux/netlink.h> die Funktion netlink_kernel_create() ist definiert als

Ich verstehe nicht, was für das erste Argument zu verwenden, net. Kann mir jemand erklären, was ich hier benutzen soll?

+0

Woher hast du die Funktionsdefinition? Denken Sie daran, dass die Benutzer-Space-zu-libc-API möglicherweise nicht genau die libc-Kernel-syscall-API ist. – stsquad

Antwort

4

Ein struct net enthält Informationen zum Netzwerknamespace, einer Gruppe von Netzwerkressourcen, die Prozessen zur Verfügung stehen. Beachten Sie, dass mehrere Netzwerknamespaces vorhanden sein können (d. H. Mehrere Instanzen des Netzwerkstapels), die meisten Treiber jedoch den Namespace init_net verwenden.

Ihr Anruf sollte in etwa wie folgt

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

aussehen wahrscheinlich, wo nl_rcv_func eine Funktion struct sk_buff *skb als einziges Argument nehmen und verarbeitet die empfangenen netlink Nachricht.

2

Sie scheinen einem Leitfaden wie this one zu folgen, der (aus dem Jahr 2005) möglicherweise durch die Entwicklung des Kernels überholt wurde. Es scheint, dass sich die interne API zum Erstellen eines Netlinks von der Kernel-Seite geändert hat.

Überprüfen Sie den Dokumentationsordner in Ihrer lokalen Kernel-Struktur auf einige (hoffentlich frischere) Dokumentation oder lesen Sie den Code selbst. Sie könnten auch trawl die Linux-Kernel-Mailing-Liste-Archive für jede Erwähnung der Änderungen, die anscheinend geschehen sind.

Here ist die eigentliche Implementierung ab 2.6.29, wenn Sie lieber rückwärts rätseln möchten (und das natürlich nicht bereits in Ihrem eigenen Baum überprüft haben).

+1

@unwind: Dein letzter Link wurde unterbrochen, also habe ich ihn geändert. Ich bin mir ziemlich sicher, aber bitte überprüfen Sie, ob ich mit der richtigen Seite verlinkt bin. –

-3

Ich würde vorschlagen, ioctl für Kernel/Benutzer-Kommunikation. Die ioctl-Schnittstelle ist Standard und die Wahrscheinlichkeit, zwischen den Kernel aktualisiert zu werden, ist gering.

+2

ioctls kann für einfache Änderungen arbeiten, aber die Schnittstelle ist eine horrende und spröde zu verwalten. Netlink ist die bevorzugte API von Kernel-Entwicklern für alles, was mäßig komplex ist. – stsquad

1

Ja, struct net ist in der Tat für die Netto-Namespace, aber es ist nicht richtig, immer verwenden init_net, sollten Sie Ihre eigenen pernet_operations registrieren, wie folgt aus:

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

und schließlich:

register_pernet_subsys(&fib_net_ops); 
Verwandte Themen