aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h3
-rw-r--r--net/wireless/nl80211.c54
2 files changed, 57 insertions, 0 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index edd21ae6acf7..73d9390d4ddb 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -387,6 +387,8 @@
387 * of any other interfaces, and other interfaces will again take 387 * of any other interfaces, and other interfaces will again take
388 * precedence when they are used. 388 * precedence when they are used.
389 * 389 *
390 * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
391 *
390 * @NL80211_CMD_MAX: highest used command number 392 * @NL80211_CMD_MAX: highest used command number
391 * @__NL80211_CMD_AFTER_LAST: internal use 393 * @__NL80211_CMD_AFTER_LAST: internal use
392 */ 394 */
@@ -489,6 +491,7 @@ enum nl80211_commands {
489 NL80211_CMD_NOTIFY_CQM, 491 NL80211_CMD_NOTIFY_CQM,
490 492
491 NL80211_CMD_SET_CHANNEL, 493 NL80211_CMD_SET_CHANNEL,
494 NL80211_CMD_SET_WDS_PEER,
492 495
493 /* add new commands above here */ 496 /* add new commands above here */
494 497
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 21061ccee557..fd92b6b7ff04 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -603,6 +603,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
603 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); 603 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
604 } 604 }
605 CMD(set_channel, SET_CHANNEL); 605 CMD(set_channel, SET_CHANNEL);
606 CMD(set_wds_peer, SET_WDS_PEER);
606 607
607#undef CMD 608#undef CMD
608 609
@@ -833,6 +834,53 @@ static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
833 return result; 834 return result;
834} 835}
835 836
837static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
838{
839 struct cfg80211_registered_device *rdev;
840 struct wireless_dev *wdev;
841 struct net_device *dev;
842 u8 *bssid;
843 int err;
844
845 if (!info->attrs[NL80211_ATTR_MAC])
846 return -EINVAL;
847
848 rtnl_lock();
849
850 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
851 if (err)
852 goto unlock_rtnl;
853
854 wdev = dev->ieee80211_ptr;
855
856 if (netif_running(dev)) {
857 err = -EBUSY;
858 goto out;
859 }
860
861 if (!rdev->ops->set_wds_peer) {
862 err = -EOPNOTSUPP;
863 goto out;
864 }
865
866 if (wdev->iftype != NL80211_IFTYPE_WDS) {
867 err = -EOPNOTSUPP;
868 goto out;
869 }
870
871 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
872 err = rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid);
873
874out:
875 cfg80211_unlock_rdev(rdev);
876 dev_put(dev);
877unlock_rtnl:
878 rtnl_unlock();
879
880 return err;
881}
882
883
836static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) 884static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
837{ 885{
838 struct cfg80211_registered_device *rdev; 886 struct cfg80211_registered_device *rdev;
@@ -5473,6 +5521,12 @@ static struct genl_ops nl80211_ops[] = {
5473 .policy = nl80211_policy, 5521 .policy = nl80211_policy,
5474 .flags = GENL_ADMIN_PERM, 5522 .flags = GENL_ADMIN_PERM,
5475 }, 5523 },
5524 {
5525 .cmd = NL80211_CMD_SET_WDS_PEER,
5526 .doit = nl80211_set_wds_peer,
5527 .policy = nl80211_policy,
5528 .flags = GENL_ADMIN_PERM,
5529 },
5476}; 5530};
5477 5531
5478static struct genl_multicast_group nl80211_mlme_mcgrp = { 5532static struct genl_multicast_group nl80211_mlme_mcgrp = {