nl80211: refactor mesh parameter parsing
Johannes Berg [Fri, 3 Dec 2010 08:20:43 +0000 (09:20 +0100)]
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>

net/wireless/nl80211.c

index cc2e5d6..c8d4d53 100644 (file)
@@ -2613,14 +2613,6 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
        return -ENOBUFS;
 }
 
-#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
-do {\
-       if (table[attr_num]) {\
-               cfg.param = nla_fn(table[attr_num]); \
-               mask |= (1 << (attr_num - 1)); \
-       } \
-} while (0);\
-
 static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
        [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
        [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
@@ -2639,31 +2631,34 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
        [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
 };
 
-static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
+static int nl80211_parse_mesh_params(struct genl_info *info,
+                                    struct mesh_config *cfg,
+                                    u32 *mask_out)
 {
-       u32 mask;
-       struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct net_device *dev = info->user_ptr[1];
-       struct mesh_config cfg;
        struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
-       struct nlattr *parent_attr;
+       u32 mask = 0;
 
-       parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
-       if (!parent_attr)
+#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
+do {\
+       if (table[attr_num]) {\
+               cfg->param = nla_fn(table[attr_num]); \
+               mask |= (1 << (attr_num - 1)); \
+       } \
+} while (0);\
+
+
+       if (!info->attrs[NL80211_ATTR_MESH_PARAMS])
                return -EINVAL;
        if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
-                       parent_attr, nl80211_meshconf_params_policy))
+                            info->attrs[NL80211_ATTR_MESH_PARAMS],
+                            nl80211_meshconf_params_policy))
                return -EINVAL;
 
-       if (!rdev->ops->set_mesh_params)
-               return -EOPNOTSUPP;
-
        /* This makes sure that there aren't more than 32 mesh config
         * parameters (otherwise our bitfield scheme would not work.) */
        BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
 
        /* Fill in the params struct */
-       mask = 0;
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
                        mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
        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)
                        NL80211_MESHCONF_HWMP_ROOTMODE,
                        nla_get_u8);
 
+       if (mask_out)
+               *mask_out = mask;
+       return 0;
+
+#undef FILL_IN_MESH_PARAM_IF_SET
+}
+
+static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct mesh_config cfg;
+       u32 mask;
+       int err;
+
+       if (!rdev->ops->set_mesh_params)
+               return -EOPNOTSUPP;
+
+       err = nl80211_parse_mesh_params(info, &cfg, &mask);
+       if (err)
+               return err;
+
        /* Apply changes */
        return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
 }
 
-#undef FILL_IN_MESH_PARAM_IF_SET
-
 static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
 {
        struct sk_buff *msg;