OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [netlink/] [genetlink.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * NETLINK      Generic Netlink Family
3
 *
4
 *              Authors:        Jamal Hadi Salim
5
 *                              Thomas Graf <tgraf@suug.ch>
6
 *                              Johannes Berg <johannes@sipsolutions.net>
7
 */
8
 
9
#include <linux/module.h>
10
#include <linux/kernel.h>
11
#include <linux/errno.h>
12
#include <linux/types.h>
13
#include <linux/socket.h>
14
#include <linux/string.h>
15
#include <linux/skbuff.h>
16
#include <linux/mutex.h>
17
#include <linux/bitmap.h>
18
#include <net/sock.h>
19
#include <net/genetlink.h>
20
 
21
struct sock *genl_sock = NULL;
22
 
23
static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */
24
 
25
static inline void genl_lock(void)
26
{
27
        mutex_lock(&genl_mutex);
28
}
29
 
30
static inline void genl_unlock(void)
31
{
32
        mutex_unlock(&genl_mutex);
33
}
34
 
35
#define GENL_FAM_TAB_SIZE       16
36
#define GENL_FAM_TAB_MASK       (GENL_FAM_TAB_SIZE - 1)
37
 
38
static struct list_head family_ht[GENL_FAM_TAB_SIZE];
39
/*
40
 * Bitmap of multicast groups that are currently in use.
41
 *
42
 * To avoid an allocation at boot of just one unsigned long,
43
 * declare it global instead.
44
 * Bit 0 is marked as already used since group 0 is invalid.
45
 */
46
static unsigned long mc_group_start = 0x1;
47
static unsigned long *mc_groups = &mc_group_start;
48
static unsigned long mc_groups_longs = 1;
49
 
50
static int genl_ctrl_event(int event, void *data);
51
 
52
static inline unsigned int genl_family_hash(unsigned int id)
53
{
54
        return id & GENL_FAM_TAB_MASK;
55
}
56
 
57
static inline struct list_head *genl_family_chain(unsigned int id)
58
{
59
        return &family_ht[genl_family_hash(id)];
60
}
61
 
62
static struct genl_family *genl_family_find_byid(unsigned int id)
63
{
64
        struct genl_family *f;
65
 
66
        list_for_each_entry(f, genl_family_chain(id), family_list)
67
                if (f->id == id)
68
                        return f;
69
 
70
        return NULL;
71
}
72
 
73
static struct genl_family *genl_family_find_byname(char *name)
74
{
75
        struct genl_family *f;
76
        int i;
77
 
78
        for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
79
                list_for_each_entry(f, genl_family_chain(i), family_list)
80
                        if (strcmp(f->name, name) == 0)
81
                                return f;
82
 
83
        return NULL;
84
}
85
 
86
static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
87
{
88
        struct genl_ops *ops;
89
 
90
        list_for_each_entry(ops, &family->ops_list, ops_list)
91
                if (ops->cmd == cmd)
92
                        return ops;
93
 
94
        return NULL;
95
}
96
 
97
/* Of course we are going to have problems once we hit
98
 * 2^16 alive types, but that can only happen by year 2K
99
*/
100
static inline u16 genl_generate_id(void)
101
{
102
        static u16 id_gen_idx;
103
        int overflowed = 0;
104
 
105
        do {
106
                if (id_gen_idx == 0)
107
                        id_gen_idx = GENL_MIN_ID;
108
 
109
                if (++id_gen_idx > GENL_MAX_ID) {
110
                        if (!overflowed) {
111
                                overflowed = 1;
112
                                id_gen_idx = 0;
113
                                continue;
114
                        } else
115
                                return 0;
116
                }
117
 
118
        } while (genl_family_find_byid(id_gen_idx));
119
 
120
        return id_gen_idx;
121
}
122
 
123
static struct genl_multicast_group notify_grp;
124
 
125
/**
126
 * genl_register_mc_group - register a multicast group
127
 *
128
 * Registers the specified multicast group and notifies userspace
129
 * about the new group.
130
 *
131
 * Returns 0 on success or a negative error code.
132
 *
133
 * @family: The generic netlink family the group shall be registered for.
134
 * @grp: The group to register, must have a name.
135
 */
136
int genl_register_mc_group(struct genl_family *family,
137
                           struct genl_multicast_group *grp)
138
{
139
        int id;
140
        unsigned long *new_groups;
141
        int err;
142
 
143
        BUG_ON(grp->name[0] == '\0');
144
 
145
        genl_lock();
146
 
147
        /* special-case our own group */
148
        if (grp == &notify_grp)
149
                id = GENL_ID_CTRL;
150
        else
151
                id = find_first_zero_bit(mc_groups,
152
                                         mc_groups_longs * BITS_PER_LONG);
153
 
154
 
155
        if (id >= mc_groups_longs * BITS_PER_LONG) {
156
                size_t nlen = (mc_groups_longs + 1) * sizeof(unsigned long);
157
 
158
                if (mc_groups == &mc_group_start) {
159
                        new_groups = kzalloc(nlen, GFP_KERNEL);
160
                        if (!new_groups) {
161
                                err = -ENOMEM;
162
                                goto out;
163
                        }
164
                        mc_groups = new_groups;
165
                        *mc_groups = mc_group_start;
166
                } else {
167
                        new_groups = krealloc(mc_groups, nlen, GFP_KERNEL);
168
                        if (!new_groups) {
169
                                err = -ENOMEM;
170
                                goto out;
171
                        }
172
                        mc_groups = new_groups;
173
                        mc_groups[mc_groups_longs] = 0;
174
                }
175
                mc_groups_longs++;
176
        }
177
 
178
        err = netlink_change_ngroups(genl_sock,
179
                                     mc_groups_longs * BITS_PER_LONG);
180
        if (err)
181
                goto out;
182
 
183
        grp->id = id;
184
        set_bit(id, mc_groups);
185
        list_add_tail(&grp->list, &family->mcast_groups);
186
        grp->family = family;
187
 
188
        genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, grp);
189
 out:
190
        genl_unlock();
191
        return err;
192
}
193
EXPORT_SYMBOL(genl_register_mc_group);
194
 
