diff options
Diffstat (limited to 'net')
54 files changed, 699 insertions, 935 deletions
diff --git a/net/Kconfig b/net/Kconfig index 0715db64a5c3..d334678c0bd8 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
| @@ -224,7 +224,7 @@ source "net/hsr/Kconfig" | |||
| 224 | 224 | ||
| 225 | config RPS | 225 | config RPS |
| 226 | boolean | 226 | boolean |
| 227 | depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS | 227 | depends on SMP && SYSFS |
| 228 | default y | 228 | default y |
| 229 | 229 | ||
| 230 | config RFS_ACCEL | 230 | config RFS_ACCEL |
| @@ -235,7 +235,7 @@ config RFS_ACCEL | |||
| 235 | 235 | ||
| 236 | config XPS | 236 | config XPS |
| 237 | boolean | 237 | boolean |
| 238 | depends on SMP && USE_GENERIC_SMP_HELPERS | 238 | depends on SMP |
| 239 | default y | 239 | default y |
| 240 | 240 | ||
| 241 | config NETPRIO_CGROUP | 241 | config NETPRIO_CGROUP |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index c41d5fbb91d0..6e6194fcd88e 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -172,6 +172,7 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) | |||
| 172 | del_nbp(p); | 172 | del_nbp(p); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | br_vlan_flush(br); | ||
| 175 | del_timer_sync(&br->gc_timer); | 176 | del_timer_sync(&br->gc_timer); |
| 176 | 177 | ||
| 177 | br_sysfs_delbr(br->dev); | 178 | br_sysfs_delbr(br->dev); |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 53f0990eab58..af5ebd18d705 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
| @@ -34,7 +34,6 @@ static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) | |||
| 34 | 34 | ||
| 35 | static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | 35 | static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) |
| 36 | { | 36 | { |
| 37 | const struct net_device_ops *ops; | ||
| 38 | struct net_bridge_port *p = NULL; | 37 | struct net_bridge_port *p = NULL; |
| 39 | struct net_bridge *br; | 38 | struct net_bridge *br; |
| 40 | struct net_device *dev; | 39 | struct net_device *dev; |
| @@ -53,17 +52,15 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | |||
| 53 | br = v->parent.br; | 52 | br = v->parent.br; |
| 54 | dev = br->dev; | 53 | dev = br->dev; |
| 55 | } | 54 | } |
| 56 | ops = dev->netdev_ops; | ||
| 57 | 55 | ||
| 58 | if (p && (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) { | 56 | if (p) { |
| 59 | /* Add VLAN to the device filter if it is supported. | 57 | /* Add VLAN to the device filter if it is supported. |
| 60 | * Stricly speaking, this is not necessary now, since | 58 | * Stricly speaking, this is not necessary now, since |
| 61 | * devices are made promiscuous by the bridge, but if | 59 | * devices are made promiscuous by the bridge, but if |
| 62 | * that ever changes this code will allow tagged | 60 | * that ever changes this code will allow tagged |
| 63 | * traffic to enter the bridge. | 61 | * traffic to enter the bridge. |
| 64 | */ | 62 | */ |
| 65 | err = ops->ndo_vlan_rx_add_vid(dev, htons(ETH_P_8021Q), | 63 | err = vlan_vid_add(dev, htons(ETH_P_8021Q), vid); |
| 66 | vid); | ||
| 67 | if (err) | 64 | if (err) |
| 68 | return err; | 65 | return err; |
| 69 | } | 66 | } |
| @@ -82,8 +79,8 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | |||
| 82 | return 0; | 79 | return 0; |
| 83 | 80 | ||
| 84 | out_filt: | 81 | out_filt: |
| 85 | if (p && (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) | 82 | if (p) |
| 86 | ops->ndo_vlan_rx_kill_vid(dev, htons(ETH_P_8021Q), vid); | 83 | vlan_vid_del(dev, htons(ETH_P_8021Q), vid); |
| 87 | return err; | 84 | return err; |
| 88 | } | 85 | } |
| 89 | 86 | ||
| @@ -95,13 +92,8 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid) | |||
| 95 | __vlan_delete_pvid(v, vid); | 92 | __vlan_delete_pvid(v, vid); |
| 96 | clear_bit(vid, v->untagged_bitmap); | 93 | clear_bit(vid, v->untagged_bitmap); |
| 97 | 94 | ||
| 98 | if (v->port_idx) { | 95 | if (v->port_idx) |
| 99 | struct net_device *dev = v->parent.port->dev; | 96 | vlan_vid_del(v->parent.port->dev, htons(ETH_P_8021Q), vid); |
| 100 | const struct net_device_ops *ops = dev->netdev_ops; | ||
| 101 | |||
| 102 | if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) | ||
| 103 | ops->ndo_vlan_rx_kill_vid(dev, htons(ETH_P_8021Q), vid); | ||
| 104 | } | ||
| 105 | 97 | ||
| 106 | clear_bit(vid, v->vlan_bitmap); | 98 | clear_bit(vid, v->vlan_bitmap); |
| 107 | v->num_vlans--; | 99 | v->num_vlans--; |
| @@ -398,6 +390,7 @@ int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) | |||
| 398 | void nbp_vlan_flush(struct net_bridge_port *port) | 390 | void nbp_vlan_flush(struct net_bridge_port *port) |
| 399 | { | 391 | { |
| 400 | struct net_port_vlans *pv; | 392 | struct net_port_vlans *pv; |
| 393 | u16 vid; | ||
| 401 | 394 | ||
| 402 | ASSERT_RTNL(); | 395 | ASSERT_RTNL(); |
| 403 | 396 | ||
| @@ -405,6 +398,9 @@ void nbp_vlan_flush(struct net_bridge_port *port) | |||
| 405 | if (!pv) | 398 | if (!pv) |
| 406 | return; | 399 | return; |
| 407 | 400 | ||
| 401 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) | ||
| 402 | vlan_vid_del(port->dev, htons(ETH_P_8021Q), vid); | ||
| 403 | |||
| 408 | __vlan_flush(pv); | 404 | __vlan_flush(pv); |
| 409 | } | 405 | } |
| 410 | 406 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 8ffc52e01ece..7e00a7342ee6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -131,6 +131,7 @@ | |||
| 131 | #include <linux/static_key.h> | 131 | #include <linux/static_key.h> |
| 132 | #include <linux/hashtable.h> | 132 | #include <linux/hashtable.h> |
| 133 | #include <linux/vmalloc.h> | 133 | #include <linux/vmalloc.h> |
| 134 | #include <linux/if_macvlan.h> | ||
| 134 | 135 | ||
| 135 | #include "net-sysfs.h" | 136 | #include "net-sysfs.h" |
| 136 | 137 | ||
| @@ -1424,6 +1425,10 @@ void dev_disable_lro(struct net_device *dev) | |||
| 1424 | if (is_vlan_dev(dev)) | 1425 | if (is_vlan_dev(dev)) |
| 1425 | dev = vlan_dev_real_dev(dev); | 1426 | dev = vlan_dev_real_dev(dev); |
| 1426 | 1427 | ||
| 1428 | /* the same for macvlan devices */ | ||
| 1429 | if (netif_is_macvlan(dev)) | ||
| 1430 | dev = macvlan_dev_real_dev(dev); | ||
| 1431 | |||
| 1427 | dev->wanted_features &= ~NETIF_F_LRO; | 1432 | dev->wanted_features &= ~NETIF_F_LRO; |
| 1428 | netdev_update_features(dev); | 1433 | netdev_update_features(dev); |
| 1429 | 1434 | ||
| @@ -1690,13 +1695,9 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | |||
| 1690 | kfree_skb(skb); | 1695 | kfree_skb(skb); |
| 1691 | return NET_RX_DROP; | 1696 | return NET_RX_DROP; |
| 1692 | } | 1697 | } |
| 1693 | skb->protocol = eth_type_trans(skb, dev); | ||
| 1694 | 1698 | ||
| 1695 | /* eth_type_trans() can set pkt_type. | ||
| 1696 | * call skb_scrub_packet() after it to clear pkt_type _after_ calling | ||
| 1697 | * eth_type_trans(). | ||
| 1698 | */ | ||
| 1699 | skb_scrub_packet(skb, true); | 1699 | skb_scrub_packet(skb, true); |
| 1700 | skb->protocol = eth_type_trans(skb, dev); | ||
| 1700 | 1701 | ||
| 1701 | return netif_rx(skb); | 1702 | return netif_rx(skb); |
| 1702 | } | 1703 | } |
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 5e78d44333b9..95897183226e 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
| @@ -106,6 +106,10 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) | |||
| 106 | return skb; | 106 | return skb; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static struct genl_multicast_group dropmon_mcgrps[] = { | ||
| 110 | { .name = "events", }, | ||
| 111 | }; | ||
| 112 | |||
| 109 | static void send_dm_alert(struct work_struct *work) | 113 | static void send_dm_alert(struct work_struct *work) |
| 110 | { | 114 | { |
| 111 | struct sk_buff *skb; | 115 | struct sk_buff *skb; |
| @@ -116,7 +120,8 @@ static void send_dm_alert(struct work_struct *work) | |||
| 116 | skb = reset_per_cpu_data(data); | 120 | skb = reset_per_cpu_data(data); |
| 117 | 121 | ||
| 118 | if (skb) | 122 | if (skb) |
| 119 | genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); | 123 | genlmsg_multicast(&net_drop_monitor_family, skb, 0, |
| 124 | 0, GFP_KERNEL); | ||
| 120 | } | 125 | } |
| 121 | 126 | ||
| 122 | /* | 127 | /* |
| @@ -333,7 +338,7 @@ out: | |||
| 333 | return NOTIFY_DONE; | 338 | return NOTIFY_DONE; |
| 334 | } | 339 | } |
| 335 | 340 | ||
| 336 | static struct genl_ops dropmon_ops[] = { | 341 | static const struct genl_ops dropmon_ops[] = { |
| 337 | { | 342 | { |
| 338 | .cmd = NET_DM_CMD_CONFIG, | 343 | .cmd = NET_DM_CMD_CONFIG, |
| 339 | .doit = net_dm_cmd_config, | 344 | .doit = net_dm_cmd_config, |
| @@ -364,13 +369,13 @@ static int __init init_net_drop_monitor(void) | |||
| 364 | return -ENOSPC; | 369 | return -ENOSPC; |
| 365 | } | 370 | } |
| 366 | 371 | ||
| 367 | rc = genl_register_family_with_ops(&net_drop_monitor_family, | 372 | rc = genl_register_family_with_ops_groups(&net_drop_monitor_family, |
| 368 | dropmon_ops, | 373 | dropmon_ops, dropmon_mcgrps); |
| 369 | ARRAY_SIZE(dropmon_ops)); | ||
| 370 | if (rc) { | 374 | if (rc) { |
| 371 | pr_err("Could not create drop monitor netlink family\n"); | 375 | pr_err("Could not create drop monitor netlink family\n"); |
| 372 | return rc; | 376 | return rc; |
| 373 | } | 377 | } |
| 378 | WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT); | ||
| 374 | 379 | ||
| 375 | rc = register_netdevice_notifier(&dropmon_net_notifier); | 380 | rc = register_netdevice_notifier(&dropmon_net_notifier); |
| 376 | if (rc < 0) { | 381 | if (rc < 0) { |
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c index 4e66bf61f585..5325af85eea6 100644 --- a/net/hsr/hsr_netlink.c +++ b/net/hsr/hsr_netlink.c | |||
| @@ -90,8 +90,8 @@ static struct genl_family hsr_genl_family = { | |||
| 90 | .maxattr = HSR_A_MAX, | 90 | .maxattr = HSR_A_MAX, |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | static struct genl_multicast_group hsr_network_genl_mcgrp = { | 93 | static const struct genl_multicast_group hsr_mcgrps[] = { |
| 94 | .name = "hsr-network", | 94 | { .name = "hsr-network", }, |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | 97 | ||
| @@ -129,7 +129,7 @@ void hsr_nl_ringerror(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN], | |||
| 129 | goto nla_put_failure; | 129 | goto nla_put_failure; |
| 130 | 130 | ||
| 131 | genlmsg_end(skb, msg_head); | 131 | genlmsg_end(skb, msg_head); |
| 132 | genlmsg_multicast(skb, 0, hsr_network_genl_mcgrp.id, GFP_ATOMIC); | 132 | genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC); |
| 133 | 133 | ||
| 134 | return; | 134 | return; |
| 135 | 135 | ||
| @@ -163,7 +163,7 @@ void hsr_nl_nodedown(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN]) | |||
| 163 | goto nla_put_failure; | 163 | goto nla_put_failure; |
| 164 | 164 | ||
| 165 | genlmsg_end(skb, msg_head); | 165 | genlmsg_end(skb, msg_head); |
| 166 | genlmsg_multicast(skb, 0, hsr_network_genl_mcgrp.id, GFP_ATOMIC); | 166 | genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC); |
| 167 | 167 | ||
| 168 | return; | 168 | return; |
| 169 | 169 | ||
| @@ -249,7 +249,7 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info) | |||
| 249 | &hsr_node_if2_age, | 249 | &hsr_node_if2_age, |
| 250 | &hsr_node_if2_seq); | 250 | &hsr_node_if2_seq); |
| 251 | if (res < 0) | 251 | if (res < 0) |
| 252 | goto fail; | 252 | goto nla_put_failure; |
| 253 | 253 | ||
| 254 | res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, | 254 | res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, |
| 255 | nla_data(info->attrs[HSR_A_NODE_ADDR])); | 255 | nla_data(info->attrs[HSR_A_NODE_ADDR])); |
| @@ -306,15 +306,6 @@ fail: | |||
| 306 | return res; | 306 | return res; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | static 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 | */ |
| 320 | static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) | 311 | static 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 | ||
| 401 | static struct genl_ops hsr_ops_get_node_list = { | 392 | static 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 | ||
| 409 | int __init hsr_netlink_init(void) | 409 | int __init hsr_netlink_init(void) |
| @@ -414,30 +414,13 @@ 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_groups(&hsr_genl_family, hsr_ops, |
| 418 | hsr_mcgrps); | ||
| 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); | ||
| 430 | if (rc) | ||
| 431 | goto fail_genl_register_mc_group; | ||
| 432 | |||
| 433 | return 0; | 422 | return 0; |
| 434 | 423 | ||
| 435 | fail_genl_register_mc_group: | ||
| 436 | genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_list); | ||
| 437 | fail_genl_register_ops_node_list: | ||
| 438 | genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status); | ||
| 439 | fail_genl_register_ops: | ||
| 440 | genl_unregister_family(&hsr_genl_family); | ||
| 441 | fail_genl_register_family: | 424 | fail_genl_register_family: |
| 442 | rtnl_link_unregister(&hsr_link_ops); | 425 | rtnl_link_unregister(&hsr_link_ops); |
| 443 | fail_rtnl_link_register: | 426 | fail_rtnl_link_register: |
| @@ -447,10 +430,7 @@ fail_rtnl_link_register: | |||
| 447 | 430 | ||
| 448 | void __exit hsr_netlink_exit(void) | 431 | void __exit hsr_netlink_exit(void) |
| 449 | { | 432 | { |
| 450 | 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); | 433 | genl_unregister_family(&hsr_genl_family); |
| 453 | |||
| 454 | rtnl_link_unregister(&hsr_link_ops); | 434 | rtnl_link_unregister(&hsr_link_ops); |
| 455 | } | 435 | } |
| 456 | 436 | ||
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 426b5df1c98f..459e200c08a4 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c | |||
| @@ -956,7 +956,7 @@ lowpan_process_data(struct sk_buff *skb) | |||
| 956 | * Traffic class carried in-line | 956 | * Traffic class carried in-line |
| 957 | * ECN + DSCP (1 byte), Flow Label is elided | 957 | * ECN + DSCP (1 byte), Flow Label is elided |
| 958 | */ | 958 | */ |
| 959 | case 1: /* 10b */ | 959 | case 2: /* 10b */ |
| 960 | if (lowpan_fetch_skb_u8(skb, &tmp)) | 960 | if (lowpan_fetch_skb_u8(skb, &tmp)) |
| 961 | goto drop; | 961 | goto drop; |
| 962 | 962 | ||
| @@ -967,7 +967,7 @@ lowpan_process_data(struct sk_buff *skb) | |||
| 967 | * Flow Label carried in-line | 967 | * Flow Label carried in-line |
| 968 | * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided | 968 | * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided |
| 969 | */ | 969 | */ |
| 970 | case 2: /* 01b */ | 970 | case 1: /* 01b */ |
| 971 | if (lowpan_fetch_skb_u8(skb, &tmp)) | 971 | if (lowpan_fetch_skb_u8(skb, &tmp)) |
| 972 | goto drop; | 972 | goto drop; |
| 973 | 973 | ||
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 581a59504bd5..1865fdf5a5a5 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
| @@ -315,9 +315,8 @@ static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 315 | if (saddr) { | 315 | if (saddr) { |
| 316 | saddr->family = AF_IEEE802154; | 316 | saddr->family = AF_IEEE802154; |
| 317 | saddr->addr = mac_cb(skb)->sa; | 317 | saddr->addr = mac_cb(skb)->sa; |
| 318 | } | ||
| 319 | if (addr_len) | ||
| 320 | *addr_len = sizeof(*saddr); | 318 | *addr_len = sizeof(*saddr); |
| 319 | } | ||
| 321 | 320 | ||
| 322 | if (flags & MSG_TRUNC) | 321 | if (flags & MSG_TRUNC) |
| 323 | copied = skb->len; | 322 | copied = skb->len; |
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h index aadec428e6ec..cee4425b9956 100644 --- a/net/ieee802154/ieee802154.h +++ b/net/ieee802154/ieee802154.h | |||
| @@ -47,7 +47,24 @@ struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info, | |||
| 47 | int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info); | 47 | int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info); |
| 48 | 48 | ||
| 49 | extern struct genl_family nl802154_family; | 49 | extern struct genl_family nl802154_family; |
| 50 | int nl802154_mac_register(void); | 50 | |
| 51 | int nl802154_phy_register(void); | 51 | /* genetlink ops/groups */ |
| 52 | int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info); | ||
| 53 | int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb); | ||
| 54 | int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info); | ||
| 55 | int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info); | ||
| 56 | |||
| 57 | enum ieee802154_mcgrp_ids { | ||
| 58 | IEEE802154_COORD_MCGRP, | ||
| 59 | IEEE802154_BEACON_MCGRP, | ||
| 60 | }; | ||
| 61 | |||
| 62 | int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info); | ||
| 63 | int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info); | ||
| 64 | int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info); | ||
| 65 | int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info); | ||
| 66 | int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info); | ||
| 67 | int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info); | ||
| 68 | int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb); | ||
| 52 | 69 | ||
| 53 | #endif | 70 | #endif |
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index 7e49bbcc6967..43f1b2bf469f 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c | |||
| @@ -70,7 +70,7 @@ int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group) | |||
| 70 | if (genlmsg_end(msg, hdr) < 0) | 70 | if (genlmsg_end(msg, hdr) < 0) |
| 71 | goto out; | 71 | goto out; |
| 72 | 72 | ||
| 73 | return genlmsg_multicast(msg, 0, group, GFP_ATOMIC); | 73 | return genlmsg_multicast(&nl802154_family, msg, 0, group, GFP_ATOMIC); |
| 74 | out: | 74 | out: |
| 75 | nlmsg_free(msg); | 75 | nlmsg_free(msg); |
| 76 | return -ENOBUFS; | 76 | return -ENOBUFS; |
| @@ -109,31 +109,36 @@ out: | |||
| 109 | return -ENOBUFS; | 109 | return -ENOBUFS; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | int __init ieee802154_nl_init(void) | 112 | static const struct genl_ops ieee8021154_ops[] = { |
| 113 | { | 113 | /* see nl-phy.c */ |
| 114 | int rc; | 114 | IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy, |
| 115 | 115 | ieee802154_dump_phy), | |
| 116 | rc = genl_register_family(&nl802154_family); | 116 | IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface), |
| 117 | if (rc) | 117 | IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface), |
| 118 | goto fail; | 118 | /* see nl-mac.c */ |
| 119 | 119 | IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req), | |
| 120 | rc = nl802154_mac_register(); | 120 | IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp), |
| 121 | if (rc) | 121 | IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req), |
| 122 | goto fail; | 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 | }; | ||
| 123 | 127 | ||
| 124 | rc = nl802154_phy_register(); | 128 | static const struct genl_multicast_group ieee802154_mcgrps[] = { |
| 125 | if (rc) | 129 | [IEEE802154_COORD_MCGRP] = { .name = IEEE802154_MCAST_COORD_NAME, }, |
| 126 | goto fail; | 130 | [IEEE802154_BEACON_MCGRP] = { .name = IEEE802154_MCAST_BEACON_NAME, }, |
| 131 | }; | ||
| 127 | 132 | ||
| 128 | return 0; | ||
| 129 | 133 | ||
| 130 | fail: | 134 | int __init ieee802154_nl_init(void) |
| 131 | genl_unregister_family(&nl802154_family); | 135 | { |
| 132 | return rc; | 136 | return genl_register_family_with_ops_groups(&nl802154_family, |
| 137 | ieee8021154_ops, | ||
| 138 | ieee802154_mcgrps); | ||
| 133 | } | 139 | } |
| 134 | 140 | ||
| 135 | void __exit ieee802154_nl_exit(void) | 141 | void __exit ieee802154_nl_exit(void) |
| 136 | { | 142 | { |
| 137 | genl_unregister_family(&nl802154_family); | 143 | genl_unregister_family(&nl802154_family); |
| 138 | } | 144 | } |
| 139 | |||
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c index b0bdd8c51e9c..ba5c1e002f37 100644 --- a/net/ieee802154/nl-mac.c +++ b/net/ieee802154/nl-mac.c | |||
| @@ -39,14 +39,6 @@ | |||
| 39 | 39 | ||
| 40 | #include "ieee802154.h" | 40 | #include "ieee802154.h" |
| 41 | 41 | ||
| 42 | static struct genl_multicast_group ieee802154_coord_mcgrp = { | ||
| 43 | .name = IEEE802154_MCAST_COORD_NAME, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static struct genl_multicast_group ieee802154_beacon_mcgrp = { | ||
| 47 | .name = IEEE802154_MCAST_BEACON_NAME, | ||
| 48 | }; | ||
| 49 | |||
| 50 | int ieee802154_nl_assoc_indic(struct net_device *dev, | 42 | int ieee802154_nl_assoc_indic(struct net_device *dev, |
| 51 | struct ieee802154_addr *addr, u8 cap) | 43 | struct ieee802154_addr *addr, u8 cap) |
| 52 | { | 44 | { |
| @@ -72,7 +64,7 @@ int ieee802154_nl_assoc_indic(struct net_device *dev, | |||
| 72 | nla_put_u8(msg, IEEE802154_ATTR_CAPABILITY, cap)) | 64 | nla_put_u8(msg, IEEE802154_ATTR_CAPABILITY, cap)) |
| 73 | goto nla_put_failure; | 65 | goto nla_put_failure; |
| 74 | 66 | ||
| 75 | return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); | 67 | return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); |
| 76 | 68 | ||
| 77 | nla_put_failure: | 69 | nla_put_failure: |
| 78 | nlmsg_free(msg); | 70 | nlmsg_free(msg); |
| @@ -98,7 +90,7 @@ int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr, | |||
| 98 | nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || | 90 | nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || |
| 99 | nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) | 91 | nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) |
| 100 | goto nla_put_failure; | 92 | goto nla_put_failure; |
| 101 | return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); | 93 | return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); |
| 102 | 94 | ||
| 103 | nla_put_failure: | 95 | nla_put_failure: |
| 104 | nlmsg_free(msg); | 96 | nlmsg_free(msg); |
| @@ -133,7 +125,7 @@ int ieee802154_nl_disassoc_indic(struct net_device *dev, | |||
| 133 | } | 125 | } |
| 134 | if (nla_put_u8(msg, IEEE802154_ATTR_REASON, reason)) | 126 | if (nla_put_u8(msg, IEEE802154_ATTR_REASON, reason)) |
| 135 | goto nla_put_failure; | 127 | goto nla_put_failure; |
| 136 | return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); | 128 | return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); |
| 137 | 129 | ||
| 138 | nla_put_failure: | 130 | nla_put_failure: |
| 139 | nlmsg_free(msg); | 131 | nlmsg_free(msg); |
| @@ -157,7 +149,7 @@ int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status) | |||
| 157 | dev->dev_addr) || | 149 | dev->dev_addr) || |
| 158 | nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) | 150 | nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) |
| 159 | goto nla_put_failure; | 151 | goto nla_put_failure; |
| 160 | return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); | 152 | return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); |
| 161 | 153 | ||
| 162 | nla_put_failure: | 154 | nla_put_failure: |
| 163 | nlmsg_free(msg); | 155 | nlmsg_free(msg); |
| @@ -183,7 +175,7 @@ int ieee802154_nl_beacon_indic(struct net_device *dev, | |||
| 183 | nla_put_u16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr) || | 175 | nla_put_u16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr) || |
| 184 | nla_put_u16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid)) | 176 | nla_put_u16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid)) |
| 185 | goto nla_put_failure; | 177 | goto nla_put_failure; |
| 186 | return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); | 178 | return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); |
| 187 | 179 | ||
| 188 | nla_put_failure: | 180 | nla_put_failure: |
| 189 | nlmsg_free(msg); | 181 | nlmsg_free(msg); |
| @@ -214,7 +206,7 @@ int ieee802154_nl_scan_confirm(struct net_device *dev, | |||
| 214 | (edl && | 206 | (edl && |
| 215 | nla_put(msg, IEEE802154_ATTR_ED_LIST, 27, edl))) | 207 | nla_put(msg, IEEE802154_ATTR_ED_LIST, 27, edl))) |
| 216 | goto nla_put_failure; | 208 | goto nla_put_failure; |
| 217 | return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); | 209 | return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); |
| 218 | 210 | ||
| 219 | nla_put_failure: | 211 | nla_put_failure: |
| 220 | nlmsg_free(msg); | 212 | nlmsg_free(msg); |
| @@ -238,7 +230,7 @@ int ieee802154_nl_start_confirm(struct net_device *dev, u8 status) | |||
| 238 | dev->dev_addr) || | 230 | dev->dev_addr) || |
| 239 | nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) | 231 | nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) |
| 240 | goto nla_put_failure; | 232 | goto nla_put_failure; |
| 241 | return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id); | 233 | return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); |
| 242 | 234 | ||
| 243 | nla_put_failure: | 235 | nla_put_failure: |
| 244 | nlmsg_free(msg); | 236 | nlmsg_free(msg); |
| @@ -309,8 +301,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info) | |||
| 309 | return dev; | 301 | return dev; |
| 310 | } | 302 | } |
| 311 | 303 | ||
| 312 | static int ieee802154_associate_req(struct sk_buff *skb, | 304 | int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info) |
| 313 | struct genl_info *info) | ||
| 314 | { | 305 | { |
| 315 | struct net_device *dev; | 306 | struct net_device *dev; |
| 316 | struct ieee802154_addr addr; | 307 | struct ieee802154_addr addr; |
| @@ -357,8 +348,7 @@ out: | |||
| 357 | return ret; | 348 | return ret; |
| 358 | } | 349 | } |
| 359 | 350 | ||
| 360 | static int ieee802154_associate_resp(struct sk_buff *skb, | 351 | int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info) |
| 361 | struct genl_info *info) | ||
| 362 | { | 352 | { |
| 363 | struct net_device *dev; | 353 | struct net_device *dev; |
| 364 | struct ieee802154_addr addr; | 354 | struct ieee802154_addr addr; |
| @@ -390,8 +380,7 @@ out: | |||
| 390 | return ret; | 380 | return ret; |
| 391 | } | 381 | } |
| 392 | 382 | ||
| 393 | static int ieee802154_disassociate_req(struct sk_buff *skb, | 383 | int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info) |
| 394 | struct genl_info *info) | ||
| 395 | { | 384 | { |
| 396 | struct net_device *dev; | 385 | struct net_device *dev; |
| 397 | struct ieee802154_addr addr; | 386 | struct ieee802154_addr addr; |
| @@ -433,7 +422,7 @@ out: | |||
| 433 | * PAN_coordinator, battery_life_extension = 0, | 422 | * PAN_coordinator, battery_life_extension = 0, |
| 434 | * coord_realignment = 0, security_enable = 0 | 423 | * coord_realignment = 0, security_enable = 0 |
| 435 | */ | 424 | */ |
| 436 | static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) | 425 | int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) |
| 437 | { | 426 | { |
| 438 | struct net_device *dev; | 427 | struct net_device *dev; |
| 439 | struct ieee802154_addr addr; | 428 | struct ieee802154_addr addr; |
| @@ -492,7 +481,7 @@ out: | |||
| 492 | return ret; | 481 | return ret; |
| 493 | } | 482 | } |
| 494 | 483 | ||
| 495 | static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) | 484 | int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) |
| 496 | { | 485 | { |
| 497 | struct net_device *dev; | 486 | struct net_device *dev; |
| 498 | int ret = -EOPNOTSUPP; | 487 | int ret = -EOPNOTSUPP; |
| @@ -530,8 +519,7 @@ out: | |||
| 530 | return ret; | 519 | return ret; |
| 531 | } | 520 | } |
| 532 | 521 | ||
| 533 | static int ieee802154_list_iface(struct sk_buff *skb, | 522 | int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info) |
| 534 | struct genl_info *info) | ||
| 535 | { | 523 | { |
| 536 | /* Request for interface name, index, type, IEEE address, | 524 | /* Request for interface name, index, type, IEEE address, |
| 537 | PAN Id, short address */ | 525 | PAN Id, short address */ |
| @@ -565,8 +553,7 @@ out_dev: | |||
| 565 | 553 | ||
| 566 | } | 554 | } |
| 567 | 555 | ||
| 568 | static int ieee802154_dump_iface(struct sk_buff *skb, | 556 | int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb) |
| 569 | struct netlink_callback *cb) | ||
| 570 | { | 557 | { |
| 571 | struct net *net = sock_net(skb->sk); | 558 | struct net *net = sock_net(skb->sk); |
| 572 | struct net_device *dev; | 559 | struct net_device *dev; |
| @@ -590,41 +577,3 @@ cont: | |||
| 590 | 577 | ||
| 591 | return skb->len; | 578 | return skb->len; |
| 592 | } | 579 | } |
| 593 | |||
| 594 | static 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 | */ | ||
| 607 | int 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 | ||
| 80 | static int ieee802154_list_phy(struct sk_buff *skb, | 80 | int 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 | ||
| 154 | static int ieee802154_dump_phy(struct sk_buff *skb, | 153 | int 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 | ||
| 173 | static int ieee802154_add_iface(struct sk_buff *skb, | 171 | int 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 | ||
| 276 | static int ieee802154_del_iface(struct sk_buff *skb, | 273 | int 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 | |||
| 360 | static 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 | */ | ||
| 370 | int 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/datagram.c b/net/ipv4/datagram.c index b28e863fe0a7..19e36376d2a0 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
| @@ -57,7 +57,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 57 | if (IS_ERR(rt)) { | 57 | if (IS_ERR(rt)) { |
| 58 | err = PTR_ERR(rt); | 58 | err = PTR_ERR(rt); |
| 59 | if (err == -ENETUNREACH) | 59 | if (err == -ENETUNREACH) |
| 60 | IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); | 60 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
| 61 | goto out; | 61 | goto out; |
| 62 | } | 62 | } |
| 63 | 63 | ||
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index caf01176a5e4..90ff9570d7d4 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
| @@ -454,6 +454,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, | |||
| 454 | tstats->rx_bytes += skb->len; | 454 | tstats->rx_bytes += skb->len; |
| 455 | u64_stats_update_end(&tstats->syncp); | 455 | u64_stats_update_end(&tstats->syncp); |
| 456 | 456 | ||
| 457 | skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev))); | ||
| 458 | |||
| 457 | if (tunnel->dev->type == ARPHRD_ETHER) { | 459 | if (tunnel->dev->type == ARPHRD_ETHER) { |
| 458 | skb->protocol = eth_type_trans(skb, tunnel->dev); | 460 | skb->protocol = eth_type_trans(skb, tunnel->dev); |
| 459 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | 461 | skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); |
| @@ -461,8 +463,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, | |||
| 461 | skb->dev = tunnel->dev; | 463 | skb->dev = tunnel->dev; |
| 462 | } | 464 | } |
| 463 | 465 | ||
| 464 | skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev))); | ||
| 465 | |||
| 466 | gro_cells_receive(&tunnel->gro_cells, skb); | 466 | gro_cells_receive(&tunnel->gro_cells, skb); |
| 467 | return 0; | 467 | return 0; |
| 468 | 468 | ||
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 5d9c845d288a..52b802a0cd8c 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
| @@ -126,6 +126,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 126 | if (!rt->dst.xfrm || | 126 | if (!rt->dst.xfrm || |
| 127 | rt->dst.xfrm->props.mode != XFRM_MODE_TUNNEL) { | 127 | rt->dst.xfrm->props.mode != XFRM_MODE_TUNNEL) { |
| 128 | dev->stats.tx_carrier_errors++; | 128 | dev->stats.tx_carrier_errors++; |
| 129 | ip_rt_put(rt); | ||
| 129 | goto tx_error_icmp; | 130 | goto tx_error_icmp; |
| 130 | } | 131 | } |
| 131 | tdev = rt->dst.dev; | 132 | tdev = rt->dst.dev; |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index cbc85f660d54..876c6ca2d8f9 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -830,8 +830,6 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 830 | { | 830 | { |
| 831 | struct inet_sock *isk = inet_sk(sk); | 831 | struct inet_sock *isk = inet_sk(sk); |
| 832 | int family = sk->sk_family; | 832 | int family = sk->sk_family; |
| 833 | struct sockaddr_in *sin; | ||
| 834 | struct sockaddr_in6 *sin6; | ||
| 835 | struct sk_buff *skb; | 833 | struct sk_buff *skb; |
| 836 | int copied, err; | 834 | int copied, err; |
| 837 | 835 | ||
| @@ -841,13 +839,6 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 841 | if (flags & MSG_OOB) | 839 | if (flags & MSG_OOB) |
| 842 | goto out; | 840 | goto out; |
| 843 | 841 | ||
| 844 | if (addr_len) { | ||
| 845 | if (family == AF_INET) | ||
| 846 | *addr_len = sizeof(*sin); | ||
| 847 | else if (family == AF_INET6 && addr_len) | ||
| 848 | *addr_len = sizeof(*sin6); | ||
| 849 | } | ||
| 850 | |||
| 851 | if (flags & MSG_ERRQUEUE) { | 842 | if (flags & MSG_ERRQUEUE) { |
| 852 | if (family == AF_INET) { | 843 | if (family == AF_INET) { |
| 853 | return ip_recv_error(sk, msg, len); | 844 | return ip_recv_error(sk, msg, len); |
| @@ -877,11 +868,15 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 877 | 868 | ||
| 878 | /* Copy the address and add cmsg data. */ | 869 | /* Copy the address and add cmsg data. */ |
| 879 | if (family == AF_INET) { | 870 | if (family == AF_INET) { |
| 880 | sin = (struct sockaddr_in *) msg->msg_name; | 871 | struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; |
| 881 | sin->sin_family = AF_INET; | 872 | |
| 882 | sin->sin_port = 0 /* skb->h.uh->source */; | 873 | if (sin) { |
| 883 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | 874 | sin->sin_family = AF_INET; |
| 884 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); | 875 | sin->sin_port = 0 /* skb->h.uh->source */; |
| 876 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | ||
| 877 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); | ||
| 878 | *addr_len = sizeof(*sin); | ||
| 879 | } | ||
| 885 | 880 | ||
| 886 | if (isk->cmsg_flags) | 881 | if (isk->cmsg_flags) |
| 887 | ip_cmsg_recv(msg, skb); | 882 | ip_cmsg_recv(msg, skb); |
| @@ -890,17 +885,21 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 890 | } else if (family == AF_INET6) { | 885 | } else if (family == AF_INET6) { |
| 891 | struct ipv6_pinfo *np = inet6_sk(sk); | 886 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 892 | struct ipv6hdr *ip6 = ipv6_hdr(skb); | 887 | struct ipv6hdr *ip6 = ipv6_hdr(skb); |
| 893 | sin6 = (struct sockaddr_in6 *) msg->msg_name; | 888 | struct sockaddr_in6 *sin6 = |
| 894 | sin6->sin6_family = AF_INET6; | 889 | (struct sockaddr_in6 *)msg->msg_name; |
| 895 | sin6->sin6_port = 0; | 890 | |
| 896 | sin6->sin6_addr = ip6->saddr; | 891 | if (sin6) { |
| 897 | 892 | sin6->sin6_family = AF_INET6; | |
| 898 | sin6->sin6_flowinfo = 0; | 893 | sin6->sin6_port = 0; |
| 899 | if (np->sndflow) | 894 | sin6->sin6_addr = ip6->saddr; |
| 900 | sin6->sin6_flowinfo = ip6_flowinfo(ip6); | 895 | sin6->sin6_flowinfo = 0; |
| 901 | 896 | if (np->sndflow) | |
| 902 | sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, | 897 | sin6->sin6_flowinfo = ip6_flowinfo(ip6); |
| 903 | IP6CB(skb)->iif); | 898 | sin6->sin6_scope_id = |
| 899 | ipv6_iface_scope_id(&sin6->sin6_addr, | ||
| 900 | IP6CB(skb)->iif); | ||
| 901 | *addr_len = sizeof(*sin6); | ||
| 902 | } | ||
| 904 | 903 | ||
| 905 | if (inet6_sk(sk)->rxopt.all) | 904 | if (inet6_sk(sk)->rxopt.all) |
| 906 | pingv6_ops.ip6_datagram_recv_ctl(sk, msg, skb); | 905 | pingv6_ops.ip6_datagram_recv_ctl(sk, msg, skb); |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 41e1d2845c8f..5cb8ddb505ee 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -696,9 +696,6 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 696 | if (flags & MSG_OOB) | 696 | if (flags & MSG_OOB) |
| 697 | goto out; | 697 | goto out; |
| 698 | 698 | ||
| 699 | if (addr_len) | ||
| 700 | *addr_len = sizeof(*sin); | ||
| 701 | |||
| 702 | if (flags & MSG_ERRQUEUE) { | 699 | if (flags & MSG_ERRQUEUE) { |
| 703 | err = ip_recv_error(sk, msg, len); | 700 | err = ip_recv_error(sk, msg, len); |
| 704 | goto out; | 701 | goto out; |
| @@ -726,6 +723,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 726 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | 723 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
| 727 | sin->sin_port = 0; | 724 | sin->sin_port = 0; |
| 728 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); | 725 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
| 726 | *addr_len = sizeof(*sin); | ||
| 729 | } | 727 | } |
| 730 | if (inet->cmsg_flags) | 728 | if (inet->cmsg_flags) |
| 731 | ip_cmsg_recv(msg, skb); | 729 | ip_cmsg_recv(msg, skb); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8e8529d3c8c9..c4638e6f0238 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -808,12 +808,6 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, | |||
| 808 | xmit_size_goal = min_t(u32, gso_size, | 808 | xmit_size_goal = min_t(u32, gso_size, |
| 809 | sk->sk_gso_max_size - 1 - hlen); | 809 | sk->sk_gso_max_size - 1 - hlen); |
| 810 | 810 | ||
| 811 | /* TSQ : try to have at least two segments in flight | ||
| 812 | * (one in NIC TX ring, another in Qdisc) | ||
| 813 | */ | ||
| 814 | xmit_size_goal = min_t(u32, xmit_size_goal, | ||
| 815 | sysctl_tcp_limit_output_bytes >> 1); | ||
| 816 | |||
| 817 | xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal); | 811 | xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal); |
| 818 | 812 | ||
| 819 | /* We try hard to avoid divides here */ | 813 | /* We try hard to avoid divides here */ |
| @@ -1431,7 +1425,7 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) | |||
| 1431 | do { | 1425 | do { |
| 1432 | if (dma_async_is_tx_complete(tp->ucopy.dma_chan, | 1426 | if (dma_async_is_tx_complete(tp->ucopy.dma_chan, |
| 1433 | last_issued, &done, | 1427 | last_issued, &done, |
| 1434 | &used) == DMA_SUCCESS) { | 1428 | &used) == DMA_COMPLETE) { |
| 1435 | /* Safe to free early-copied skbs now */ | 1429 | /* Safe to free early-copied skbs now */ |
| 1436 | __skb_queue_purge(&sk->sk_async_wait_queue); | 1430 | __skb_queue_purge(&sk->sk_async_wait_queue); |
| 1437 | break; | 1431 | break; |
| @@ -1439,7 +1433,7 @@ static void tcp_service_net_dma(struct sock *sk, bool wait) | |||
| 1439 | struct sk_buff *skb; | 1433 | struct sk_buff *skb; |
| 1440 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && | 1434 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && |
| 1441 | (dma_async_is_complete(skb->dma_cookie, done, | 1435 | (dma_async_is_complete(skb->dma_cookie, done, |
| 1442 | used) == DMA_SUCCESS)) { | 1436 | used) == DMA_COMPLETE)) { |
| 1443 | __skb_dequeue(&sk->sk_async_wait_queue); | 1437 | __skb_dequeue(&sk->sk_async_wait_queue); |
| 1444 | kfree_skb(skb); | 1438 | kfree_skb(skb); |
| 1445 | } | 1439 | } |
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 2ab09cbae74d..06493736fbc8 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c | |||
| @@ -663,10 +663,13 @@ void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, | |||
| 663 | void tcp_fastopen_cache_set(struct sock *sk, u16 mss, | 663 | void tcp_fastopen_cache_set(struct sock *sk, u16 mss, |
| 664 | struct tcp_fastopen_cookie *cookie, bool syn_lost) | 664 | struct tcp_fastopen_cookie *cookie, bool syn_lost) |
| 665 | { | 665 | { |
| 666 | struct dst_entry *dst = __sk_dst_get(sk); | ||
| 666 | struct tcp_metrics_block *tm; | 667 | struct tcp_metrics_block *tm; |
| 667 | 668 | ||
| 669 | if (!dst) | ||
| 670 | return; | ||
| 668 | rcu_read_lock(); | 671 | rcu_read_lock(); |
| 669 | tm = tcp_get_metrics(sk, __sk_dst_get(sk), true); | 672 | tm = tcp_get_metrics(sk, dst, true); |
| 670 | if (tm) { | 673 | if (tm) { |
| 671 | struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen; | 674 | struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen; |
| 672 | 675 | ||
| @@ -988,7 +991,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
| 988 | return 0; | 991 | return 0; |
| 989 | } | 992 | } |
| 990 | 993 | ||
| 991 | static struct genl_ops tcp_metrics_nl_ops[] = { | 994 | static const struct genl_ops tcp_metrics_nl_ops[] = { |
| 992 | { | 995 | { |
| 993 | .cmd = TCP_METRICS_CMD_GET, | 996 | .cmd = TCP_METRICS_CMD_GET, |
| 994 | .doit = tcp_metrics_nl_cmd_get, | 997 | .doit = tcp_metrics_nl_cmd_get, |
| @@ -1079,8 +1082,7 @@ void __init tcp_metrics_init(void) | |||
| 1079 | if (ret < 0) | 1082 | if (ret < 0) |
| 1080 | goto cleanup; | 1083 | goto cleanup; |
| 1081 | ret = genl_register_family_with_ops(&tcp_metrics_nl_family, | 1084 | ret = genl_register_family_with_ops(&tcp_metrics_nl_family, |
| 1082 | tcp_metrics_nl_ops, | 1085 | tcp_metrics_nl_ops); |
| 1083 | ARRAY_SIZE(tcp_metrics_nl_ops)); | ||
| 1084 | if (ret < 0) | 1086 | if (ret < 0) |
| 1085 | goto cleanup_subsys; | 1087 | goto cleanup_subsys; |
| 1086 | return; | 1088 | return; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 672854664ff5..7820f3a7dd70 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -1875,8 +1875,12 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
| 1875 | * - better RTT estimation and ACK scheduling | 1875 | * - better RTT estimation and ACK scheduling |
| 1876 | * - faster recovery | 1876 | * - faster recovery |
| 1877 | * - high rates | 1877 | * - high rates |
| 1878 | * Alas, some drivers / subsystems require a fair amount | ||
| 1879 | * of queued bytes to ensure line rate. | ||
| 1880 | * One example is wifi aggregation (802.11 AMPDU) | ||
| 1878 | */ | 1881 | */ |
| 1879 | limit = max(skb->truesize, sk->sk_pacing_rate >> 10); | 1882 | limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes, |
| 1883 | sk->sk_pacing_rate >> 10); | ||
| 1880 | 1884 | ||
| 1881 | if (atomic_read(&sk->sk_wmem_alloc) > limit) { | 1885 | if (atomic_read(&sk->sk_wmem_alloc) > limit) { |
| 1882 | set_bit(TSQ_THROTTLED, &tp->tsq_flags); | 1886 | set_bit(TSQ_THROTTLED, &tp->tsq_flags); |
| @@ -3093,7 +3097,6 @@ void tcp_send_window_probe(struct sock *sk) | |||
| 3093 | { | 3097 | { |
| 3094 | if (sk->sk_state == TCP_ESTABLISHED) { | 3098 | if (sk->sk_state == TCP_ESTABLISHED) { |
| 3095 | tcp_sk(sk)->snd_wl1 = tcp_sk(sk)->rcv_nxt - 1; | 3099 | tcp_sk(sk)->snd_wl1 = tcp_sk(sk)->rcv_nxt - 1; |
| 3096 | tcp_sk(sk)->snd_nxt = tcp_sk(sk)->write_seq; | ||
| 3097 | tcp_xmit_probe_skb(sk, 0); | 3100 | tcp_xmit_probe_skb(sk, 0); |
| 3098 | } | 3101 | } |
| 3099 | } | 3102 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index de86e5bc4462..5944d7d668dd 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -1235,12 +1235,6 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1235 | int is_udplite = IS_UDPLITE(sk); | 1235 | int is_udplite = IS_UDPLITE(sk); |
| 1236 | bool slow; | 1236 | bool slow; |
| 1237 | 1237 | ||
| 1238 | /* | ||
| 1239 | * Check any passed addresses | ||
| 1240 | */ | ||
| 1241 | if (addr_len) | ||
| 1242 | *addr_len = sizeof(*sin); | ||
| 1243 | |||
| 1244 | if (flags & MSG_ERRQUEUE) | 1238 | if (flags & MSG_ERRQUEUE) |
| 1245 | return ip_recv_error(sk, msg, len); | 1239 | return ip_recv_error(sk, msg, len); |
| 1246 | 1240 | ||
| @@ -1302,6 +1296,7 @@ try_again: | |||
| 1302 | sin->sin_port = udp_hdr(skb)->source; | 1296 | sin->sin_port = udp_hdr(skb)->source; |
| 1303 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | 1297 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
| 1304 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); | 1298 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); |
| 1299 | *addr_len = sizeof(*sin); | ||
| 1305 | } | 1300 | } |
| 1306 | if (inet->cmsg_flags) | 1301 | if (inet->cmsg_flags) |
| 1307 | ip_cmsg_recv(msg, skb); | 1302 | ip_cmsg_recv(msg, skb); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 5658d9d51637..12c97d8aa6bb 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -1996,23 +1996,6 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
| 1996 | ip6_route_add(&cfg); | 1996 | ip6_route_add(&cfg); |
| 1997 | } | 1997 | } |
| 1998 | 1998 | ||
| 1999 | #if IS_ENABLED(CONFIG_IPV6_SIT) | ||
| 2000 | static void sit_route_add(struct net_device *dev) | ||
| 2001 | { | ||
| 2002 | struct fib6_config cfg = { | ||
| 2003 | .fc_table = RT6_TABLE_MAIN, | ||
| 2004 | .fc_metric = IP6_RT_PRIO_ADDRCONF, | ||
| 2005 | .fc_ifindex = dev->ifindex, | ||
| 2006 | .fc_dst_len = 96, | ||
| 2007 | .fc_flags = RTF_UP | RTF_NONEXTHOP, | ||
| 2008 | .fc_nlinfo.nl_net = dev_net(dev), | ||
| 2009 | }; | ||
| 2010 | |||
| 2011 | /* prefix length - 96 bits "::d.d.d.d" */ | ||
| 2012 | ip6_route_add(&cfg); | ||
| 2013 | } | ||
| 2014 | #endif | ||
| 2015 | |||
| 2016 | static struct inet6_dev *addrconf_add_dev(struct net_device *dev) | 1999 | static struct inet6_dev *addrconf_add_dev(struct net_device *dev) |
| 2017 | { | 2000 | { |
| 2018 | struct inet6_dev *idev; | 2001 | struct inet6_dev *idev; |
| @@ -2542,7 +2525,8 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
| 2542 | struct in6_addr addr; | 2525 | struct in6_addr addr; |
| 2543 | struct net_device *dev; | 2526 | struct net_device *dev; |
| 2544 | struct net *net = dev_net(idev->dev); | 2527 | struct net *net = dev_net(idev->dev); |
| 2545 | int scope; | 2528 | int scope, plen; |
| 2529 | u32 pflags = 0; | ||
| 2546 | 2530 | ||
| 2547 | ASSERT_RTNL(); | 2531 | ASSERT_RTNL(); |
| 2548 | 2532 | ||
| @@ -2552,12 +2536,16 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
| 2552 | if (idev->dev->flags&IFF_POINTOPOINT) { | 2536 | if (idev->dev->flags&IFF_POINTOPOINT) { |
| 2553 | addr.s6_addr32[0] = htonl(0xfe800000); | 2537 | addr.s6_addr32[0] = htonl(0xfe800000); |
| 2554 | scope = IFA_LINK; | 2538 | scope = IFA_LINK; |
| 2539 | plen = 64; | ||
| 2555 | } else { | 2540 | } else { |
| 2556 | scope = IPV6_ADDR_COMPATv4; | 2541 | scope = IPV6_ADDR_COMPATv4; |
| 2542 | plen = 96; | ||
| 2543 | pflags |= RTF_NONEXTHOP; | ||
| 2557 | } | 2544 | } |
| 2558 | 2545 | ||
| 2559 | if (addr.s6_addr32[3]) { | 2546 | if (addr.s6_addr32[3]) { |
| 2560 | add_addr(idev, &addr, 128, scope); | 2547 | add_addr(idev, &addr, plen, scope); |
| 2548 | addrconf_prefix_route(&addr, plen, idev->dev, 0, pflags); | ||
| 2561 | return; | 2549 | return; |
| 2562 | } | 2550 | } |
| 2563 | 2551 | ||
| @@ -2569,7 +2557,6 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
| 2569 | int flag = scope; | 2557 | int flag = scope; |
| 2570 | 2558 | ||
| 2571 | for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { | 2559 | for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { |
| 2572 | int plen; | ||
| 2573 | 2560 | ||
| 2574 | addr.s6_addr32[3] = ifa->ifa_local; | 2561 | addr.s6_addr32[3] = ifa->ifa_local; |
| 2575 | 2562 | ||
| @@ -2580,12 +2567,10 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
| 2580 | continue; | 2567 | continue; |
| 2581 | flag |= IFA_HOST; | 2568 | flag |= IFA_HOST; |
| 2582 | } | 2569 | } |
| 2583 | if (idev->dev->flags&IFF_POINTOPOINT) | ||
| 2584 | plen = 64; | ||
| 2585 | else | ||
| 2586 | plen = 96; | ||
| 2587 | 2570 | ||
| 2588 | add_addr(idev, &addr, plen, flag); | 2571 | add_addr(idev, &addr, plen, flag); |
| 2572 | addrconf_prefix_route(&addr, plen, idev->dev, 0, | ||
| 2573 | pflags); | ||
| 2589 | } | 2574 | } |
| 2590 | } | 2575 | } |
| 2591 | } | 2576 | } |
| @@ -2711,7 +2696,6 @@ static void addrconf_sit_config(struct net_device *dev) | |||
| 2711 | struct in6_addr addr; | 2696 | struct in6_addr addr; |
| 2712 | 2697 | ||
| 2713 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); | 2698 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); |
| 2714 | addrconf_prefix_route(&addr, 64, dev, 0, 0); | ||
| 2715 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) | 2699 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) |
| 2716 | addrconf_add_linklocal(idev, &addr); | 2700 | addrconf_add_linklocal(idev, &addr); |
| 2717 | return; | 2701 | return; |
| @@ -2721,8 +2705,6 @@ static void addrconf_sit_config(struct net_device *dev) | |||
| 2721 | 2705 | ||
| 2722 | if (dev->flags&IFF_POINTOPOINT) | 2706 | if (dev->flags&IFF_POINTOPOINT) |
| 2723 | addrconf_add_mroute(dev); | 2707 | addrconf_add_mroute(dev); |
| 2724 | else | ||
| 2725 | sit_route_add(dev); | ||
| 2726 | } | 2708 | } |
| 2727 | #endif | 2709 | #endif |
| 2728 | 2710 | ||
| @@ -2740,8 +2722,6 @@ static void addrconf_gre_config(struct net_device *dev) | |||
| 2740 | } | 2722 | } |
| 2741 | 2723 | ||
| 2742 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); | 2724 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); |
| 2743 | addrconf_prefix_route(&addr, 64, dev, 0, 0); | ||
| 2744 | |||
| 2745 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) | 2725 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) |
| 2746 | addrconf_add_linklocal(idev, &addr); | 2726 | addrconf_add_linklocal(idev, &addr); |
| 2747 | } | 2727 | } |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index ff75313f27a8..4fbdb7046d28 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -972,10 +972,10 @@ out: | |||
| 972 | 972 | ||
| 973 | #ifdef CONFIG_SYSCTL | 973 | #ifdef CONFIG_SYSCTL |
| 974 | sysctl_fail: | 974 | sysctl_fail: |
| 975 | ipv6_packet_cleanup(); | 975 | pingv6_exit(); |
| 976 | #endif | 976 | #endif |
| 977 | pingv6_fail: | 977 | pingv6_fail: |
| 978 | pingv6_exit(); | 978 | ipv6_packet_cleanup(); |
| 979 | ipv6_packet_fail: | 979 | ipv6_packet_fail: |
| 980 | tcpv6_exit(); | 980 | tcpv6_exit(); |
| 981 | tcpv6_fail: | 981 | tcpv6_fail: |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index df1fa58528c6..d6062325db08 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
| @@ -1642,6 +1642,15 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[], | |||
| 1642 | return ip6_tnl_update(t, &p); | 1642 | return ip6_tnl_update(t, &p); |
| 1643 | } | 1643 | } |
| 1644 | 1644 | ||
| 1645 | static void ip6_tnl_dellink(struct net_device *dev, struct list_head *head) | ||
| 1646 | { | ||
| 1647 | struct net *net = dev_net(dev); | ||
| 1648 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); | ||
| 1649 | |||
| 1650 | if (dev != ip6n->fb_tnl_dev) | ||
| 1651 | unregister_netdevice_queue(dev, head); | ||
| 1652 | } | ||
| 1653 | |||
| 1645 | static size_t ip6_tnl_get_size(const struct net_device *dev) | 1654 | static size_t ip6_tnl_get_size(const struct net_device *dev) |
| 1646 | { | 1655 | { |
| 1647 | return | 1656 | return |
| @@ -1706,6 +1715,7 @@ static struct rtnl_link_ops ip6_link_ops __read_mostly = { | |||
| 1706 | .validate = ip6_tnl_validate, | 1715 | .validate = ip6_tnl_validate, |
| 1707 | .newlink = ip6_tnl_newlink, | 1716 | .newlink = ip6_tnl_newlink, |
| 1708 | .changelink = ip6_tnl_changelink, | 1717 | .changelink = ip6_tnl_changelink, |
| 1718 | .dellink = ip6_tnl_dellink, | ||
| 1709 | .get_size = ip6_tnl_get_size, | 1719 | .get_size = ip6_tnl_get_size, |
| 1710 | .fill_info = ip6_tnl_fill_info, | 1720 | .fill_info = ip6_tnl_fill_info, |
| 1711 | }; | 1721 | }; |
| @@ -1722,9 +1732,9 @@ static struct xfrm6_tunnel ip6ip6_handler __read_mostly = { | |||
| 1722 | .priority = 1, | 1732 | .priority = 1, |
| 1723 | }; | 1733 | }; |
| 1724 | 1734 | ||
| 1725 | static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) | 1735 | static void __net_exit ip6_tnl_destroy_tunnels(struct net *net) |
| 1726 | { | 1736 | { |
| 1727 | struct net *net = dev_net(ip6n->fb_tnl_dev); | 1737 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); |
| 1728 | struct net_device *dev, *aux; | 1738 | struct net_device *dev, *aux; |
| 1729 | int h; | 1739 | int h; |
| 1730 | struct ip6_tnl *t; | 1740 | struct ip6_tnl *t; |
| @@ -1792,10 +1802,8 @@ err_alloc_dev: | |||
| 1792 | 1802 | ||
| 1793 | static void __net_exit ip6_tnl_exit_net(struct net *net) | 1803 | static void __net_exit ip6_tnl_exit_net(struct net *net) |
| 1794 | { | 1804 | { |
| 1795 | struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); | ||
| 1796 | |||
| 1797 | rtnl_lock(); | 1805 | rtnl_lock(); |
| 1798 | ip6_tnl_destroy_tunnels(ip6n); | 1806 | ip6_tnl_destroy_tunnels(net); |
| 1799 | rtnl_unlock(); | 1807 | rtnl_unlock(); |
| 1800 | } | 1808 | } |
| 1801 | 1809 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f8a55ff1971b..3512177deb4d 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1726,8 +1726,8 @@ int __init ndisc_init(void) | |||
| 1726 | &ndisc_ifinfo_sysctl_change); | 1726 | &ndisc_ifinfo_sysctl_change); |
| 1727 | if (err) | 1727 | if (err) |
| 1728 | goto out_unregister_pernet; | 1728 | goto out_unregister_pernet; |
| 1729 | #endif | ||
| 1730 | out: | 1729 | out: |
| 1730 | #endif | ||
| 1731 | return err; | 1731 | return err; |
| 1732 | 1732 | ||
| 1733 | #ifdef CONFIG_SYSCTL | 1733 | #ifdef CONFIG_SYSCTL |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 3c00842b0079..e24ff1df0401 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -465,9 +465,6 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 465 | if (flags & MSG_OOB) | 465 | if (flags & MSG_OOB) |
| 466 | return -EOPNOTSUPP; | 466 | return -EOPNOTSUPP; |
| 467 | 467 | ||
| 468 | if (addr_len) | ||
| 469 | *addr_len=sizeof(*sin6); | ||
| 470 | |||
| 471 | if (flags & MSG_ERRQUEUE) | 468 | if (flags & MSG_ERRQUEUE) |
| 472 | return ipv6_recv_error(sk, msg, len); | 469 | return ipv6_recv_error(sk, msg, len); |
| 473 | 470 | ||
| @@ -506,6 +503,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 506 | sin6->sin6_flowinfo = 0; | 503 | sin6->sin6_flowinfo = 0; |
| 507 | sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, | 504 | sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, |
| 508 | IP6CB(skb)->iif); | 505 | IP6CB(skb)->iif); |
| 506 | *addr_len = sizeof(*sin6); | ||
| 509 | } | 507 | } |
| 510 | 508 | ||
| 511 | sock_recv_ts_and_drops(msg, sk, skb); | 509 | sock_recv_ts_and_drops(msg, sk, skb); |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index bfc6fcea3841..1b4a4a953675 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -1619,6 +1619,15 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = { | |||
| 1619 | #endif | 1619 | #endif |
| 1620 | }; | 1620 | }; |
| 1621 | 1621 | ||
| 1622 | static void ipip6_dellink(struct net_device *dev, struct list_head *head) | ||
| 1623 | { | ||
| 1624 | struct net *net = dev_net(dev); | ||
| 1625 | struct sit_net *sitn = net_generic(net, sit_net_id); | ||
| 1626 | |||
| 1627 | if (dev != sitn->fb_tunnel_dev) | ||
| 1628 | unregister_netdevice_queue(dev, head); | ||
| 1629 | } | ||
| 1630 | |||
| 1622 | static struct rtnl_link_ops sit_link_ops __read_mostly = { | 1631 | static struct rtnl_link_ops sit_link_ops __read_mostly = { |
| 1623 | .kind = "sit", | 1632 | .kind = "sit", |
| 1624 | .maxtype = IFLA_IPTUN_MAX, | 1633 | .maxtype = IFLA_IPTUN_MAX, |
| @@ -1630,6 +1639,7 @@ static struct rtnl_link_ops sit_link_ops __read_mostly = { | |||
| 1630 | .changelink = ipip6_changelink, | 1639 | .changelink = ipip6_changelink, |
| 1631 | .get_size = ipip6_get_size, | 1640 | .get_size = ipip6_get_size, |
| 1632 | .fill_info = ipip6_fill_info, | 1641 | .fill_info = ipip6_fill_info, |
| 1642 | .dellink = ipip6_dellink, | ||
| 1633 | }; | 1643 | }; |
| 1634 | 1644 | ||
| 1635 | static struct xfrm_tunnel sit_handler __read_mostly = { | 1645 | static struct xfrm_tunnel sit_handler __read_mostly = { |
| @@ -1644,9 +1654,10 @@ static struct xfrm_tunnel ipip_handler __read_mostly = { | |||
| 1644 | .priority = 2, | 1654 | .priority = 2, |
| 1645 | }; | 1655 | }; |
| 1646 | 1656 | ||
| 1647 | static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) | 1657 | static void __net_exit sit_destroy_tunnels(struct net *net, |
| 1658 | struct list_head *head) | ||
| 1648 | { | 1659 | { |
| 1649 | struct net *net = dev_net(sitn->fb_tunnel_dev); | 1660 | struct sit_net *sitn = net_generic(net, sit_net_id); |
| 1650 | struct net_device *dev, *aux; | 1661 | struct net_device *dev, *aux; |
| 1651 | int prio; | 1662 | int prio; |
| 1652 | 1663 | ||
| @@ -1721,11 +1732,10 @@ err_alloc_dev: | |||
| 1721 | 1732 | ||
| 1722 | static void __net_exit sit_exit_net(struct net *net) | 1733 | static void __net_exit sit_exit_net(struct net *net) |
| 1723 | { | 1734 | { |
| 1724 | struct sit_net *sitn = net_generic(net, sit_net_id); | ||
| 1725 | LIST_HEAD(list); | 1735 | LIST_HEAD(list); |
| 1726 | 1736 | ||
| 1727 | rtnl_lock(); | 1737 | rtnl_lock(); |
| 1728 | sit_destroy_tunnels(sitn, &list); | 1738 | sit_destroy_tunnels(net, &list); |
| 1729 | unregister_netdevice_many(&list); | 1739 | unregister_netdevice_many(&list); |
| 1730 | rtnl_unlock(); | 1740 | rtnl_unlock(); |
| 1731 | } | 1741 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index f3893e897f72..81eb8cf8389b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -392,9 +392,6 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 392 | int is_udp4; | 392 | int is_udp4; |
| 393 | bool slow; | 393 | bool slow; |
| 394 | 394 | ||
| 395 | if (addr_len) | ||
| 396 | *addr_len = sizeof(struct sockaddr_in6); | ||
| 397 | |||
| 398 | if (flags & MSG_ERRQUEUE) | 395 | if (flags & MSG_ERRQUEUE) |
| 399 | return ipv6_recv_error(sk, msg, len); | 396 | return ipv6_recv_error(sk, msg, len); |
| 400 | 397 | ||
| @@ -480,7 +477,7 @@ try_again: | |||
| 480 | ipv6_iface_scope_id(&sin6->sin6_addr, | 477 | ipv6_iface_scope_id(&sin6->sin6_addr, |
| 481 | IP6CB(skb)->iif); | 478 | IP6CB(skb)->iif); |
| 482 | } | 479 | } |
| 483 | 480 | *addr_len = sizeof(*sin6); | |
| 484 | } | 481 | } |
| 485 | if (is_udp4) { | 482 | if (is_udp4) { |
| 486 | if (inet->cmsg_flags) | 483 | if (inet->cmsg_flags) |
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index c32971269280..a37b81fe0479 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 | ||
| 134 | static struct genl_ops irda_nl_ops[] = { | 134 | static 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, |
| @@ -149,8 +149,7 @@ static struct genl_ops irda_nl_ops[] = { | |||
| 149 | 149 | ||
| 150 | int irda_nl_register(void) | 150 | int irda_nl_register(void) |
| 151 | { | 151 | { |
| 152 | return genl_register_family_with_ops(&irda_nl_family, | 152 | return genl_register_family_with_ops(&irda_nl_family, irda_nl_ops); |
| 153 | irda_nl_ops, ARRAY_SIZE(irda_nl_ops)); | ||
| 154 | } | 153 | } |
| 155 | 154 | ||
| 156 | void irda_nl_unregister(void) | 155 | void irda_nl_unregister(void) |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 571db8dd2292..da1a1cee1a08 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
| @@ -518,9 +518,6 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
| 518 | if (flags & MSG_OOB) | 518 | if (flags & MSG_OOB) |
| 519 | goto out; | 519 | goto out; |
| 520 | 520 | ||
| 521 | if (addr_len) | ||
| 522 | *addr_len = sizeof(*sin); | ||
| 523 | |||
| 524 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 521 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
| 525 | if (!skb) | 522 | if (!skb) |
| 526 | goto out; | 523 | goto out; |
| @@ -543,6 +540,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
| 543 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | 540 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
| 544 | sin->sin_port = 0; | 541 | sin->sin_port = 0; |
| 545 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); | 542 | memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
| 543 | *addr_len = sizeof(*sin); | ||
| 546 | } | 544 | } |
| 547 | if (inet->cmsg_flags) | 545 | if (inet->cmsg_flags) |
| 548 | ip_cmsg_recv(msg, skb); | 546 | ip_cmsg_recv(msg, skb); |
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index be446d517bc9..4cfd722e9153 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 | ||
| 796 | static struct genl_ops l2tp_nl_ops[] = { | 796 | static 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, |
| @@ -887,13 +887,8 @@ EXPORT_SYMBOL_GPL(l2tp_nl_unregister_ops); | |||
| 887 | 887 | ||
| 888 | static int l2tp_nl_init(void) | 888 | static int l2tp_nl_init(void) |
| 889 | { | 889 | { |
| 890 | int err; | ||
| 891 | |||
| 892 | pr_info("L2TP netlink interface\n"); | 890 | pr_info("L2TP netlink interface\n"); |
| 893 | err = genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops, | 891 | return genl_register_family_with_ops(&l2tp_nl_family, l2tp_nl_ops); |
| 894 | ARRAY_SIZE(l2tp_nl_ops)); | ||
| 895 | |||
| 896 | return err; | ||
| 897 | } | 892 | } |
| 898 | 893 | ||
| 899 | static void l2tp_nl_cleanup(void) | 894 | static void l2tp_nl_cleanup(void) |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 1ded5c6d268c..35be035ee0ce 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
| @@ -3580,7 +3580,7 @@ out: | |||
| 3580 | } | 3580 | } |
| 3581 | 3581 | ||
| 3582 | 3582 | ||
| 3583 | static struct genl_ops ip_vs_genl_ops[] __read_mostly = { | 3583 | static const struct genl_ops ip_vs_genl_ops[] __read_mostly = { |
| 3584 | { | 3584 | { |
| 3585 | .cmd = IPVS_CMD_NEW_SERVICE, | 3585 | .cmd = IPVS_CMD_NEW_SERVICE, |
| 3586 | .flags = GENL_ADMIN_PERM, | 3586 | .flags = GENL_ADMIN_PERM, |
| @@ -3679,7 +3679,7 @@ static struct genl_ops ip_vs_genl_ops[] __read_mostly = { | |||
| 3679 | static int __init ip_vs_genl_register(void) | 3679 | static int __init ip_vs_genl_register(void) |
| 3680 | { | 3680 | { |
| 3681 | return genl_register_family_with_ops(&ip_vs_genl_family, | 3681 | return genl_register_family_with_ops(&ip_vs_genl_family, |
| 3682 | ip_vs_genl_ops, ARRAY_SIZE(ip_vs_genl_ops)); | 3682 | ip_vs_genl_ops); |
| 3683 | } | 3683 | } |
| 3684 | 3684 | ||
| 3685 | static void ip_vs_genl_unregister(void) | 3685 | static void ip_vs_genl_unregister(void) |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index a1100640495d..69345cebe3a3 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 | ||
| 740 | static struct genl_ops netlbl_cipsov4_ops[] = { | 740 | static 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, |
| @@ -783,5 +783,5 @@ static struct genl_ops netlbl_cipsov4_ops[] = { | |||
| 783 | int __init netlbl_cipsov4_genl_init(void) | 783 | int __init netlbl_cipsov4_genl_init(void) |
| 784 | { | 784 | { |
| 785 | return genl_register_family_with_ops(&netlbl_cipsov4_gnl_family, | 785 | return genl_register_family_with_ops(&netlbl_cipsov4_gnl_family, |
| 786 | netlbl_cipsov4_ops, ARRAY_SIZE(netlbl_cipsov4_ops)); | 786 | netlbl_cipsov4_ops); |
| 787 | } | 787 | } |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index dd1c37d7acbc..8ef83ee97c6a 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 | ||
| 708 | static struct genl_ops netlbl_mgmt_genl_ops[] = { | 708 | static 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, |
| @@ -779,5 +779,5 @@ static struct genl_ops netlbl_mgmt_genl_ops[] = { | |||
| 779 | int __init netlbl_mgmt_genl_init(void) | 779 | int __init netlbl_mgmt_genl_init(void) |
| 780 | { | 780 | { |
| 781 | return genl_register_family_with_ops(&netlbl_mgmt_gnl_family, | 781 | return genl_register_family_with_ops(&netlbl_mgmt_gnl_family, |
| 782 | netlbl_mgmt_genl_ops, ARRAY_SIZE(netlbl_mgmt_genl_ops)); | 782 | netlbl_mgmt_genl_ops); |
| 783 | } | 783 | } |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 8f0897407a2c..43817d73ccf9 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 | ||
| 1326 | static struct genl_ops netlbl_unlabel_genl_ops[] = { | 1326 | static 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, |
| @@ -1397,7 +1397,7 @@ static struct genl_ops netlbl_unlabel_genl_ops[] = { | |||
| 1397 | int __init netlbl_unlabel_genl_init(void) | 1397 | int __init netlbl_unlabel_genl_init(void) |
| 1398 | { | 1398 | { |
| 1399 | return genl_register_family_with_ops(&netlbl_unlabel_gnl_family, | 1399 | return genl_register_family_with_ops(&netlbl_unlabel_gnl_family, |
| 1400 | netlbl_unlabel_genl_ops, ARRAY_SIZE(netlbl_unlabel_genl_ops)); | 1400 | netlbl_unlabel_genl_ops); |
| 1401 | } | 1401 | } |
| 1402 | 1402 | ||
| 1403 | /* | 1403 | /* |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 8df7f64c6db3..f0176e1a5a81 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -2017,7 +2017,7 @@ out: | |||
| 2017 | * netlink_set_err - report error to broadcast listeners | 2017 | * netlink_set_err - report error to broadcast listeners |
| 2018 | * @ssk: the kernel netlink socket, as returned by netlink_kernel_create() | 2018 | * @ssk: the kernel netlink socket, as returned by netlink_kernel_create() |
| 2019 | * @portid: the PORTID of a process that we want to skip (if any) | 2019 | * @portid: the PORTID of a process that we want to skip (if any) |
| 2020 | * @groups: the broadcast group that will notice the error | 2020 | * @group: the broadcast group that will notice the error |
| 2021 | * @code: error code, must be negative (as usual in kernelspace) | 2021 | * @code: error code, must be negative (as usual in kernelspace) |
| 2022 | * | 2022 | * |
| 2023 | * This function returns the number of broadcast listeners that have set the | 2023 | * This function returns the number of broadcast listeners that have set the |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 0c741cec4d0d..7dbc4f732c75 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
| @@ -65,12 +65,24 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE]; | |||
| 65 | * To avoid an allocation at boot of just one unsigned long, | 65 | * To avoid an allocation at boot of just one unsigned long, |
| 66 | * declare it global instead. | 66 | * declare it global instead. |
| 67 | * Bit 0 is marked as already used since group 0 is invalid. | 67 | * Bit 0 is marked as already used since group 0 is invalid. |
| 68 | * Bit 1 is marked as already used since the drop-monitor code | ||
| 69 | * abuses the API and thinks it can statically use group 1. | ||
| 70 | * That group will typically conflict with other groups that | ||
| 71 | * any proper users use. | ||
| 72 | * Bit 16 is marked as used since it's used for generic netlink | ||
| 73 | * and the code no longer marks pre-reserved IDs as used. | ||
| 74 | * Bit 17 is marked as already used since the VFS quota code | ||
| 75 | * also abused this API and relied on family == group ID, we | ||
| 76 | * cater to that by giving it a static family and group ID. | ||
| 68 | */ | 77 | */ |
| 69 | static unsigned long mc_group_start = 0x1; | 78 | static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) | |
| 79 | BIT(GENL_ID_VFS_DQUOT); | ||
| 70 | static unsigned long *mc_groups = &mc_group_start; | 80 | static unsigned long *mc_groups = &mc_group_start; |
| 71 | static unsigned long mc_groups_longs = 1; | 81 | static unsigned long mc_groups_longs = 1; |
| 72 | 82 | ||
| 73 | static int genl_ctrl_event(int event, void *data); | 83 | static int genl_ctrl_event(int event, struct genl_family *family, |
| 84 | const struct genl_multicast_group *grp, | ||
| 85 | int grp_id); | ||
| 74 | 86 | ||
| 75 | static inline unsigned int genl_family_hash(unsigned int id) | 87 | static inline unsigned int genl_family_hash(unsigned int id) |
| 76 | { | 88 | { |
| @@ -106,13 +118,13 @@ static struct genl_family *genl_family_find_byname(char *name) | |||
| 106 | return NULL; | 118 | return NULL; |
| 107 | } | 119 | } |
| 108 | 120 | ||
| 109 | static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) | 121 | static const struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) |
| 110 | { | 122 | { |
| 111 | struct genl_ops *ops; | 123 | int i; |
| 112 | 124 | ||
| 113 | list_for_each_entry(ops, &family->ops_list, ops_list) | 125 | for (i = 0; i < family->n_ops; i++) |
| 114 | if (ops->cmd == cmd) | 126 | if (family->ops[i].cmd == cmd) |
| 115 | return ops; | 127 | return &family->ops[i]; |
| 116 | 128 | ||
| 117 | return NULL; | 129 | return NULL; |
| 118 | } | 130 | } |
| @@ -126,7 +138,8 @@ static u16 genl_generate_id(void) | |||
| 126 | int i; | 138 | int i; |
| 127 | 139 | ||
| 128 | for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) { | 140 | for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) { |
| 129 | if (!genl_family_find_byid(id_gen_idx)) | 141 | if (id_gen_idx != GENL_ID_VFS_DQUOT && |
| 142 | !genl_family_find_byid(id_gen_idx)) | ||
| 130 | return id_gen_idx; | 143 | return id_gen_idx; |
| 131 | if (++id_gen_idx > GENL_MAX_ID) | 144 | if (++id_gen_idx > GENL_MAX_ID) |
| 132 | id_gen_idx = GENL_MIN_ID; | 145 | id_gen_idx = GENL_MIN_ID; |
| @@ -135,62 +148,110 @@ static u16 genl_generate_id(void) | |||
| 135 | return 0; | 148 | return 0; |
| 136 | } | 149 | } |
| 137 | 150 | ||
| 138 | static struct genl_multicast_group notify_grp; | 151 | static int genl_allocate_reserve_groups(int n_groups, int *first_id) |
| 139 | |||
| 140 | /** | ||
| 141 | * genl_register_mc_group - register a multicast group | ||
| 142 | * | ||
| 143 | * Registers the specified multicast group and notifies userspace | ||
| 144 | * about the new group. | ||
| 145 | * | ||
| 146 | * Returns 0 on success or a negative error code. | ||
| 147 | * | ||
| 148 | * @family: The generic netlink family the group shall be registered for. | ||
| 149 | * @grp: The group to register, must have a name. | ||
| 150 | */ | ||
| 151 | int genl_register_mc_group(struct genl_family *family, | ||
| 152 | struct genl_multicast_group *grp) | ||
| 153 | { | 152 | { |
| 154 | int id; | ||
| 155 | unsigned long *new_groups; | 153 | unsigned long *new_groups; |
| 156 | int err = 0; | 154 | int start = 0; |
| 155 | int i; | ||
| 156 | int id; | ||
| 157 | bool fits; | ||
| 158 | |||
| 159 | do { | ||
| 160 | if (start == 0) | ||
| 161 | id = find_first_zero_bit(mc_groups, | ||
| 162 | mc_groups_longs * | ||
| 163 | BITS_PER_LONG); | ||
| 164 | else | ||
| 165 | id = find_next_zero_bit(mc_groups, | ||
| 166 | mc_groups_longs * BITS_PER_LONG, | ||
| 167 | start); | ||
| 168 | |||
| 169 | fits = true; | ||
| 170 | for (i = id; | ||
| 171 | i < min_t(int, id + n_groups, | ||
| 172 | mc_groups_longs * BITS_PER_LONG); | ||
| 173 | i++) { | ||
| 174 | if (test_bit(i, mc_groups)) { | ||
| 175 | start = i; | ||
| 176 | fits = false; | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | } | ||
| 157 | 180 | ||
| 158 | BUG_ON(grp->name[0] == '\0'); | 181 | if (id >= mc_groups_longs * BITS_PER_LONG) { |
| 159 | BUG_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL); | 182 | unsigned long new_longs = mc_groups_longs + |
| 183 | BITS_TO_LONGS(n_groups); | ||
| 184 | size_t nlen = new_longs * sizeof(unsigned long); | ||
| 185 | |||
| 186 | if (mc_groups == &mc_group_start) { | ||
| 187 | new_groups = kzalloc(nlen, GFP_KERNEL); | ||
| 188 | if (!new_groups) | ||
| 189 | return -ENOMEM; | ||
| 190 | mc_groups = new_groups; | ||
| 191 | *mc_groups = mc_group_start; | ||
| 192 | } else { | ||
| 193 | new_groups = krealloc(mc_groups, nlen, | ||
| 194 | GFP_KERNEL); | ||
| 195 | if (!new_groups) | ||
| 196 | return -ENOMEM; | ||
| 197 | mc_groups = new_groups; | ||
| 198 | for (i = 0; i < BITS_TO_LONGS(n_groups); i++) | ||
| 199 | mc_groups[mc_groups_longs + i] = 0; | ||
| 200 | } | ||
| 201 | mc_groups_longs = new_longs; | ||
| 202 | } | ||
| 203 | } while (!fits); | ||
| 160 | 204 | ||
| 161 | genl_lock_all(); | 205 | for (i = id; i < id + n_groups; i++) |
| 206 | set_bit(i, mc_groups); | ||
| 207 | *first_id = id; | ||
| 208 | return 0; | ||
| 209 | } | ||
| 162 | 210 | ||
| 163 | /* special-case our own group */ | 211 | static struct genl_family genl_ctrl; |
| 164 | if (grp == ¬ify_grp) | ||
| 165 | id = GENL_ID_CTRL; | ||
| 166 | else | ||
| 167 | id = find_first_zero_bit(mc_groups, | ||
| 168 | mc_groups_longs * BITS_PER_LONG); | ||
| 169 | 212 | ||
| 213 | static int genl_validate_assign_mc_groups(struct genl_family *family) | ||
| 214 | { | ||
| 215 | int first_id; | ||
| 216 | int n_groups = family->n_mcgrps; | ||
| 217 | int err, i; | ||
| 218 | bool groups_allocated = false; | ||
| 170 | 219 | ||
| 171 | if (id >= mc_groups_longs * BITS_PER_LONG) { | 220 | if (!n_groups) |
| 172 | size_t nlen = (mc_groups_longs + 1) * sizeof(unsigned long); | 221 | return 0; |
| 173 | 222 | ||
| 174 | if (mc_groups == &mc_group_start) { | 223 | for (i = 0; i < n_groups; i++) { |
| 175 | new_groups = kzalloc(nlen, GFP_KERNEL); | 224 | const struct genl_multicast_group *grp = &family->mcgrps[i]; |
| 176 | if (!new_groups) { | 225 | |
| 177 | err = -ENOMEM; | 226 | if (WARN_ON(grp->name[0] == '\0')) |
| 178 | goto out; | 227 | return -EINVAL; |
| 179 | } | 228 | if (WARN_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL)) |
| 180 | mc_groups = new_groups; | 229 | return -EINVAL; |
| 181 | *mc_groups = mc_group_start; | 230 | } |
| 182 | } else { | 231 | |
| 183 | new_groups = krealloc(mc_groups, nlen, GFP_KERNEL); | 232 | /* special-case our own group and hacks */ |
| 184 | if (!new_groups) { | 233 | if (family == &genl_ctrl) { |
| 185 | err = -ENOMEM; | 234 | first_id = GENL_ID_CTRL; |
| 186 | goto out; | 235 | BUG_ON(n_groups != 1); |
| 187 | } | 236 | } else if (strcmp(family->name, "NET_DM") == 0) { |
| 188 | mc_groups = new_groups; | 237 | first_id = 1; |
| 189 | mc_groups[mc_groups_longs] = 0; | 238 | BUG_ON(n_groups != 1); |
| 190 | } | 239 | } else if (strcmp(family->name, "VFS_DQUOT") == 0) { |
| 191 | mc_groups_longs++; | 240 | first_id = GENL_ID_VFS_DQUOT; |
| 241 | BUG_ON(n_groups != 1); | ||
| 242 | } else { | ||
| 243 | groups_allocated = true; | ||
| 244 | err = genl_allocate_reserve_groups(n_groups, &first_id); | ||
| 245 | if (err) | ||
| 246 | return err; | ||
| 192 | } | 247 | } |
| 193 | 248 | ||
| 249 | family->mcgrp_offset = first_id; | ||
| 250 | |||
| 251 | /* if still initializing, can't and don't need to to realloc bitmaps */ | ||
| 252 | if (!init_net.genl_sock) | ||
| 253 | return 0; | ||
| 254 | |||
| 194 | if (family->netnsok) { | 255 | if (family->netnsok) { |
| 195 | struct net *net; | 256 | struct net *net; |
| 196 | 257 | ||
| @@ -206,9 +267,7 @@ int genl_register_mc_group(struct genl_family *family, | |||
| 206 | * number of _possible_ groups has been | 267 | * number of _possible_ groups has been |
| 207 | * increased on some sockets which is ok. | 268 | * increased on some sockets which is ok. |
| 208 | */ | 269 | */ |
| 209 | rcu_read_unlock(); | 270 | break; |
| 210 | netlink_table_ungrab(); | ||
| 211 | goto out; | ||
| 212 | } | 271 | } |
| 213 | } | 272 | } |
| 214 | rcu_read_unlock(); | 273 | rcu_read_unlock(); |
| @@ -216,152 +275,67 @@ int genl_register_mc_group(struct genl_family *family, | |||
| 216 | } else { | 275 | } else { |
| 217 | err = netlink_change_ngroups(init_net.genl_sock, | 276 | err = netlink_change_ngroups(init_net.genl_sock, |
| 218 | mc_groups_longs * BITS_PER_LONG); | 277 | mc_groups_longs * BITS_PER_LONG); |
| 219 | if (err) | ||
| 220 | goto out; | ||
| 221 | } | 278 | } |
| 222 | 279 | ||
| 223 | grp->id = id; | 280 | if (groups_allocated && err) { |
| 224 | set_bit(id, mc_groups); | 281 | for (i = 0; i < family->n_mcgrps; i++) |
| 225 | list_add_tail(&grp->list, &family->mcast_groups); | 282 | clear_bit(family->mcgrp_offset + i, mc_groups); |
| 226 | grp->family = family; | 283 | } |
| 227 | 284 | ||
| 228 | genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, grp); | ||
| 229 | out: | ||
| 230 | genl_unlock_all(); | ||
| 231 | return err; | 285 | return err; |
| 232 | } | 286 | } |
| 233 | EXPORT_SYMBOL(genl_register_mc_group); | ||
| 234 | 287 | ||
| 235 | static void __genl_unregister_mc_group(struct genl_family *family, | 288 | static void genl_unregister_mc_groups(struct genl_family *family) |
| 236 | struct genl_multicast_group *grp) | ||
| 237 | { | 289 | { |
| 238 | struct net *net; | 290 | struct net *net; |
| 239 | BUG_ON(grp->family != family); | 291 | int i; |
| 240 | 292 | ||
| 241 | netlink_table_grab(); | 293 | netlink_table_grab(); |
| 242 | rcu_read_lock(); | 294 | rcu_read_lock(); |
| 243 | for_each_net_rcu(net) | 295 | for_each_net_rcu(net) { |
| 244 | __netlink_clear_multicast_users(net->genl_sock, grp->id); | 296 | for (i = 0; i < family->n_mcgrps; i++) |
| 297 | __netlink_clear_multicast_users( | ||
| 298 | net->genl_sock, family->mcgrp_offset + i); | ||
| 299 | } | ||
| 245 | rcu_read_unlock(); | 300 | rcu_read_unlock(); |
| 246 | netlink_table_ungrab(); | 301 | netlink_table_ungrab(); |
| 247 | 302 | ||
| 248 | clear_bit(grp->id, mc_groups); | 303 | for (i = 0; i < family->n_mcgrps; i++) { |
| 249 | list_del(&grp->list); | 304 | int grp_id = family->mcgrp_offset + i; |
| 250 | genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp); | ||
| 251 | grp->id = 0; | ||
| 252 | grp->family = NULL; | ||
| 253 | } | ||
| 254 | 305 | ||
| 255 | /** | 306 | if (grp_id != 1) |
| 256 | * genl_unregister_mc_group - unregister a multicast group | 307 | clear_bit(grp_id, mc_groups); |
| 257 | * | 308 | genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, family, |
| 258 | * Unregisters the specified multicast group and notifies userspace | 309 | &family->mcgrps[i], grp_id); |
| 259 | * about it. All current listeners on the group are removed. | 310 | } |
| 260 | * | ||
| 261 | * Note: It is not necessary to unregister all multicast groups before | ||
| 262 | * unregistering the family, unregistering the family will cause | ||
| 263 | * all assigned multicast groups to be unregistered automatically. | ||
| 264 | * | ||
| 265 | * @family: Generic netlink family the group belongs to. | ||
| 266 | * @grp: The group to unregister, must have been registered successfully | ||
| 267 | * previously. | ||
| 268 | */ | ||
| 269 | void genl_unregister_mc_group(struct genl_family *family, | ||
| 270 | struct genl_multicast_group *grp) | ||
| 271 | { | ||
| 272 | genl_lock_all(); | ||
| 273 | __genl_unregister_mc_group(family, grp); | ||
| 274 | genl_unlock_all(); | ||
| 275 | } | 311 | } |
| 276 | EXPORT_SYMBOL(genl_unregister_mc_group); | ||
| 277 | 312 | ||
| 278 | static void genl_unregister_mc_groups(struct genl_family *family) | 313 | static int genl_validate_ops(struct genl_family *family) |
| 279 | { | 314 | { |
| 280 | struct genl_multicast_group *grp, *tmp; | 315 | const struct genl_ops *ops = family->ops; |
| 316 | unsigned int n_ops = family->n_ops; | ||
| 317 | int i, j; | ||
| 281 | 318 | ||
| 282 | list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list) | 319 | if (WARN_ON(n_ops && !ops)) |
| 283 | __genl_unregister_mc_group(family, grp); | 320 | return -EINVAL; |
| 284 | } | ||
| 285 | |||
| 286 | /** | ||
| 287 | * genl_register_ops - register generic netlink operations | ||
| 288 | * @family: generic netlink family | ||
| 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 | */ | ||
| 301 | int genl_register_ops(struct genl_family *family, struct genl_ops *ops) | ||
| 302 | { | ||
| 303 | int err = -EINVAL; | ||
| 304 | 321 | ||
| 305 | if (ops->dumpit == NULL && ops->doit == NULL) | 322 | if (!n_ops) |
| 306 | goto errout; | 323 | return 0; |
| 307 | 324 | ||
| 308 | if (genl_get_cmd(ops->cmd, family)) { | 325 | for (i = 0; i < n_ops; i++) { |
| 309 | err = -EEXIST; | 326 | if (ops[i].dumpit == NULL && ops[i].doit == NULL) |
| 310 | goto errout; | 327 | return -EINVAL; |
| 328 | for (j = i + 1; j < n_ops; j++) | ||
| 329 | if (ops[i].cmd == ops[j].cmd) | ||
| 330 | return -EINVAL; | ||
| 311 | } | 331 | } |
| 312 | 332 | ||
| 313 | if (ops->dumpit) | 333 | /* family is not registered yet, so no locking needed */ |
| 314 | ops->flags |= GENL_CMD_CAP_DUMP; | 334 | family->ops = ops; |
| 315 | if (ops->doit) | 335 | family->n_ops = n_ops; |
| 316 | ops->flags |= GENL_CMD_CAP_DO; | ||
| 317 | if (ops->policy) | ||
| 318 | ops->flags |= GENL_CMD_CAP_HASPOL; | ||
| 319 | 336 | ||
| 320 | genl_lock_all(); | 337 | return 0; |
| 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; | ||
| 326 | errout: | ||
| 327 | return err; | ||
| 328 | } | ||
| 329 | EXPORT_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 | */ | ||
| 347 | int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops) | ||
| 348 | { | ||
| 349 | struct genl_ops *rc; | ||
| 350 | |||
| 351 | genl_lock_all(); | ||
| 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 | } | 338 | } |
| 364 | EXPORT_SYMBOL(genl_unregister_ops); | ||
| 365 | 339 | ||
| 366 | /** | 340 | /** |
| 367 | * __genl_register_family - register a generic netlink family | 341 | * __genl_register_family - register a generic netlink family |
| @@ -372,11 +346,14 @@ EXPORT_SYMBOL(genl_unregister_ops); | |||
| 372 | * The family id may equal GENL_ID_GENERATE causing an unique id to | 346 | * The family id may equal GENL_ID_GENERATE causing an unique id to |
| 373 | * be automatically generated and assigned. | 347 | * be automatically generated and assigned. |
| 374 | * | 348 | * |
| 349 | * The family's ops array must already be assigned, you can use the | ||
| 350 | * genl_register_family_with_ops() helper function. | ||
| 351 | * | ||
| 375 | * Return 0 on success or a negative error code. | 352 | * Return 0 on success or a negative error code. |
| 376 | */ | 353 | */ |
| 377 | int __genl_register_family(struct genl_family *family) | 354 | int __genl_register_family(struct genl_family *family) |
| 378 | { | 355 | { |
| 379 | int err = -EINVAL; | 356 | int err = -EINVAL, i; |
| 380 | 357 | ||
| 381 | if (family->id && family->id < GENL_MIN_ID) | 358 | if (family->id && family->id < GENL_MIN_ID) |
| 382 | goto errout; | 359 | goto errout; |
| @@ -384,8 +361,9 @@ int __genl_register_family(struct genl_family *family) | |||
| 384 | if (family->id > GENL_MAX_ID) | 361 | if (family->id > GENL_MAX_ID) |
| 385 | goto errout; | 362 | goto errout; |
| 386 | 363 | ||
| 387 | INIT_LIST_HEAD(&family->ops_list); | 364 | err = genl_validate_ops(family); |
| 388 | INIT_LIST_HEAD(&family->mcast_groups); | 365 | if (err) |
| 366 | return err; | ||
| 389 | 367 | ||
| 390 | genl_lock_all(); | 368 | genl_lock_all(); |
| 391 | 369 | ||
| @@ -418,10 +396,18 @@ int __genl_register_family(struct genl_family *family) | |||
| 418 | } else | 396 | } else |
| 419 | family->attrbuf = NULL; | 397 | family->attrbuf = NULL; |
| 420 | 398 | ||
| 399 | err = genl_validate_assign_mc_groups(family); | ||
| 400 | if (err) | ||
| 401 | goto errout_locked; | ||
| 402 | |||
| 421 | list_add_tail(&family->family_list, genl_family_chain(family->id)); | 403 | list_add_tail(&family->family_list, genl_family_chain(family->id)); |
| 422 | genl_unlock_all(); | 404 | genl_unlock_all(); |
| 423 | 405 | ||
| 424 | genl_ctrl_event(CTRL_CMD_NEWFAMILY, family); | 406 | /* send all events */ |
| 407 | genl_ctrl_event(CTRL_CMD_NEWFAMILY, family, NULL, 0); | ||
| 408 | for (i = 0; i < family->n_mcgrps; i++) | ||
| 409 | genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, family, | ||
| 410 | &family->mcgrps[i], family->mcgrp_offset + i); | ||
| 425 | 411 | ||
| 426 | return 0; | 412 | return 0; |
| 427 | 413 | ||
| @@ -433,52 +419,6 @@ errout: | |||
| 433 | EXPORT_SYMBOL(__genl_register_family); | 419 | EXPORT_SYMBOL(__genl_register_family); |
| 434 | 420 | ||
| 435 | /** | 421 | /** |
| 436 | * __genl_register_family_with_ops - register a generic netlink family | ||
| 437 | * @family: generic netlink family | ||
| 438 | * @ops: operations to be registered | ||
| 439 | * @n_ops: number of elements to register | ||
| 440 | * | ||
| 441 | * Registers the specified family and operations from the specified table. | ||
| 442 | * Only one family may be registered with the same family name or identifier. | ||
| 443 | * | ||
| 444 | * The family id may equal GENL_ID_GENERATE causing an unique id to | ||
| 445 | * be automatically generated and assigned. | ||
| 446 | * | ||
| 447 | * Either a doit or dumpit callback must be specified for every registered | ||
| 448 | * operation or the function will fail. Only one operation structure per | ||
| 449 | * command identifier may be registered. | ||
| 450 | * | ||
| 451 | * See include/net/genetlink.h for more documenation on the operations | ||
| 452 | * structure. | ||
| 453 | * | ||
| 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. | ||
| 459 | */ | ||
| 460 | int __genl_register_family_with_ops(struct genl_family *family, | ||
| 461 | struct genl_ops *ops, size_t n_ops) | ||
| 462 | { | ||
| 463 | int err, i; | ||
| 464 | |||
| 465 | err = __genl_register_family(family); | ||
| 466 | if (err) | ||
| 467 | return err; | ||
| 468 | |||
| 469 | for (i = 0; i < n_ops; ++i, ++ops) { | ||
| 470 | err = genl_register_ops(family, ops); | ||
| 471 | if (err) | ||
| 472 | goto err_out; | ||
| 473 | } | ||
| 474 | return 0; | ||
| 475 | err_out: | ||
| 476 | genl_unregister_family(family); | ||
| 477 | return err; | ||
| 478 | } | ||
| 479 | EXPORT_SYMBOL(__genl_register_family_with_ops); | ||
| 480 | |||
| 481 | /** | ||
| 482 | * genl_unregister_family - unregister generic netlink family | 422 | * genl_unregister_family - unregister generic netlink family |
| 483 | * @family: generic netlink family | 423 | * @family: generic netlink family |
| 484 | * | 424 | * |
| @@ -499,11 +439,11 @@ int genl_unregister_family(struct genl_family *family) | |||
| 499 | continue; | 439 | continue; |
| 500 | 440 | ||
| 501 | list_del(&rc->family_list); | 441 | list_del(&rc->family_list); |
| 502 | INIT_LIST_HEAD(&family->ops_list); | 442 | family->n_ops = 0; |
| 503 | genl_unlock_all(); | 443 | genl_unlock_all(); |
| 504 | 444 | ||
| 505 | kfree(family->attrbuf); | 445 | kfree(family->attrbuf); |
| 506 | genl_ctrl_event(CTRL_CMD_DELFAMILY, family); | 446 | genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0); |
| 507 | return 0; | 447 | return 0; |
| 508 | } | 448 | } |
| 509 | 449 | ||
| @@ -546,7 +486,8 @@ EXPORT_SYMBOL(genlmsg_put); | |||
| 546 | 486 | ||
| 547 | static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) | 487 | static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) |
| 548 | { | 488 | { |
| 549 | 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; | ||
| 550 | int rc; | 491 | int rc; |
| 551 | 492 | ||
| 552 | genl_lock(); | 493 | genl_lock(); |
| @@ -557,7 +498,8 @@ static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 557 | 498 | ||
| 558 | static int genl_lock_done(struct netlink_callback *cb) | 499 | static int genl_lock_done(struct netlink_callback *cb) |
| 559 | { | 500 | { |
| 560 | struct genl_ops *ops = cb->data; | 501 | /* our ops are always const - netlink API doesn't propagate that */ |
| 502 | const struct genl_ops *ops = cb->data; | ||
| 561 | int rc = 0; | 503 | int rc = 0; |
| 562 | 504 | ||
| 563 | if (ops->done) { | 505 | if (ops->done) { |
| @@ -572,7 +514,7 @@ static int genl_family_rcv_msg(struct genl_family *family, | |||
| 572 | struct sk_buff *skb, | 514 | struct sk_buff *skb, |
| 573 | struct nlmsghdr *nlh) | 515 | struct nlmsghdr *nlh) |
| 574 | { | 516 | { |
| 575 | struct genl_ops *ops; | 517 | const struct genl_ops *ops; |
| 576 | struct net *net = sock_net(skb->sk); | 518 | struct net *net = sock_net(skb->sk); |
| 577 | struct genl_info info; | 519 | struct genl_info info; |
| 578 | struct genlmsghdr *hdr = nlmsg_data(nlh); | 520 | struct genlmsghdr *hdr = nlmsg_data(nlh); |
| @@ -604,7 +546,8 @@ static int genl_family_rcv_msg(struct genl_family *family, | |||
| 604 | if (!family->parallel_ops) { | 546 | if (!family->parallel_ops) { |
| 605 | struct netlink_dump_control c = { | 547 | struct netlink_dump_control c = { |
| 606 | .module = family->module, | 548 | .module = family->module, |
| 607 | .data = ops, | 549 | /* we have const, but the netlink API doesn't */ |
| 550 | .data = (void *)ops, | ||
| 608 | .dump = genl_lock_dumpit, | 551 | .dump = genl_lock_dumpit, |
| 609 | .done = genl_lock_done, | 552 | .done = genl_lock_done, |
| 610 | }; | 553 | }; |
| @@ -726,24 +669,32 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq, | |||
| 726 | nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr)) | 669 | nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr)) |
| 727 | goto nla_put_failure; | 670 | goto nla_put_failure; |
| 728 | 671 | ||
| 729 | if (!list_empty(&family->ops_list)) { | 672 | if (family->n_ops) { |
| 730 | struct nlattr *nla_ops; | 673 | struct nlattr *nla_ops; |
| 731 | struct genl_ops *ops; | 674 | int i; |
| 732 | int idx = 1; | ||
| 733 | 675 | ||
| 734 | nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); | 676 | nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); |
| 735 | if (nla_ops == NULL) | 677 | if (nla_ops == NULL) |
| 736 | goto nla_put_failure; | 678 | goto nla_put_failure; |
| 737 | 679 | ||
| 738 | list_for_each_entry(ops, &family->ops_list, ops_list) { | 680 | for (i = 0; i < family->n_ops; i++) { |
| 739 | struct nlattr *nest; | 681 | struct nlattr *nest; |
| 682 | const struct genl_ops *ops = &family->ops[i]; | ||
| 683 | u32 op_flags = ops->flags; | ||
| 740 | 684 | ||
| 741 | nest = nla_nest_start(skb, idx++); | 685 | if (ops->dumpit) |
| 686 | op_flags |= GENL_CMD_CAP_DUMP; | ||
| 687 | if (ops->doit) | ||
| 688 | op_flags |= GENL_CMD_CAP_DO; | ||
| 689 | if (ops->policy) | ||
| 690 | op_flags |= GENL_CMD_CAP_HASPOL; | ||
| 691 | |||
| 692 | nest = nla_nest_start(skb, i + 1); | ||
| 742 | if (nest == NULL) | 693 | if (nest == NULL) |
| 743 | goto nla_put_failure; | 694 | goto nla_put_failure; |
| 744 | 695 | ||
| 745 | if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) || | 696 | if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) || |
| 746 | nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags)) | 697 | nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, op_flags)) |
| 747 | goto nla_put_failure; | 698 | goto nla_put_failure; |
| 748 | 699 | ||
| 749 | nla_nest_end(skb, nest); | 700 | nla_nest_end(skb, nest); |
| @@ -752,23 +703,26 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq, | |||
| 752 | nla_nest_end(skb, nla_ops); | 703 | nla_nest_end(skb, nla_ops); |
| 753 | } | 704 | } |
| 754 | 705 | ||
| 755 | if (!list_empty(&family->mcast_groups)) { | 706 | if (family->n_mcgrps) { |
| 756 | struct genl_multicast_group *grp; | ||
| 757 | struct nlattr *nla_grps; | 707 | struct nlattr *nla_grps; |
| 758 | int idx = 1; | 708 | int i; |
| 759 | 709 | ||
| 760 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); | 710 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); |
| 761 | if (nla_grps == NULL) | 711 | if (nla_grps == NULL) |
| 762 | goto nla_put_failure; | 712 | goto nla_put_failure; |
| 763 | 713 | ||
| 764 | list_for_each_entry(grp, &family->mcast_groups, list) { | 714 | for (i = 0; i < family->n_mcgrps; i++) { |
| 765 | struct nlattr *nest; | 715 | struct nlattr *nest; |
| 716 | const struct genl_multicast_group *grp; | ||
| 717 | |||
| 718 | grp = &family->mcgrps[i]; | ||
| 766 | 719 | ||
| 767 | nest = nla_nest_start(skb, idx++); | 720 | nest = nla_nest_start(skb, i + 1); |
| 768 | if (nest == NULL) | 721 | if (nest == NULL) |
| 769 | goto nla_put_failure; | 722 | goto nla_put_failure; |
| 770 | 723 | ||
| 771 | if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) || | 724 | if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, |
| 725 | family->mcgrp_offset + i) || | ||
| 772 | nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, | 726 | nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, |
| 773 | grp->name)) | 727 | grp->name)) |
| 774 | goto nla_put_failure; | 728 | goto nla_put_failure; |
| @@ -785,9 +739,10 @@ nla_put_failure: | |||
| 785 | return -EMSGSIZE; | 739 | return -EMSGSIZE; |
| 786 | } | 740 | } |
| 787 | 741 | ||
| 788 | static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | 742 | static int ctrl_fill_mcgrp_info(struct genl_family *family, |
| 789 | u32 seq, u32 flags, struct sk_buff *skb, | 743 | const struct genl_multicast_group *grp, |
| 790 | u8 cmd) | 744 | int grp_id, u32 portid, u32 seq, u32 flags, |
| 745 | struct sk_buff *skb, u8 cmd) | ||
| 791 | { | 746 | { |
| 792 | void *hdr; | 747 | void *hdr; |
| 793 | struct nlattr *nla_grps; | 748 | struct nlattr *nla_grps; |
| @@ -797,8 +752,8 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | |||
| 797 | if (hdr == NULL) | 752 | if (hdr == NULL) |
| 798 | return -1; | 753 | return -1; |
| 799 | 754 | ||
| 800 | if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name) || | 755 | if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) || |
| 801 | nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id)) | 756 | nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id)) |
| 802 | goto nla_put_failure; | 757 | goto nla_put_failure; |
| 803 | 758 | ||
| 804 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); | 759 | nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS); |
| @@ -809,7 +764,7 @@ static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 portid, | |||
| 809 | if (nest == NULL) | 764 | if (nest == NULL) |
| 810 | goto nla_put_failure; | 765 | goto nla_put_failure; |
| 811 | 766 | ||
| 812 | if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) || | 767 | if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp_id) || |
| 813 | nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, | 768 | nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME, |
| 814 | grp->name)) | 769 | grp->name)) |
| 815 | goto nla_put_failure; | 770 | goto nla_put_failure; |
| @@ -875,8 +830,10 @@ static struct sk_buff *ctrl_build_family_msg(struct genl_family *family, | |||
| 875 | return skb; | 830 | return skb; |
| 876 | } | 831 | } |
| 877 | 832 | ||
| 878 | static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, | 833 | static struct sk_buff * |
| 879 | u32 portid, int seq, u8 cmd) | 834 | ctrl_build_mcgrp_msg(struct genl_family *family, |
| 835 | const struct genl_multicast_group *grp, | ||
| 836 | int grp_id, u32 portid, int seq, u8 cmd) | ||
| 880 | { | 837 | { |
| 881 | struct sk_buff *skb; | 838 | struct sk_buff *skb; |
| 882 | int err; | 839 | int err; |
| @@ -885,7 +842,8 @@ static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp, | |||
| 885 | if (skb == NULL) | 842 | if (skb == NULL) |
| 886 | return ERR_PTR(-ENOBUFS); | 843 | return ERR_PTR(-ENOBUFS); |
| 887 | 844 | ||
| 888 | err = ctrl_fill_mcgrp_info(grp, portid, seq, 0, skb, cmd); | 845 | err = ctrl_fill_mcgrp_info(family, grp, grp_id, portid, |
| 846 | seq, 0, skb, cmd); | ||
| 889 | if (err < 0) { | 847 | if (err < 0) { |
| 890 | nlmsg_free(skb); | 848 | nlmsg_free(skb); |
| 891 | return ERR_PTR(err); | 849 | return ERR_PTR(err); |
| @@ -947,11 +905,11 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) | |||
| 947 | return genlmsg_reply(msg, info); | 905 | return genlmsg_reply(msg, info); |
| 948 | } | 906 | } |
| 949 | 907 | ||
| 950 | static int genl_ctrl_event(int event, void *data) | 908 | static int genl_ctrl_event(int event, struct genl_family *family, |
| 909 | const struct genl_multicast_group *grp, | ||
| 910 | int grp_id) | ||
| 951 | { | 911 | { |
| 952 | struct sk_buff *msg; | 912 | struct sk_buff *msg; |
| 953 | struct genl_family *family; | ||
| 954 | struct genl_multicast_group *grp; | ||
| 955 | 913 | ||
| 956 | /* genl is still initialising */ | 914 | /* genl is still initialising */ |
| 957 | if (!init_net.genl_sock) | 915 | if (!init_net.genl_sock) |
| @@ -960,14 +918,13 @@ static int genl_ctrl_event(int event, void *data) | |||
| 960 | switch (event) { | 918 | switch (event) { |
| 961 | case CTRL_CMD_NEWFAMILY: | 919 | case CTRL_CMD_NEWFAMILY: |
| 962 | case CTRL_CMD_DELFAMILY: | 920 | case CTRL_CMD_DELFAMILY: |
| 963 | family = data; | 921 | WARN_ON(grp); |
| 964 | msg = ctrl_build_family_msg(family, 0, 0, event); | 922 | msg = ctrl_build_family_msg(family, 0, 0, event); |
| 965 | break; | 923 | break; |
| 966 | case CTRL_CMD_NEWMCAST_GRP: | 924 | case CTRL_CMD_NEWMCAST_GRP: |
| 967 | case CTRL_CMD_DELMCAST_GRP: | 925 | case CTRL_CMD_DELMCAST_GRP: |
| 968 | grp = data; | 926 | BUG_ON(!grp); |
| 969 | family = grp->family; | 927 | msg = ctrl_build_mcgrp_msg(family, grp, grp_id, 0, 0, event); |
| 970 | msg = ctrl_build_mcgrp_msg(data, 0, 0, event); | ||
| 971 | break; | 928 | break; |
| 972 | default: | 929 | default: |
| 973 | return -EINVAL; | 930 | return -EINVAL; |
| @@ -977,26 +934,29 @@ static int genl_ctrl_event(int event, void *data) | |||
| 977 | return PTR_ERR(msg); | 934 | return PTR_ERR(msg); |
| 978 | 935 | ||
| 979 | if (!family->netnsok) { | 936 | if (!family->netnsok) { |
| 980 | genlmsg_multicast_netns(&init_net, msg, 0, | 937 | genlmsg_multicast_netns(&genl_ctrl, &init_net, msg, 0, |
| 981 | GENL_ID_CTRL, GFP_KERNEL); | 938 | 0, GFP_KERNEL); |
| 982 | } else { | 939 | } else { |
| 983 | rcu_read_lock(); | 940 | rcu_read_lock(); |
| 984 | genlmsg_multicast_allns(msg, 0, GENL_ID_CTRL, GFP_ATOMIC); | 941 | genlmsg_multicast_allns(&genl_ctrl, msg, 0, |
| 942 | 0, GFP_ATOMIC); | ||
| 985 | rcu_read_unlock(); | 943 | rcu_read_unlock(); |
| 986 | } | 944 | } |
| 987 | 945 | ||
| 988 | return 0; | 946 | return 0; |
| 989 | } | 947 | } |
| 990 | 948 | ||
| 991 | static struct genl_ops genl_ctrl_ops = { | 949 | static struct genl_ops genl_ctrl_ops[] = { |
| 992 | .cmd = CTRL_CMD_GETFAMILY, | 950 | { |
| 993 | .doit = ctrl_getfamily, | 951 | .cmd = CTRL_CMD_GETFAMILY, |
| 994 | .dumpit = ctrl_dumpfamily, | 952 | .doit = ctrl_getfamily, |
| 995 | .policy = ctrl_policy, | 953 | .dumpit = ctrl_dumpfamily, |
| 954 | .policy = ctrl_policy, | ||
| 955 | }, | ||
| 996 | }; | 956 | }; |
| 997 | 957 | ||
| 998 | static struct genl_multicast_group notify_grp = { | 958 | static struct genl_multicast_group genl_ctrl_groups[] = { |
| 999 | .name = "notify", | 959 | { .name = "notify", }, |
| 1000 | }; | 960 | }; |
| 1001 | 961 | ||
| 1002 | static int __net_init genl_pernet_init(struct net *net) | 962 | static int __net_init genl_pernet_init(struct net *net) |
| @@ -1036,7 +996,8 @@ static int __init genl_init(void) | |||
| 1036 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) | 996 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) |
| 1037 | INIT_LIST_HEAD(&family_ht[i]); | 997 | INIT_LIST_HEAD(&family_ht[i]); |
| 1038 | 998 | ||
| 1039 | err = genl_register_family_with_ops(&genl_ctrl, &genl_ctrl_ops, 1); | 999 | err = genl_register_family_with_ops_groups(&genl_ctrl, genl_ctrl_ops, |
| 1000 | genl_ctrl_groups); | ||
| 1040 | if (err < 0) | 1001 | if (err < 0) |
| 1041 | goto problem; | 1002 | goto problem; |
| 1042 | 1003 | ||
| @@ -1044,10 +1005,6 @@ static int __init genl_init(void) | |||
| 1044 | if (err) | 1005 | if (err) |
| 1045 | goto problem; | 1006 | goto problem; |
| 1046 | 1007 | ||
| 1047 | err = genl_register_mc_group(&genl_ctrl, ¬ify_grp); | ||
| 1048 | if (err < 0) | ||
| 1049 | goto problem; | ||
| 1050 | |||
| 1051 | return 0; | 1008 | return 0; |
| 1052 | 1009 | ||
| 1053 | problem: | 1010 | problem: |
| @@ -1085,14 +1042,18 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group, | |||
| 1085 | return err; | 1042 | return err; |
| 1086 | } | 1043 | } |
| 1087 | 1044 | ||
| 1088 | int genlmsg_multicast_allns(struct sk_buff *skb, u32 portid, unsigned int group, | 1045 | int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb, |
| 1089 | gfp_t flags) | 1046 | u32 portid, unsigned int group, gfp_t flags) |
| 1090 | { | 1047 | { |
| 1048 | if (group >= family->n_mcgrps) | ||
| 1049 | return -EINVAL; | ||
| 1050 | group = family->mcgrp_offset + group; | ||
| 1091 | return genlmsg_mcast(skb, portid, group, flags); | 1051 | return genlmsg_mcast(skb, portid, group, flags); |
| 1092 | } | 1052 | } |
| 1093 | EXPORT_SYMBOL(genlmsg_multicast_allns); | 1053 | EXPORT_SYMBOL(genlmsg_multicast_allns); |
| 1094 | 1054 | ||
| 1095 | void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group, | 1055 | void genl_notify(struct genl_family *family, |
| 1056 | struct sk_buff *skb, struct net *net, u32 portid, u32 group, | ||
| 1096 | struct nlmsghdr *nlh, gfp_t flags) | 1057 | struct nlmsghdr *nlh, gfp_t flags) |
| 1097 | { | 1058 | { |
| 1098 | struct sock *sk = net->genl_sock; | 1059 | struct sock *sk = net->genl_sock; |
| @@ -1101,6 +1062,9 @@ void genl_notify(struct sk_buff *skb, struct net *net, u32 portid, u32 group, | |||
| 1101 | if (nlh) | 1062 | if (nlh) |
| 1102 | report = nlmsg_report(nlh); | 1063 | report = nlmsg_report(nlh); |
| 1103 | 1064 | ||
| 1065 | if (group >= family->n_mcgrps) | ||
| 1066 | return; | ||
| 1067 | group = family->mcgrp_offset + group; | ||
| 1104 | nlmsg_notify(sk, skb, portid, group, report, flags); | 1068 | nlmsg_notify(sk, skb, portid, group, report, flags); |
| 1105 | } | 1069 | } |
| 1106 | EXPORT_SYMBOL(genl_notify); | 1070 | EXPORT_SYMBOL(genl_notify); |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 84b7e3ea7b7a..a9b2342d5253 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
| @@ -30,8 +30,8 @@ | |||
| 30 | #include "nfc.h" | 30 | #include "nfc.h" |
| 31 | #include "llcp.h" | 31 | #include "llcp.h" |
| 32 | 32 | ||
| 33 | static struct genl_multicast_group nfc_genl_event_mcgrp = { | 33 | static const struct genl_multicast_group nfc_genl_mcgrps[] = { |
| 34 | .name = NFC_GENL_MCAST_EVENT_NAME, | 34 | { .name = NFC_GENL_MCAST_EVENT_NAME, }, |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | static struct genl_family nfc_genl_family = { | 37 | static struct genl_family nfc_genl_family = { |
| @@ -194,7 +194,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev) | |||
| 194 | 194 | ||
| 195 | genlmsg_end(msg, hdr); | 195 | genlmsg_end(msg, hdr); |
| 196 | 196 | ||
| 197 | return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); | 197 | return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC); |
| 198 | 198 | ||
| 199 | nla_put_failure: | 199 | nla_put_failure: |
| 200 | genlmsg_cancel(msg, hdr); | 200 | genlmsg_cancel(msg, hdr); |
| @@ -223,7 +223,7 @@ int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx) | |||
| 223 | 223 | ||
| 224 | genlmsg_end(msg, hdr); | 224 | genlmsg_end(msg, hdr); |
| 225 | 225 | ||
| 226 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 226 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 227 | 227 | ||
| 228 | return 0; | 228 | return 0; |
| 229 | 229 | ||
| @@ -255,7 +255,7 @@ int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol) | |||
| 255 | 255 | ||
| 256 | genlmsg_end(msg, hdr); | 256 | genlmsg_end(msg, hdr); |
| 257 | 257 | ||
| 258 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 258 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 259 | 259 | ||
| 260 | return 0; | 260 | return 0; |
| 261 | 261 | ||
| @@ -285,7 +285,7 @@ int nfc_genl_tm_deactivated(struct nfc_dev *dev) | |||
| 285 | 285 | ||
| 286 | genlmsg_end(msg, hdr); | 286 | genlmsg_end(msg, hdr); |
| 287 | 287 | ||
| 288 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 288 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 289 | 289 | ||
| 290 | return 0; | 290 | return 0; |
| 291 | 291 | ||
| @@ -318,7 +318,7 @@ int nfc_genl_device_added(struct nfc_dev *dev) | |||
| 318 | 318 | ||
| 319 | genlmsg_end(msg, hdr); | 319 | genlmsg_end(msg, hdr); |
| 320 | 320 | ||
| 321 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 321 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 322 | 322 | ||
| 323 | return 0; | 323 | return 0; |
| 324 | 324 | ||
| @@ -348,7 +348,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev) | |||
| 348 | 348 | ||
| 349 | genlmsg_end(msg, hdr); | 349 | genlmsg_end(msg, hdr); |
| 350 | 350 | ||
| 351 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 351 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 352 | 352 | ||
| 353 | return 0; | 353 | return 0; |
| 354 | 354 | ||
| @@ -414,7 +414,7 @@ int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list) | |||
| 414 | 414 | ||
| 415 | genlmsg_end(msg, hdr); | 415 | genlmsg_end(msg, hdr); |
| 416 | 416 | ||
| 417 | return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); | 417 | return genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC); |
| 418 | 418 | ||
| 419 | nla_put_failure: | 419 | nla_put_failure: |
| 420 | genlmsg_cancel(msg, hdr); | 420 | genlmsg_cancel(msg, hdr); |
| @@ -448,7 +448,7 @@ int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type) | |||
| 448 | 448 | ||
| 449 | genlmsg_end(msg, hdr); | 449 | genlmsg_end(msg, hdr); |
| 450 | 450 | ||
| 451 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 451 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 452 | 452 | ||
| 453 | return 0; | 453 | return 0; |
| 454 | 454 | ||
| @@ -479,7 +479,7 @@ int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx) | |||
| 479 | 479 | ||
| 480 | genlmsg_end(msg, hdr); | 480 | genlmsg_end(msg, hdr); |
| 481 | 481 | ||
| 482 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 482 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 483 | 483 | ||
| 484 | return 0; | 484 | return 0; |
| 485 | 485 | ||
| @@ -600,7 +600,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, | |||
| 600 | 600 | ||
| 601 | dev->dep_link_up = true; | 601 | dev->dep_link_up = true; |
| 602 | 602 | ||
| 603 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); | 603 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC); |
| 604 | 604 | ||
| 605 | return 0; | 605 | return 0; |
| 606 | 606 | ||
| @@ -632,7 +632,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev) | |||
| 632 | 632 | ||
| 633 | genlmsg_end(msg, hdr); | 633 | genlmsg_end(msg, hdr); |
| 634 | 634 | ||
| 635 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC); | 635 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_ATOMIC); |
| 636 | 636 | ||
| 637 | return 0; | 637 | return 0; |
| 638 | 638 | ||
| @@ -1137,7 +1137,7 @@ int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name, | |||
| 1137 | 1137 | ||
| 1138 | genlmsg_end(msg, hdr); | 1138 | genlmsg_end(msg, hdr); |
| 1139 | 1139 | ||
| 1140 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 1140 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 1141 | 1141 | ||
| 1142 | return 0; | 1142 | return 0; |
| 1143 | 1143 | ||
| @@ -1308,7 +1308,7 @@ static void se_io_cb(void *context, u8 *apdu, size_t apdu_len, int err) | |||
| 1308 | 1308 | ||
| 1309 | genlmsg_end(msg, hdr); | 1309 | genlmsg_end(msg, hdr); |
| 1310 | 1310 | ||
| 1311 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | 1311 | genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL); |
| 1312 | 1312 | ||
| 1313 | kfree(ctx); | 1313 | kfree(ctx); |
| 1314 | 1314 | ||
| @@ -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 | ||
| 1367 | static struct genl_ops nfc_genl_ops[] = { | 1367 | static 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, |
| @@ -1536,16 +1536,15 @@ int __init nfc_genl_init(void) | |||
| 1536 | { | 1536 | { |
| 1537 | int rc; | 1537 | int rc; |
| 1538 | 1538 | ||
| 1539 | rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops, | 1539 | rc = genl_register_family_with_ops_groups(&nfc_genl_family, |
| 1540 | ARRAY_SIZE(nfc_genl_ops)); | 1540 | nfc_genl_ops, |
| 1541 | nfc_genl_mcgrps); | ||
| 1541 | if (rc) | 1542 | if (rc) |
| 1542 | return rc; | 1543 | return rc; |
| 1543 | 1544 | ||
| 1544 | rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp); | ||
| 1545 | |||
| 1546 | netlink_register_notifier(&nl_notifier); | 1545 | netlink_register_notifier(&nl_notifier); |
| 1547 | 1546 | ||
| 1548 | return rc; | 1547 | return 0; |
| 1549 | } | 1548 | } |
| 1550 | 1549 | ||
| 1551 | /** | 1550 | /** |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 449e0776a2c0..6f5e1dd3be2d 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -61,11 +61,11 @@ | |||
| 61 | 61 | ||
| 62 | int ovs_net_id __read_mostly; | 62 | int ovs_net_id __read_mostly; |
| 63 | 63 | ||
| 64 | static void ovs_notify(struct sk_buff *skb, struct genl_info *info, | 64 | static void ovs_notify(struct genl_family *family, |
| 65 | struct genl_multicast_group *grp) | 65 | struct sk_buff *skb, struct genl_info *info) |
| 66 | { | 66 | { |
| 67 | genl_notify(skb, genl_info_net(info), info->snd_portid, | 67 | genl_notify(family, skb, genl_info_net(info), info->snd_portid, |
| 68 | grp->id, info->nlhdr, GFP_KERNEL); | 68 | 0, info->nlhdr, GFP_KERNEL); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | /** | 71 | /** |
| @@ -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 | ||
| 560 | static struct genl_ops dp_packet_genl_ops[] = { | 560 | static 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, |
| @@ -877,10 +877,10 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info) | |||
| 877 | ovs_unlock(); | 877 | ovs_unlock(); |
| 878 | 878 | ||
| 879 | if (!IS_ERR(reply)) | 879 | if (!IS_ERR(reply)) |
| 880 | ovs_notify(reply, info, &ovs_dp_flow_multicast_group); | 880 | ovs_notify(&dp_flow_genl_family, reply, info); |
| 881 | else | 881 | else |
| 882 | netlink_set_err(sock_net(skb->sk)->genl_sock, 0, | 882 | genl_set_err(&dp_flow_genl_family, sock_net(skb->sk), 0, |
| 883 | ovs_dp_flow_multicast_group.id, PTR_ERR(reply)); | 883 | 0, PTR_ERR(reply)); |
| 884 | return 0; | 884 | return 0; |
| 885 | 885 | ||
| 886 | err_flow_free: | 886 | err_flow_free: |
| @@ -990,7 +990,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
| 990 | ovs_flow_free(flow, true); | 990 | ovs_flow_free(flow, true); |
| 991 | ovs_unlock(); | 991 | ovs_unlock(); |
| 992 | 992 | ||
| 993 | ovs_notify(reply, info, &ovs_dp_flow_multicast_group); | 993 | ovs_notify(&dp_flow_genl_family, reply, info); |
| 994 | return 0; | 994 | return 0; |
| 995 | unlock: | 995 | unlock: |
| 996 | ovs_unlock(); | 996 | ovs_unlock(); |
| @@ -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 | ||
| 1037 | static struct genl_ops dp_flow_genl_ops[] = { | 1037 | static 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, |
| @@ -1243,7 +1243,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
| 1243 | 1243 | ||
| 1244 | ovs_unlock(); | 1244 | ovs_unlock(); |
| 1245 | 1245 | ||
| 1246 | ovs_notify(reply, info, &ovs_dp_datapath_multicast_group); | 1246 | ovs_notify(&dp_datapath_genl_family, reply, info); |
| 1247 | return 0; | 1247 | return 0; |
| 1248 | 1248 | ||
| 1249 | err_destroy_local_port: | 1249 | err_destroy_local_port: |
| @@ -1308,7 +1308,7 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
| 1308 | __dp_destroy(dp); | 1308 | __dp_destroy(dp); |
| 1309 | ovs_unlock(); | 1309 | ovs_unlock(); |
| 1310 | 1310 | ||
| 1311 | ovs_notify(reply, info, &ovs_dp_datapath_multicast_group); | 1311 | ovs_notify(&dp_datapath_genl_family, reply, info); |
| 1312 | 1312 | ||
| 1313 | return 0; | 1313 | return 0; |
| 1314 | unlock: | 1314 | unlock: |
| @@ -1332,14 +1332,14 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
| 1332 | info->snd_seq, OVS_DP_CMD_NEW); | 1332 | info->snd_seq, OVS_DP_CMD_NEW); |
| 1333 | if (IS_ERR(reply)) { | 1333 | if (IS_ERR(reply)) { |
| 1334 | err = PTR_ERR(reply); | 1334 | err = PTR_ERR(reply); |
| 1335 | netlink_set_err(sock_net(skb->sk)->genl_sock, 0, | 1335 | genl_set_err(&dp_datapath_genl_family, sock_net(skb->sk), 0, |
| 1336 | ovs_dp_datapath_multicast_group.id, err); | 1336 | 0, err); |
| 1337 | err = 0; | 1337 | err = 0; |
| 1338 | goto unlock; | 1338 | goto unlock; |
| 1339 | } | 1339 | } |
| 1340 | 1340 | ||
| 1341 | ovs_unlock(); | 1341 | ovs_unlock(); |
| 1342 | ovs_notify(reply, info, &ovs_dp_datapath_multicast_group); | 1342 | ovs_notify(&dp_datapath_genl_family, reply, info); |
| 1343 | 1343 | ||
| 1344 | return 0; | 1344 | return 0; |
| 1345 | unlock: | 1345 | unlock: |
| @@ -1398,7 +1398,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1398 | return skb->len; | 1398 | return skb->len; |
| 1399 | } | 1399 | } |
| 1400 | 1400 | ||
| 1401 | static struct genl_ops dp_datapath_genl_ops[] = { | 1401 | static const struct genl_ops dp_datapath_genl_ops[] = { |
| 1402 | { .cmd = OVS_DP_CMD_NEW, | 1402 | { .cmd = OVS_DP_CMD_NEW, |
| 1403 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ | 1403 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ |
| 1404 | .policy = datapath_policy, | 1404 | .policy = datapath_policy, |
| @@ -1431,7 +1431,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = { | |||
| 1431 | [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, | 1431 | [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, |
| 1432 | }; | 1432 | }; |
| 1433 | 1433 | ||
| 1434 | static struct genl_family dp_vport_genl_family = { | 1434 | struct genl_family dp_vport_genl_family = { |
| 1435 | .id = GENL_ID_GENERATE, | 1435 | .id = GENL_ID_GENERATE, |
| 1436 | .hdrsize = sizeof(struct ovs_header), | 1436 | .hdrsize = sizeof(struct ovs_header), |
| 1437 | .name = OVS_VPORT_FAMILY, | 1437 | .name = OVS_VPORT_FAMILY, |
| @@ -1601,7 +1601,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
| 1601 | goto exit_unlock; | 1601 | goto exit_unlock; |
| 1602 | } | 1602 | } |
| 1603 | 1603 | ||
| 1604 | ovs_notify(reply, info, &ovs_dp_vport_multicast_group); | 1604 | ovs_notify(&dp_vport_genl_family, reply, info); |
| 1605 | 1605 | ||
| 1606 | exit_unlock: | 1606 | exit_unlock: |
| 1607 | ovs_unlock(); | 1607 | ovs_unlock(); |
| @@ -1648,7 +1648,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
| 1648 | BUG_ON(err < 0); | 1648 | BUG_ON(err < 0); |
| 1649 | 1649 | ||
| 1650 | ovs_unlock(); | 1650 | ovs_unlock(); |
| 1651 | ovs_notify(reply, info, &ovs_dp_vport_multicast_group); | 1651 | ovs_notify(&dp_vport_genl_family, reply, info); |
| 1652 | return 0; | 1652 | return 0; |
| 1653 | 1653 | ||
| 1654 | exit_free: | 1654 | exit_free: |
| @@ -1685,7 +1685,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info) | |||
| 1685 | err = 0; | 1685 | err = 0; |
| 1686 | ovs_dp_detach_port(vport); | 1686 | ovs_dp_detach_port(vport); |
| 1687 | 1687 | ||
| 1688 | ovs_notify(reply, info, &ovs_dp_vport_multicast_group); | 1688 | ovs_notify(&dp_vport_genl_family, reply, info); |
| 1689 | 1689 | ||
| 1690 | exit_unlock: | 1690 | exit_unlock: |
| 1691 | ovs_unlock(); | 1691 | ovs_unlock(); |
| @@ -1759,7 +1759,7 @@ out: | |||
| 1759 | return skb->len; | 1759 | return skb->len; |
| 1760 | } | 1760 | } |
| 1761 | 1761 | ||
| 1762 | static struct genl_ops dp_vport_genl_ops[] = { | 1762 | static const struct genl_ops dp_vport_genl_ops[] = { |
| 1763 | { .cmd = OVS_VPORT_CMD_NEW, | 1763 | { .cmd = OVS_VPORT_CMD_NEW, |
| 1764 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ | 1764 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ |
| 1765 | .policy = vport_policy, | 1765 | .policy = vport_policy, |
| @@ -1785,9 +1785,9 @@ static struct genl_ops dp_vport_genl_ops[] = { | |||
| 1785 | 1785 | ||
| 1786 | struct genl_family_and_ops { | 1786 | struct genl_family_and_ops { |
| 1787 | struct genl_family *family; | 1787 | struct genl_family *family; |
| 1788 | struct genl_ops *ops; | 1788 | const struct genl_ops *ops; |
| 1789 | int n_ops; | 1789 | int n_ops; |
| 1790 | struct genl_multicast_group *group; | 1790 | const struct genl_multicast_group *group; |
| 1791 | }; | 1791 | }; |
| 1792 | 1792 | ||
| 1793 | static const struct genl_family_and_ops dp_genl_families[] = { | 1793 | static const struct genl_family_and_ops dp_genl_families[] = { |
| @@ -1823,17 +1823,14 @@ static int dp_register_genl(void) | |||
| 1823 | for (i = 0; i < ARRAY_SIZE(dp_genl_families); i++) { | 1823 | for (i = 0; i < ARRAY_SIZE(dp_genl_families); i++) { |
| 1824 | const struct genl_family_and_ops *f = &dp_genl_families[i]; | 1824 | const struct genl_family_and_ops *f = &dp_genl_families[i]; |
| 1825 | 1825 | ||
| 1826 | err = genl_register_family_with_ops(f->family, f->ops, | 1826 | f->family->ops = f->ops; |
| 1827 | f->n_ops); | 1827 | f->family->n_ops = f->n_ops; |
| 1828 | f->family->mcgrps = f->group; | ||
| 1829 | f->family->n_mcgrps = f->group ? 1 : 0; | ||
| 1830 | err = genl_register_family(f->family); | ||
| 1828 | if (err) | 1831 | if (err) |
| 1829 | goto error; | 1832 | goto error; |
| 1830 | n_registered++; | 1833 | n_registered++; |
| 1831 | |||
| 1832 | if (f->group) { | ||
| 1833 | err = genl_register_mc_group(f->family, f->group); | ||
| 1834 | if (err) | ||
| 1835 | goto error; | ||
| 1836 | } | ||
| 1837 | } | 1834 | } |
| 1838 | 1835 | ||
| 1839 | return 0; | 1836 | return 0; |
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index d3d14a58aa91..4067ea41be28 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h | |||
| @@ -177,6 +177,7 @@ static inline struct vport *ovs_vport_ovsl(const struct datapath *dp, int port_n | |||
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | extern struct notifier_block ovs_dp_device_notifier; | 179 | extern struct notifier_block ovs_dp_device_notifier; |
| 180 | extern struct genl_family dp_vport_genl_family; | ||
| 180 | extern struct genl_multicast_group ovs_dp_vport_multicast_group; | 181 | extern struct genl_multicast_group ovs_dp_vport_multicast_group; |
| 181 | 182 | ||
| 182 | void ovs_dp_process_received_packet(struct vport *, struct sk_buff *); | 183 | void ovs_dp_process_received_packet(struct vport *, struct sk_buff *); |
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c index 5c2dab276109..2c631fe76be1 100644 --- a/net/openvswitch/dp_notify.c +++ b/net/openvswitch/dp_notify.c | |||
| @@ -34,15 +34,14 @@ static void dp_detach_port_notify(struct vport *vport) | |||
| 34 | OVS_VPORT_CMD_DEL); | 34 | OVS_VPORT_CMD_DEL); |
| 35 | ovs_dp_detach_port(vport); | 35 | ovs_dp_detach_port(vport); |
| 36 | if (IS_ERR(notify)) { | 36 | if (IS_ERR(notify)) { |
| 37 | netlink_set_err(ovs_dp_get_net(dp)->genl_sock, 0, | 37 | genl_set_err(&dp_vport_genl_family, ovs_dp_get_net(dp), 0, |
| 38 | ovs_dp_vport_multicast_group.id, | 38 | 0, PTR_ERR(notify)); |
| 39 | PTR_ERR(notify)); | ||
| 40 | return; | 39 | return; |
| 41 | } | 40 | } |
| 42 | 41 | ||
| 43 | genlmsg_multicast_netns(ovs_dp_get_net(dp), notify, 0, | 42 | genlmsg_multicast_netns(&dp_vport_genl_family, |
| 44 | ovs_dp_vport_multicast_group.id, | 43 | ovs_dp_get_net(dp), notify, 0, |
| 45 | GFP_KERNEL); | 44 | 0, GFP_KERNEL); |
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | void ovs_dp_notify_wq(struct work_struct *work) | 47 | void ovs_dp_notify_wq(struct work_struct *work) |
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c index 12c30f3e643e..38946b26e471 100644 --- a/net/phonet/datagram.c +++ b/net/phonet/datagram.c | |||
| @@ -139,9 +139,6 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 139 | MSG_CMSG_COMPAT)) | 139 | MSG_CMSG_COMPAT)) |
| 140 | goto out_nofree; | 140 | goto out_nofree; |
| 141 | 141 | ||
| 142 | if (addr_len) | ||
| 143 | *addr_len = sizeof(sa); | ||
| 144 | |||
| 145 | skb = skb_recv_datagram(sk, flags, noblock, &rval); | 142 | skb = skb_recv_datagram(sk, flags, noblock, &rval); |
| 146 | if (skb == NULL) | 143 | if (skb == NULL) |
| 147 | goto out_nofree; | 144 | goto out_nofree; |
| @@ -162,8 +159,10 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 162 | 159 | ||
| 163 | rval = (flags & MSG_TRUNC) ? skb->len : copylen; | 160 | rval = (flags & MSG_TRUNC) ? skb->len : copylen; |
| 164 | 161 | ||
| 165 | if (msg->msg_name != NULL) | 162 | if (msg->msg_name != NULL) { |
| 166 | memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn)); | 163 | memcpy(msg->msg_name, &sa, sizeof(sa)); |
| 164 | *addr_len = sizeof(sa); | ||
| 165 | } | ||
| 167 | 166 | ||
| 168 | out: | 167 | out: |
| 169 | skb_free_datagram(sk, skb); | 168 | skb_free_datagram(sk, skb); |
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index fdc041c57853..95d843961907 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c | |||
| @@ -88,7 +88,7 @@ struct fq_sched_data { | |||
| 88 | struct fq_flow internal; /* for non classified or high prio packets */ | 88 | struct fq_flow internal; /* for non classified or high prio packets */ |
| 89 | u32 quantum; | 89 | u32 quantum; |
| 90 | u32 initial_quantum; | 90 | u32 initial_quantum; |
| 91 | u32 flow_default_rate;/* rate per flow : bytes per second */ | 91 | u32 flow_refill_delay; |
| 92 | u32 flow_max_rate; /* optional max rate per flow */ | 92 | u32 flow_max_rate; /* optional max rate per flow */ |
| 93 | u32 flow_plimit; /* max packets per flow */ | 93 | u32 flow_plimit; /* max packets per flow */ |
| 94 | struct rb_root *fq_root; | 94 | struct rb_root *fq_root; |
| @@ -115,6 +115,7 @@ static struct fq_flow detached, throttled; | |||
| 115 | static void fq_flow_set_detached(struct fq_flow *f) | 115 | static void fq_flow_set_detached(struct fq_flow *f) |
| 116 | { | 116 | { |
| 117 | f->next = &detached; | 117 | f->next = &detached; |
| 118 | f->age = jiffies; | ||
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | static bool fq_flow_is_detached(const struct fq_flow *f) | 121 | static bool fq_flow_is_detached(const struct fq_flow *f) |
| @@ -209,21 +210,15 @@ static void fq_gc(struct fq_sched_data *q, | |||
| 209 | } | 210 | } |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | static const u8 prio2band[TC_PRIO_MAX + 1] = { | ||
| 213 | 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 | ||
| 214 | }; | ||
| 215 | |||
| 216 | static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q) | 213 | static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q) |
| 217 | { | 214 | { |
| 218 | struct rb_node **p, *parent; | 215 | struct rb_node **p, *parent; |
| 219 | struct sock *sk = skb->sk; | 216 | struct sock *sk = skb->sk; |
| 220 | struct rb_root *root; | 217 | struct rb_root *root; |
| 221 | struct fq_flow *f; | 218 | struct fq_flow *f; |
| 222 | int band; | ||
| 223 | 219 | ||
| 224 | /* warning: no starvation prevention... */ | 220 | /* warning: no starvation prevention... */ |
| 225 | band = prio2band[skb->priority & TC_PRIO_MAX]; | 221 | if (unlikely((skb->priority & TC_PRIO_MAX) == TC_PRIO_CONTROL)) |
| 226 | if (unlikely(band == 0)) | ||
| 227 | return &q->internal; | 222 | return &q->internal; |
| 228 | 223 | ||
| 229 | if (unlikely(!sk)) { | 224 | if (unlikely(!sk)) { |
| @@ -373,17 +368,20 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 373 | } | 368 | } |
| 374 | 369 | ||
| 375 | f->qlen++; | 370 | f->qlen++; |
| 376 | flow_queue_add(f, skb); | ||
| 377 | if (skb_is_retransmit(skb)) | 371 | if (skb_is_retransmit(skb)) |
| 378 | q->stat_tcp_retrans++; | 372 | q->stat_tcp_retrans++; |
| 379 | sch->qstats.backlog += qdisc_pkt_len(skb); | 373 | sch->qstats.backlog += qdisc_pkt_len(skb); |
| 380 | if (fq_flow_is_detached(f)) { | 374 | if (fq_flow_is_detached(f)) { |
| 381 | fq_flow_add_tail(&q->new_flows, f); | 375 | fq_flow_add_tail(&q->new_flows, f); |
| 382 | if (q->quantum > f->credit) | 376 | if (time_after(jiffies, f->age + q->flow_refill_delay)) |
| 383 | f->credit = q->quantum; | 377 | f->credit = max_t(u32, f->credit, q->quantum); |
| 384 | q->inactive_flows--; | 378 | q->inactive_flows--; |
| 385 | qdisc_unthrottled(sch); | 379 | qdisc_unthrottled(sch); |
| 386 | } | 380 | } |
| 381 | |||
| 382 | /* Note: this overwrites f->age */ | ||
| 383 | flow_queue_add(f, skb); | ||
| 384 | |||
| 387 | if (unlikely(f == &q->internal)) { | 385 | if (unlikely(f == &q->internal)) { |
| 388 | q->stat_internal_packets++; | 386 | q->stat_internal_packets++; |
| 389 | qdisc_unthrottled(sch); | 387 | qdisc_unthrottled(sch); |
| @@ -461,7 +459,6 @@ begin: | |||
| 461 | fq_flow_add_tail(&q->old_flows, f); | 459 | fq_flow_add_tail(&q->old_flows, f); |
| 462 | } else { | 460 | } else { |
| 463 | fq_flow_set_detached(f); | 461 | fq_flow_set_detached(f); |
| 464 | f->age = jiffies; | ||
| 465 | q->inactive_flows++; | 462 | q->inactive_flows++; |
| 466 | } | 463 | } |
| 467 | goto begin; | 464 | goto begin; |
| @@ -615,6 +612,7 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = { | |||
| 615 | [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 }, | 612 | [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 }, |
| 616 | [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 }, | 613 | [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 }, |
| 617 | [TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 }, | 614 | [TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 }, |
| 615 | [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 }, | ||
| 618 | }; | 616 | }; |
| 619 | 617 | ||
| 620 | static int fq_change(struct Qdisc *sch, struct nlattr *opt) | 618 | static int fq_change(struct Qdisc *sch, struct nlattr *opt) |
| @@ -656,7 +654,8 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 656 | q->initial_quantum = nla_get_u32(tb[TCA_FQ_INITIAL_QUANTUM]); | 654 | q->initial_quantum = nla_get_u32(tb[TCA_FQ_INITIAL_QUANTUM]); |
| 657 | 655 | ||
| 658 | if (tb[TCA_FQ_FLOW_DEFAULT_RATE]) | 656 | if (tb[TCA_FQ_FLOW_DEFAULT_RATE]) |
| 659 | q->flow_default_rate = nla_get_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]); | 657 | pr_warn_ratelimited("sch_fq: defrate %u ignored.\n", |
| 658 | nla_get_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE])); | ||
| 660 | 659 | ||
| 661 | if (tb[TCA_FQ_FLOW_MAX_RATE]) | 660 | if (tb[TCA_FQ_FLOW_MAX_RATE]) |
| 662 | q->flow_max_rate = nla_get_u32(tb[TCA_FQ_FLOW_MAX_RATE]); | 661 | q->flow_max_rate = nla_get_u32(tb[TCA_FQ_FLOW_MAX_RATE]); |
| @@ -670,6 +669,12 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 670 | err = -EINVAL; | 669 | err = -EINVAL; |
| 671 | } | 670 | } |
| 672 | 671 | ||
| 672 | if (tb[TCA_FQ_FLOW_REFILL_DELAY]) { | ||
| 673 | u32 usecs_delay = nla_get_u32(tb[TCA_FQ_FLOW_REFILL_DELAY]) ; | ||
| 674 | |||
| 675 | q->flow_refill_delay = usecs_to_jiffies(usecs_delay); | ||
| 676 | } | ||
| 677 | |||
| 673 | if (!err) | 678 | if (!err) |
| 674 | err = fq_resize(q, fq_log); | 679 | err = fq_resize(q, fq_log); |
| 675 | 680 | ||
| @@ -705,7 +710,7 @@ static int fq_init(struct Qdisc *sch, struct nlattr *opt) | |||
| 705 | q->flow_plimit = 100; | 710 | q->flow_plimit = 100; |
| 706 | q->quantum = 2 * psched_mtu(qdisc_dev(sch)); | 711 | q->quantum = 2 * psched_mtu(qdisc_dev(sch)); |
| 707 | q->initial_quantum = 10 * psched_mtu(qdisc_dev(sch)); | 712 | q->initial_quantum = 10 * psched_mtu(qdisc_dev(sch)); |
| 708 | q->flow_default_rate = 0; | 713 | q->flow_refill_delay = msecs_to_jiffies(40); |
| 709 | q->flow_max_rate = ~0U; | 714 | q->flow_max_rate = ~0U; |
| 710 | q->rate_enable = 1; | 715 | q->rate_enable = 1; |
| 711 | q->new_flows.first = NULL; | 716 | q->new_flows.first = NULL; |
| @@ -732,15 +737,16 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
| 732 | if (opts == NULL) | 737 | if (opts == NULL) |
| 733 | goto nla_put_failure; | 738 | goto nla_put_failure; |
| 734 | 739 | ||
| 735 | /* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore, | 740 | /* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore */ |
| 736 | * do not bother giving its value | 741 | |
| 737 | */ | ||
| 738 | if (nla_put_u32(skb, TCA_FQ_PLIMIT, sch->limit) || | 742 | if (nla_put_u32(skb, TCA_FQ_PLIMIT, sch->limit) || |
| 739 | nla_put_u32(skb, TCA_FQ_FLOW_PLIMIT, q->flow_plimit) || | 743 | nla_put_u32(skb, TCA_FQ_FLOW_PLIMIT, q->flow_plimit) || |
| 740 | nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) || | 744 | nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) || |
| 741 | nla_put_u32(skb, TCA_FQ_INITIAL_QUANTUM, q->initial_quantum) || | 745 | nla_put_u32(skb, TCA_FQ_INITIAL_QUANTUM, q->initial_quantum) || |
| 742 | nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) || | 746 | nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) || |
| 743 | nla_put_u32(skb, TCA_FQ_FLOW_MAX_RATE, q->flow_max_rate) || | 747 | nla_put_u32(skb, TCA_FQ_FLOW_MAX_RATE, q->flow_max_rate) || |
| 748 | nla_put_u32(skb, TCA_FQ_FLOW_REFILL_DELAY, | ||
| 749 | jiffies_to_usecs(q->flow_refill_delay)) || | ||
| 744 | nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log)) | 750 | nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log)) |
| 745 | goto nla_put_failure; | 751 | goto nla_put_failure; |
| 746 | 752 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index c9b91cb1cb0d..68a27f9796d2 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -907,8 +907,8 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, | |||
| 907 | if (!first || t->last_time_heard > first->last_time_heard) { | 907 | if (!first || t->last_time_heard > first->last_time_heard) { |
| 908 | second = first; | 908 | second = first; |
| 909 | first = t; | 909 | first = t; |
| 910 | } | 910 | } else if (!second || |
| 911 | if (!second || t->last_time_heard > second->last_time_heard) | 911 | t->last_time_heard > second->last_time_heard) |
| 912 | second = t; | 912 | second = t; |
| 913 | } | 913 | } |
| 914 | 914 | ||
| @@ -929,6 +929,8 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, | |||
| 929 | first = asoc->peer.primary_path; | 929 | first = asoc->peer.primary_path; |
| 930 | } | 930 | } |
| 931 | 931 | ||
| 932 | if (!second) | ||
| 933 | second = first; | ||
| 932 | /* If we failed to find a usable transport, just camp on the | 934 | /* If we failed to find a usable transport, just camp on the |
| 933 | * primary, even if it is inactive. | 935 | * primary, even if it is inactive. |
| 934 | */ | 936 | */ |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index d0d14a04dce1..bf04b30a788a 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -471,15 +471,6 @@ struct rpc_filelist { | |||
| 471 | umode_t mode; | 471 | umode_t mode; |
| 472 | }; | 472 | }; |
| 473 | 473 | ||
| 474 | static int rpc_delete_dentry(const struct dentry *dentry) | ||
| 475 | { | ||
| 476 | return 1; | ||
| 477 | } | ||
| 478 | |||
| 479 | static const struct dentry_operations rpc_dentry_operations = { | ||
| 480 | .d_delete = rpc_delete_dentry, | ||
| 481 | }; | ||
| 482 | |||
| 483 | static struct inode * | 474 | static struct inode * |
| 484 | rpc_get_inode(struct super_block *sb, umode_t mode) | 475 | rpc_get_inode(struct super_block *sb, umode_t mode) |
| 485 | { | 476 | { |
| @@ -1266,7 +1257,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1266 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 1257 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
| 1267 | sb->s_magic = RPCAUTH_GSSMAGIC; | 1258 | sb->s_magic = RPCAUTH_GSSMAGIC; |
| 1268 | sb->s_op = &s_ops; | 1259 | sb->s_op = &s_ops; |
| 1269 | sb->s_d_op = &rpc_dentry_operations; | 1260 | sb->s_d_op = &simple_dentry_operations; |
| 1270 | sb->s_time_gran = 1; | 1261 | sb->s_time_gran = 1; |
| 1271 | 1262 | ||
| 1272 | inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); | 1263 | inode = rpc_get_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); |
diff --git a/net/tipc/link.c b/net/tipc/link.c index cf465d66ccde..69cd9bf3f561 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -2358,7 +2358,8 @@ int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail, | |||
| 2358 | *head = frag; | 2358 | *head = frag; |
| 2359 | skb_frag_list_init(*head); | 2359 | skb_frag_list_init(*head); |
| 2360 | return 0; | 2360 | return 0; |
| 2361 | } else if (skb_try_coalesce(*head, frag, &headstolen, &delta)) { | 2361 | } else if (*head && |
| 2362 | skb_try_coalesce(*head, frag, &headstolen, &delta)) { | ||
| 2362 | kfree_skb_partial(frag, headstolen); | 2363 | kfree_skb_partial(frag, headstolen); |
| 2363 | } else { | 2364 | } else { |
| 2364 | if (!*head) | 2365 | if (!*head) |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 8bcd4985d0fb..9f72a6376362 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
| @@ -76,9 +76,11 @@ static struct genl_family tipc_genl_family = { | |||
| 76 | .maxattr = 0, | 76 | .maxattr = 0, |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | static struct genl_ops tipc_genl_ops = { | 79 | static struct genl_ops tipc_genl_ops[] = { |
| 80 | .cmd = TIPC_GENL_CMD, | 80 | { |
| 81 | .doit = handle_cmd, | 81 | .cmd = TIPC_GENL_CMD, |
| 82 | .doit = handle_cmd, | ||
| 83 | }, | ||
| 82 | }; | 84 | }; |
| 83 | 85 | ||
| 84 | static int tipc_genl_family_registered; | 86 | static int tipc_genl_family_registered; |
| @@ -87,8 +89,7 @@ int tipc_netlink_start(void) | |||
| 87 | { | 89 | { |
| 88 | int res; | 90 | int res; |
| 89 | 91 | ||
| 90 | res = genl_register_family_with_ops(&tipc_genl_family, | 92 | res = genl_register_family_with_ops(&tipc_genl_family, tipc_genl_ops); |
| 91 | &tipc_genl_ops, 1); | ||
| 92 | if (res) { | 93 | if (res) { |
| 93 | pr_err("Failed to register netlink interface\n"); | 94 | pr_err("Failed to register netlink interface\n"); |
| 94 | return res; | 95 | return res; |
diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c index 0694d62e4dbc..c278b3356f75 100644 --- a/net/wimax/op-msg.c +++ b/net/wimax/op-msg.c | |||
| @@ -279,7 +279,7 @@ int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb) | |||
| 279 | 279 | ||
| 280 | d_printf(1, dev, "CTX: wimax msg, %zu bytes\n", size); | 280 | d_printf(1, dev, "CTX: wimax msg, %zu bytes\n", size); |
| 281 | d_dump(2, dev, msg, size); | 281 | d_dump(2, dev, msg, size); |
| 282 | genlmsg_multicast(skb, 0, wimax_gnl_mcg.id, GFP_KERNEL); | 282 | genlmsg_multicast(&wimax_gnl_family, skb, 0, 0, GFP_KERNEL); |
| 283 | d_printf(1, dev, "CTX: genl multicast done\n"); | 283 | d_printf(1, dev, "CTX: genl multicast done\n"); |
| 284 | return 0; | 284 | return 0; |
| 285 | } | 285 | } |
| @@ -321,17 +321,6 @@ int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name, | |||
| 321 | } | 321 | } |
| 322 | EXPORT_SYMBOL_GPL(wimax_msg); | 322 | EXPORT_SYMBOL_GPL(wimax_msg); |
| 323 | 323 | ||
| 324 | |||
| 325 | static 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 | */ |
| 343 | static | ||
| 344 | int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info) | 332 | int 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 | |||
| 426 | struct 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) | |||
| 92 | EXPORT_SYMBOL(wimax_reset); | 92 | EXPORT_SYMBOL(wimax_reset); |
| 93 | 93 | ||
| 94 | 94 | ||
| 95 | static 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 | */ |
| 109 | static | ||
| 110 | int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info) | 102 | int 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 | |||
| 135 | struct 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 | ||
| 414 | static 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 | |||
| 424 | static | ||
| 425 | int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info) | 414 | int 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 | |||
| 462 | struct 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 | ||
| 36 | static 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 | */ |
| 51 | static | ||
| 52 | int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info) | 44 | int 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 | |||
| 77 | struct 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..ef2191b969a7 100644 --- a/net/wimax/stack.c +++ b/net/wimax/stack.c | |||
| @@ -116,8 +116,9 @@ struct sk_buff *wimax_gnl_re_state_change_alloc( | |||
| 116 | dev_err(dev, "RE_STCH: can't create message\n"); | 116 | dev_err(dev, "RE_STCH: can't create message\n"); |
| 117 | goto error_new; | 117 | goto error_new; |
| 118 | } | 118 | } |
| 119 | data = genlmsg_put(report_skb, 0, wimax_gnl_mcg.id, &wimax_gnl_family, | 119 | /* FIXME: sending a group ID as the seq is wrong */ |
| 120 | 0, WIMAX_GNL_RE_STATE_CHANGE); | 120 | data = genlmsg_put(report_skb, 0, wimax_gnl_family.mcgrp_offset, |
| 121 | &wimax_gnl_family, 0, WIMAX_GNL_RE_STATE_CHANGE); | ||
| 121 | if (data == NULL) { | 122 | if (data == NULL) { |
| 122 | dev_err(dev, "RE_STCH: can't put data into message\n"); | 123 | dev_err(dev, "RE_STCH: can't put data into message\n"); |
| 123 | goto error_put; | 124 | goto error_put; |
| @@ -177,7 +178,7 @@ int wimax_gnl_re_state_change_send( | |||
| 177 | goto out; | 178 | goto out; |
| 178 | } | 179 | } |
| 179 | genlmsg_end(report_skb, header); | 180 | genlmsg_end(report_skb, header); |
| 180 | genlmsg_multicast(report_skb, 0, wimax_gnl_mcg.id, GFP_KERNEL); | 181 | genlmsg_multicast(&wimax_gnl_family, report_skb, 0, 0, GFP_KERNEL); |
| 181 | out: | 182 | out: |
| 182 | d_fnend(3, dev, "(wimax_dev %p report_skb %p) = %d\n", | 183 | d_fnend(3, dev, "(wimax_dev %p report_skb %p) = %d\n", |
| 183 | wimax_dev, report_skb, result); | 184 | wimax_dev, report_skb, result); |
| @@ -402,22 +403,44 @@ void wimax_dev_init(struct wimax_dev *wimax_dev) | |||
| 402 | } | 403 | } |
| 403 | EXPORT_SYMBOL_GPL(wimax_dev_init); | 404 | EXPORT_SYMBOL_GPL(wimax_dev_init); |
| 404 | 405 | ||
| 405 | /* | 406 | static 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 -- | 407 | [WIMAX_GNL_RESET_IFIDX] = { .type = NLA_U32, }, |
| 407 | * both declarations are a list of the same | 408 | [WIMAX_GNL_RFKILL_IFIDX] = { .type = NLA_U32, }, |
| 408 | */ | 409 | [WIMAX_GNL_RFKILL_STATE] = { |
| 409 | extern struct genl_ops | 410 | .type = NLA_U32 /* enum wimax_rf_state */ |
| 410 | wimax_gnl_msg_from_user, | 411 | }, |
| 411 | wimax_gnl_reset, | 412 | [WIMAX_GNL_STGET_IFIDX] = { .type = NLA_U32, }, |
| 412 | wimax_gnl_rfkill, | 413 | [WIMAX_GNL_MSG_IFIDX] = { .type = NLA_U32, }, |
| 413 | wimax_gnl_state_get; | 414 | [WIMAX_GNL_MSG_DATA] = { |
| 415 | .type = NLA_UNSPEC, /* libnl doesn't grok BINARY yet */ | ||
| 416 | }, | ||
| 417 | }; | ||
| 414 | 418 | ||
| 415 | static | 419 | static const struct genl_ops wimax_gnl_ops[] = { |
| 416 | struct genl_ops *wimax_gnl_ops[] = { | 420 | { |
| 417 | &wimax_gnl_msg_from_user, | 421 | .cmd = WIMAX_GNL_OP_MSG_FROM_USER, |
| 418 | &wimax_gnl_reset, | 422 | .flags = GENL_ADMIN_PERM, |
| 419 | &wimax_gnl_rfkill, | 423 | .policy = wimax_gnl_policy, |
| 420 | &wimax_gnl_state_get, | 424 | .doit = wimax_gnl_doit_msg_from_user, |
| 425 | }, | ||
| 426 | { | ||
| 427 | .cmd = WIMAX_GNL_OP_RESET, | ||
| 428 | .flags = GENL_ADMIN_PERM, | ||
| 429 | .policy = wimax_gnl_policy, | ||
| 430 | .doit = wimax_gnl_doit_reset, | ||
| 431 | }, | ||
| 432 | { | ||
| 433 | .cmd = WIMAX_GNL_OP_RFKILL, | ||
| 434 | .flags = GENL_ADMIN_PERM, | ||
| 435 | .policy = wimax_gnl_policy, | ||
| 436 | .doit = wimax_gnl_doit_rfkill, | ||
| 437 | }, | ||
| 438 | { | ||
| 439 | .cmd = WIMAX_GNL_OP_STATE_GET, | ||
| 440 | .flags = GENL_ADMIN_PERM, | ||
| 441 | .policy = wimax_gnl_policy, | ||
| 442 | .doit = wimax_gnl_doit_state_get, | ||
| 443 | }, | ||
| 421 | }; | 444 | }; |
| 422 | 445 | ||
| 423 | 446 | ||
| @@ -557,8 +580,8 @@ struct genl_family wimax_gnl_family = { | |||
| 557 | .maxattr = WIMAX_GNL_ATTR_MAX, | 580 | .maxattr = WIMAX_GNL_ATTR_MAX, |
| 558 | }; | 581 | }; |
| 559 | 582 | ||
| 560 | struct genl_multicast_group wimax_gnl_mcg = { | 583 | static const struct genl_multicast_group wimax_gnl_mcgrps[] = { |
| 561 | .name = "msg", | 584 | { .name = "msg", }, |
| 562 | }; | 585 | }; |
| 563 | 586 | ||
| 564 | 587 | ||
| @@ -567,7 +590,7 @@ struct genl_multicast_group wimax_gnl_mcg = { | |||
| 567 | static | 590 | static |
| 568 | int __init wimax_subsys_init(void) | 591 | int __init wimax_subsys_init(void) |
| 569 | { | 592 | { |
| 570 | int result, cnt; | 593 | int result; |
| 571 | 594 | ||
| 572 | d_fnstart(4, NULL, "()\n"); | 595 | d_fnstart(4, NULL, "()\n"); |
| 573 | d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params, | 596 | d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params, |
| @@ -575,37 +598,18 @@ int __init wimax_subsys_init(void) | |||
| 575 | 598 | ||
| 576 | snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name), | 599 | snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name), |
| 577 | "WiMAX"); | 600 | "WiMAX"); |
| 578 | result = genl_register_family(&wimax_gnl_family); | 601 | result = genl_register_family_with_ops_groups(&wimax_gnl_family, |
| 602 | wimax_gnl_ops, | ||
| 603 | wimax_gnl_mcgrps); | ||
| 579 | if (unlikely(result < 0)) { | 604 | if (unlikely(result < 0)) { |
| 580 | printk(KERN_ERR "cannot register generic netlink family: %d\n", | 605 | printk(KERN_ERR "cannot register generic netlink family: %d\n", |
| 581 | result); | 606 | result); |
| 582 | goto error_register_family; | 607 | goto error_register_family; |
| 583 | } | 608 | } |
| 584 | 609 | ||
| 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); | ||
| 599 | if (result < 0) | ||
| 600 | goto error_mc_group; | ||
| 601 | d_fnend(4, NULL, "() = 0\n"); | 610 | d_fnend(4, NULL, "() = 0\n"); |
| 602 | return 0; | 611 | return 0; |
| 603 | 612 | ||
| 604 | error_mc_group: | ||
| 605 | error_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); | 613 | genl_unregister_family(&wimax_gnl_family); |
| 610 | error_register_family: | 614 | error_register_family: |
| 611 | d_fnend(4, NULL, "() = %d\n", result); | 615 | d_fnend(4, NULL, "() = %d\n", result); |
| @@ -619,12 +623,7 @@ module_init(wimax_subsys_init); | |||
| 619 | static | 623 | static |
| 620 | void __exit wimax_subsys_exit(void) | 624 | void __exit wimax_subsys_exit(void) |
| 621 | { | 625 | { |
| 622 | int cnt; | ||
| 623 | wimax_id_table_release(); | 626 | 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); | 627 | genl_unregister_family(&wimax_gnl_family); |
| 629 | } | 628 | } |
| 630 | module_exit(wimax_subsys_exit); | 629 | module_exit(wimax_subsys_exit); |
diff --git a/net/wimax/wimax-internal.h b/net/wimax/wimax-internal.h index 5dcd9c067bf0..b445b82020a8 100644 --- a/net/wimax/wimax-internal.h +++ b/net/wimax/wimax-internal.h | |||
| @@ -84,8 +84,14 @@ void wimax_id_table_release(void); | |||
| 84 | int wimax_rfkill_add(struct wimax_dev *); | 84 | int wimax_rfkill_add(struct wimax_dev *); |
| 85 | void wimax_rfkill_rm(struct wimax_dev *); | 85 | void wimax_rfkill_rm(struct wimax_dev *); |
| 86 | 86 | ||
| 87 | /* generic netlink */ | ||
| 87 | extern struct genl_family wimax_gnl_family; | 88 | extern struct genl_family wimax_gnl_family; |
| 88 | extern struct genl_multicast_group wimax_gnl_mcg; | 89 | |
| 90 | /* ops */ | ||
| 91 | int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info); | ||
| 92 | int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info); | ||
| 93 | int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info); | ||
| 94 | int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info); | ||
| 89 | 95 | ||
| 90 | #endif /* #ifdef __KERNEL__ */ | 96 | #endif /* #ifdef __KERNEL__ */ |
| 91 | #endif /* #ifndef __WIMAX_INTERNAL_H__ */ | 97 | #endif /* #ifndef __WIMAX_INTERNAL_H__ */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a7f4e7902104..a1eb21073176 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 | ||
| 33 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | 33 | static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, |
| 34 | struct genl_info *info); | 34 | struct genl_info *info); |
| 35 | static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, | 35 | static 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 */ |
| @@ -47,6 +47,25 @@ static struct genl_family nl80211_fam = { | |||
| 47 | .post_doit = nl80211_post_doit, | 47 | .post_doit = nl80211_post_doit, |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | /* multicast groups */ | ||
| 51 | enum nl80211_multicast_groups { | ||
| 52 | NL80211_MCGRP_CONFIG, | ||
| 53 | NL80211_MCGRP_SCAN, | ||
| 54 | NL80211_MCGRP_REGULATORY, | ||
| 55 | NL80211_MCGRP_MLME, | ||
| 56 | NL80211_MCGRP_TESTMODE /* keep last - ifdef! */ | ||
| 57 | }; | ||
| 58 | |||
| 59 | static const struct genl_multicast_group nl80211_mcgrps[] = { | ||
| 60 | [NL80211_MCGRP_CONFIG] = { .name = "config", }, | ||
| 61 | [NL80211_MCGRP_SCAN] = { .name = "scan", }, | ||
| 62 | [NL80211_MCGRP_REGULATORY] = { .name = "regulatory", }, | ||
| 63 | [NL80211_MCGRP_MLME] = { .name = "mlme", }, | ||
| 64 | #ifdef CONFIG_NL80211_TESTMODE | ||
| 65 | [NL80211_MCGRP_TESTMODE] = { .name = "testmode", } | ||
| 66 | #endif | ||
| 67 | }; | ||
| 68 | |||
| 50 | /* returns ERR_PTR values */ | 69 | /* returns ERR_PTR values */ |
| 51 | static struct wireless_dev * | 70 | static struct wireless_dev * |
| 52 | __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) | 71 | __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) |
| @@ -6656,10 +6675,6 @@ static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info) | |||
| 6656 | 6675 | ||
| 6657 | 6676 | ||
| 6658 | #ifdef CONFIG_NL80211_TESTMODE | 6677 | #ifdef CONFIG_NL80211_TESTMODE |
| 6659 | static struct genl_multicast_group nl80211_testmode_mcgrp = { | ||
| 6660 | .name = "testmode", | ||
| 6661 | }; | ||
| 6662 | |||
| 6663 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) | 6678 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) |
| 6664 | { | 6679 | { |
| 6665 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6680 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| @@ -6868,8 +6883,8 @@ void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) | |||
| 6868 | 6883 | ||
| 6869 | nla_nest_end(skb, data); | 6884 | nla_nest_end(skb, data); |
| 6870 | genlmsg_end(skb, hdr); | 6885 | genlmsg_end(skb, hdr); |
| 6871 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0, | 6886 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), skb, 0, |
| 6872 | nl80211_testmode_mcgrp.id, gfp); | 6887 | NL80211_MCGRP_TESTMODE, gfp); |
| 6873 | } | 6888 | } |
| 6874 | EXPORT_SYMBOL(cfg80211_testmode_event); | 6889 | EXPORT_SYMBOL(cfg80211_testmode_event); |
| 6875 | #endif | 6890 | #endif |
| @@ -8851,7 +8866,7 @@ static int nl80211_crit_protocol_stop(struct sk_buff *skb, | |||
| 8851 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ | 8866 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ |
| 8852 | NL80211_FLAG_CHECK_NETDEV_UP) | 8867 | NL80211_FLAG_CHECK_NETDEV_UP) |
| 8853 | 8868 | ||
| 8854 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | 8869 | static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, |
| 8855 | struct genl_info *info) | 8870 | struct genl_info *info) |
| 8856 | { | 8871 | { |
| 8857 | struct cfg80211_registered_device *rdev; | 8872 | struct cfg80211_registered_device *rdev; |
| @@ -8920,7 +8935,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | |||
| 8920 | return 0; | 8935 | return 0; |
| 8921 | } | 8936 | } |
| 8922 | 8937 | ||
| 8923 | static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, | 8938 | static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, |
| 8924 | struct genl_info *info) | 8939 | struct genl_info *info) |
| 8925 | { | 8940 | { |
| 8926 | if (info->user_ptr[1]) { | 8941 | if (info->user_ptr[1]) { |
| @@ -8937,7 +8952,7 @@ static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, | |||
| 8937 | rtnl_unlock(); | 8952 | rtnl_unlock(); |
| 8938 | } | 8953 | } |
| 8939 | 8954 | ||
| 8940 | static struct genl_ops nl80211_ops[] = { | 8955 | static const struct genl_ops nl80211_ops[] = { |
| 8941 | { | 8956 | { |
| 8942 | .cmd = NL80211_CMD_GET_WIPHY, | 8957 | .cmd = NL80211_CMD_GET_WIPHY, |
| 8943 | .doit = nl80211_get_wiphy, | 8958 | .doit = nl80211_get_wiphy, |
| @@ -9566,21 +9581,6 @@ static struct genl_ops nl80211_ops[] = { | |||
| 9566 | }, | 9581 | }, |
| 9567 | }; | 9582 | }; |
| 9568 | 9583 | ||
| 9569 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | ||
| 9570 | .name = "mlme", | ||
| 9571 | }; | ||
| 9572 | |||
| 9573 | /* multicast groups */ | ||
| 9574 | static struct genl_multicast_group nl80211_config_mcgrp = { | ||
| 9575 | .name = "config", | ||
| 9576 | }; | ||
| 9577 | static struct genl_multicast_group nl80211_scan_mcgrp = { | ||
| 9578 | .name = "scan", | ||
| 9579 | }; | ||
| 9580 | static struct genl_multicast_group nl80211_regulatory_mcgrp = { | ||
| 9581 | .name = "regulatory", | ||
| 9582 | }; | ||
| 9583 | |||
| 9584 | /* notification functions */ | 9584 | /* notification functions */ |
| 9585 | 9585 | ||
| 9586 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | 9586 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) |
| @@ -9597,8 +9597,8 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | |||
| 9597 | return; | 9597 | return; |
| 9598 | } | 9598 | } |
| 9599 | 9599 | ||
| 9600 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9600 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9601 | nl80211_config_mcgrp.id, GFP_KERNEL); | 9601 | NL80211_MCGRP_CONFIG, GFP_KERNEL); |
| 9602 | } | 9602 | } |
| 9603 | 9603 | ||
| 9604 | static int nl80211_add_scan_req(struct sk_buff *msg, | 9604 | static int nl80211_add_scan_req(struct sk_buff *msg, |
| @@ -9707,8 +9707,8 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | |||
| 9707 | return; | 9707 | return; |
| 9708 | } | 9708 | } |
| 9709 | 9709 | ||
| 9710 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9710 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9711 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 9711 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
| 9712 | } | 9712 | } |
| 9713 | 9713 | ||
| 9714 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 9714 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, |
| @@ -9726,8 +9726,8 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | |||
| 9726 | return; | 9726 | return; |
| 9727 | } | 9727 | } |
| 9728 | 9728 | ||
| 9729 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9729 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9730 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 9730 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
| 9731 | } | 9731 | } |
| 9732 | 9732 | ||
| 9733 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 9733 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, |
| @@ -9745,8 +9745,8 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | |||
| 9745 | return; | 9745 | return; |
| 9746 | } | 9746 | } |
| 9747 | 9747 | ||
| 9748 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9748 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9749 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 9749 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
| 9750 | } | 9750 | } |
| 9751 | 9751 | ||
| 9752 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | 9752 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, |
| @@ -9764,8 +9764,8 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | |||
| 9764 | return; | 9764 | return; |
| 9765 | } | 9765 | } |
| 9766 | 9766 | ||
| 9767 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9767 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9768 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 9768 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
| 9769 | } | 9769 | } |
| 9770 | 9770 | ||
| 9771 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | 9771 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, |
| @@ -9782,8 +9782,8 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | |||
| 9782 | return; | 9782 | return; |
| 9783 | } | 9783 | } |
| 9784 | 9784 | ||
| 9785 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9785 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9786 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 9786 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
| 9787 | } | 9787 | } |
| 9788 | 9788 | ||
| 9789 | /* | 9789 | /* |
| @@ -9837,8 +9837,8 @@ void nl80211_send_reg_change_event(struct regulatory_request *request) | |||
| 9837 | genlmsg_end(msg, hdr); | 9837 | genlmsg_end(msg, hdr); |
| 9838 | 9838 | ||
| 9839 | rcu_read_lock(); | 9839 | rcu_read_lock(); |
| 9840 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 9840 | genlmsg_multicast_allns(&nl80211_fam, msg, 0, |
| 9841 | GFP_ATOMIC); | 9841 | NL80211_MCGRP_REGULATORY, GFP_ATOMIC); |
| 9842 | rcu_read_unlock(); | 9842 | rcu_read_unlock(); |
| 9843 | 9843 | ||
| 9844 | return; | 9844 | return; |
| @@ -9873,8 +9873,8 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | |||
| 9873 | 9873 | ||
| 9874 | genlmsg_end(msg, hdr); | 9874 | genlmsg_end(msg, hdr); |
| 9875 | 9875 | ||
| 9876 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9876 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9877 | nl80211_mlme_mcgrp.id, gfp); | 9877 | NL80211_MCGRP_MLME, gfp); |
| 9878 | return; | 9878 | return; |
| 9879 | 9879 | ||
| 9880 | nla_put_failure: | 9880 | nla_put_failure: |
| @@ -9961,8 +9961,8 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, | |||
| 9961 | 9961 | ||
| 9962 | genlmsg_end(msg, hdr); | 9962 | genlmsg_end(msg, hdr); |
| 9963 | 9963 | ||
| 9964 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9964 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 9965 | nl80211_mlme_mcgrp.id, gfp); | 9965 | NL80211_MCGRP_MLME, gfp); |
| 9966 | return; | 9966 | return; |
| 9967 | 9967 | ||
| 9968 | nla_put_failure: | 9968 | nla_put_failure: |
| @@ -10017,8 +10017,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, | |||
| 10017 | 10017 | ||
| 10018 | genlmsg_end(msg, hdr); | 10018 | genlmsg_end(msg, hdr); |
| 10019 | 10019 | ||
| 10020 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10020 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10021 | nl80211_mlme_mcgrp.id, gfp); | 10021 | NL80211_MCGRP_MLME, gfp); |
| 10022 | return; | 10022 | return; |
| 10023 | 10023 | ||
| 10024 | nla_put_failure: | 10024 | nla_put_failure: |
| @@ -10056,8 +10056,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, | |||
| 10056 | 10056 | ||
| 10057 | genlmsg_end(msg, hdr); | 10057 | genlmsg_end(msg, hdr); |
| 10058 | 10058 | ||
| 10059 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10059 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10060 | nl80211_mlme_mcgrp.id, gfp); | 10060 | NL80211_MCGRP_MLME, gfp); |
| 10061 | return; | 10061 | return; |
| 10062 | 10062 | ||
| 10063 | nla_put_failure: | 10063 | nla_put_failure: |
| @@ -10094,8 +10094,8 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, | |||
| 10094 | 10094 | ||
| 10095 | genlmsg_end(msg, hdr); | 10095 | genlmsg_end(msg, hdr); |
| 10096 | 10096 | ||
| 10097 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10097 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10098 | nl80211_mlme_mcgrp.id, GFP_KERNEL); | 10098 | NL80211_MCGRP_MLME, GFP_KERNEL); |
| 10099 | return; | 10099 | return; |
| 10100 | 10100 | ||
| 10101 | nla_put_failure: | 10101 | nla_put_failure: |
| @@ -10128,8 +10128,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, | |||
| 10128 | 10128 | ||
| 10129 | genlmsg_end(msg, hdr); | 10129 | genlmsg_end(msg, hdr); |
| 10130 | 10130 | ||
| 10131 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10131 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10132 | nl80211_mlme_mcgrp.id, gfp); | 10132 | NL80211_MCGRP_MLME, gfp); |
| 10133 | return; | 10133 | return; |
| 10134 | 10134 | ||
| 10135 | nla_put_failure: | 10135 | nla_put_failure: |
| @@ -10169,8 +10169,8 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr, | |||
| 10169 | 10169 | ||
| 10170 | genlmsg_end(msg, hdr); | 10170 | genlmsg_end(msg, hdr); |
| 10171 | 10171 | ||
| 10172 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10172 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10173 | nl80211_mlme_mcgrp.id, gfp); | 10173 | NL80211_MCGRP_MLME, gfp); |
| 10174 | return; | 10174 | return; |
| 10175 | 10175 | ||
| 10176 | nla_put_failure: | 10176 | nla_put_failure: |
| @@ -10208,8 +10208,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | |||
| 10208 | 10208 | ||
| 10209 | genlmsg_end(msg, hdr); | 10209 | genlmsg_end(msg, hdr); |
| 10210 | 10210 | ||
| 10211 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10211 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10212 | nl80211_mlme_mcgrp.id, gfp); | 10212 | NL80211_MCGRP_MLME, gfp); |
| 10213 | return; | 10213 | return; |
| 10214 | 10214 | ||
| 10215 | nla_put_failure: | 10215 | nla_put_failure: |
| @@ -10261,8 +10261,8 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy, | |||
| 10261 | genlmsg_end(msg, hdr); | 10261 | genlmsg_end(msg, hdr); |
| 10262 | 10262 | ||
| 10263 | rcu_read_lock(); | 10263 | rcu_read_lock(); |
| 10264 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 10264 | genlmsg_multicast_allns(&nl80211_fam, msg, 0, |
| 10265 | GFP_ATOMIC); | 10265 | NL80211_MCGRP_REGULATORY, GFP_ATOMIC); |
| 10266 | rcu_read_unlock(); | 10266 | rcu_read_unlock(); |
| 10267 | 10267 | ||
| 10268 | return; | 10268 | return; |
| @@ -10307,8 +10307,8 @@ static void nl80211_send_remain_on_chan_event( | |||
| 10307 | 10307 | ||
| 10308 | genlmsg_end(msg, hdr); | 10308 | genlmsg_end(msg, hdr); |
| 10309 | 10309 | ||
| 10310 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10310 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10311 | nl80211_mlme_mcgrp.id, gfp); | 10311 | NL80211_MCGRP_MLME, gfp); |
| 10312 | return; | 10312 | return; |
| 10313 | 10313 | ||
| 10314 | nla_put_failure: | 10314 | nla_put_failure: |
| @@ -10362,8 +10362,8 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, | |||
| 10362 | return; | 10362 | return; |
| 10363 | } | 10363 | } |
| 10364 | 10364 | ||
| 10365 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10365 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10366 | nl80211_mlme_mcgrp.id, gfp); | 10366 | NL80211_MCGRP_MLME, gfp); |
| 10367 | } | 10367 | } |
| 10368 | EXPORT_SYMBOL(cfg80211_new_sta); | 10368 | EXPORT_SYMBOL(cfg80211_new_sta); |
| 10369 | 10369 | ||
| @@ -10392,8 +10392,8 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) | |||
| 10392 | 10392 | ||
| 10393 | genlmsg_end(msg, hdr); | 10393 | genlmsg_end(msg, hdr); |
| 10394 | 10394 | ||
| 10395 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10395 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10396 | nl80211_mlme_mcgrp.id, gfp); | 10396 | NL80211_MCGRP_MLME, gfp); |
| 10397 | return; | 10397 | return; |
| 10398 | 10398 | ||
| 10399 | nla_put_failure: | 10399 | nla_put_failure: |
| @@ -10428,8 +10428,8 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | |||
| 10428 | 10428 | ||
| 10429 | genlmsg_end(msg, hdr); | 10429 | genlmsg_end(msg, hdr); |
| 10430 | 10430 | ||
| 10431 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10431 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10432 | nl80211_mlme_mcgrp.id, gfp); | 10432 | NL80211_MCGRP_MLME, gfp); |
| 10433 | return; | 10433 | return; |
| 10434 | 10434 | ||
| 10435 | nla_put_failure: | 10435 | nla_put_failure: |
| @@ -10590,8 +10590,8 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, | |||
| 10590 | 10590 | ||
| 10591 | genlmsg_end(msg, hdr); | 10591 | genlmsg_end(msg, hdr); |
| 10592 | 10592 | ||
| 10593 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10593 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10594 | nl80211_mlme_mcgrp.id, gfp); | 10594 | NL80211_MCGRP_MLME, gfp); |
| 10595 | return; | 10595 | return; |
| 10596 | 10596 | ||
| 10597 | nla_put_failure: | 10597 | nla_put_failure: |
| @@ -10639,8 +10639,8 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, | |||
| 10639 | 10639 | ||
| 10640 | genlmsg_end(msg, hdr); | 10640 | genlmsg_end(msg, hdr); |
| 10641 | 10641 | ||
| 10642 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10642 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10643 | nl80211_mlme_mcgrp.id, gfp); | 10643 | NL80211_MCGRP_MLME, gfp); |
| 10644 | return; | 10644 | return; |
| 10645 | 10645 | ||
| 10646 | nla_put_failure: | 10646 | nla_put_failure: |
| @@ -10684,8 +10684,8 @@ static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | |||
| 10684 | 10684 | ||
| 10685 | genlmsg_end(msg, hdr); | 10685 | genlmsg_end(msg, hdr); |
| 10686 | 10686 | ||
| 10687 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10687 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10688 | nl80211_mlme_mcgrp.id, gfp); | 10688 | NL80211_MCGRP_MLME, gfp); |
| 10689 | return; | 10689 | return; |
| 10690 | 10690 | ||
| 10691 | nla_put_failure: | 10691 | nla_put_failure: |
| @@ -10742,8 +10742,8 @@ nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | |||
| 10742 | 10742 | ||
| 10743 | genlmsg_end(msg, hdr); | 10743 | genlmsg_end(msg, hdr); |
| 10744 | 10744 | ||
| 10745 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10745 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10746 | nl80211_mlme_mcgrp.id, gfp); | 10746 | NL80211_MCGRP_MLME, gfp); |
| 10747 | return; | 10747 | return; |
| 10748 | 10748 | ||
| 10749 | nla_put_failure: | 10749 | nla_put_failure: |
| @@ -10789,8 +10789,8 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, | |||
| 10789 | 10789 | ||
| 10790 | genlmsg_end(msg, hdr); | 10790 | genlmsg_end(msg, hdr); |
| 10791 | 10791 | ||
| 10792 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10792 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10793 | nl80211_mlme_mcgrp.id, gfp); | 10793 | NL80211_MCGRP_MLME, gfp); |
| 10794 | return; | 10794 | return; |
| 10795 | 10795 | ||
| 10796 | nla_put_failure: | 10796 | nla_put_failure: |
| @@ -10866,8 +10866,8 @@ void cfg80211_cqm_txe_notify(struct net_device *dev, | |||
| 10866 | 10866 | ||
| 10867 | genlmsg_end(msg, hdr); | 10867 | genlmsg_end(msg, hdr); |
| 10868 | 10868 | ||
| 10869 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10869 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10870 | nl80211_mlme_mcgrp.id, gfp); | 10870 | NL80211_MCGRP_MLME, gfp); |
| 10871 | return; | 10871 | return; |
| 10872 | 10872 | ||
| 10873 | nla_put_failure: | 10873 | nla_put_failure: |
| @@ -10915,8 +10915,8 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev, | |||
| 10915 | 10915 | ||
| 10916 | genlmsg_end(msg, hdr); | 10916 | genlmsg_end(msg, hdr); |
| 10917 | 10917 | ||
| 10918 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10918 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10919 | nl80211_mlme_mcgrp.id, gfp); | 10919 | NL80211_MCGRP_MLME, gfp); |
| 10920 | return; | 10920 | return; |
| 10921 | 10921 | ||
| 10922 | nla_put_failure: | 10922 | nla_put_failure: |
| @@ -10962,8 +10962,8 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, | |||
| 10962 | 10962 | ||
| 10963 | genlmsg_end(msg, hdr); | 10963 | genlmsg_end(msg, hdr); |
| 10964 | 10964 | ||
| 10965 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 10965 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 10966 | nl80211_mlme_mcgrp.id, gfp); | 10966 | NL80211_MCGRP_MLME, gfp); |
| 10967 | return; | 10967 | return; |
| 10968 | 10968 | ||
| 10969 | nla_put_failure: | 10969 | nla_put_failure: |
| @@ -11002,8 +11002,8 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | |||
| 11002 | 11002 | ||
| 11003 | genlmsg_end(msg, hdr); | 11003 | genlmsg_end(msg, hdr); |
| 11004 | 11004 | ||
| 11005 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 11005 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 11006 | nl80211_mlme_mcgrp.id, gfp); | 11006 | NL80211_MCGRP_MLME, gfp); |
| 11007 | return; | 11007 | return; |
| 11008 | 11008 | ||
| 11009 | nla_put_failure: | 11009 | nla_put_failure: |
| @@ -11154,8 +11154,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
| 11154 | 11154 | ||
| 11155 | genlmsg_end(msg, hdr); | 11155 | genlmsg_end(msg, hdr); |
| 11156 | 11156 | ||
| 11157 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 11157 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 11158 | nl80211_mlme_mcgrp.id, gfp); | 11158 | NL80211_MCGRP_MLME, gfp); |
| 11159 | return; | 11159 | return; |
| 11160 | 11160 | ||
| 11161 | free_msg: | 11161 | free_msg: |
| @@ -11196,8 +11196,8 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, | |||
| 11196 | 11196 | ||
| 11197 | genlmsg_end(msg, hdr); | 11197 | genlmsg_end(msg, hdr); |
| 11198 | 11198 | ||
| 11199 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 11199 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 11200 | nl80211_mlme_mcgrp.id, gfp); | 11200 | NL80211_MCGRP_MLME, gfp); |
| 11201 | return; | 11201 | return; |
| 11202 | 11202 | ||
| 11203 | nla_put_failure: | 11203 | nla_put_failure: |
| @@ -11279,8 +11279,8 @@ void cfg80211_ft_event(struct net_device *netdev, | |||
| 11279 | 11279 | ||
| 11280 | genlmsg_end(msg, hdr); | 11280 | genlmsg_end(msg, hdr); |
| 11281 | 11281 | ||
| 11282 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 11282 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 11283 | nl80211_mlme_mcgrp.id, GFP_KERNEL); | 11283 | NL80211_MCGRP_MLME, GFP_KERNEL); |
| 11284 | } | 11284 | } |
| 11285 | EXPORT_SYMBOL(cfg80211_ft_event); | 11285 | EXPORT_SYMBOL(cfg80211_ft_event); |
| 11286 | 11286 | ||
| @@ -11329,33 +11329,11 @@ int nl80211_init(void) | |||
| 11329 | { | 11329 | { |
| 11330 | int err; | 11330 | int err; |
| 11331 | 11331 | ||
| 11332 | err = genl_register_family_with_ops(&nl80211_fam, | 11332 | err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops, |
| 11333 | nl80211_ops, ARRAY_SIZE(nl80211_ops)); | 11333 | nl80211_mcgrps); |
| 11334 | if (err) | 11334 | if (err) |
| 11335 | return err; | 11335 | return err; |
| 11336 | 11336 | ||
| 11337 | err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); | ||
| 11338 | if (err) | ||
| 11339 | goto err_out; | ||
| 11340 | |||
| 11341 | err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp); | ||
| 11342 | if (err) | ||
| 11343 | goto err_out; | ||
| 11344 | |||
| 11345 | err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp); | ||
| 11346 | if (err) | ||
| 11347 | goto err_out; | ||
| 11348 | |||
| 11349 | err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp); | ||
| 11350 | if (err) | ||
| 11351 | goto err_out; | ||
| 11352 | |||
| 11353 | #ifdef CONFIG_NL80211_TESTMODE | ||
| 11354 | err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp); | ||
| 11355 | if (err) | ||
| 11356 | goto err_out; | ||
| 11357 | #endif | ||
| 11358 | |||
| 11359 | err = netlink_register_notifier(&nl80211_netlink_notifier); | 11337 | err = netlink_register_notifier(&nl80211_netlink_notifier); |
| 11360 | if (err) | 11338 | if (err) |
| 11361 | goto err_out; | 11339 | goto err_out; |
