سؤال

وأريد استخدام netlink للاتصال بين تطبيق والفضاء النواة. بلدي نواة لينكس الإصدار 2.6.28، ويلي هو بلدي رمز الخطأ:

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

ورسالة الخطأ مختصرة هي:

error: too few arguments to function 'netlink_kernel_create'

في ل<linux/netlink.h> ملف، يتم تعريف 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. يمكن للشخص أن يفسر ما ينبغي أن تستخدم هنا؟

هل كانت مفيدة؟

المحلول

وA struct net يحتوي على معلومات حول مساحة الاسم الشبكة، ومجموعة من موارد الشبكة المتوفرة إلى العمليات. لاحظ أنه يمكن أن تكون هناك مساحات أسماء متعددة للشبكة (أي حالات متعددة من كومة الشبكات)، ولكن معظم السائقين استخدام مساحة init_net.

يجب أن

مكالمتك ربما تبدو شيء كما يلي

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

وحيث nl_rcv_func هي وظيفة اتخاذ struct sk_buff *skb كما الحجة الوحيدة وبمعالجة رسالة netlink الواردة.

نصائح أخرى

ويبدو أنك أتابع دليل مثل هذا واحد ، والتي ( كونه من 2005) قد يكون قد تم فاق من خلال تطوير النواة. يبدو أن API الداخلي لخلق netlink من تغير الجانب النواة.

وإما فحص الوثائق / مجلد في شجرة نواة المحلية لبعض (نأمل أعذب) وثائق، أو قراءة رمز نفسها. هل يمكن أيضا الجر نواة لينكس المحفوظات القائمة البريدية لأي ذكر للتغييرات التي يبدو أن يكون قد حدث.

هنا هو implemntation الفعلي اعتبارا من 2.6.29، إذا كنت تفضل لغز بها إلى الوراء (ولم فحص هذا بالفعل في الشجرة الخاصة بك، بطبيعة الحال).

نعم، شبكة البنية هو في الواقع لصافي مساحة الاسم، ولكن ليس من المناسب لاستخدامها دائما 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);

وأود أن أقترح IOCTL للاتصال نواة / المستخدم. واجهة IOCTL هو المعيار وفرصة للتم تحديثها بين حبات صغيرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top