195
static void __genl_unregister_mc_group(struct genl_family *family,
196
                                       struct genl_multicast_group *grp)
197
{
198
        BUG_ON(grp->family != family);
199
        netlink_clear_multicast_users(genl_sock, grp->id);
200
        clear_bit(grp->id, mc_groups);
201
        list_del(&grp->list);
202
        genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp);
203
        grp->id = 0;
204
        grp->family = NULL;
205
}
206
 
207
/**
208
 * genl_unregister_mc_group - unregister a multicast group
209
 *
210
 * Unregisters the specified multicast group and notifies userspace
211
 * about it. All current listeners on the group are removed.
212
 *
213
 * Note: It is not necessary to unregister all multicast groups before
214
 *       unregistering the family, unregistering the family will cause
215
 *       all assigned multicast groups to be unregistered automatically.
216
 *
217
 * @family: Generic netlink family the group belongs to.
218
 * @grp: The group to unregister, must have been registered successfully
219
 *       previously.
220
 */
221
void genl_unregister_mc_group(struct genl_family *family,
222
                              struct genl_multicast_group *grp)
223
{
224
        genl_lock();
225
        __genl_unregister_mc_group(family, grp);
226
        genl_unlock();
227
}
228
 
229
static void genl_unregister_mc_groups(struct genl_family *family)
230
{
231
        struct genl_multicast_group *grp, *tmp;
232
 
233
        genl_lock();
234
        list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list)
235
                __genl_unregister_mc_group(family, grp);
236
        genl_unlock();
237
}
238
 
239
/**
240
 * genl_register_ops - register generic netlink operations
241
 * @family: generic netlink family
242
 * @ops: operations to be registered
243
 *
244
 * Registers the specified operations and assigns them to the specified
245
 * family. Either a doit or dumpit callback must be specified or the
246
 * operation will fail. Only one operation structure per command
247
 * identifier may be registered.
248
 *
249
 * See include/net/genetlink.h for more documenation on the operations
250
 * structure.
251
 *
252
 * Returns 0 on success or a negative error code.
253
 */
