diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-12-03 03:20:43 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-06 16:01:29 -0500 |
commit | bd90fdcc5fbd99a2a778999610420cf793bd1be2 (patch) | |
tree | 18019688bd7edb6432f5f12ac258e6cf81ee9e61 /net/wireless | |
parent | f9e10ce4cf86945eb5efcab31284c971877ed012 (diff) |
nl80211: refactor mesh parameter parsing
I'm going to need this in a new place later.
Tested-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/nl80211.c | 61 |
1 files changed, 38 insertions, 23 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index cc2e5d6163de..c8d4d53fc450 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2613,14 +2613,6 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, | |||
2613 | return -ENOBUFS; | 2613 | return -ENOBUFS; |
2614 | } | 2614 | } |
2615 | 2615 | ||
2616 | #define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ | ||
2617 | do {\ | ||
2618 | if (table[attr_num]) {\ | ||
2619 | cfg.param = nla_fn(table[attr_num]); \ | ||
2620 | mask |= (1 << (attr_num - 1)); \ | ||
2621 | } \ | ||
2622 | } while (0);\ | ||
2623 | |||
2624 | static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { | 2616 | static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { |
2625 | [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 }, | 2617 | [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 }, |
2626 | [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 }, | 2618 | [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 }, |
@@ -2639,31 +2631,34 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A | |||
2639 | [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, | 2631 | [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, |
2640 | }; | 2632 | }; |
2641 | 2633 | ||
2642 | static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) | 2634 | static int nl80211_parse_mesh_params(struct genl_info *info, |
2635 | struct mesh_config *cfg, | ||
2636 | u32 *mask_out) | ||
2643 | { | 2637 | { |
2644 | u32 mask; | ||
2645 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
2646 | struct net_device *dev = info->user_ptr[1]; | ||
2647 | struct mesh_config cfg; | ||
2648 | struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; | 2638 | struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; |
2649 | struct nlattr *parent_attr; | 2639 | u32 mask = 0; |
2650 | 2640 | ||
2651 | parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS]; | 2641 | #define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ |
2652 | if (!parent_attr) | 2642 | do {\ |
2643 | if (table[attr_num]) {\ | ||
2644 | cfg->param = nla_fn(table[attr_num]); \ | ||
2645 | mask |= (1 << (attr_num - 1)); \ | ||
2646 | } \ | ||
2647 | } while (0);\ | ||
2648 | |||
2649 | |||
2650 | if (!info->attrs[NL80211_ATTR_MESH_PARAMS]) | ||
2653 | return -EINVAL; | 2651 | return -EINVAL; |
2654 | if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, | 2652 | if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, |
2655 | parent_attr, nl80211_meshconf_params_policy)) | 2653 | info->attrs[NL80211_ATTR_MESH_PARAMS], |
2654 | nl80211_meshconf_params_policy)) | ||
2656 | return -EINVAL; | 2655 | return -EINVAL; |
2657 | 2656 | ||
2658 | if (!rdev->ops->set_mesh_params) | ||
2659 | return -EOPNOTSUPP; | ||
2660 | |||
2661 | /* This makes sure that there aren't more than 32 mesh config | 2657 | /* This makes sure that there aren't more than 32 mesh config |
2662 | * parameters (otherwise our bitfield scheme would not work.) */ | 2658 | * parameters (otherwise our bitfield scheme would not work.) */ |
2663 | BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); | 2659 | BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); |
2664 | 2660 | ||
2665 | /* Fill in the params struct */ | 2661 | /* Fill in the params struct */ |
2666 | mask = 0; | ||
2667 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, | 2662 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, |
2668 | mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16); | 2663 | mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16); |
2669 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, | 2664 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, |
@@ -2703,12 +2698,32 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) | |||
2703 | NL80211_MESHCONF_HWMP_ROOTMODE, | 2698 | NL80211_MESHCONF_HWMP_ROOTMODE, |
2704 | nla_get_u8); | 2699 | nla_get_u8); |
2705 | 2700 | ||
2701 | if (mask_out) | ||
2702 | *mask_out = mask; | ||
2703 | return 0; | ||
2704 | |||
2705 | #undef FILL_IN_MESH_PARAM_IF_SET | ||
2706 | } | ||
2707 | |||
2708 | static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) | ||
2709 | { | ||
2710 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
2711 | struct net_device *dev = info->user_ptr[1]; | ||
2712 | struct mesh_config cfg; | ||
2713 | u32 mask; | ||
2714 | int err; | ||
2715 | |||
2716 | if (!rdev->ops->set_mesh_params) | ||
2717 | return -EOPNOTSUPP; | ||
2718 | |||
2719 | err = nl80211_parse_mesh_params(info, &cfg, &mask); | ||
2720 | if (err) | ||
2721 | return err; | ||
2722 | |||
2706 | /* Apply changes */ | 2723 | /* Apply changes */ |
2707 | return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); | 2724 | return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); |
2708 | } | 2725 | } |
2709 | 2726 | ||
2710 | #undef FILL_IN_MESH_PARAM_IF_SET | ||
2711 | |||
2712 | static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | 2727 | static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) |
2713 | { | 2728 | { |
2714 | struct sk_buff *msg; | 2729 | struct sk_buff *msg; |