cfg80211/nl80211: Add userspace authentication flag to mesh setup
Javier Cardona [Thu, 7 Apr 2011 22:08:28 +0000 (15:08 -0700)]
During mesh setup, use NL80211_MESH_SETUP_USERSPACE_AUTH flag to create
a secure mesh and route management frames to userspace.

Also, NL80211_CMD_GET_WIPHY now returns a flag NL80211_SUPPORT_MESH_AUTH
if the wiphy's mesh implementation supports routing of mesh auth frames
to userspace.  This is useful for forward compatibility between old
kernels and new userspace tools.

Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

include/linux/nl80211.h
include/net/cfg80211.h
net/wireless/mesh.c
net/wireless/nl80211.c

index ecf6b68..0e652d8 100644 (file)
@@ -887,6 +887,9 @@ enum nl80211_commands {
  *     changed once the mesh is active.
  * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute
  *     containing attributes from &enum nl80211_meshconf_params.
+ * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver
+ *     allows auth frames in a mesh to be passed to userspace for processing via
+ *     the @NL80211_MESH_SETUP_USERSPACE_AUTH flag.
  *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1075,6 +1078,8 @@ enum nl80211_attrs {
        NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
        NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
 
+       NL80211_ATTR_SUPPORT_MESH_AUTH,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -1724,6 +1729,9 @@ enum nl80211_meshconf_params {
  * robust security network ie, or a vendor specific information element that
  * vendors will use to identify the path selection methods and metrics in use.
  *
+ * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication
+ * daemon will be authenticating mesh candidates.
+ *
  * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
  * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
  */
@@ -1732,6 +1740,7 @@ enum nl80211_mesh_setup_params {
        NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
        NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
        NL80211_MESH_SETUP_IE,
+       NL80211_MESH_SETUP_USERSPACE_AUTH,
 
        /* keep last */
        __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
index 1d02ddf..e77603b 100644 (file)
@@ -691,6 +691,7 @@ struct mesh_config {
  * @path_metric: which metric to use
  * @ie: vendor information elements (optional)
  * @ie_len: length of vendor information elements
+ * @is_secure: or not
  *
  * These parameters are fixed when the mesh is created.
  */
@@ -701,6 +702,7 @@ struct mesh_setup {
        u8  path_metric;
        const u8 *ie;
        u8 ie_len;
+       bool is_secure;
 };
 
 /**
@@ -1451,6 +1453,8 @@ struct cfg80211_ops {
  * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
  * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
  *     unicast and multicast TX keys.
+ * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing
+ *     auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH.
  */
 enum wiphy_flags {
        WIPHY_FLAG_CUSTOM_REGULATORY            = BIT(0),
@@ -1463,6 +1467,7 @@ enum wiphy_flags {
        WIPHY_FLAG_CONTROL_PORT_PROTOCOL        = BIT(7),
        WIPHY_FLAG_IBSS_RSN                     = BIT(8),
        WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
+       WIPHY_FLAG_MESH_AUTH                    = BIT(10),
 };
 
 struct mac_address {
index 0d4b226..0e5c122 100644 (file)
@@ -72,6 +72,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
        if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
                return -EOPNOTSUPP;
 
+       if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
+             setup->is_secure)
+               return -EOPNOTSUPP;
+
        if (wdev->mesh_id_len)
                return -EALREADY;
 
index ccd825a..cbedfc2 100644 (file)
@@ -124,6 +124,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
 
        [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
+       [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
 
        [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
                                         .len = NL80211_HT_CAPABILITY_LEN },
@@ -594,6 +595,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 
        if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
                NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
+       if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
 
        NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
                sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -2823,6 +2826,7 @@ static const struct nla_policy
        nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
        [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
        [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
+       [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
        [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
                .len = IEEE80211_MAX_DATA_LEN },
 };
@@ -2934,6 +2938,7 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
                setup->ie = nla_data(ieattr);
                setup->ie_len = nla_len(ieattr);
        }
+       setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
 
        return 0;
 }