254
int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
255
{
256
        int err = -EINVAL;
257
 
258
        if (ops->dumpit == NULL && ops->doit == NULL)
259
                goto errout;
260
 
261
        if (genl_get_cmd(ops->cmd, family)) {
262
                err = -EEXIST;
263
                goto errout;
264
        }
265
 
266
        if (ops->dumpit)
267
                ops->flags |= GENL_CMD_CAP_DUMP;
268
        if (ops->doit)
269
                ops->flags |= GENL_CMD_CAP_DO;
270
        if (ops->policy)
271
                ops->flags |= GENL_CMD_CAP_HASPOL;
272
 
273
        genl_lock();
274
        list_add_tail(&ops->ops_list, &family->ops_list);
275
        genl_unlock();
276
 
277
        genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
278
        err = 0;
279
errout:
280
        return err;
281
}
282
 
283
/**
284
 * genl_unregister_ops - unregister generic netlink operations
285
 * @family: generic netlink family
286
 * @ops: operations to be unregistered
287
 *
288
 * Unregisters the specified operations and unassigns them from the
289
 * specified family. The operation blocks until the current message
290
 * processing has finished and doesn't start again until the
291
 * unregister process has finished.
292
 *
293
 * Note: It is not necessary to unregister all operations before
294
 *       unregistering the family, unregistering the family will cause
295
 *       all assigned operations to be unregistered automatically.
296
 *
297
 * Returns 0 on success or a negative error code.
298
 */
299
int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
300
{
301
        struct genl_ops *rc;
302
 
303
        genl_lock();
304
        list_for_each_entry(rc, &family->ops_list, ops_list) {
305
                if (rc == ops) {
306
                        list_del(&ops->ops_list);
307
                        genl_unlock();
308
                        genl_ctrl_event(CTRL_CMD_DELOPS, ops);
309
                        return 0;
310
                }
311
        }
312
        genl_unlock();
313
 
314
        return -ENOENT;
315
}
316
 
317
/**
318
 * genl_register_family - register a generic netlink family
319
 * @family: generic netlink family
320
 *
321
 * Registers the specified family after validating it first. Only one
322
 * family may be registered with the same family name or identifier.
323
 * The family id may equal GENL_ID_GENERATE causing an unique id to
324
 * be automatically generated and assigned.
325
 *
326
 * Return 0 on success or a negative error code.
327
 */
328
int genl_register_family(struct genl_family *family)
329
{
330
        int err = -EINVAL;
331
 
332
        if (family->id && family->id < GENL_MIN_ID)
333
                goto errout;
334
 
335
        if (family->id > GENL_MAX_ID)
336
                goto errout;
337
 
338
        INIT_LIST_HEAD(&family->ops_list);
339
        INIT_LIST_HEAD(&family->mcast_groups);
340
 
341
        genl_lock();
342
 
343
        if (genl_family_find_byname(family->name)) {
344
                err = -EEXIST;
345
                goto errout_locked;
346
        }
347
 
348
        if (genl_family_find_byid(family->id)) {
349
                err = -EEXIST;
350
                goto errout_locked;
351
        }
352
 
353
        if (family->id == GENL_ID_GENERATE) {
354
                u16 newid = genl_generate_id();
355
 
356
                if (!newid) {
357
                        err = -ENOMEM;
358
                        goto errout_locked;
359
                }
360
 
361
                family->id = newid;
362
        }
363
 
364
        if (family->maxattr) {
365
                family->attrbuf = kmalloc((family->maxattr+1) *
366
                                        sizeof(struct nlattr *), GFP_KERNEL);
367
                if (family->attrbuf == NULL) {
368
                        err = -ENOMEM;
369
                        goto errout_locked;
370
                }
371
        } else
372
                family->attrbuf = NULL;
373
 
374
        list_add_tail(&family->family_list, genl_family_chain(family->id));
375
        genl_unlock();
376
 
377
        genl_ctrl_event(CTRL_CMD_NEWFAMILY, family);
378
 
379
        return 0;
380
 
381
errout_locked:
382
        genl_unlock();
383
errout:
384
        return err;
385
}
386
 
