diff --git a/include/net/genetlink.h b/include/net/genetlink.h index d4802af1a8b3f8f9f4701656830aa20026562ad2..d87486aa06114af7ab5bfcd1ce8a0d6724371657 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -52,14 +52,14 @@ struct genl_family { unsigned int maxattr; bool netnsok; bool parallel_ops; - int (*pre_doit)(struct genl_ops *ops, + int (*pre_doit)(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info); - void (*post_doit)(struct genl_ops *ops, + void (*post_doit)(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info); struct nlattr ** attrbuf; /* private */ - struct genl_ops * ops; /* private */ + const struct genl_ops * ops; /* private */ unsigned int n_ops; /* private */ struct list_head family_list; /* private */ struct list_head mcast_groups; /* private */ @@ -132,10 +132,10 @@ static inline int genl_register_family(struct genl_family *family) } int __genl_register_family_with_ops(struct genl_family *family, - struct genl_ops *ops, size_t n_ops); + const struct genl_ops *ops, size_t n_ops); static inline int genl_register_family_with_ops(struct genl_family *family, - struct genl_ops *ops, size_t n_ops) + const struct genl_ops *ops, size_t n_ops) { family->module = THIS_MODULE; return __genl_register_family_with_ops(family, ops, n_ops); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index d8273b057763bfc5cdab87e588bf4a9fbc2765d4..a7c62d3d05a153f615e4aad95310f5a5fed41d89 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) return NULL; } -static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) +static const struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) { int i; @@ -283,7 +283,8 @@ static void genl_unregister_mc_groups(struct genl_family *family) __genl_unregister_mc_group(family, grp); } -static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *ops, +static int genl_validate_add_ops(struct genl_family *family, + const struct genl_ops *ops, unsigned int n_ops) { int i, j; @@ -294,12 +295,6 @@ static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *op for (j = i + 1; j < n_ops; j++) if (ops[i].cmd == ops[j].cmd) return -EINVAL; - if (ops[i].dumpit) - ops[i].flags |= GENL_CMD_CAP_DUMP; - if (ops[i].doit) - ops[i].flags |= GENL_CMD_CAP_DO; - if (ops[i].policy) - ops[i].flags |= GENL_CMD_CAP_HASPOL; } /* family is not registered yet, so no locking needed */ @@ -399,7 +394,7 @@ EXPORT_SYMBOL(__genl_register_family); * Return 0 on success or a negative error code. */ int __genl_register_family_with_ops(struct genl_family *family, - struct genl_ops *ops, size_t n_ops) + const struct genl_ops *ops, size_t n_ops) { int err; @@ -479,7 +474,8 @@ EXPORT_SYMBOL(genlmsg_put); static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) { - struct genl_ops *ops = cb->data; + /* our ops are always const - netlink API doesn't propagate that */ + const struct genl_ops *ops = cb->data; int rc; genl_lock(); @@ -490,7 +486,8 @@ static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) static int genl_lock_done(struct netlink_callback *cb) { - struct genl_ops *ops = cb->data; + /* our ops are always const - netlink API doesn't propagate that */ + const struct genl_ops *ops = cb->data; int rc = 0; if (ops->done) { @@ -505,7 +502,7 @@ static int genl_family_rcv_msg(struct genl_family *family, struct sk_buff *skb, struct nlmsghdr *nlh) { - struct genl_ops *ops; + const struct genl_ops *ops; struct net *net = sock_net(skb->sk); struct genl_info info; struct genlmsghdr *hdr = nlmsg_data(nlh); @@ -537,7 +534,8 @@ static int genl_family_rcv_msg(struct genl_family *family, if (!family->parallel_ops) { struct netlink_dump_control c = { .module = family->module, - .data = ops, + /* we have const, but the netlink API doesn't */ + .data = (void *)ops, .dump = genl_lock_dumpit, .done = genl_lock_done, }; @@ -669,14 +667,22 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq, for (i = 0; i < family->n_ops; i++) { struct nlattr *nest; - struct genl_ops *ops = &family->ops[i]; + const struct genl_ops *ops = &family->ops[i]; + u32 flags = ops->flags; + + if (ops->dumpit) + flags |= GENL_CMD_CAP_DUMP; + if (ops->doit) + flags |= GENL_CMD_CAP_DO; + if (ops->policy) + flags |= GENL_CMD_CAP_HASPOL; nest = nla_nest_start(skb, i + 1); if (nest == NULL) goto nla_put_failure; if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) || - nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags)) + nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, flags)) goto nla_put_failure; nla_nest_end(skb, nest); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a7f4e7902104907adf86c9fffcfc0ab956d36095..3fef55958e982567242a8b5934b059e1ab0838c6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -30,9 +30,9 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, struct cfg80211_crypto_settings *settings, int cipher_limit); -static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, +static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info); -static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, +static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info); /* the netlink family */ @@ -8851,7 +8851,7 @@ static int nl80211_crit_protocol_stop(struct sk_buff *skb, #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ NL80211_FLAG_CHECK_NETDEV_UP) -static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, +static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev; @@ -8920,7 +8920,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, return 0; } -static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, +static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, struct genl_info *info) { if (info->user_ptr[1]) {