diff options
author | Thomas Graf <tgraf@suug.ch> | 2006-11-23 14:44:37 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:30:23 -0500 |
commit | e94ef682053a6eeca91aefdaecf8efe7fd7e33a5 (patch) | |
tree | a3b4796490471d313bab2af4510594a157a400a9 /net | |
parent | cdbc6dae5cc90d7d9e109e7d0568979d5355b653 (diff) |
[GENETLINK] ctrl: Avoid empty CTRL_ATTR_OPS attribute when dumping
Based on Jamal's patch but compiled and even tested. :-)
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netlink/genetlink.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 8903ef93db5b..cc874f0fcbdb 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -394,10 +394,7 @@ static struct genl_family genl_ctrl = { | |||
394 | 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, |
395 | u32 flags, struct sk_buff *skb, u8 cmd) | 395 | u32 flags, struct sk_buff *skb, u8 cmd) |
396 | { | 396 | { |
397 | struct nlattr *nla_ops; | ||
398 | struct genl_ops *ops; | ||
399 | void *hdr; | 397 | void *hdr; |
400 | int idx = 1; | ||
401 | 398 | ||
402 | hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd); | 399 | hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd); |
403 | if (hdr == NULL) | 400 | if (hdr == NULL) |
@@ -409,33 +406,39 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, | |||
409 | NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize); | 406 | NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize); |
410 | NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr); | 407 | NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr); |
411 | 408 | ||
412 | nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); | 409 | if (!list_empty(&family->ops_list)) { |
413 | if (nla_ops == NULL) | 410 | struct nlattr *nla_ops; |
414 | goto nla_put_failure; | 411 | struct genl_ops *ops; |
415 | 412 | int idx = 1; | |
416 | list_for_each_entry(ops, &family->ops_list, ops_list) { | ||
417 | struct nlattr *nest; | ||
418 | 413 | ||
419 | nest = nla_nest_start(skb, idx++); | 414 | nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); |
420 | if (nest == NULL) | 415 | if (nla_ops == NULL) |
421 | goto nla_put_failure; | 416 | goto nla_put_failure; |
422 | 417 | ||
423 | NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); | 418 | list_for_each_entry(ops, &family->ops_list, ops_list) { |
424 | NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); | 419 | struct nlattr *nest; |
425 | 420 | ||
426 | if (ops->policy) | 421 | nest = nla_nest_start(skb, idx++); |
427 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY); | 422 | if (nest == NULL) |
423 | goto nla_put_failure; | ||
428 | 424 | ||
429 | if (ops->doit) | 425 | NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); |
430 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT); | 426 | NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); |
431 | 427 | ||
432 | if (ops->dumpit) | 428 | if (ops->policy) |
433 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT); | 429 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY); |
434 | 430 | ||
435 | nla_nest_end(skb, nest); | 431 | if (ops->doit) |
436 | } | 432 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT); |
433 | |||
434 | if (ops->dumpit) | ||
435 | NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT); | ||
437 | 436 | ||
438 | nla_nest_end(skb, nla_ops); | 437 | nla_nest_end(skb, nest); |
438 | } | ||
439 | |||
440 | nla_nest_end(skb, nla_ops); | ||
441 | } | ||
439 | 442 | ||
440 | return genlmsg_end(skb, hdr); | 443 | return genlmsg_end(skb, hdr); |
441 | 444 | ||