ipv4: fix redirect handling
[linux-2.6.git] / net / wireless / mesh.c
index e0b9747..5c11608 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/ieee80211.h>
 #include <net/cfg80211.h>
+#include "nl80211.h"
 #include "core.h"
 
 /* Default values, timeouts in ms */
@@ -50,17 +51,20 @@ const struct mesh_config default_mesh_config = {
        .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
 };
 
+const struct mesh_setup default_mesh_setup = {
+       .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
+       .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
+       .ie = NULL,
+       .ie_len = 0,
+       .is_secure = false,
+};
 
 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
                         struct net_device *dev,
-                        const u8 *mesh_id, u8 mesh_id_len,
+                        const struct mesh_setup *setup,
                         const struct mesh_config *conf)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
-       struct mesh_setup setup = {
-               .mesh_id = mesh_id,
-               .mesh_id_len = mesh_id_len,
-       };
        int err;
 
        BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
@@ -70,19 +74,23 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
        if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
                return -EOPNOTSUPP;
 
+       if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
+             setup->is_secure)
+               return -EOPNOTSUPP;
+
        if (wdev->mesh_id_len)
                return -EALREADY;
 
-       if (!mesh_id_len)
+       if (!setup->mesh_id_len)
                return -EINVAL;
 
        if (!rdev->ops->join_mesh)
                return -EOPNOTSUPP;
 
-       err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup);
+       err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
        if (!err) {
-               memcpy(wdev->ssid, mesh_id, mesh_id_len);
-               wdev->mesh_id_len = mesh_id_len;
+               memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
+               wdev->mesh_id_len = setup->mesh_id_len;
        }
 
        return err;
@@ -90,19 +98,32 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 
 int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
                       struct net_device *dev,
-                      const u8 *mesh_id, u8 mesh_id_len,
+                      const struct mesh_setup *setup,
                       const struct mesh_config *conf)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        int err;
 
        wdev_lock(wdev);
-       err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf);
+       err = __cfg80211_join_mesh(rdev, dev, setup, conf);
        wdev_unlock(wdev);
 
        return err;
 }
 
+void cfg80211_notify_new_peer_candidate(struct net_device *dev,
+               const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
+               return;
+
+       nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev,
+                       macaddr, ie, ie_len, gfp);
+}
+EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
+
 static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
                                 struct net_device *dev)
 {