2009-04-30 15 views
4

アプリケーションとカーネル空間の間の通信にnetlinkを使用したいと思います。略しエラ​​ーメッセージがあるカーネルとユーザー空間の間に「ネットリンク」を作成するにはどうすればよいですか?

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

:私のLinuxカーネルのバージョンは2.6.28で、次は私の間違ったコードであるファイル<linux/netlink.h>

error: too few arguments to function 'netlink_kernel_create' 

、機能netlink_kernel_create()

のように定義されます
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) 

最初の引数に何を使用するのか分かりませんが、netです。誰かが私がここで使うべきことを説明することができますか?

+0

どこから関数定義を取得しましたか?ユーザスペースからlibc APIは、libcからカーネルのsyscall APIと正確には異なる場合があることを覚えておいてください。 – stsquad

答えて

4

struct netには、プロセスに使用できるネットワークネームスペースに関する情報が含まれています。複数のネットワーク名前空間(ネットワークスタックの複数のインスタンス)が存在する可能性がありますが、ほとんどのドライバはinit_net名前空間を使用します。

あなたの呼び出しは、おそらくnl_rcv_funcが唯一の引数としてstruct sk_buff *skbを取る関数であり、受け取ったネットリンクメッセージを処理し、次の

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

ようになるはずです。

2

あなたはthis oneのようなガイドに従っているようですが(2005年以降)、カーネルの開発によって凌駕されている可能性があります。カーネル側からネットリンクを作成するための内部APIが変更されたようです。

ローカルカーネルツリーのDocumentation /フォルダを調べて、うまくいけばドキュメントを読んだり、コード自体を読んだりしてください。また、Linuxカーネルのメーリングリストのアーカイブには、起こったような変更についての言及があります。trawlもあります。

Hereは実際には2.6.29で実装されています。むしろ後ろ向きにパズルしたいのですが(もちろん自分のツリーでこれをチェックしていない)。

+1

@unwind:あなたの最後のリンクが壊れていたので、私はそれを変更しました。私の推測には自信がありますが、正しいページにリンクしていることを確認してください。 –

-3

私は、カーネルとユーザのコミュニケーションのためにioctlを提案します。 ioctlインタフェースは標準であり、カーネル間で更新される可能性は低いです。

+2

ioctlは単純な変更のために動作するかもしれませんが、インターフェイスは管理するために老廃物です。 Netlinkは、中程度の複雑さを持つカーネル開発者にとって望ましいAPIです。 – stsquad

1

はい、構造体のネットはネットの名前空間のために確かにあるが、常にinit_net使用するための適切ではありません、あなたはこのように、あなた自身のpernet_operationsを登録する必要があります。

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

し、最終的に:

register_pernet_subsys(&fib_net_ops); 
関連する問題