aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2011-05-03 19:57:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-11 14:37:47 -0400
commitb130e5cec958bae3867cf6ab09a9b24ba8fada01 (patch)
tree945eca0ace3d299dfd83de7b7e13c60aa36ba2e9
parentf3a57fd148a4afd3c38f558c5b44972cb29ea8ba (diff)
nl80211: Introduce NL80211_MESH_SETUP_USERSPACE_AMPE
Introduce a new configuration option to support AMPE from userspace. Prior to this series we only supported authentication in userspace: an authentication daemon would authenticate peer candidates in userspace and hand them over to the kernel. From that point the mesh stack would take over and establish a peer link (Mesh Peering Management). These patches introduce support for Authenticated Mesh Peering Exchange in userspace. The userspace daemon implements the AMPE protocol and on successfull completion create mesh peers and install encryption keys. Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/linux/nl80211.h10
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--net/mac80211/cfg.c6
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mesh_plink.c5
-rw-r--r--net/wireless/nl80211.c4
7 files changed, 30 insertions, 7 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index a75dea9c416e..c53b916036c5 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1769,6 +1769,15 @@ enum nl80211_meshconf_params {
1769 * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication 1769 * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication
1770 * daemon will be authenticating mesh candidates. 1770 * daemon will be authenticating mesh candidates.
1771 * 1771 *
1772 * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication
1773 * daemon will be securing peer link frames. AMPE is a secured version of Mesh
1774 * Peering Management (MPM) and is implemented with the assistance of a
1775 * userspace daemon. When this flag is set, the kernel will send peer
1776 * management frames to a userspace daemon that will implement AMPE
1777 * functionality (security capabilities selection, key confirmation, and key
1778 * management). When the flag is unset (default), the kernel can autonomously
1779 * complete (unsecured) mesh peering without the need of a userspace daemon.
1780 *
1772 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number 1781 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
1773 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use 1782 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
1774 */ 1783 */
@@ -1778,6 +1787,7 @@ enum nl80211_mesh_setup_params {
1778 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, 1787 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
1779 NL80211_MESH_SETUP_IE, 1788 NL80211_MESH_SETUP_IE,
1780 NL80211_MESH_SETUP_USERSPACE_AUTH, 1789 NL80211_MESH_SETUP_USERSPACE_AUTH,
1790 NL80211_MESH_SETUP_USERSPACE_AMPE,
1781 1791
1782 /* keep last */ 1792 /* keep last */
1783 __NL80211_MESH_SETUP_ATTR_AFTER_LAST, 1793 __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0920daf36807..10c17d68059f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -695,7 +695,8 @@ struct mesh_config {
695 * @path_metric: which metric to use 695 * @path_metric: which metric to use
696 * @ie: vendor information elements (optional) 696 * @ie: vendor information elements (optional)
697 * @ie_len: length of vendor information elements 697 * @ie_len: length of vendor information elements
698 * @is_secure: or not 698 * @is_authenticated: this mesh requires authentication
699 * @is_secure: this mesh uses security
699 * 700 *
700 * These parameters are fixed when the mesh is created. 701 * These parameters are fixed when the mesh is created.
701 */ 702 */
@@ -706,6 +707,7 @@ struct mesh_setup {
706 u8 path_metric; 707 u8 path_metric;
707 const u8 *ie; 708 const u8 *ie;
708 u8 ie_len; 709 u8 ie_len;
710 bool is_authenticated;
709 bool is_secure; 711 bool is_secure;
710}; 712};
711 713
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1ebc13383ae7..18c2555e04e6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1064,7 +1064,11 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1064 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1064 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1065 ifmsh->mesh_pp_id = setup->path_sel_proto; 1065 ifmsh->mesh_pp_id = setup->path_sel_proto;
1066 ifmsh->mesh_pm_id = setup->path_metric; 1066 ifmsh->mesh_pm_id = setup->path_metric;
1067 ifmsh->is_secure = setup->is_secure; 1067 ifmsh->security = IEEE80211_MESH_SEC_NONE;
1068 if (setup->is_authenticated)
1069 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
1070 if (setup->is_secure)
1071 ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
1068 1072
1069 return 0; 1073 return 0;
1070} 1074}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e89bc27f8dc3..7f4d0dc1d534 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -490,7 +490,11 @@ struct ieee80211_if_mesh {
490 bool accepting_plinks; 490 bool accepting_plinks;
491 const u8 *ie; 491 const u8 *ie;
492 u8 ie_len; 492 u8 ie_len;
493 bool is_secure; 493 enum {
494 IEEE80211_MESH_SEC_NONE = 0x0,
495 IEEE80211_MESH_SEC_AUTHED = 0x1,
496 IEEE80211_MESH_SEC_SECURED = 0x2,
497 } security;
494}; 498};
495 499
496#ifdef CONFIG_MAC80211_MESH 500#ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c1299e249541..2a59eb345131 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -574,7 +574,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
574 &elems); 574 &elems);
575 575
576 /* ignore beacons from secure mesh peers if our security is off */ 576 /* ignore beacons from secure mesh peers if our security is off */
577 if (elems.rsn_len && !sdata->u.mesh.is_secure) 577 if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE)
578 return; 578 return;
579 579
580 if (elems.ds_params && elems.ds_params_len == 1) 580 if (elems.ds_params && elems.ds_params_len == 1)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 84e5b056af02..87abf8deb369 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -251,7 +251,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
251 rcu_read_unlock(); 251 rcu_read_unlock();
252 /* Userspace handles peer allocation when security is enabled 252 /* Userspace handles peer allocation when security is enabled
253 * */ 253 * */
254 if (sdata->u.mesh.is_secure) 254 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, 255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
256 elems->ie_start, elems->total_len, 256 elems->ie_start, elems->total_len,
257 GFP_KERNEL); 257 GFP_KERNEL);
@@ -460,7 +460,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
460 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 460 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
461 return; 461 return;
462 } 462 }
463 if (elems.rsn_len && !sdata->u.mesh.is_secure) { 463 if (elems.rsn_len &&
464 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
464 mpl_dbg("Mesh plink: can't establish link with secure peer\n"); 465 mpl_dbg("Mesh plink: can't establish link with secure peer\n");
465 return; 466 return;
466 } 467 }
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0a199a1ca9b6..64efc2d7a7ad 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2871,6 +2871,7 @@ static const struct nla_policy
2871 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 2871 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
2872 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 2872 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
2873 .len = IEEE80211_MAX_DATA_LEN }, 2873 .len = IEEE80211_MAX_DATA_LEN },
2874 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
2874}; 2875};
2875 2876
2876static int nl80211_parse_mesh_config(struct genl_info *info, 2877static int nl80211_parse_mesh_config(struct genl_info *info,
@@ -2980,7 +2981,8 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
2980 setup->ie = nla_data(ieattr); 2981 setup->ie = nla_data(ieattr);
2981 setup->ie_len = nla_len(ieattr); 2982 setup->ie_len = nla_len(ieattr);
2982 } 2983 }
2983 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); 2984 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
2985 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
2984 2986
2985 return 0; 2987 return 0;
2986} 2988}