387
/**
388
 * genl_unregister_family - unregister generic netlink family
389
 * @family: generic netlink family
390
 *
391
 * Unregisters the specified family.
392
 *
393
 * Returns 0 on success or a negative error code.
394
 */
395
int genl_unregister_family(struct genl_family *family)
396
{
397
        struct genl_family *rc;
398
 
399
        genl_unregister_mc_groups(family);
400
 
401
        genl_lock();
402
 
403
        list_for_each_entry(rc, genl_family_chain(family->id), family_list) {
404
                if (family->id != rc->id || strcmp(rc->name, family->name))
405
                        continue;
406
 
407
                list_del(&rc->family_list);
408
                INIT_LIST_HEAD(&family->ops_list);
409
                genl_unlock();
410
 
411
                kfree(family->attrbuf);
412
                genl_ctrl_event(CTRL_CMD_DELFAMILY, family);
413
                return 0;
414
        }
415
 
416
        genl_unlock();
417
 
418
        return -ENOENT;
419
}
420
 
421
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
422
{
423
        struct genl_ops *ops;
424
        struct genl_family *family;
425
        struct genl_info info;
426
        struct genlmsghdr *hdr = nlmsg_data(nlh);
427
        int hdrlen, err;
428
 
429
        family = genl_family_find_byid(nlh->nlmsg_type);
430
        if (family == NULL)
431
                return -ENOENT;
432
 
433
        hdrlen = GENL_HDRLEN + family->hdrsize;
434
        if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
435
                return -EINVAL;
436
 
437
        ops = genl_get_cmd(hdr->cmd, family);
438
        if (ops == NULL)
439
                return -EOPNOTSUPP;
440
 
441
        if ((ops->flags & GENL_ADMIN_PERM) &&
442
            security_netlink_recv(skb, CAP_NET_ADMIN))
443
                return -EPERM;
444
 
445
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
446
                if (ops->dumpit == NULL)
447
                        return -EOPNOTSUPP;
448
 
449
                return netlink_dump_start(genl_sock, skb, nlh,
450
                                          ops->dumpit, ops->done);
451
        }
452
 
453
        if (ops->doit == NULL)
454
                return -EOPNOTSUPP;
455
 
456
        if (family->attrbuf) {
457
                err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
458
                                  ops->policy);
459
                if (err < 0)
460
                        return err;
461
        }
462
 
463
        info.snd_seq = nlh->nlmsg_seq;
464
        info.snd_pid = NETLINK_CB(skb).pid;
465
        info.nlhdr = nlh;
466
        info.genlhdr = nlmsg_data(nlh);
467
        info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
468
        info.attrs = family->attrbuf;
469
 
470
        return ops->doit(skb, &info);
471
}
472
 
473
static void genl_rcv(struct sk_buff *skb)
474
{
475
        genl_lock();
476
        netlink_rcv_skb(skb, &genl_rcv_msg);
477
        genl_unlock();
478
}
479
 
480
/**************************************************************************
481
 * Controller
482
 **************************************************************************/
483
 
484
static struct genl_family genl_ctrl = {
485
        .id = GENL_ID_CTRL,
486
        .name = "nlctrl",
487
        .version = 0x2,
488
        .maxattr = CTRL_ATTR_MAX,
489
};
490
 
491
static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
492
                          u32 flags, struct sk_buff *skb, u8 cmd)
493
{
494
        void *hdr;
495
 
496
        hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd);
497
        if (hdr == NULL)
498
                return -1;
499
 
500
        NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
501
        NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
502
        NLA_PUT_U32(skb, CTRL_ATTR_VERSION, family->version);
503
        NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize);
504
        NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr);
505
 
506
        if (!list_empty(&family->ops_list)) {
507
                struct nlattr *nla_ops;
508
                struct genl_ops *ops;
509
                int idx = 1;
510
 
511
                nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
512
                if (nla_ops == NULL)
513
                        goto nla_put_failure;
514
 
515
                list_for_each_entry(ops, &family->ops_list, ops_list) {
516
                        struct nlattr *nest;
517
 
518
                        nest = nla_nest_start(skb, idx++);
519
                        if (nest == NULL)
520
                                goto nla_put_failure;
521
 
522
                        NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd);
523
                        NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags);
