diff options
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; |