aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2010-12-16 20:37:49 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-20 14:46:57 -0500
commitc80d545da3f7c0e534ccd4a780f322f80a92cff1 (patch)
treeedd5c51676b4677fc1a0b2fc692ffe97df863f25 /net/mac80211/cfg.c
parent24bdd9f4c9af75b33b438d60381a67626de0128d (diff)
mac80211: Let userspace enable and configure vendor specific path selection.
Userspace will now be allowed to toggle between the default path selection algorithm (HWMP, implemented in the kernel), and a vendor specific alternative. Also in the same patch, allow userspace to add information elements to mesh beacons. This is accordance with the Extensible Path Selection Framework specified in version 7.0 of the 802.11s draft. Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1c94a2ae22ee..ae2c7127a8aa 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1000,6 +1000,36 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
1000 return (mask >> (parm-1)) & 0x1; 1000 return (mask >> (parm-1)) & 0x1;
1001} 1001}
1002 1002
1003static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1004 const struct mesh_setup *setup)
1005{
1006 u8 *new_ie;
1007 const u8 *old_ie;
1008
1009 /* first allocate the new vendor information element */
1010 new_ie = NULL;
1011 old_ie = ifmsh->vendor_ie;
1012
1013 ifmsh->vendor_ie_len = setup->vendor_ie_len;
1014 if (setup->vendor_ie_len) {
1015 new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
1016 GFP_KERNEL);
1017 if (!new_ie)
1018 return -ENOMEM;
1019 }
1020
1021 /* now copy the rest of the setup parameters */
1022 ifmsh->mesh_id_len = setup->mesh_id_len;
1023 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1024 ifmsh->mesh_pp_id = setup->path_sel_proto;
1025 ifmsh->mesh_pm_id = setup->path_metric;
1026 ifmsh->vendor_ie = new_ie;
1027
1028 kfree(old_ie);
1029
1030 return 0;
1031}
1032
1003static int ieee80211_update_mesh_config(struct wiphy *wiphy, 1033static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1004 struct net_device *dev, u32 mask, 1034 struct net_device *dev, u32 mask,
1005 const struct mesh_config *nconf) 1035 const struct mesh_config *nconf)
@@ -1059,11 +1089,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1059{ 1089{
1060 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1090 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1061 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1091 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1092 int err;
1062 1093
1063 memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config)); 1094 memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
1064 ifmsh->mesh_id_len = setup->mesh_id_len; 1095 err = copy_mesh_setup(ifmsh, setup);
1065 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1096 if (err)
1066 1097 return err;
1067 ieee80211_start_mesh(sdata); 1098 ieee80211_start_mesh(sdata);
1068 1099
1069 return 0; 1100 return 0;