524
 
525
                        nla_nest_end(skb, nest);
526
                }
527
 
528
                nla_nest_end(skb, nla_ops);
529
        }
530
 
531
        if (!list_empty(&family->mcast_groups)) {
532
                struct genl_multicast_group *grp;
533
                struct nlattr *nla_grps;
534
                int idx = 1;
535
 
536
                nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
537
                if (nla_grps == NULL)
538
                        goto nla_put_failure;
539
 
540
                list_for_each_entry(grp, &family->mcast_groups, list) {
541
                        struct nlattr *nest;
542
 
543
                        nest = nla_nest_start(skb, idx++);
544
                        if (nest == NULL)
545
                                goto nla_put_failure;
546
 
547
                        NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
548
                        NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
549
                                       grp->name);
550
 
551
                        nla_nest_end(skb, nest);
552
                }
553
                nla_nest_end(skb, nla_grps);
554
        }
555
 
556
        return genlmsg_end(skb, hdr);
557
 
558
nla_put_failure:
559
        return genlmsg_cancel(skb, hdr);
560
}
561
 
562
static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 pid,
563
                                u32 seq, u32 flags, struct sk_buff *skb,
564
                                u8 cmd)
565
{
566
        void *hdr;
567
        struct nlattr *nla_grps;
568
        struct nlattr *nest;
569
 
570
        hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd);
571
        if (hdr == NULL)
572
                return -1;
573
 
574
        NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name);
575
        NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id);
576
 
577
        nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
578
        if (nla_grps == NULL)
579
                goto nla_put_failure;
580
 
581
        nest = nla_nest_start(skb, 1);
582
        if (nest == NULL)
583
                goto nla_put_failure;
584
 
585
        NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
586
        NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
587
                       grp->name);
588
 
589
        nla_nest_end(skb, nest);
590
        nla_nest_end(skb, nla_grps);
591
 
592
        return genlmsg_end(skb, hdr);
593
 
594
nla_put_failure:
595
        return genlmsg_cancel(skb, hdr);
596
}
597
 
598
static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
599
{
600
 
601
        int i, n = 0;
602
        struct genl_family *rt;
603
        int chains_to_skip = cb->args[0];
604
        int fams_to_skip = cb->args[1];
605
 
606
        if (chains_to_skip != 0)
607
                genl_lock();
608
 
609
        for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
610
                if (i < chains_to_skip)
611
                        continue;
612
                n = 0;
613
                list_for_each_entry(rt, genl_family_chain(i), family_list) {
614
                        if (++n < fams_to_skip)
615
                                continue;
616
                        if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
617
                                           cb->nlh->nlmsg_seq, NLM_F_MULTI,
618
                                           skb, CTRL_CMD_NEWFAMILY) < 0)
619
                                goto errout;
620
                }
621
 
622
                fams_to_skip = 0;
623
        }
624
 
625
errout:
626
        if (chains_to_skip != 0)
627
                genl_unlock();
628
 
629
        cb->args[0] = i;
630
        cb->args[1] = n;
631
 
632
        return skb->len;
633
}
634
 
635
static struct sk_buff *ctrl_build_family_msg(struct genl_family *family,
636
                                             u32 pid, int seq, u8 cmd)
637
{
638
        struct sk_buff *skb;
639
        int err;
640
 
641
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
642
        if (skb == NULL)
643
                return ERR_PTR(-ENOBUFS);
644
 
645
        err = ctrl_fill_info(family, pid, seq, 0, skb, cmd);
646
        if (err < 0) {
647
                nlmsg_free(skb);
648
                return ERR_PTR(err);
649
        }
650
 
651
        return skb;
652
}
653
 
654
static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp,
655
                                            u32 pid, int seq, u8 cmd)
