diff options
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r-- | net/netlink/genetlink.c | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 49bc2db7982b..b9b03747c1f3 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -331,7 +331,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
331 | } | 331 | } |
332 | 332 | ||
333 | *errp = err = netlink_dump_start(genl_sock, skb, nlh, | 333 | *errp = err = netlink_dump_start(genl_sock, skb, nlh, |
334 | ops->dumpit, NULL); | 334 | ops->dumpit, ops->done); |
335 | if (err == 0) | 335 | if (err == 0) |
336 | skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len), | 336 | skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len), |
337 | skb->len)); | 337 | skb->len)); |
@@ -384,16 +384,19 @@ static void genl_rcv(struct sock *sk, int len) | |||
384 | * Controller | 384 | * Controller |
385 | **************************************************************************/ | 385 | **************************************************************************/ |
386 | 386 | ||
387 | static struct genl_family genl_ctrl = { | ||
388 | .id = GENL_ID_CTRL, | ||
389 | .name = "nlctrl", | ||
390 | .version = 0x1, | ||
391 | .maxattr = CTRL_ATTR_MAX, | ||
392 | }; | ||
393 | |||
387 | static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, | 394 | static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, |
388 | u32 flags, struct sk_buff *skb, u8 cmd) | 395 | u32 flags, struct sk_buff *skb, u8 cmd) |
389 | { | 396 | { |
390 | struct nlattr *nla_ops; | ||
391 | struct genl_ops *ops; | ||
392 | void *hdr; | 397 | void *hdr; |
393 | int idx = 1; | ||
394 | 398 | ||
395 | hdr = genlmsg_put(skb, pid, seq, GENL_ID_CTRL, 0, flags, cmd, | 399 | hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd); |
396 | family->version); | ||
397 | if (hdr == NULL) | 400 | if (hdr == NULL) |
398 | return -1; | 401 | return -1; |
399 | 402 | ||
@@ -403,33 +406,39 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, | |||
403 | NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize); | 406 | NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize); |
404 | NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr); | 407 | NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr); |
405 | 408 | ||
406 | nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); | 409 | if (!list_empty(&family->ops_list)) { |
407 | if (nla_ops == NULL) | 410 | struct nlattr *nla_ops; |
408 | goto nla_put_failure; | 411 | struct genl_ops *ops; |
409 | 412 | int idx = 1; | |
410 | list_for_each_entry(ops, &family->ops_list, ops_list) { | ||
411 | struct nlattr *nest; | ||
412 | 413 | ||
413 | nest = nla_nest_start(skb, idx++); | 414 | nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); |
414 | if (nest == NULL) | 415 | if (nla_ops == NULL) |
415 | goto nla_put_failure; | 416 | goto nla_put_failure; |
416 | 417 | ||
417 | NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); | 418 | list_for_each_entry(ops, &family->ops_list, ops_list) { |
418 | NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); | 419 | struct nlattr *nest; |
419 | 420 | ||
420 | if (ops->policy) | 421 | nest = nla_nest_start(skb, idx++); |
421 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY); | 422 | if (nest == NULL) |
423 | goto nla_put_failure; | ||
422 | 424 | ||
423 | if (ops->doit) | 425 | NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); |
424 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT); | 426 | NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); |
425 | 427 | ||
426 | if (ops->dumpit) | 428 | if (ops->policy) |
427 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT); | 429 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY); |
428 | 430 | ||
429 | nla_nest_end(skb, nest); | 431 | if (ops->doit) |
430 | } | 432 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT); |
431 | 433 | ||
432 | nla_nest_end(skb, nla_ops); | 434 | if (ops->dumpit) |
435 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT); | ||
436 | |||
437 | nla_nest_end(skb, nest); | ||
438 | } | ||
439 | |||
440 | nla_nest_end(skb, nla_ops); | ||
441 | } | ||
433 | 442 | ||
434 | return genlmsg_end(skb, hdr); | 443 | return genlmsg_end(skb, hdr); |
435 | 444 | ||
@@ -480,7 +489,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, | |||
480 | struct sk_buff *skb; | 489 | struct sk_buff *skb; |
481 | int err; | 490 | int err; |
482 | 491 | ||
483 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 492 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
484 | if (skb == NULL) | 493 | if (skb == NULL) |
485 | return ERR_PTR(-ENOBUFS); | 494 | return ERR_PTR(-ENOBUFS); |
486 | 495 | ||
@@ -529,7 +538,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) | |||
529 | goto errout; | 538 | goto errout; |
530 | } | 539 | } |
531 | 540 | ||
532 | err = genlmsg_unicast(msg, info->snd_pid); | 541 | err = genlmsg_reply(msg, info); |
533 | errout: | 542 | errout: |
534 | return err; | 543 | return err; |
535 | } | 544 | } |
@@ -562,13 +571,6 @@ static struct genl_ops genl_ctrl_ops = { | |||
562 | .policy = ctrl_policy, | 571 | .policy = ctrl_policy, |
563 | }; | 572 | }; |
564 | 573 | ||
565 | static struct genl_family genl_ctrl = { | ||
566 | .id = GENL_ID_CTRL, | ||
567 | .name = "nlctrl", | ||
568 | .version = 0x1, | ||
569 | .maxattr = CTRL_ATTR_MAX, | ||
570 | }; | ||
571 | |||
572 | static int __init genl_init(void) | 574 | static int __init genl_init(void) |
573 | { | 575 | { |
574 | int i, err; | 576 | int i, err; |