diff options
author | Javier Cardona <javier@cozybit.com> | 2010-12-16 20:37:49 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-20 14:46:57 -0500 |
commit | c80d545da3f7c0e534ccd4a780f322f80a92cff1 (patch) | |
tree | edd5c51676b4677fc1a0b2fc692ffe97df863f25 /net/mac80211/cfg.c | |
parent | 24bdd9f4c9af75b33b438d60381a67626de0128d (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.c | 39 |
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 | ||
1003 | static 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 | |||
1003 | static int ieee80211_update_mesh_config(struct wiphy *wiphy, | 1033 | static 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; |