|
@@ -637,6 +637,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
|
|
|
[HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING },
|
|
|
[HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
|
|
|
[HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
|
|
|
+ [HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
|
|
|
};
|
|
|
|
|
|
static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
|
|
@@ -2408,6 +2409,7 @@ struct hwsim_new_radio_params {
|
|
|
bool destroy_on_close;
|
|
|
const char *hwname;
|
|
|
bool no_vif;
|
|
|
+ const u8 *perm_addr;
|
|
|
};
|
|
|
|
|
|
static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
|
|
@@ -2572,15 +2574,25 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
|
|
|
skb_queue_head_init(&data->pending);
|
|
|
|
|
|
SET_IEEE80211_DEV(hw, data->dev);
|
|
|
- eth_zero_addr(addr);
|
|
|
- addr[0] = 0x02;
|
|
|
- addr[3] = idx >> 8;
|
|
|
- addr[4] = idx;
|
|
|
- memcpy(data->addresses[0].addr, addr, ETH_ALEN);
|
|
|
- memcpy(data->addresses[1].addr, addr, ETH_ALEN);
|
|
|
- data->addresses[1].addr[0] |= 0x40;
|
|
|
- hw->wiphy->n_addresses = 2;
|
|
|
- hw->wiphy->addresses = data->addresses;
|
|
|
+ if (!param->perm_addr) {
|
|
|
+ eth_zero_addr(addr);
|
|
|
+ addr[0] = 0x02;
|
|
|
+ addr[3] = idx >> 8;
|
|
|
+ addr[4] = idx;
|
|
|
+ memcpy(data->addresses[0].addr, addr, ETH_ALEN);
|
|
|
+ /* Why need here second address ? */
|
|
|
+ data->addresses[1].addr[0] |= 0x40;
|
|
|
+ memcpy(data->addresses[1].addr, addr, ETH_ALEN);
|
|
|
+ hw->wiphy->n_addresses = 2;
|
|
|
+ hw->wiphy->addresses = data->addresses;
|
|
|
+ /* possible address clash is checked at hash table insertion */
|
|
|
+ } else {
|
|
|
+ memcpy(data->addresses[0].addr, param->perm_addr, ETH_ALEN);
|
|
|
+ /* compatibility with automatically generated mac addr */
|
|
|
+ memcpy(data->addresses[1].addr, param->perm_addr, ETH_ALEN);
|
|
|
+ hw->wiphy->n_addresses = 2;
|
|
|
+ hw->wiphy->addresses = data->addresses;
|
|
|
+ }
|
|
|
|
|
|
data->channels = param->channels;
|
|
|
data->use_chanctx = param->use_chanctx;
|
|
@@ -3210,6 +3222,19 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
|
|
|
param.regd = hwsim_world_regdom_custom[idx];
|
|
|
}
|
|
|
|
|
|
+ if (info->attrs[HWSIM_ATTR_PERM_ADDR]) {
|
|
|
+ if (!is_valid_ether_addr(
|
|
|
+ nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
|
|
|
+ GENL_SET_ERR_MSG(info,"MAC is no valid source addr");
|
|
|
+ NL_SET_BAD_ATTR(info->extack,
|
|
|
+ info->attrs[HWSIM_ATTR_PERM_ADDR]);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
|
|
|
+ }
|
|
|
+
|
|
|
ret = mac80211_hwsim_new_radio(info, ¶m);
|
|
|
kfree(hwname);
|
|
|
return ret;
|