aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/team/team.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c2
-rw-r--r--include/net/genetlink.h23
-rw-r--r--kernel/taskstats.c39
-rw-r--r--net/core/drop_monitor.c2
-rw-r--r--net/hsr/hsr_netlink.c46
-rw-r--r--net/ieee802154/ieee802154.h19
-rw-r--r--net/ieee802154/netlink.c28
-rw-r--r--net/ieee802154/nl-mac.c61
-rw-r--r--net/ieee802154/nl-phy.c37
-rw-r--r--net/ipv4/tcp_metrics.c2
-rw-r--r--net/irda/irnetlink.c2
-rw-r--r--net/l2tp/l2tp_netlink.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c2
-rw-r--r--net/netlabel/netlabel_cipso_v4.c2
-rw-r--r--net/netlabel/netlabel_mgmt.c2
-rw-r--r--net/netlabel/netlabel_unlabeled.c2
-rw-r--r--net/netlink/genetlink.c153
-rw-r--r--net/nfc/netlink.c2
-rw-r--r--net/openvswitch/datapath.c10
-rw-r--r--net/wimax/op-msg.c25
-rw-r--r--net/wimax/op-reset.c17
-rw-r--r--net/wimax/op-rfkill.c21
-rw-r--r--net/wimax/op-state-get.c17
-rw-r--r--net/wimax/stack.c79
-rw-r--r--net/wimax/wimax-internal.h7
-rw-r--r--net/wireless/nl80211.c10
27 files changed, 207 insertions, 407 deletions
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 50e43e64d51..6390254beb7 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2644,7 +2644,7 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb,
return err;
}
-static struct genl_ops team_nl_ops[] = {
+static const struct genl_ops team_nl_ops[] = {
{
.cmd = TEAM_CMD_NOOP,
.doit = team_nl_cmd_noop,
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index de0df86704e..cfc3fda79a2 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2097,7 +2097,7 @@ out:
}
/* Generic Netlink operations array */
-static struct genl_ops hwsim_ops[] = {
+static const struct genl_ops hwsim_ops[] = {
{
.cmd = HWSIM_CMD_REGISTER,
.policy = hwsim_genl_policy,
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 9b787b62cf1..0b6a144468c 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -39,9 +39,10 @@ struct genl_info;
* @post_doit: called after an operation's doit callback, it may
* undo operations done by pre_doit, for example release locks
* @attrbuf: buffer to store parsed attributes
- * @ops_list: list of all assigned operations
* @family_list: family list
* @mcast_groups: multicast groups list
+ * @ops: the operations supported by this family (private)
+ * @n_ops: number of operations supported by this family (private)
*/
struct genl_family {
unsigned int id;
@@ -51,14 +52,15 @@ 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 list_head ops_list; /* private */
+ const struct genl_ops * ops; /* private */
+ unsigned int n_ops; /* private */
struct list_head family_list; /* private */
struct list_head mcast_groups; /* private */
struct module *module;
@@ -110,16 +112,15 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
* @ops_list: operations list
*/
struct genl_ops {
- u8 cmd;
- u8 internal_flags;
- unsigned int flags;
const struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
struct genl_info *info);
int (*dumpit)(struct sk_buff *skb,
struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
- struct list_head ops_list;
+ u8 cmd;
+ u8 internal_flags;
+ u8 flags;
};
int __genl_register_family(struct genl_family *family);
@@ -131,18 +132,16 @@ 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);
}
int genl_unregister_family(struct genl_family *family);
-int genl_register_ops(struct genl_family *, struct genl_ops *ops);
-int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
int genl_register_mc_group(struct genl_family *family,
struct genl_multicast_group *grp);
void genl_unregister_mc_group(struct genl_family *family,
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 9f4618eb51c..76595cd9d21 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -673,17 +673,18 @@ err:
nlmsg_free(rep_skb);
}
-static struct genl_ops taskstats_ops = {
- .cmd = TASKSTATS_CMD_GET,
- .doit = taskstats_user_cmd,
- .policy = taskstats_cmd_get_policy,
- .flags = GENL_ADMIN_PERM,
-};
-
-static struct genl_ops cgroupstats_ops = {
- .cmd = CGROUPSTATS_CMD_GET,
- .doit = cgroupstats_user_cmd,
- .policy = cgroupstats_cmd_get_policy,
+static const struct genl_ops taskstats_ops[] = {
+ {
+ .cmd = TASKSTATS_CMD_GET,
+ .doit = taskstats_user_cmd,
+ .policy = taskstats_cmd_get_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = CGROUPSTATS_CMD_GET,
+ .doit = cgroupstats_user_cmd,
+ .policy = cgroupstats_cmd_get_policy,
+ },
};
/* Needed early in initialization */
@@ -702,26 +703,14 @@ static int __init taskstats_init(void)
{
int rc;
- rc = genl_register_family(&family);
+ rc = genl_register_family_with_ops(&family, taskstats_ops,
+ ARRAY_SIZE(taskstats_ops));
if (rc)
return rc;
- rc = genl_register_ops(&family, &taskstats_ops);
- if (rc < 0)
- goto err;
-
- rc = genl_register_ops(&family, &cgroupstats_ops);
- if (rc < 0)
- goto err_cgroup_ops;
-
family_registered = 1;
pr_info("registered taskstats version %d\n", TASKSTATS_GENL_VERSION);
return 0;
-err_cgroup_ops:
- genl_unregister_ops(&family, &taskstats_ops);
-err:
- genl_unregister_family(&family);
- return rc;
}
/*
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 5e78d44333b..f9fe2f22d20 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -333,7 +333,7 @@ out:
return NOTIFY_DONE;
}
-static struct genl_ops dropmon_ops[] = {
+static const struct genl_ops dropmon_ops[] = {
{
.cmd = NET_DM_CMD_CONFIG,
.doit = net_dm_cmd_config,
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 4e66bf61f58..79d72ca309c 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -306,15 +306,6 @@ fail:
return res;
}
-static struct genl_ops hsr_ops_get_node_status = {
- .cmd = HSR_C_GET_NODE_STATUS,
- .flags = 0,
- .policy = hsr_genl_policy,
- .doit = hsr_get_node_status,
- .dumpit = NULL,
-};
-
-
/* Get a list of MacAddressA of all nodes known to this node (other than self).
*/
static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
@@ -398,12 +389,21 @@ fail:
}
-static struct genl_ops hsr_ops_get_node_list = {
- .cmd = HSR_C_GET_NODE_LIST,
- .flags = 0,
- .policy = hsr_genl_policy,
- .doit = hsr_get_node_list,
- .dumpit = NULL,
+static const struct genl_ops hsr_ops[] = {
+ {
+ .cmd = HSR_C_GET_NODE_STATUS,
+ .flags = 0,
+ .policy = hsr_genl_policy,
+ .doit = hsr_get_node_status,
+ .dumpit = NULL,
+ },
+ {
+ .cmd = HSR_C_GET_NODE_LIST,
+ .flags = 0,
+ .policy = hsr_genl_policy,
+ .doit = hsr_get_node_list,
+ .dumpit = NULL,
+ },
};
int __init hsr_netlink_init(void)
@@ -414,18 +414,11 @@ int __init hsr_netlink_init(void)
if (rc)
goto fail_rtnl_link_register;
- rc = genl_register_family(&hsr_genl_family);
+ rc = genl_register_family_with_ops(&hsr_genl_family, hsr_ops,
+ ARRAY_SIZE(hsr_ops));
if (rc)
goto fail_genl_register_family;
- rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_status);
- if (rc)
- goto fail_genl_register_ops;
-
- rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_list);
- if (rc)
- goto fail_genl_register_ops_node_list;
-
rc = genl_register_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
if (rc)
goto fail_genl_register_mc_group;
@@ -433,10 +426,6 @@ int __init hsr_netlink_init(void)
return 0;
fail_genl_register_mc_group:
- genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_list);
-fail_genl_register_ops_node_list:
- genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
-fail_genl_register_ops:
genl_unregister_family(&hsr_genl_family);
fail_genl_register_family:
rtnl_link_unregister(&hsr_link_ops);
@@ -448,7 +437,6 @@ fail_rtnl_link_register:
void __exit hsr_netlink_exit(void)
{
genl_unregister_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
- genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
genl_unregister_family(&hsr_genl_family);
rtnl_link_unregister(&hsr_link_ops);
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index aadec428e6e..14d5dab4436 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -47,7 +47,22 @@ struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info);
extern struct genl_family nl802154_family;
-int nl802154_mac_register(void);
-int nl802154_phy_register(void);
+
+/* genetlink ops/groups */
+int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
+int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
+
+extern struct genl_multicast_group ieee802154_coord_mcgrp;
+extern struct genl_multicast_group ieee802154_beacon_mcgrp;
+
+int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb);
#endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 7e49bbcc696..3ffcdbb56aa 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -109,24 +109,39 @@ out:
return -ENOBUFS;
}
+static const struct genl_ops ieee8021154_ops[] = {
+ /* see nl-phy.c */
+ IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
+ ieee802154_dump_phy),
+ IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
+ IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
+ /* see nl-mac.c */
+ IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
+ IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
+ IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
+ IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
+ IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
+ IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
+ ieee802154_dump_iface),
+};
+
int __init ieee802154_nl_init(void)
{
int rc;
- rc = genl_register_family(&nl802154_family);
+ rc = genl_register_family_with_ops(&nl802154_family, ieee8021154_ops,
+ ARRAY_SIZE(ieee8021154_ops));
if (rc)
- goto fail;
+ return rc;
- rc = nl802154_mac_register();
+ rc = genl_register_mc_group(&nl802154_family, &ieee802154_coord_mcgrp);
if (rc)
goto fail;
- rc = nl802154_phy_register();
+ rc = genl_register_mc_group(&nl802154_family, &ieee802154_beacon_mcgrp);
if (rc)
goto fail;
-
return 0;
-
fail:
genl_unregister_family(&nl802154_family);
return rc;
@@ -136,4 +151,3 @@ void __exit ieee802154_nl_exit(void)
{
genl_unregister_family(&nl802154_family);
}
-
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index b0bdd8c51e9..28d49303213 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -39,11 +39,11 @@
#include "ieee802154.h"
-static struct genl_multicast_group ieee802154_coord_mcgrp = {
+struct genl_multicast_group ieee802154_coord_mcgrp = {
.name = IEEE802154_MCAST_COORD_NAME,
};
-static struct genl_multicast_group ieee802154_beacon_mcgrp = {
+struct genl_multicast_group ieee802154_beacon_mcgrp = {
.name = IEEE802154_MCAST_BEACON_NAME,
};
@@ -309,8 +309,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
return dev;
}
-static int ieee802154_associate_req(struct sk_buff *skb,
- struct genl_info *info)
+int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info)
{
struct net_device *dev;
struct ieee802154_addr addr;
@@ -357,8 +356,7 @@ out:
return ret;
}
-static int ieee802154_associate_resp(struct sk_buff *skb,
- struct genl_info *info)
+int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info)
{
struct net_device *dev;
struct ieee802154_addr addr;
@@ -390,8 +388,7 @@ out:
return ret;
}
-static int ieee802154_disassociate_req(struct sk_buff *skb,
- struct genl_info *info)
+int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info)
{
struct net_device *dev;
struct ieee802154_addr addr;
@@ -433,7 +430,7 @@ out:
* PAN_coordinator, battery_life_extension = 0,
* coord_realignment = 0, security_enable = 0
*/
-static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
+int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
{
struct net_device *dev;
struct ieee802154_addr addr;
@@ -492,7 +489,7 @@ out:
return ret;
}
-static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
+int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
{
struct net_device *dev;
int ret = -EOPNOTSUPP;
@@ -530,8 +527,7 @@ out:
return ret;
}
-static int ieee802154_list_iface(struct sk_buff *skb,
- struct genl_info *info)
+int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info)
{
/* Request for interface name, index, type, IEEE address,
PAN Id, short address */
@@ -565,8 +561,7 @@ out_dev:
}
-static int ieee802154_dump_iface(struct sk_buff *skb,
- struct netlink_callback *cb)
+int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
struct net_device *dev;
@@ -590,41 +585,3 @@ cont:
return skb->len;
}
-
-static struct genl_ops ieee802154_coordinator_ops[] = {
- IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
- IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
- IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
- IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
- IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
- IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
- ieee802154_dump_iface),
-};
-
-/*
- * No need to unregister as family unregistration will do it.
- */
-int nl802154_mac_register(void)
-{
- int i;
- int rc;
-
- rc = genl_register_mc_group(&nl802154_family,
- &ieee802154_coord_mcgrp);
- if (rc)
- return rc;
-
- rc = genl_register_mc_group(&nl802154_family,
- &ieee802154_beacon_mcgrp);
- if (rc)
- return rc;
-
- for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
- rc = genl_register_ops(&nl802154_family,
- &ieee802154_coordinator_ops[i]);
- if (rc)
- return rc;
- }
-
- return 0;
-}
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 22b1a7058fd..d08c7a43dcd 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -77,8 +77,7 @@ out:
return -EMSGSIZE;
}
-static int ieee802154_list_phy(struct sk_buff *skb,
- struct genl_info *info)
+int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info)
{
/* Request for interface name, index, type, IEEE address,
PAN Id, short address */
@@ -151,8 +150,7 @@ static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
return 0;
}
-static int ieee802154_dump_phy(struct sk_buff *skb,
- struct netlink_callback *cb)
+int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb)
{
struct dump_phy_data data = {
.cb = cb,
@@ -170,8 +168,7 @@ static int ieee802154_dump_phy(struct sk_buff *skb,
return skb->len;
}
-static int ieee802154_add_iface(struct sk_buff *skb,
- struct genl_info *info)
+int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
{
struct sk_buff *msg;
struct wpan_phy *phy;
@@ -273,8 +270,7 @@ out_dev:
return rc;
}
-static int ieee802154_del_iface(struct sk_buff *skb,
- struct genl_info *info)
+int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info)
{
struct sk_buff *msg;
struct wpan_phy *phy;
@@ -356,28 +352,3 @@ out_dev:
return rc;
}
-
-static struct genl_ops ieee802154_phy_ops[] = {
- IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
- ieee802154_dump_phy),
- IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
- IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
-};
-
-/*
- * No need to unregister as family unregistration will do it.
- */
-int nl802154_phy_register(void)
-{
- int i;
- int rc;
-
- for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) {
- rc = genl_register_ops(&nl802154_family,
- &ieee802154_phy_ops[i]);
- if (rc)
- return rc;
- }
-
- return 0;
-}
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index d3ee2e0c28b..8c121b523ee 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -991,7 +991,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
return 0;
}
-static struct genl_ops tcp_metrics_nl_ops[] = {
+static const struct genl_ops tcp_metrics_nl_ops[] = {
{
.cmd = TCP_METRICS_CMD_GET,
.doit = tcp_metrics_nl_cmd_get,
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index c3297126928..bf5d7d476da 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -131,7 +131,7 @@ static const struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = {
[IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
};
-static struct genl_ops irda_nl_ops[] = {
+static const struct genl_ops irda_nl_ops[] = {
{
.cmd = IRDA_NL_CMD_SET_MODE,
.doit = irda_nl_set_mode,
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index be446d517bc..57db66e24f1 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -793,7 +793,7 @@ static struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
},
};
-static struct genl_ops l2tp_nl_ops[] = {
+static const struct genl_ops l2tp_nl_ops[] = {
{
.cmd = L2TP_CMD_NOOP,
.doit = l2tp_nl_cmd_noop,
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 62786a495ce..fc8a04ed885 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3567,7 +3567,7 @@ out:
}
-static struct genl_ops ip_vs_genl_ops[] __read_mostly = {
+static const struct genl_ops ip_vs_genl_ops[] __read_mostly = {
{
.cmd = IPVS_CMD_NEW_SERVICE,
.flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index a1100640495..706691739b9 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -737,7 +737,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_cipsov4_ops[] = {
+static const struct genl_ops netlbl_cipsov4_ops[] = {
{
.cmd = NLBL_CIPSOV4_C_ADD,
.flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index dd1c37d7acb..7de6f660b80 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -705,7 +705,7 @@ version_failure:
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_mgmt_genl_ops[] = {
+static const struct genl_ops netlbl_mgmt_genl_ops[] = {
{
.cmd = NLBL_MGMT_C_ADD,
.flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 8f0897407a2..76ee9252daa 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1323,7 +1323,7 @@ unlabel_staticlistdef_return:
* NetLabel Generic NETLINK Command Definitions
*/
-static struct genl_ops netlbl_unlabel_genl_ops[] = {
+static const struct genl_ops netlbl_unlabel_genl_ops[] = {
{
.cmd = NLBL_UNLABEL_C_STATICADD,
.flags = GENL_ADMIN_PERM,
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 0c741cec4d0..a7c62d3d05a 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -106,13 +106,13 @@ 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)
{
- struct genl_ops *ops;
+ int i;
- list_for_each_entry(ops, &family->ops_list, ops_list)
- if (ops->cmd == cmd)
- return ops;
+ for (i = 0; i < family->n_ops; i++)
+ if (family->ops[i].cmd == cmd)
+ return &family->ops[i];
return NULL;
}
@@ -283,85 +283,26 @@ static void genl_unregister_mc_groups(struct genl_family *family)
__genl_unregister_mc_group(family, grp);
}
-/**
- * genl_register_ops - register generic netlink operations
- * @family: generic netlink family
- * @ops: operations to be registered
- *
- * Registers the specified operations and assigns them to the specified
- * family. Either a doit or dumpit callback must be specified or the
- * operation will fail. Only one operation structure per command
- * identifier may be registered.
- *
- * See include/net/genetlink.h for more documenation on the operations
- * structure.
- *
- * Returns 0 on success or a negative error code.
- */
-int genl_register_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 err = -EINVAL;
-
- if (ops->dumpit == NULL && ops->doit == NULL)
- goto errout;
-
- if (genl_get_cmd(ops->cmd, family)) {
- err = -EEXIST;
- goto errout;
+ int i, j;
+
+ for (i = 0; i < n_ops; i++) {
+ if (ops[i].dumpit == NULL && ops[i].doit == NULL)
+ return -EINVAL;
+ for (j = i + 1; j < n_ops; j++)
+ if (ops[i].cmd == ops[j].cmd)
+ return -EINVAL;
}
- if (ops->dumpit)
- ops->flags |= GENL_CMD_CAP_DUMP;
- if (ops->doit)
- ops->flags |= GENL_CMD_CAP_DO;
- if (ops->policy)
- ops->flags |= GENL_CMD_CAP_HASPOL;
-
- genl_lock_all();
- list_add_tail(&ops->ops_list, &family->ops_list);
- genl_unlock_all();
-
- genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
- err = 0;
-errout:
- return err;
-}
-EXPORT_SYMBOL(genl_register_ops);
-
-/**
- * genl_unregister_ops - unregister generic netlink operations
- * @family: generic netlink family
- * @ops: operations to be unregistered
- *
- * Unregisters the specified operations and unassigns them from the
- * specified family. The operation blocks until the current message
- * processing has finished and doesn't start again until the
- * unregister process has finished.
- *
- * Note: It is not necessary to unregister all operations before
- * unregistering the family, unregistering the family will cause
- * all assigned operations to be unregistered automatically.
- *
- * Returns 0 on success or a negative error code.
- */
-int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
-{
- struct genl_ops *rc;
+ /* family is not registered yet, so no locking needed */
+ family->ops = ops;
+ family->n_ops = n_ops;
- genl_lock_all();
- list_for_each_entry(rc, &family->ops_list, ops_list) {
- if (rc == ops) {
- list_del(&ops->ops_list);
- genl_unlock_all();
- genl_ctrl_event(CTRL_CMD_DELOPS, ops);
- return 0;
- }
- }
- genl_unlock_all();
-
- return -ENOENT;
+ return 0;
}
-EXPORT_SYMBOL(genl_unregister_ops);
/**
* __genl_register_family - register a generic netlink family
@@ -384,7 +325,6 @@ int __genl_register_family(struct genl_family *family)
if (family->id > GENL_MAX_ID)
goto errout;
- INIT_LIST_HEAD(&family->ops_list);
INIT_LIST_HEAD(&family->mcast_groups);
genl_lock_all();
@@ -451,30 +391,18 @@ EXPORT_SYMBOL(__genl_register_family);
* See include/net/genetlink.h for more documenation on the operations
* structure.
*
- * This is equivalent to calling genl_register_family() followed by
- * genl_register_ops() for every operation entry in the table taking
- * care to unregister the family on error path.
- *
* 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, i;
+ int err;
- err = __genl_register_family(family);
+ err = genl_validate_add_ops(family, ops, n_ops);
if (err)
return err;
- for (i = 0; i < n_ops; ++i, ++ops) {
- err = genl_register_ops(family, ops);
- if (err)
- goto err_out;
- }
- return 0;
-err_out:
- genl_unregister_family(family);
- return err;
+ return __genl_register_family(family);
}
EXPORT_SYMBOL(__genl_register_family_with_ops);
@@ -499,7 +427,7 @@ int genl_unregister_family(struct genl_family *family)
continue;
list_del(&rc->family_list);
- INIT_LIST_HEAD(&family->ops_list);
+ family->n_ops = 0;
genl_unlock_all();
kfree(family->attrbuf);
@@ -546,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();
@@ -557,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) {
@@ -572,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);
@@ -604,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,
};
@@ -726,24 +657,32 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
goto nla_put_failure;
- if (!list_empty(&family->ops_list)) {
+ if (family->n_ops) {
struct nlattr *nla_ops;
- struct genl_ops *ops;
- int idx = 1;
+ int i;
nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
if (nla_ops == NULL)
goto nla_put_failure;
- list_for_each_entry(ops, &family->ops_list, ops_list) {
+ for (i = 0; i < family->n_ops; i++) {
struct nlattr *nest;
+ const struct genl_ops *ops = &family->ops[i];
+ u32 flags = ops->flags;
- nest = nla_nest_start(skb, idx++);
+ 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/nfc/netlink.c b/net/nfc/netlink.c
index 84b7e3ea7b7..f5585611c09 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1364,7 +1364,7 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
return dev->ops->se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
}
-st