Search Linux Wireless

Re: [PATCH/RFC] nl80211/cfg80211/mac80211: add NL80211_CMD_GET_MESH_SETUP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Bob,

On Fri, Dec 14, 2012 at 7:14 AM, Bob Copeland <me@xxxxxxxxxxxxxxx> wrote:
> Add a new netlink call to get the parameters used at join time
> for the mesh.  This provides a way for userspace to get
> some basic mesh properties that are otherwise unavailable, such
> as the meshid and (eventually) configured dtim and beacon
> values.
>
> Signed-off-by: Bob Copeland <bob@xxxxxxxxxxx>

This would be very useful, yes.  Just one minor suggestion below...

> ---
> We can currently return the config values in GET_MESH_CONFIG
> but not the fixed join-time values.
>
> My use case is to have a way to get the locally configured
> dtim and beacon interval, once Marco's patches are in
> (obviously not handled yet in this patch).  Note the local
> values might be different from peer mesh STAs' settings.
>
> Thomas suggested a general GET_MESH_SETUP would be good to
> also allow userspace to get the meshid and to know if mesh
> is running without doing a bogus SET_MESH_CONFIG.
>
> Presumably, once someone implements beacon collision avoidance,
> I'd rather have the current dtim/beacon_int values, which isn't
> really setup anymore, but maybe we don't care so much.
>
> Thoughts?
>
>  include/net/cfg80211.h       |    3 ++
>  include/uapi/linux/nl80211.h |    5 +++
>  net/mac80211/cfg.c           |   30 ++++++++++++++++
>  net/wireless/nl80211.c       |   78 ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 116 insertions(+)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 8e6a6b7..51386b8 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -1833,6 +1833,9 @@ struct cfg80211_ops {
>         int     (*update_mesh_config)(struct wiphy *wiphy,
>                                       struct net_device *dev, u32 mask,
>                                       const struct mesh_config *nconf);
> +       int     (*get_mesh_setup)(struct wiphy *wiphy,
> +                                 struct net_device *dev,
> +                                 struct mesh_setup *setup);
>         int     (*join_mesh)(struct wiphy *wiphy, struct net_device *dev,
>                              const struct mesh_config *conf,
>                              const struct mesh_setup *setup);
> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index e3e19f8..3974a92 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -586,6 +586,9 @@
>   * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
>   *     for IBSS or MESH vif.
>   *
> + * @NL80211_CMD_GET_MESH_SETUP: Retrieve mesh properties that are set at
> + *      mesh join time, for the interface identified by %NL80211_ATTR_IFINDEX.
> + *
>   * @NL80211_CMD_MAX: highest used command number
>   * @__NL80211_CMD_AFTER_LAST: internal use
>   */
> @@ -736,6 +739,8 @@ enum nl80211_commands {
>
>         NL80211_CMD_SET_MCAST_RATE,
>
> +       NL80211_CMD_GET_MESH_SETUP,
> +
>         /* add new commands above here */
>
>         /* used to define NL80211_CMD_MAX below */
> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index 5c61677..36e9c97 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -1616,6 +1616,35 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
>         return 0;
>  }
>
> +static int ieee80211_get_mesh_setup(struct wiphy *wiphy,
> +                                   struct net_device *dev,
> +                                   struct mesh_setup *setup)
> +{
> +       struct ieee80211_sub_if_data *sdata;
> +       struct ieee80211_if_mesh *ifmsh;
> +
> +       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
> +       ifmsh = &sdata->u.mesh;
> +
> +       if (!ifmsh->mesh_id_len)
> +               return -ENOLINK;
> +
> +       setup->mesh_id = ifmsh->mesh_id;
> +       setup->mesh_id_len = ifmsh->mesh_id_len;
> +       setup->sync_method = ifmsh->mesh_sp_id;
> +       setup->path_sel_proto = ifmsh->mesh_pp_id;
> +       setup->path_metric = ifmsh->mesh_pm_id;
> +       setup->is_authenticated = ifmsh->security & IEEE80211_MESH_SEC_AUTHED;
+       setup->is_authenticated = !!(ifmsh->security &
IEEE80211_MESH_SEC_AUTHED));

i.e. to force the value to be 0 or 1.

> +       setup->is_secure = ifmsh->security & IEEE80211_MESH_SEC_SECURED;
+       setup->is_secure = !!(ifmsh->security & IEEE80211_MESH_SEC_SECURED);

same.

> +       setup->ie = ifmsh->ie;
> +       setup->ie_len = ifmsh->ie_len;
> +
> +       memcpy(setup->mcast_rate, sdata->vif.bss_conf.mcast_rate,
> +               sizeof(sdata->vif.bss_conf.mcast_rate));
> +       return 0;
> +}
> +
> +
>  static int ieee80211_update_mesh_config(struct wiphy *wiphy,
>                                         struct net_device *dev, u32 mask,
>                                         const struct mesh_config *nconf)
> @@ -3206,6 +3235,7 @@ struct cfg80211_ops mac80211_config_ops = {
>         .dump_mpath = ieee80211_dump_mpath,
>         .update_mesh_config = ieee80211_update_mesh_config,
>         .get_mesh_config = ieee80211_get_mesh_config,
> +       .get_mesh_setup = ieee80211_get_mesh_setup,
>         .join_mesh = ieee80211_join_mesh,
>         .leave_mesh = ieee80211_leave_mesh,
>  #endif
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index f45706a..84a6a45 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -3921,6 +3921,76 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
>         return -ENOBUFS;
>  }
>
> +static int nl80211_get_mesh_setup(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 wireless_dev *wdev = dev->ieee80211_ptr;
> +       struct mesh_setup setup;
> +       int err = 0;
> +       void *hdr;
> +       struct nlattr *pinfoattr;
> +       struct sk_buff *msg;
> +
> +       if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
> +               return -EOPNOTSUPP;
> +
> +       if (!rdev->ops->get_mesh_setup)
> +               return -EOPNOTSUPP;
> +
> +       wdev_lock(wdev);
> +       err = rdev->ops->get_mesh_setup(&rdev->wiphy, dev, &setup);
> +       if (err)
> +               goto out;
> +
> +       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> +       if (!msg) {
> +               err = -ENOMEM;
> +               goto out;
> +       }
> +
> +       hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
> +                            NL80211_CMD_GET_MESH_SETUP);
> +       if (!hdr)
> +               goto out_err;
> +
> +       if (nla_put(msg, NL80211_ATTR_MESH_ID, setup.mesh_id_len,
> +                   setup.mesh_id))
> +               goto nla_put_failure;
> +
> +       pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP);
> +       if (!pinfoattr)
> +               goto nla_put_failure;
> +
> +       if (nla_put_u8(msg, NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC,
> +                      setup.sync_method) ||
> +           nla_put_u8(msg, NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
> +                      setup.path_sel_proto) ||
> +           nla_put_u8(msg, NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
> +                      setup.path_metric) ||
> +           (setup.is_authenticated &&
> +            nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AUTH)) ||
> +           (setup.is_secure &&
> +            nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AMPE)))
> +               goto nla_put_failure;
> +
> +       nla_nest_end(msg, pinfoattr);
> +       genlmsg_end(msg, hdr);
> +
> +       err = genlmsg_reply(msg, info);
> +       goto out;
> +
> + nla_put_failure:
> +       genlmsg_cancel(msg, hdr);
> + out_err:
> +       nlmsg_free(msg);
> +       err = -ENOBUFS;
> + out:
> +       wdev_unlock(wdev);
> +       return err;
> +}
> +
>  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 },
> @@ -7784,6 +7854,14 @@ static struct genl_ops nl80211_ops[] = {
>                 .internal_flags = NL80211_FLAG_NEED_NETDEV |
>                                   NL80211_FLAG_NEED_RTNL,
>         },
> +       {
> +               .cmd = NL80211_CMD_GET_MESH_SETUP,
> +               .doit = nl80211_get_mesh_setup,
> +               .policy = nl80211_policy,
> +               /* can be retrieved by unprivileged users */
> +               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
> +                                 NL80211_FLAG_NEED_RTNL,
> +       },
>  };
>
>  static struct genl_multicast_group nl80211_mlme_mcgrp = {
> --
> 1.7.10.4
>
> --
> Bob Copeland %% www.bobcopeland.com
> _______________________________________________
> Devel mailing list
> Devel@xxxxxxxxxxxxxxxxxxxx
> http://lists.open80211s.org/cgi-bin/mailman/listinfo/devel



-- 
Javier Cardona
cozybit Inc.
http://www.cozybit.com
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux