--- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -32,8 +32,22 @@ static int nl80211_crypto_settings(struc struct cfg80211_crypto_settings *settings, int cipher_limit); +static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); +static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + /* the netlink family */ -static struct genl_family nl80211_fam; +static struct genl_family nl80211_fam = { + .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ + .name = NL80211_GENL_NAME, /* have users key off the name instead */ + .hdrsize = 0, /* no private header */ + .version = 1, /* no particular meaning now */ + .maxattr = NL80211_ATTR_MAX, + .netnsok = true, + .pre_doit = nl80211_pre_doit, + .post_doit = nl80211_post_doit, +}; /* multicast groups */ enum nl80211_multicast_groups { @@ -549,14 +563,13 @@ static int nl80211_prepare_wdev_dump(str if (!cb->args[0]) { err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, - genl_family_attrbuf(&nl80211_fam), - nl80211_fam.maxattr, nl80211_policy); + nl80211_fam.attrbuf, nl80211_fam.maxattr, + nl80211_policy); if (err) goto out_unlock; - *wdev = __cfg80211_wdev_from_attrs( - sock_net(skb->sk), - genl_family_attrbuf(&nl80211_fam)); + *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); if (IS_ERR(*wdev)) { err = PTR_ERR(*wdev); goto out_unlock; @@ -1903,7 +1916,7 @@ static int nl80211_dump_wiphy_parse(stru struct netlink_callback *cb, struct nl80211_dump_wiphy_state *state) { - struct nlattr **tb = genl_family_attrbuf(&nl80211_fam); + struct nlattr **tb = nl80211_fam.attrbuf; int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, tb, nl80211_fam.maxattr, nl80211_policy); /* ignore parse errors for backward compatibility */ @@ -7733,7 +7746,6 @@ static int nl80211_send_survey(struct sk static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) { - struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam); struct survey_info survey; struct cfg80211_registered_device *rdev; struct wireless_dev *wdev; @@ -7746,7 +7758,7 @@ static int nl80211_dump_survey(struct sk return res; /* prepare_wdev_dump parsed the attributes */ - radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS]; + radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS]; if (!wdev->netdev) { res = -EINVAL; @@ -8594,14 +8606,14 @@ static int nl80211_testmode_dump(struct */ phy_idx = cb->args[0] - 1; } else { - struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam); - err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, - attrbuf, nl80211_fam.maxattr, nl80211_policy); + nl80211_fam.attrbuf, nl80211_fam.maxattr, + nl80211_policy); if (err) goto out_err; - rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf); + rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); if (IS_ERR(rdev)) { err = PTR_ERR(rdev); goto out_err; @@ -8609,8 +8621,9 @@ static int nl80211_testmode_dump(struct phy_idx = rdev->wiphy_idx; rdev = NULL; - if (attrbuf[NL80211_ATTR_TESTDATA]) - cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA]; + if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) + cb->args[1] = + (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; } if (cb->args[1]) { @@ -10814,7 +10827,8 @@ static int handle_nan_filter(struct nlat i = 0; nla_for_each_nested(attr, attr_filter, rem) { - filter[i].filter = nla_memdup(attr, GFP_KERNEL); + filter[i].filter = kmemdup(nla_data(attr), nla_len(attr), + GFP_KERNEL); filter[i].len = nla_len(attr); i++; } @@ -11450,7 +11464,6 @@ static int nl80211_prepare_vendor_dump(s struct cfg80211_registered_device **rdev, struct wireless_dev **wdev) { - struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam); u32 vid, subcmd; unsigned int i; int vcmd_idx = -1; @@ -11486,28 +11499,31 @@ static int nl80211_prepare_vendor_dump(s } err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, - attrbuf, nl80211_fam.maxattr, nl80211_policy); + nl80211_fam.attrbuf, nl80211_fam.maxattr, + nl80211_policy); if (err) goto out_unlock; - if (!attrbuf[NL80211_ATTR_VENDOR_ID] || - !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) { + if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] || + !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) { err = -EINVAL; goto out_unlock; } - *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf); + *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); if (IS_ERR(*wdev)) *wdev = NULL; - *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf); + *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), + nl80211_fam.attrbuf); if (IS_ERR(*rdev)) { err = PTR_ERR(*rdev); goto out_unlock; } - vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]); - subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]); + vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]); + subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]); for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) { const struct wiphy_vendor_command *vcmd; @@ -11531,9 +11547,9 @@ static int nl80211_prepare_vendor_dump(s goto out_unlock; } - if (attrbuf[NL80211_ATTR_VENDOR_DATA]) { - data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]); - data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]); + if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) { + data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]); + data_len = nla_len(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]); } /* 0 is the first index - add 1 to parse only once */ @@ -12795,21 +12811,6 @@ static __genl_const struct genl_ops nl80 }, }; -static struct genl_family nl80211_fam __ro_after_init = { - .name = NL80211_GENL_NAME, /* have users key off the name instead */ - .hdrsize = 0, /* no private header */ - .version = 1, /* no particular meaning now */ - .maxattr = NL80211_ATTR_MAX, - .netnsok = true, - .pre_doit = nl80211_pre_doit, - .post_doit = nl80211_post_doit, - .module = THIS_MODULE, - .ops = nl80211_ops, - .n_ops = ARRAY_SIZE(nl80211_ops), - .mcgrps = nl80211_mcgrps, - .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps), -}; - /* notification functions */ void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev, @@ -14759,11 +14760,12 @@ void nl80211_send_ap_stopped(struct wire /* initialisation/exit functions */ -int __init nl80211_init(void) +int nl80211_init(void) { int err; - err = genl_register_family(&nl80211_fam); + err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops, + nl80211_mcgrps); if (err) return err; --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -587,8 +587,15 @@ struct hwsim_radiotap_ack_hdr { __le16 rt_chbitmask; } __packed; -/* MAC80211_HWSIM netlink family */ -static struct genl_family hwsim_genl_family; +/* MAC80211_HWSIM netlinf family */ +static struct genl_family hwsim_genl_family = { + .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = "MAC80211_HWSIM", + .version = 1, + .maxattr = HWSIM_ATTR_MAX, + .netnsok = true, +}; enum hwsim_multicast_groups { HWSIM_MCGRP_CONFIG, @@ -3250,18 +3257,6 @@ static __genl_const struct genl_ops hwsi }, }; -static struct genl_family hwsim_genl_family __ro_after_init = { - .name = "MAC80211_HWSIM", - .version = 1, - .maxattr = HWSIM_ATTR_MAX, - .netnsok = true, - .module = THIS_MODULE, - .ops = hwsim_ops, - .n_ops = ARRAY_SIZE(hwsim_ops), - .mcgrps = hwsim_mcgrps, - .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps), -}; - static void destroy_radio(struct work_struct *work) { struct mac80211_hwsim_data *data = @@ -3309,13 +3304,15 @@ static struct notifier_block hwsim_netli .notifier_call = mac80211_hwsim_netlink_notify, }; -static int __init hwsim_init_netlink(void) +static int hwsim_init_netlink(void) { int rc; printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); - rc = genl_register_family(&hwsim_genl_family); + rc = genl_register_family_with_ops_groups(&hwsim_genl_family, + hwsim_ops, + hwsim_mcgrps); if (rc) goto failure;