aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-14 17:11:17 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-14 17:11:17 -0500
commit4fb09a8705623b84a9f085345aa59b38d3649902 (patch)
tree422a5d96f5a43193e7792ec93bb6faf10b85dc87 /net
parent1e9f3d6f1c403dd2b6270f654b4747147aa2306f (diff)
parent3f5ccd06aecd0eb1651dd451439d5cb365170854 (diff)
Merge branch 'genetlink'
Johannes Berg says: ==================== genetlink: reduce ops size and complexity (v2) As before - reduce the complexity and data/code size of genetlink ops by making them an array rather than a linked list. Most users already use an array thanks to genl_register_family_with_ops(), so convert the remaining ones allowing us to get rid of the list head in each op. Also make them const, this just makes sense at that point and the security people like making function pointers const as well :-) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-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
23 files changed, 180 insertions, 368 deletions
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 5e78d44333b9..f9fe2f22d20b 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -333,7 +333,7 @@ out:
333 return NOTIFY_DONE; 333 return NOTIFY_DONE;
334} 334}
335 335
336static struct genl_ops dropmon_ops[] = { 336static const struct genl_ops dropmon_ops[] = {
337 { 337 {
338 .cmd = NET_DM_CMD_CONFIG, 338 .cmd = NET_DM_CMD_CONFIG,
339 .doit = net_dm_cmd_config, 339 .doit = net_dm_cmd_config,
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 4e66bf61f585..79d72ca309ce 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -306,15 +306,6 @@ fail:
306 return res; 306 return res;
307} 307}
308 308
309static struct genl_ops hsr_ops_get_node_status = {
310 .cmd = HSR_C_GET_NODE_STATUS,
311 .flags = 0,
312 .policy = hsr_genl_policy,
313 .doit = hsr_get_node_status,
314 .dumpit = NULL,
315};
316
317
318/* Get a list of MacAddressA of all nodes known to this node (other than self). 309/* Get a list of MacAddressA of all nodes known to this node (other than self).
319 */ 310 */
320static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) 311static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
@@ -398,12 +389,21 @@ fail:
398} 389}
399 390
400 391
401static struct genl_ops hsr_ops_get_node_list = { 392static const struct genl_ops hsr_ops[] = {
402 .cmd = HSR_C_GET_NODE_LIST, 393 {
403 .flags = 0, 394 .cmd = HSR_C_GET_NODE_STATUS,
404 .policy = hsr_genl_policy, 395 .flags = 0,
405 .doit = hsr_get_node_list, 396 .policy = hsr_genl_policy,
406 .dumpit = NULL, 397 .doit = hsr_get_node_status,
398 .dumpit = NULL,
399 },
400 {
401 .cmd = HSR_C_GET_NODE_LIST,
402 .flags = 0,
403 .policy = hsr_genl_policy,
404 .doit = hsr_get_node_list,
405 .dumpit = NULL,
406 },
407}; 407};
408 408
409int __init hsr_netlink_init(void) 409int __init hsr_netlink_init(void)
@@ -414,18 +414,11 @@ int __init hsr_netlink_init(void)
414 if (rc) 414 if (rc)
415 goto fail_rtnl_link_register; 415 goto fail_rtnl_link_register;
416 416
417 rc = genl_register_family(&hsr_genl_family); 417 rc = genl_register_family_with_ops(&hsr_genl_family, hsr_ops,
418 ARRAY_SIZE(hsr_ops));
418 if (rc) 419 if (rc)
419 goto fail_genl_register_family; 420 goto fail_genl_register_family;
420 421
421 rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_status);
422 if (rc)
423 goto fail_genl_register_ops;
424
425 rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_list);
426 if (rc)
427 goto fail_genl_register_ops_node_list;
428
429 rc = genl_register_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp); 422 rc = genl_register_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
430 if (rc) 423 if (rc)
431 goto fail_genl_register_mc_group; 424 goto fail_genl_register_mc_group;
@@ -433,10 +426,6 @@ int __init hsr_netlink_init(void)
433 return 0; 426 return 0;
434 427
435fail_genl_register_mc_group: 428fail_genl_register_mc_group:
436 genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_list);
437fail_genl_register_ops_node_list:
438 genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
439fail_genl_register_ops:
440 genl_unregister_family(&hsr_genl_family); 429 genl_unregister_family(&hsr_genl_family);
441fail_genl_register_family: 430fail_genl_register_family:
442 rtnl_link_unregister(&hsr_link_ops); 431 rtnl_link_unregister(&hsr_link_ops);
@@ -448,7 +437,6 @@ fail_rtnl_link_register:
448void __exit hsr_netlink_exit(void) 437void __exit hsr_netlink_exit(void)
449{ 438{
450 genl_unregister_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp); 439 genl_unregister_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
451 genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
452 genl_unregister_family(&hsr_genl_family); 440 genl_unregister_family(&hsr_genl_family);
453 441
454 rtnl_link_unregister(&hsr_link_ops); 442 rtnl_link_unregister(&hsr_link_ops);
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index aadec428e6ec..14d5dab4436f 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,
47int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info); 47int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info);
48 48
49extern struct genl_family nl802154_family; 49extern struct genl_family nl802154_family;
50int nl802154_mac_register(void); 50
51int nl802154_phy_register(void); 51/* genetlink ops/groups */
52int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info);
53int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
54int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
55int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
56
57extern struct genl_multicast_group ieee802154_coord_mcgrp;
58extern struct genl_multicast_group ieee802154_beacon_mcgrp;
59
60int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info);
61int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info);
62int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info);
63int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info);
64int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info);
65int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info);
66int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb);
52 67
53#endif 68#endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 7e49bbcc6967..3ffcdbb56aab 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -109,24 +109,39 @@ out:
109 return -ENOBUFS; 109 return -ENOBUFS;
110} 110}
111 111
112static const struct genl_ops ieee8021154_ops[] = {
113 /* see nl-phy.c */
114 IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
115 ieee802154_dump_phy),
116 IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
117 IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
118 /* see nl-mac.c */
119 IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
120 IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
121 IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
122 IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
123 IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
124 IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
125 ieee802154_dump_iface),
126};
127
112int __init ieee802154_nl_init(void) 128int __init ieee802154_nl_init(void)
113{ 129{
114 int rc; 130 int rc;
115 131
116 rc = genl_register_family(&nl802154_family); 132 rc = genl_register_family_with_ops(&nl802154_family, ieee8021154_ops,
133 ARRAY_SIZE(ieee8021154_ops));
117 if (rc) 134 if (rc)
118 goto fail; 135 return rc;
119 136
120 rc = nl802154_mac_register(); 137 rc = genl_register_mc_group(&nl802154_family, &ieee802154_coord_mcgrp);
121 if (rc) 138 if (rc)
122 goto fail; 139 goto fail;
123 140
124 rc = nl802154_phy_register(); 141 rc = genl_register_mc_group(&nl802154_family, &ieee802154_beacon_mcgrp);
125 if (rc) 142 if (rc)
126 goto fail; 143 goto fail;
127
128 return 0; 144 return 0;
129
130fail: 145fail:
131 genl_unregister_family(&nl802154_family); 146 genl_unregister_family(&nl802154_family);
132 return rc; 147 return rc;
@@ -136,4 +151,3 @@ void __exit ieee802154_nl_exit(void)
136{ 151{
137 genl_unregister_family(&nl802154_family); 152 genl_unregister_family(&nl802154_family);
138} 153}
139
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index b0bdd8c51e9c..28d493032132 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -39,11 +39,11 @@
39 39
40#include "ieee802154.h" 40#include "ieee802154.h"
41 41
42static struct genl_multicast_group ieee802154_coord_mcgrp = { 42struct genl_multicast_group ieee802154_coord_mcgrp = {
43 .name = IEEE802154_MCAST_COORD_NAME, 43 .name = IEEE802154_MCAST_COORD_NAME,
44}; 44};
45 45
46static struct genl_multicast_group ieee802154_beacon_mcgrp = { 46struct genl_multicast_group ieee802154_beacon_mcgrp = {
47 .name = IEEE802154_MCAST_BEACON_NAME, 47 .name = IEEE802154_MCAST_BEACON_NAME,
48}; 48};
49 49
@@ -309,8 +309,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
309 return dev; 309 return dev;
310} 310}
311 311
312static int ieee802154_associate_req(struct sk_buff *skb, 312int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info)
313 struct genl_info *info)
314{ 313{
315 struct net_device *dev; 314 struct net_device *dev;
316 struct ieee802154_addr addr; 315 struct ieee802154_addr addr;
@@ -357,8 +356,7 @@ out:
357 return ret; 356 return ret;
358} 357}
359 358
360static int ieee802154_associate_resp(struct sk_buff *skb, 359int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info)
361 struct genl_info *info)
362{ 360{
363 struct net_device *dev; 361 struct net_device *dev;
364 struct ieee802154_addr addr; 362 struct ieee802154_addr addr;
@@ -390,8 +388,7 @@ out:
390 return ret; 388 return ret;
391} 389}
392 390
393static int ieee802154_disassociate_req(struct sk_buff *skb, 391int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info)
394 struct genl_info *info)
395{ 392{
396 struct net_device *dev; 393 struct net_device *dev;
397 struct ieee802154_addr addr; 394 struct ieee802154_addr addr;
@@ -433,7 +430,7 @@ out:
433 * PAN_coordinator, battery_life_extension = 0, 430 * PAN_coordinator, battery_life_extension = 0,
434 * coord_realignment = 0, security_enable = 0 431 * coord_realignment = 0, security_enable = 0
435*/ 432*/
436static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) 433int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
437{ 434{
438 struct net_device *dev; 435 struct net_device *dev;
439 struct ieee802154_addr addr; 436 struct ieee802154_addr addr;
@@ -492,7 +489,7 @@ out:
492 return ret; 489 return ret;
493} 490}
494 491
495static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) 492int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
496{ 493{
497 struct net_device *dev; 494 struct net_device *dev;
498 int ret = -EOPNOTSUPP; 495 int ret = -EOPNOTSUPP;
@@ -530,8 +527,7 @@ out:
530 return ret; 527 return ret;
531} 528}
532 529
533static int ieee802154_list_iface(struct sk_buff *skb, 530int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info)
534 struct genl_info *info)
535{ 531{
536 /* Request for interface name, index, type, IEEE address, 532 /* Request for interface name, index, type, IEEE address,
537 PAN Id, short address */ 533 PAN Id, short address */
@@ -565,8 +561,7 @@ out_dev:
565 561
566} 562}
567 563
568static int ieee802154_dump_iface(struct sk_buff *skb, 564int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
569 struct netlink_callback *cb)
570{ 565{
571 struct net *net = sock_net(skb->sk); 566 struct net *net = sock_net(skb->sk);
572 struct net_device *dev; 567 struct net_device *dev;
@@ -590,41 +585,3 @@ cont:
590 585
591 return skb->len; 586 return skb->len;
592} 587}
593
594static struct genl_ops ieee802154_coordinator_ops[] = {
595 IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
596 IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
597 IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
598 IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
599 IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
600 IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
601 ieee802154_dump_iface),
602};
603
604/*
605 * No need to unregister as family unregistration will do it.
606 */
607int nl802154_mac_register(void)
608{
609 int i;
610 int rc;
611
612 rc = genl_register_mc_group(&nl802154_family,
613 &ieee802154_coord_mcgrp);
614 if (rc)
615 return rc;
616
617 rc = genl_register_mc_group(&nl802154_family,
618 &ieee802154_beacon_mcgrp);
619 if (rc)
620 return rc;
621
622 for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
623 rc = genl_register_ops(&nl802154_family,
624 &ieee802154_coordinator_ops[i]);
625 if (rc)
626 return rc;
627 }
628
629 return 0;
630}
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 22b1a7058fd3..d08c7a43dcd1 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -77,8 +77,7 @@ out:
77 return -EMSGSIZE; 77 return -EMSGSIZE;
78} 78}
79 79
80static int ieee802154_list_phy(struct sk_buff *skb, 80int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info)
81 struct genl_info *info)
82{ 81{
83 /* Request for interface name, index, type, IEEE address, 82 /* Request for interface name, index, type, IEEE address,
84 PAN Id, short address */ 83 PAN Id, short address */
@@ -151,8 +150,7 @@ static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
151 return 0; 150 return 0;
152} 151}
153 152
154static int ieee802154_dump_phy(struct sk_buff *skb, 153int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb)
155 struct netlink_callback *cb)
156{ 154{
157 struct dump_phy_data data = { 155 struct dump_phy_data data = {
158 .cb = cb, 156 .cb = cb,
@@ -170,8 +168,7 @@ static int ieee802154_dump_phy(struct sk_buff *skb,
170 return skb->len; 168 return skb->len;
171} 169}
172 170
173static int ieee802154_add_iface(struct sk_buff *skb, 171int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
174 struct genl_info *info)
175{ 172{
176 struct sk_buff *msg; 173 struct sk_buff *msg;
177 struct wpan_phy *phy; 174 struct wpan_phy *phy;
@@ -273,8 +270,7 @@ out_dev:
273 return rc; 270 return rc;
274} 271}
275 272
276static int ieee802154_del_iface(struct sk_buff *skb, 273int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info)
277 struct genl_info *info)
278{ 274{
279 struct sk_buff *msg; 275 struct sk_buff *msg;
280 struct wpan_phy *phy; 276 struct wpan_phy *phy;
@@ -356,28 +352,3 @@ out_dev:
356 352
357 return rc; 353 return rc;
358} 354}
359
360static struct genl_ops ieee802154_phy_ops[] = {
361 IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
362 ieee802154_dump_phy),
363 IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
364 IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
365};
366
367/*
368 * No need to unregister as family unregistration will do it.
369 */
370int nl802154_phy_register(void)
371{
372 int i;
373 int rc;
374
375 for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) {
376 rc = genl_register_ops(&nl802154_family,
377 &ieee802154_phy_ops[i]);
378 if (rc)
379 return rc;
380 }
381
382 return 0;
383}
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index d3ee2e0c28b6..8c121b523eee 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)
991 return 0; 991 return 0;
992} 992}
993 993
994static struct genl_ops tcp_metrics_nl_ops[] = { 994static const struct genl_ops tcp_metrics_nl_ops[] = {
995 { 995 {
996 .cmd = TCP_METRICS_CMD_GET, 996 .cmd = TCP_METRICS_CMD_GET,
997 .doit = tcp_metrics_nl_cmd_get, 997 .doit = tcp_metrics_nl_cmd_get,
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index c32971269280..bf5d7d476dae 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] = {
131 [IRDA_NL_ATTR_MODE] = { .type = NLA_U32 }, 131 [IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
132}; 132};
133 133
134static struct genl_ops irda_nl_ops[] = { 134static const struct genl_ops irda_nl_ops[] = {
135 { 135 {
136 .cmd = IRDA_NL_CMD_SET_MODE, 136 .cmd = IRDA_NL_CMD_SET_MODE,
137 .doit = irda_nl_set_mode, 137 .doit = irda_nl_set_mode,
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index be446d517bc9..57db66e24f1f 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] = {
793 }, 793 },
794}; 794};
795 795
796static struct genl_ops l2tp_nl_ops[] = { 796static const struct genl_ops l2tp_nl_ops[] = {
797 { 797 {
798 .cmd = L2TP_CMD_NOOP, 798 .cmd = L2TP_CMD_NOOP,
799 .doit = l2tp_nl_cmd_noop, 799 .doit = l2tp_nl_cmd_noop,
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 62786a495cea..fc8a04ed8854 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3567,7 +3567,7 @@ out:
3567} 3567}
3568 3568
3569 3569
3570static struct genl_ops ip_vs_genl_ops[] __read_mostly = { 3570static const struct genl_ops ip_vs_genl_ops[] __read_mostly = {
3571 { 3571 {
3572 .cmd = IPVS_CMD_NEW_SERVICE, 3572 .cmd = IPVS_CMD_NEW_SERVICE,
3573 .flags = GENL_ADMIN_PERM, 3573 .flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index a1100640495d..706691739b99 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)
737 * NetLabel Generic NETLINK Command Definitions 737 * NetLabel Generic NETLINK Command Definitions
738 */ 738 */
739 739
740static struct genl_ops netlbl_cipsov4_ops[] = { 740static const struct genl_ops netlbl_cipsov4_ops[] = {
741 { 741 {
742 .cmd = NLBL_CIPSOV4_C_ADD, 742 .cmd = NLBL_CIPSOV4_C_ADD,
743 .flags = GENL_ADMIN_PERM, 743 .flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index dd1c37d7acbc..7de6f660b80a 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -705,7 +705,7 @@ version_failure:
705 * NetLabel Generic NETLINK Command Definitions 705 * NetLabel Generic NETLINK Command Definitions
706 */ 706 */
707 707
708static struct genl_ops netlbl_mgmt_genl_ops[] = { 708static const struct genl_ops netlbl_mgmt_genl_ops[] = {
709 { 709 {
710 .cmd = NLBL_MGMT_C_ADD, 710 .cmd = NLBL_MGMT_C_ADD,
711 .flags = GENL_ADMIN_PERM, 711 .flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 8f0897407a2c..76ee9252daa7 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1323,7 +1323,7 @@ unlabel_staticlistdef_return:
1323 * NetLabel Generic NETLINK Command Definitions 1323 * NetLabel Generic NETLINK Command Definitions
1324 */ 1324 */
1325 1325
1326static struct genl_ops netlbl_unlabel_genl_ops[] = { 1326static const struct genl_ops netlbl_unlabel_genl_ops[] = {
1327 { 1327 {
1328 .cmd = NLBL_UNLABEL_C_STATICADD, 1328 .cmd = NLBL_UNLABEL_C_STATICADD,
1329 .flags = GENL_ADMIN_PERM, 1329 .flags = GENL_ADMIN_PERM,
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 0c741cec4d0d..a7c62d3d05a1 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)
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 struct genl_ops *ops; 111 int i;
112 112
113 list_for_each_entry(ops, &family->ops_list, ops_list) 113 for (i = 0; i < family->n_ops; i++)
114 if (ops->cmd == cmd) 114 if (family->ops[i].cmd == cmd)
115 return ops; 115 return &family->ops[i];
116 116
117 return NULL; 117 return NULL;
118} 118}
@@ -283,85 +283,26 @@ 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
286/** 286static int genl_validate_add_ops(struct genl_family *family,
287 * genl_register_ops - register generic netlink operations 287 const struct genl_ops *ops,
288 * @family: generic netlink family 288 unsigned int n_ops)
289 * @ops: operations to be registered
290 *
291 * Registers the specified operations and assigns them to the specified
292 * family. Either a doit or dumpit callback must be specified or the
293 * operation will fail. Only one operation structure per command
294 * identifier may be registered.
295 *
296 * See include/net/genetlink.h for more documenation on the operations
297 * structure.
298 *
299 * Returns 0 on success or a negative error code.
300 */
301int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
302{ 289{
303 int err = -EINVAL; 290 int i, j;
304 291
305 if (ops->dumpit == NULL && ops->doit == NULL) 292 for (i = 0; i < n_ops; i++) {
306 goto errout; 293 if (ops[i].dumpit == NULL && ops[i].doit == NULL)
307 294 return -EINVAL;
308 if (genl_get_cmd(ops->cmd, family)) { 295 for (j = i + 1; j < n_ops; j++)
309 err = -EEXIST; 296 if (ops[i].cmd == ops[j].cmd)
310 goto errout; 297 return -EINVAL;
311 } 298 }
312 299
313 if (ops->dumpit) 300 /* family is not registered yet, so no locking needed */
314 ops->flags |= GENL_CMD_CAP_DUMP; 301 family->ops = ops;
315 if (ops->doit) 302 family->n_ops = n_ops;
316 ops->flags |= GENL_CMD_CAP_DO;
317 if (ops->policy)
318 ops->flags |= GENL_CMD_CAP_HASPOL;
319
320 genl_lock_all();
321 list_add_tail(&ops->ops_list, &family->ops_list);
322 genl_unlock_all();
323
324 genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
325 err = 0;
326errout:
327 return err;
328}
329EXPORT_SYMBOL(genl_register_ops);
330
331/**
332 * genl_unregister_ops - unregister generic netlink operations
333 * @family: generic netlink family
334 * @ops: operations to be unregistered
335 *
336 * Unregisters the specified operations and unassigns them from the
337 * specified family. The operation blocks until the current message
338 * processing has finished and doesn't start again until the
339 * unregister process has finished.
340 *
341 * Note: It is not necessary to unregister all operations before
342 * unregistering the family, unregistering the family will cause
343 * all assigned operations to be unregistered automatically.
344 *
345 * Returns 0 on success or a negative error code.
346 */
347int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
348{
349 struct genl_ops *rc;
350 303
351 genl_lock_all(); 304 return 0;
352 list_for_each_entry(rc, &family->ops_list, ops_list) {
353 if (rc == ops) {
354 list_del(&ops->ops_list);
355 genl_unlock_all();
356 genl_ctrl_event(CTRL_CMD_DELOPS, ops);
357 return 0;
358 }
359 }
360 genl_unlock_all();
361
362 return -ENOENT;
363} 305}
364EXPORT_SYMBOL(genl_unregister_ops);
365 306
366/** 307/**
367 * __genl_register_family - register a generic netlink family 308 * __genl_register_family - register a generic netlink family
@@ -384,7 +325,6 @@ int __genl_register_family(struct genl_family *family)
384 if (family->id > GENL_MAX_ID) 325 if (family->id > GENL_MAX_ID)
385 goto errout; 326 goto errout;
386 327
387 INIT_LIST_HEAD(&family->ops_list);
388 INIT_LIST_HEAD(&family->mcast_groups); 328 INIT_LIST_HEAD(&family->mcast_groups);
389 329
390 genl_lock_all(); 330 genl_lock_all();
@@ -451,30 +391,18 @@ EXPORT_SYMBOL(__genl_register_family);
451 * See include/net/genetlink.h for more documenation on the operations 391 * See include/net/genetlink.h for more documenation on the operations
452 * structure. 392 * structure.
453 * 393 *
454 * This is equivalent to calling genl_register_family() followed by
455 * genl_register_ops() for every operation entry in the table taking
456 * care to unregister the family on error path.
457 *
458 * Return 0 on success or a negative error code. 394 * Return 0 on success or a negative error code.
459 */ 395 */
460int __genl_register_family_with_ops(struct genl_family *family, 396int __genl_register_family_with_ops(struct genl_family *family,
461 struct genl_ops *ops, size_t n_ops) 397 const struct genl_ops *ops, size_t n_ops)
462{ 398{
463 int err, i; 399 int err;
464 400
465 err = __genl_register_family(family); 401 err = genl_validate_add_ops(family, ops, n_ops);
466 if (err) 402 if (err)
467 return err; 403 return err;
468 404
469 for (i = 0; i < n_ops; ++i, ++ops) { 405 return __genl_register_family(family);
470 err = genl_register_ops(family, ops);
471 if (err)
472 goto err_out;
473 }
474 return 0;
475err_out:
476 genl_unregister_family(family);
477 return err;
478} 406}
479EXPORT_SYMBOL(__genl_register_family_with_ops); 407EXPORT_SYMBOL(__genl_register_family_with_ops);
480 408
@@ -499,7 +427,7 @@ int genl_unregister_family(struct genl_family *family)
499 continue; 427 continue;
500 428
501 list_del(&rc->family_list); 429 list_del(&rc->family_list);
502 INIT_LIST_HEAD(&family->ops_list); 430 family->n_ops = 0;
503 genl_unlock_all(); 431 genl_unlock_all();
504 432
505 kfree(family->attrbuf); 433 kfree(family->attrbuf);
@@ -546,7 +474,8 @@ EXPORT_SYMBOL(genlmsg_put);
546 474
547static 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)
548{ 476{
549 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;
550 int rc; 479 int rc;
551 480
552 genl_lock(); 481 genl_lock();
@@ -557,7 +486,8 @@ static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
557 486
558static int genl_lock_done(struct netlink_callback *cb) 487static int genl_lock_done(struct netlink_callback *cb)
559{ 488{
560 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;
561 int rc = 0; 491 int rc = 0;
562 492
563 if (ops->done) { 493 if (ops->done) {
@@ -572,7 +502,7 @@ static int genl_family_rcv_msg(struct genl_family *family,
572 struct sk_buff *skb, 502 struct sk_buff *skb,
573 struct nlmsghdr *nlh) 503 struct nlmsghdr *nlh)
574{ 504{
575 struct genl_ops *ops; 505 const struct genl_ops *ops;
576 struct net *net = sock_net(skb->sk); 506 struct net *net = sock_net(skb->sk);
577 struct genl_info info; 507 struct genl_info info;
578 struct genlmsghdr *hdr = nlmsg_data(nlh); 508 struct genlmsghdr *hdr = nlmsg_data(nlh);
@@ -604,7 +534,8 @@ static int genl_family_rcv_msg(struct genl_family *family,
604 if (!family->parallel_ops) { 534 if (!family->parallel_ops) {
605 struct netlink_dump_control c = { 535 struct netlink_dump_control c = {
606 .module = family->module, 536 .module = family->module,
607 .data = ops, 537 /* we have const, but the netlink API doesn't */
538 .data = (void *)ops,
608 .dump = genl_lock_dumpit, 539 .dump = genl_lock_dumpit,
609 .done = genl_lock_done, 540 .done = genl_lock_done,
610 }; 541 };
@@ -726,24 +657,32 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
726 nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr)) 657 nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
727 goto nla_put_failure; 658 goto nla_put_failure;
728 659
729 if (!list_empty(&family->ops_list)) { 660 if (family->n_ops) {
730 struct nlattr *nla_ops; 661 struct nlattr *nla_ops;
731 struct genl_ops *ops; 662 int i;
732 int idx = 1;
733 663
734 nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); 664 nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
735 if (nla_ops == NULL) 665 if (nla_ops == NULL)
736 goto nla_put_failure; 666 goto nla_put_failure;
737 667
738 list_for_each_entry(ops, &family->ops_list, ops_list) { 668 for (i = 0; i < family->n_ops; i++) {
739 struct nlattr *nest; 669 struct nlattr *nest;
670 const struct genl_ops *ops = &family->ops[i];
671 u32 flags = ops->flags;
740 672
741 nest = nla_nest_start(skb, idx++); 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;
679
680 nest = nla_nest_start(skb, i + 1);
742 if (nest == NULL) 681 if (nest == NULL)
743 goto nla_put_failure; 682 goto nla_put_failure;
744 683
745 if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) || 684 if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) ||
746 nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags)) 685 nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, flags))
747 goto nla_put_failure; 686 goto nla_put_failure;
748 687
749 nla_nest_end(skb, nest); 688 nla_nest_end(skb, nest);
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 84b7e3ea7b7a..f5585611c098 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)
1364 return dev->ops->se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx); 1364 return dev->ops->se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
1365} 1365}
1366 1366
1367static struct genl_ops nfc_genl_ops[] = { 1367static const struct genl_ops nfc_genl_ops[] = {
1368 { 1368 {
1369 .cmd = NFC_CMD_GET_DEVICE, 1369 .cmd = NFC_CMD_GET_DEVICE,
1370 .doit = nfc_genl_get_device, 1370 .doit = nfc_genl_get_device,
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 1408adc2a2a7..91e1c927a465 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -557,7 +557,7 @@ static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
557 [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED }, 557 [OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
558}; 558};
559 559
560static struct genl_ops dp_packet_genl_ops[] = { 560static const struct genl_ops dp_packet_genl_ops[] = {
561 { .cmd = OVS_PACKET_CMD_EXECUTE, 561 { .cmd = OVS_PACKET_CMD_EXECUTE,
562 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 562 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
563 .policy = packet_policy, 563 .policy = packet_policy,
@@ -1034,7 +1034,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1034 return skb->len; 1034 return skb->len;
1035} 1035}
1036 1036
1037static struct genl_ops dp_flow_genl_ops[] = { 1037static const struct genl_ops dp_flow_genl_ops[] = {
1038 { .cmd = OVS_FLOW_CMD_NEW, 1038 { .cmd = OVS_FLOW_CMD_NEW,
1039 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1039 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1040 .policy = flow_policy, 1040 .policy = flow_policy,
@@ -1392,7 +1392,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
1392 return skb->len; 1392 return skb->len;
1393} 1393}
1394 1394
1395static struct genl_ops dp_datapath_genl_ops[] = { 1395static const struct genl_ops dp_datapath_genl_ops[] = {
1396 { .cmd = OVS_DP_CMD_NEW, 1396 { .cmd = OVS_DP_CMD_NEW,
1397 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1397 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1398 .policy = datapath_policy, 1398 .policy = datapath_policy,
@@ -1753,7 +1753,7 @@ out:
1753 return skb->len; 1753 return skb->len;
1754} 1754}
1755 1755
1756static struct genl_ops dp_vport_genl_ops[] = { 1756static const struct genl_ops dp_vport_genl_ops[] = {
1757 { .cmd = OVS_VPORT_CMD_NEW, 1757 { .cmd = OVS_VPORT_CMD_NEW,
1758 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ 1758 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
1759 .policy = vport_policy, 1759 .policy = vport_policy,
@@ -1779,7 +1779,7 @@ static struct genl_ops dp_vport_genl_ops[] = {
1779 1779
1780struct genl_family_and_ops { 1780struct genl_family_and_ops {
1781 struct genl_family *family; 1781 struct genl_family *family;
1782 struct genl_ops *ops; 1782 const struct genl_ops *ops;
1783 int n_ops; 1783 int n_ops;
1784 struct genl_multicast_group *group; 1784 struct genl_multicast_group *group;
1785}; 1785};
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index 0694d62e4dbc..ff19cbeaf607 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -321,17 +321,6 @@ int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name,
321} 321}
322EXPORT_SYMBOL_GPL(wimax_msg); 322EXPORT_SYMBOL_GPL(wimax_msg);
323 323
324
325static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = {
326 [WIMAX_GNL_MSG_IFIDX] = {
327 .type = NLA_U32,
328 },
329 [WIMAX_GNL_MSG_DATA] = {
330 .type = NLA_UNSPEC, /* libnl doesn't grok BINARY yet */
331 },
332};
333
334
335/* 324/*
336 * Relays a message from user space to the driver 325 * Relays a message from user space to the driver
337 * 326 *
@@ -340,7 +329,6 @@ static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = {
340 * 329 *
341 * This call will block while handling/relaying the message. 330 * This call will block while handling/relaying the message.
342 */ 331 */
343static
344int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info) 332int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info)
345{ 333{
346 int result, ifindex; 334 int result, ifindex;
@@ -418,16 +406,3 @@ error_no_wimax_dev:
418 return result; 406 return result;
419} 407}
420 408
421
422/*
423 * Generic Netlink glue
424 */
425
426struct genl_ops wimax_gnl_msg_from_user = {
427 .cmd = WIMAX_GNL_OP_MSG_FROM_USER,
428 .flags = GENL_ADMIN_PERM,
429 .policy = wimax_gnl_msg_policy,
430 .doit = wimax_gnl_doit_msg_from_user,
431 .dumpit = NULL,
432};
433
diff --git a/net/wimax/op-reset.c b/net/wimax/op-reset.c
index 7ceffe39d70e..eb4580784d9d 100644
--- a/net/wimax/op-reset.c
+++ b/net/wimax/op-reset.c
@@ -92,13 +92,6 @@ int wimax_reset(struct wimax_dev *wimax_dev)
92EXPORT_SYMBOL(wimax_reset); 92EXPORT_SYMBOL(wimax_reset);
93 93
94 94
95static const struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] = {
96 [WIMAX_GNL_RESET_IFIDX] = {
97 .type = NLA_U32,
98 },
99};
100
101
102/* 95/*
103 * Exporting to user space over generic netlink 96 * Exporting to user space over generic netlink
104 * 97 *
@@ -106,7 +99,6 @@ static const struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] =
106 * 99 *
107 * No attributes. 100 * No attributes.
108 */ 101 */
109static
110int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info) 102int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info)
111{ 103{
112 int result, ifindex; 104 int result, ifindex;
@@ -130,12 +122,3 @@ error_no_wimax_dev:
130 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result); 122 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
131 return result; 123 return result;
132} 124}
133
134
135struct genl_ops wimax_gnl_reset = {
136 .cmd = WIMAX_GNL_OP_RESET,
137 .flags = GENL_ADMIN_PERM,
138 .policy = wimax_gnl_reset_policy,
139 .doit = wimax_gnl_doit_reset,
140 .dumpit = NULL,
141};
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index 7ab60babdd22..403078d670a9 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -411,17 +411,6 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
411 * just query). 411 * just query).
412 */ 412 */
413 413
414static const struct nla_policy wimax_gnl_rfkill_policy[WIMAX_GNL_ATTR_MAX + 1] = {
415 [WIMAX_GNL_RFKILL_IFIDX] = {
416 .type = NLA_U32,
417 },
418 [WIMAX_GNL_RFKILL_STATE] = {
419 .type = NLA_U32 /* enum wimax_rf_state */
420 },
421};
422
423
424static
425int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info) 414int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info)
426{ 415{
427 int result, ifindex; 416 int result, ifindex;
@@ -457,13 +446,3 @@ error_no_wimax_dev:
457 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result); 446 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
458 return result; 447 return result;
459} 448}
460
461
462struct genl_ops wimax_gnl_rfkill = {
463 .cmd = WIMAX_GNL_OP_RFKILL,
464 .flags = GENL_ADMIN_PERM,
465 .policy = wimax_gnl_rfkill_policy,
466 .doit = wimax_gnl_doit_rfkill,
467 .dumpit = NULL,
468};
469
diff --git a/net/wimax/op-state-get.c b/net/wimax/op-state-get.c
index aff8776e2d41..995c08c827b5 100644
--- a/net/wimax/op-state-get.c
+++ b/net/wimax/op-state-get.c
@@ -33,13 +33,6 @@
33#include "debug-levels.h" 33#include "debug-levels.h"
34 34
35 35
36static const struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = {
37 [WIMAX_GNL_STGET_IFIDX] = {
38 .type = NLA_U32,
39 },
40};
41
42
43/* 36/*
44 * Exporting to user space over generic netlink 37 * Exporting to user space over generic netlink
45 * 38 *
@@ -48,7 +41,6 @@ static const struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1
48 * 41 *
49 * No attributes. 42 * No attributes.
50 */ 43 */
51static
52int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info) 44int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info)
53{ 45{
54 int result, ifindex; 46 int result, ifindex;
@@ -72,12 +64,3 @@ error_no_wimax_dev:
72 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result); 64 d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
73 return result; 65 return result;
74} 66}
75
76
77struct genl_ops wimax_gnl_state_get = {
78 .cmd = WIMAX_GNL_OP_STATE_GET,
79 .flags = GENL_ADMIN_PERM,
80 .policy = wimax_gnl_state_get_policy,
81 .doit = wimax_gnl_doit_state_get,
82 .dumpit = NULL,
83};
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index a6470ac39498..47170c9495f1 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -402,22 +402,44 @@ void wimax_dev_init(struct wimax_dev *wimax_dev)
402} 402}
403EXPORT_SYMBOL_GPL(wimax_dev_init); 403EXPORT_SYMBOL_GPL(wimax_dev_init);
404 404
405/* 405static const struct nla_policy wimax_gnl_policy[WIMAX_GNL_ATTR_MAX + 1] = {
406 * This extern is declared here because it's easier to keep track -- 406 [WIMAX_GNL_RESET_IFIDX] = { .type = NLA_U32, },
407 * both declarations are a list of the same 407 [WIMAX_GNL_RFKILL_IFIDX] = { .type = NLA_U32, },
408 */ 408 [WIMAX_GNL_RFKILL_STATE] = {
409extern struct genl_ops 409 .type = NLA_U32 /* enum wimax_rf_state */
410 wimax_gnl_msg_from_user, 410 },
411 wimax_gnl_reset, 411 [WIMAX_GNL_STGET_IFIDX] = { .type = NLA_U32, },
412 wimax_gnl_rfkill, 412 [WIMAX_GNL_MSG_IFIDX] = { .type = NLA_U32, },
413 wimax_gnl_state_get; 413 [WIMAX_GNL_MSG_DATA] = {
414 .type = NLA_UNSPEC, /* libnl doesn't grok BINARY yet */
415 },
416};
414 417
415static 418static const struct genl_ops wimax_gnl_ops[] = {
416struct genl_ops *wimax_gnl_ops[] = { 419 {
417 &wimax_gnl_msg_from_user, 420 .cmd = WIMAX_GNL_OP_MSG_FROM_USER,
418 &wimax_gnl_reset, 421 .flags = GENL_ADMIN_PERM,
419 &wimax_gnl_rfkill, 422 .policy = wimax_gnl_policy,
420 &wimax_gnl_state_get, 423 .doit = wimax_gnl_doit_msg_from_user,
424 },
425 {
426 .cmd = WIMAX_GNL_OP_RESET,
427 .flags = GENL_ADMIN_PERM,
428 .policy = wimax_gnl_policy,
429 .doit = wimax_gnl_doit_reset,
430 },
431 {
432 .cmd = WIMAX_GNL_OP_RFKILL,
433 .flags = GENL_ADMIN_PERM,
434 .policy = wimax_gnl_policy,
435 .doit = wimax_gnl_doit_rfkill,
436 },
437 {
438 .cmd = WIMAX_GNL_OP_STATE_GET,
439 .flags = GENL_ADMIN_PERM,
440 .policy = wimax_gnl_policy,
441 .doit = wimax_gnl_doit_state_get,
442 },
421}; 443};
422 444
423 445
@@ -567,7 +589,7 @@ struct genl_multicast_group wimax_gnl_mcg = {
567static 589static
568int __init wimax_subsys_init(void) 590int __init wimax_subsys_init(void)
569{ 591{
570 int result, cnt; 592 int result;
571 593
572 d_fnstart(4, NULL, "()\n"); 594 d_fnstart(4, NULL, "()\n");
573 d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params, 595 d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params,
@@ -575,26 +597,14 @@ int __init wimax_subsys_init(void)
575 597
576 snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name), 598 snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name),
577 "WiMAX"); 599 "WiMAX");
578 result = genl_register_family(&wimax_gnl_family); 600 result = genl_register_family_with_ops(&wimax_gnl_family, wimax_gnl_ops,
601 ARRAY_SIZE(wimax_gnl_ops));
579 if (unlikely(result < 0)) { 602 if (unlikely(result < 0)) {
580 printk(KERN_ERR "cannot register generic netlink family: %d\n", 603 printk(KERN_ERR "cannot register generic netlink family: %d\n",
581 result); 604 result);
582 goto error_register_family; 605 goto error_register_family;
583 } 606 }
584 607
585 for (cnt = 0; cnt < ARRAY_SIZE(wimax_gnl_ops); cnt++) {
586 result = genl_register_ops(&wimax_gnl_family,
587 wimax_gnl_ops[cnt]);
588 d_printf(4, NULL, "registering generic netlink op code "
589 "%u: %d\n", wimax_gnl_ops[cnt]->cmd, result);
590 if (unlikely(result < 0)) {
591 printk(KERN_ERR "cannot register generic netlink op "
592 "code %u: %d\n",
593 wimax_gnl_ops[cnt]->cmd, result);
594 goto error_register_ops;
595 }
596 }
597
598 result = genl_register_mc_group(&wimax_gnl_family, &wimax_gnl_mcg); 608 result = genl_register_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
599 if (result < 0) 609 if (result < 0)
600 goto error_mc_group; 610 goto error_mc_group;
@@ -602,10 +612,6 @@ int __init wimax_subsys_init(void)
602 return 0; 612 return 0;
603 613
604error_mc_group: 614error_mc_group:
605error_register_ops:
606 for (cnt--; cnt >= 0; cnt--)
607 genl_unregister_ops(&wimax_gnl_family,
608 wimax_gnl_ops[cnt]);
609 genl_unregister_family(&wimax_gnl_family); 615 genl_unregister_family(&wimax_gnl_family);
610error_register_family: 616error_register_family:
611 d_fnend(4, NULL, "() = %d\n", result); 617 d_fnend(4, NULL, "() = %d\n", result);
@@ -619,12 +625,7 @@ module_init(wimax_subsys_init);
619static 625static
620void __exit wimax_subsys_exit(void) 626void __exit wimax_subsys_exit(void)
621{ 627{
622 int cnt;
623 wimax_id_table_release(); 628 wimax_id_table_release();
624 genl_unregister_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
625 for (cnt = ARRAY_SIZE(wimax_gnl_ops) - 1; cnt >= 0; cnt--)
626 genl_unregister_ops(&wimax_gnl_family,
627 wimax_gnl_ops[cnt]);
628 genl_unregister_family(&wimax_gnl_family); 629 genl_unregister_family(&wimax_gnl_family);
629} 630}
630module_exit(wimax_subsys_exit); 631module_exit(wimax_subsys_exit);
diff --git a/net/wimax/wimax-internal.h b/net/wimax/wimax-internal.h
index 5dcd9c067bf0..8567d3079a83 100644
--- a/net/wimax/wimax-internal.h
+++ b/net/wimax/wimax-internal.h
@@ -84,8 +84,15 @@ void wimax_id_table_release(void);
84int wimax_rfkill_add(struct wimax_dev *); 84int wimax_rfkill_add(struct wimax_dev *);
85void wimax_rfkill_rm(struct wimax_dev *); 85void wimax_rfkill_rm(struct wimax_dev *);
86 86
87/* generic netlink */
87extern struct genl_family wimax_gnl_family; 88extern struct genl_family wimax_gnl_family;
88extern struct genl_multicast_group wimax_gnl_mcg; 89extern struct genl_multicast_group wimax_gnl_mcg;
89 90
91/* ops */
92int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info);
93int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info);
94int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info);
95int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info);
96
90#endif /* #ifdef __KERNEL__ */ 97#endif /* #ifdef __KERNEL__ */
91#endif /* #ifndef __WIMAX_INTERNAL_H__ */ 98#endif /* #ifndef __WIMAX_INTERNAL_H__ */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a7f4e7902104..58c43c8e149f 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,
30 struct cfg80211_crypto_settings *settings, 30 struct cfg80211_crypto_settings *settings,
31 int cipher_limit); 31 int cipher_limit);
32 32
33static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, 33static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
34 struct genl_info *info); 34 struct genl_info *info);
35static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 35static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
36 struct genl_info *info); 36 struct genl_info *info);
37 37
38/* the netlink family */ 38/* the netlink family */
@@ -8851,7 +8851,7 @@ static int nl80211_crit_protocol_stop(struct sk_buff *skb,
8851#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ 8851#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
8852 NL80211_FLAG_CHECK_NETDEV_UP) 8852 NL80211_FLAG_CHECK_NETDEV_UP)
8853 8853
8854static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, 8854static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
8855 struct genl_info *info) 8855 struct genl_info *info)
8856{ 8856{
8857 struct cfg80211_registered_device *rdev; 8857 struct cfg80211_registered_device *rdev;
@@ -8920,7 +8920,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8920 return 0; 8920 return 0;
8921} 8921}
8922 8922
8923static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 8923static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
8924 struct genl_info *info) 8924 struct genl_info *info)
8925{ 8925{
8926 if (info->user_ptr[1]) { 8926 if (info->user_ptr[1]) {
@@ -8937,7 +8937,7 @@ static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
8937 rtnl_unlock(); 8937 rtnl_unlock();
8938} 8938}
8939 8939
8940static struct genl_ops nl80211_ops[] = { 8940static const struct genl_ops nl80211_ops[] = {
8941 { 8941 {
8942 .cmd = NL80211_CMD_GET_WIPHY, 8942 .cmd = NL80211_CMD_GET_WIPHY,
8943 .doit = nl80211_get_wiphy, 8943 .doit = nl80211_get_wiphy,