656
{
657
        struct sk_buff *skb;
658
        int err;
659
 
660
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
661
        if (skb == NULL)
662
                return ERR_PTR(-ENOBUFS);
663
 
664
        err = ctrl_fill_mcgrp_info(grp, pid, seq, 0, skb, cmd);
665
        if (err < 0) {
666
                nlmsg_free(skb);
667
                return ERR_PTR(err);
668
        }
669
 
670
        return skb;
671
}
672
 
673
static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
674
        [CTRL_ATTR_FAMILY_ID]   = { .type = NLA_U16 },
675
        [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
676
                                    .len = GENL_NAMSIZ - 1 },
677
};
678
 
679
static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
680
{
681
        struct sk_buff *msg;
682
        struct genl_family *res = NULL;
683
        int err = -EINVAL;
684
 
685
        if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
686
                u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
687
                res = genl_family_find_byid(id);
688
        }
689
 
690
        if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
691
                char *name;
692
 
693
                name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]);
694
                res = genl_family_find_byname(name);
695
        }
696
 
697
        if (res == NULL) {
698
                err = -ENOENT;
699
                goto errout;
700
        }
701
 
702
        msg = ctrl_build_family_msg(res, info->snd_pid, info->snd_seq,
703
                                    CTRL_CMD_NEWFAMILY);
704
        if (IS_ERR(msg)) {
705
                err = PTR_ERR(msg);
706
                goto errout;
707
        }
708
 
709
        err = genlmsg_reply(msg, info);
710
errout:
711
        return err;
712
}
713
 
714
static int genl_ctrl_event(int event, void *data)
715
{
716
        struct sk_buff *msg;
717
 
718
        if (genl_sock == NULL)
719
                return 0;
720
 
721
        switch (event) {
722
        case CTRL_CMD_NEWFAMILY:
723
        case CTRL_CMD_DELFAMILY:
724
                msg = ctrl_build_family_msg(data, 0, 0, event);
725
                if (IS_ERR(msg))
726
                        return PTR_ERR(msg);
727
 
728
                genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
729
                break;
730
        case CTRL_CMD_NEWMCAST_GRP:
731
        case CTRL_CMD_DELMCAST_GRP:
732
                msg = ctrl_build_mcgrp_msg(data, 0, 0, event);
733
                if (IS_ERR(msg))
734
                        return PTR_ERR(msg);
735
 
736
                genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
737
                break;
738
        }
739
 
740
        return 0;
741
}
742
 
743
static struct genl_ops genl_ctrl_ops = {
744
        .cmd            = CTRL_CMD_GETFAMILY,
745
        .doit           = ctrl_getfamily,
746
        .dumpit         = ctrl_dumpfamily,
747
        .policy         = ctrl_policy,
748
};
749
 
750
static struct genl_multicast_group notify_grp = {
751
        .name           = "notify",
752
};
753
 
754
static int __init genl_init(void)
755
{
756
        int i, err;
757
 
758
        for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
759
                INIT_LIST_HEAD(&family_ht[i]);
760
 
761
        err = genl_register_family(&genl_ctrl);
762
        if (err < 0)
763
                goto errout;
764
 
765
        err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
766
        if (err < 0)
767
                goto errout_register;
768
 
769
        netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
770
 
771
        /* we'll bump the group number right afterwards */
772
        genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0,
773
                                          genl_rcv, NULL, THIS_MODULE);
774
        if (genl_sock == NULL)
775
                panic("GENL: Cannot initialize generic netlink\n");
776
 
777
        err = genl_register_mc_group(&genl_ctrl, &notify_grp);
778
        if (err < 0)
779
                goto errout_register;
780
 
781
        return 0;
782
 
783
errout_register:
784
        genl_unregister_family(&genl_ctrl);
785
errout:
786
        panic("GENL: Cannot register controller: %d\n", err);
787
}
788
 
789
subsys_initcall(genl_init);
790
 
791
EXPORT_SYMBOL(genl_sock);
792
EXPORT_SYMBOL(genl_register_ops);
793
EXPORT_SYMBOL(genl_unregister_ops);
794
EXPORT_SYMBOL(genl_register_family);
795
EXPORT_SYMBOL(genl_unregister_family);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.