aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/genetlink.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-11-14 11:14:45 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-14 17:10:41 -0500
commitf84f771d942182e39a56ec2989d6a67d3ca33a13 (patch)
tree6649cb4e7b88ebec4826252a1a3675fb75ba4621 /net/netlink/genetlink.c
parentd91824c08fbcb265ec930d863fa905e8daa836a4 (diff)
genetlink: allow making ops const
Allow making the ops array const by not modifying the ops flags on registration but rather only when ops are sent out in the family information. No users are updated yet except for the pre_doit/post_doit calls in wireless (the only ones that exist now.) Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r--net/netlink/genetlink.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index d8273b057763..a7c62d3d05a1 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -106,7 +106,7 @@ static struct genl_family *genl_family_find_byname(char *name)
106 return NULL; 106 return NULL;
107} 107}
108 108
109static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) 109static const struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
110{ 110{
111 int i; 111 int i;
112 112
@@ -283,7 +283,8 @@ static void genl_unregister_mc_groups(struct genl_family *family)
283 __genl_unregister_mc_group(family, grp); 283 __genl_unregister_mc_group(family, grp);
284} 284}
285 285
286static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *ops, 286static int genl_validate_add_ops(struct genl_family *family,
287 const struct genl_ops *ops,
287 unsigned int n_ops) 288 unsigned int n_ops)
288{ 289{
289 int i, j; 290 int i, j;
@@ -294,12 +295,6 @@ static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *op
294 for (j = i + 1; j < n_ops; j++) 295 for (j = i + 1; j < n_ops; j++)
295 if (ops[i].cmd == ops[j].cmd) 296 if (ops[i].cmd == ops[j].cmd)
296 return -EINVAL; 297 return -EINVAL;
297 if (ops[i].dumpit)
298 ops[i].flags |= GENL_CMD_CAP_DUMP;
299 if (ops[i].doit)
300 ops[i].flags |= GENL_CMD_CAP_DO;
301 if (ops[i].policy)
302 ops[i].flags |= GENL_CMD_CAP_HASPOL;
303 } 298 }
304 299
305 /* family is not registered yet, so no locking needed */ 300 /* family is not registered yet, so no locking needed */
@@ -399,7 +394,7 @@ EXPORT_SYMBOL(__genl_register_family);
399 * Return 0 on success or a negative error code. 394 * Return 0 on success or a negative error code.
400 */ 395 */
401int __genl_register_family_with_ops(struct genl_family *family, 396int __genl_register_family_with_ops(struct genl_family *family,
402 struct genl_ops *ops, size_t n_ops) 397 const struct genl_ops *ops, size_t n_ops)
403{ 398{
404 int err; 399 int err;
405 400
@@ -479,7 +474,8 @@ EXPORT_SYMBOL(genlmsg_put);
479 474
480static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 475static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
481{ 476{
482 struct genl_ops *ops = cb->data; 477 /* our ops are always const - netlink API doesn't propagate that */
478 const struct genl_ops *ops = cb->data;
483 int rc; 479 int rc;
484 480
485 genl_lock(); 481 genl_lock();
@@ -490,7 +486,8 @@ static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
490 486
491static int genl_lock_done(struct netlink_callback *cb) 487static int genl_lock_done(struct netlink_callback *cb)
492{ 488{
493 struct genl_ops *ops = cb->data; 489 /* our ops are always const - netlink API doesn't propagate that */
490 const struct genl_ops *ops = cb->data;
494 int rc = 0; 491 int rc = 0;
495 492
496 if (ops->done) { 493 if (ops->done) {
@@ -505,7 +502,7 @@ static int genl_family_rcv_msg(struct genl_family *family,
505 struct sk_buff *skb, 502 struct sk_buff *skb,
506 struct nlmsghdr *nlh) 503 struct nlmsghdr *nlh)
507{ 504{
508 struct genl_ops *ops; 505 const struct genl_ops *ops;
509 struct net *net = sock_net(skb->sk); 506 struct net *net = sock_net(skb->sk);
510 struct genl_info info; 507 struct genl_info info;
511 struct genlmsghdr *hdr = nlmsg_data(nlh); 508 struct genlmsghdr *hdr = nlmsg_data(nlh);
@@ -537,7 +534,8 @@ static int genl_family_rcv_msg(struct genl_family *family,
537 if (!family->parallel_ops) { 534 if (!family->parallel_ops) {
538 struct netlink_dump_control c = { 535 struct netlink_dump_control c = {
539 .module = family->module, 536 .module = family->module,
540 .data = ops, 537 /* we have const, but the netlink API doesn't */
538 .data = (void *)ops,
541 .dump = genl_lock_dumpit, 539 .dump = genl_lock_dumpit,
542 .done = genl_lock_done, 540 .done = genl_lock_done,
543 }; 541 };
@@ -669,14 +667,22 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
669 667
670 for (i = 0; i < family->n_ops; i++) { 668 for (i = 0; i < family->n_ops; i++) {
671 struct nlattr *nest; 669 struct nlattr *nest;
672 struct genl_ops *ops = &family->ops[i]; 670 const struct genl_ops *ops = &family->ops[i];
671 u32 flags = ops->flags;
672
673 if (ops->dumpit)
674 flags |= GENL_CMD_CAP_DUMP;
675 if (ops->doit)
676 flags |= GENL_CMD_CAP_DO;
677 if (ops->policy)
678 flags |= GENL_CMD_CAP_HASPOL;
673 679
674 nest = nla_nest_start(skb, i + 1); 680 nest = nla_nest_start(skb, i + 1);
675 if (nest == NULL) 681 if (nest == NULL)
676 goto nla_put_failure; 682 goto nla_put_failure;
677 683
678 if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) || 684 if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) ||
679 nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags)) 685 nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, flags))
680 goto nla_put_failure; 686 goto nla_put_failure;
681 687
682 nla_nest_end(skb, nest); 688 nla_nest_end(skb, nest);