summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/genetlink.h10
-rw-r--r--net/netlink/genetlink.c36
-rw-r--r--net/wireless/nl80211.c8
3 files changed, 30 insertions, 24 deletions
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index d4802af1a8b3..d87486aa0611 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 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)
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 a7f4e7902104..3fef55958e98 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]) {