]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Add support for cross connection
authorJouni Malinen <jouni.malinen@atheros.com>
Sat, 10 Jul 2010 17:19:34 +0000 (10:19 -0700)
committerJouni Malinen <j@w1.fi>
Thu, 9 Sep 2010 14:17:20 +0000 (07:17 -0700)
If enabled, cross connection allows GO to forward IPv4 packets
using masquerading NAT from the P2P clients in the group to an
uplink WLAN connection. This is disabled by default and can be
enabled with "wpa_cli p2p_set cross_connect 1" on the P2P device
interface.

15 files changed:
src/common/wpa_ctrl.h
src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_go_neg.c
src/p2p/p2p_group.c
src/p2p/p2p_i.h
src/p2p/p2p_parse.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/examples/p2p-action.sh
wpa_supplicant/notify.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_cli.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 88412ba7164e382c73e02bba434ce76f4a8d37bd..b70cf7a378ecb41e8c7252e3140c1e9d4147b829 100644 (file)
@@ -101,6 +101,8 @@ extern "C" {
 #define P2P_EVENT_GROUP_FORMATION_FAILURE "P2P-GROUP-FORMATION-FAILURE "
 #define P2P_EVENT_GROUP_STARTED "P2P-GROUP-STARTED "
 #define P2P_EVENT_GROUP_REMOVED "P2P-GROUP-REMOVED "
+#define P2P_EVENT_CROSS_CONNECT_ENABLE "P2P-CROSS-CONNECT-ENABLE "
+#define P2P_EVENT_CROSS_CONNECT_DISABLE "P2P-CROSS-CONNECT-DISABLE "
 /* parameters: <peer address> <PIN> */
 #define P2P_EVENT_PROV_DISC_SHOW_PIN "P2P-PROV-DISC-SHOW-PIN "
 /* parameters: <peer address> */
index 9fc6abff62b7094083dc27c5ef8b6de984fef41b..86261cac22317a175d007fa8ae529827fb8f7f98 100644 (file)
@@ -1612,6 +1612,7 @@ static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid,
        u8 *lpos;
        size_t tmplen;
        int res;
+       u8 group_capab;
 
        if (p2p_ie == NULL)
                return 0; /* WLAN AP is not a P2P manager */
@@ -1627,7 +1628,15 @@ static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid,
                return -1;
 
        lpos = p2p_buf_add_ie_hdr(tmp);
-       p2p_buf_add_capability(tmp, p2p->dev_capab, 0);
+       group_capab = 0;
+       if (p2p->num_groups > 0) {
+               group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER;
+               if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
+                   (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) &&
+                   p2p->cross_connect)
+                       group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
+       }
+       p2p_buf_add_capability(tmp, p2p->dev_capab, group_capab);
        if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
            (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED))
                p2p_buf_add_p2p_interface(tmp, p2p);
@@ -2960,3 +2969,14 @@ void p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr)
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Enable peer "
                        "filter for " MACSTR, MAC2STR(p2p->peer_filter));
 }
+
+
+void p2p_set_cross_connect(struct p2p_data *p2p, int enabled)
+{
+       wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cross connection %s",
+               enabled ? "enabled" : "disabled");
+       if (p2p->cross_connect == enabled)
+               return;
+       p2p->cross_connect = enabled;
+       /* TODO: may need to tear down any action group where we are GO(?) */
+}
index e108172a09aa6f7fd9b92d196e7cd86bc3eaabac..8be8aead49bd411157e1460bc4c1bc344f88cb7c 100644 (file)
@@ -1170,6 +1170,13 @@ int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params);
  */
 u8 p2p_get_group_capab(const struct wpabuf *p2p_ie);
 
+/**
+ * p2p_get_cross_connect_disallowed - Does WLAN AP disallows cross connection
+ * @p2p_ie: P2P IE(s) contents
+ * Returns: 0 if cross connection is allow, 1 if not
+ */
+int p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie);
+
 /**
  * p2p_get_go_dev_addr - Get P2P Device Address from P2P IE data
  * @p2p_ie: P2P IE(s) contents
@@ -1216,4 +1223,11 @@ int p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr,
 
 void p2p_set_peer_filter(struct p2p_data *p2p, const u8 *addr);
 
+/**
+ * p2p_set_cross_connect - Set cross connection capability
+ * @p2p: P2P module context from p2p_init()
+ * @enabled: Whether cross connection will be enabled
+ */
+void p2p_set_cross_connect(struct p2p_data *p2p, int enabled);
+
 #endif /* P2P_H */
index 4686007db5a6a3d97825d8a1d20c114381a0dc09..227b47c801310fc4c7db6229e89f9687dc01616c 100644 (file)
@@ -158,6 +158,8 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
        group_capab = 0;
        if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP)
                group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
+       if (p2p->cross_connect)
+               group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
        p2p_buf_add_capability(buf, p2p->dev_capab, group_capab);
        p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) |
                              p2p->next_tie_breaker);
@@ -242,8 +244,12 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
        len = p2p_buf_add_ie_hdr(buf);
        p2p_buf_add_status(buf, status);
        group_capab = 0;
-       if (peer && (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP))
-               group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
+       if (peer && peer->go_state == LOCAL_GO) {
+               if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP)
+                       group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
+               if (p2p->cross_connect)
+                       group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
+       }
        p2p_buf_add_capability(buf, p2p->dev_capab, group_capab);
        p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
        p2p_buf_add_config_timeout(buf, 100, 20);
@@ -631,8 +637,12 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p,
        len = p2p_buf_add_ie_hdr(buf);
        p2p_buf_add_status(buf, status);
        group_capab = 0;
-       if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP)
-               group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
+       if (peer->go_state == LOCAL_GO) {
+               if (peer->flags & P2P_DEV_PREFER_PERSISTENT_GROUP)
+                       group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
+               if (p2p->cross_connect)
+                       group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
+       }
        p2p_buf_add_capability(buf, p2p->dev_capab, group_capab);
        if (go || resp_chan == NULL)
                p2p_buf_add_operating_channel(buf, p2p->cfg->country,
index dd938d6ede55d836dfe73a32470dcbb5a5616359..17837cbae9886eed1ef32bc6b04062ce6c9e2c79 100644 (file)
@@ -145,6 +145,8 @@ static void p2p_group_add_common_ies(struct p2p_group *group,
        group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
        if (group->group_formation)
                group_capab |= P2P_GROUP_CAPAB_GROUP_FORMATION;
+       if (group->p2p->cross_connect)
+               group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
        p2p_buf_add_capability(ie, dev_capab, group_capab);
 }
 
index 5c9d0ebdadeab07d24299e76926daca3680024a3..f349bc7b699ce80c38d22bd668ec248c12f888bd 100644 (file)
@@ -365,6 +365,8 @@ struct p2p_data {
        unsigned int ext_listen_interval_usec;
 
        u8 peer_filter[ETH_ALEN];
+
+       int cross_connect;
 };
 
 /**
index 07b9b51d7b1809b97c1a35d066596ac9a07fbc12..b82848e49023eb9407a01826c9ef01aef42ed909 100644 (file)
@@ -650,6 +650,21 @@ int p2p_attr_text(struct wpabuf *data, char *buf, char *end)
 }
 
 
+int p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie)
+{
+       struct p2p_message msg;
+
+       os_memset(&msg, 0, sizeof(msg));
+       if (p2p_parse_p2p_ie(p2p_ie, &msg))
+               return 0;
+
+       if (!msg.manageability)
+               return 0;
+
+       return !(msg.capability[0] & P2P_MAN_CROSS_CONNECTIION_PERMITTED);
+}
+
+
 u8 p2p_get_group_capab(const struct wpabuf *p2p_ie)
 {
        struct p2p_message msg;
index 83557574773a9e8a1bc9d12ea1a933990a993447..739b9e903db09566efdfdd8022af33f41d389871 100644 (file)
@@ -2476,6 +2476,9 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
                return 0;
        }
 
+       if (os_strcmp(cmd, "cross_connect") == 0)
+               return wpas_p2p_set_cross_connect(wpa_s, atoi(param));
+
        wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
                   cmd);
 
index ee645cb4efba15202931c029d99ef4ae9ce026bf..38fd8d65d9c6e983f6fe3f9aea5244296f2ffda2 100755 (executable)
@@ -54,3 +54,24 @@ if [ "$CMD" = "P2P-GROUP-REMOVED" ]; then
        ifconfig $GIFNAME 0.0.0.0
     fi
 fi
+
+if [ "$CMD" = "P2P-CROSS-CONNECT-ENABLE" ]; then
+    GIFNAME=$3
+    UPLINK=$4
+    # enable NAT/masquarade $GIFNAME -> $UPLINK
+    iptables -P FORWARD DROP
+    iptables -t nat -A POSTROUTING -o $UPLINK -j MASQUERADE
+    iptables -A FORWARD -i $UPLINK -o $GIFNAME -m state --state RELATED,ESTABLISHED -j ACCEPT
+    iptables -A FORWARD -i $GIFNAME -o $UPLINK -j ACCEPT
+    sysctl net.ipv4.ip_forward=1
+fi
+
+if [ "$CMD" = "P2P-CROSS-CONNECT-DISABLE" ]; then
+    GIFNAME=$3
+    UPLINK=$4
+    # disable NAT/masquarade $GIFNAME -> $UPLINK
+    sysctl net.ipv4.ip_forward=0
+    iptables -t nat -D POSTROUTING -o $UPLINK -j MASQUERADE
+    iptables -D FORWARD -i $UPLINK -o $GIFNAME -m state --state RELATED,ESTABLISHED -j ACCEPT
+    iptables -D FORWARD -i $GIFNAME -o $UPLINK -j ACCEPT
+fi
index ac65b4f0defd35cf3a3fc4137367de5ecc032c46..c9a1b4b1b4c8d89f14bdd8d66a47fb7706e72121 100644 (file)
@@ -24,6 +24,7 @@
 #include "dbus/dbus_new.h"
 #include "driver_i.h"
 #include "scan.h"
+#include "p2p_supplicant.h"
 #include "notify.h"
 
 int wpas_notify_supplicant_initialized(struct wpa_global *global)
@@ -81,6 +82,13 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
 
        /* notify the new DBus API */
        wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
+
+#ifdef CONFIG_P2P
+       if (new_state == WPA_COMPLETED)
+               wpas_p2p_notif_connected(wpa_s);
+       else if (new_state < WPA_ASSOCIATED)
+               wpas_p2p_notif_disconnected(wpa_s);
+#endif /* CONFIG_P2P */
 }
 
 
index b25765432178329aa5cd109c833daffc84ab0a3e..cbe1c4f2648d6084d08e9448410387f3c53da41c 100644 (file)
@@ -45,6 +45,7 @@ static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
 static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
                         const u8 *dev_addr, enum p2p_wps_method wps_method);
 static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s);
+static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
 
 
 static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
@@ -201,6 +202,12 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
                gtype = "client";
        } else
                gtype = "GO";
+       if (wpa_s->cross_connect_in_use) {
+               wpa_s->cross_connect_in_use = 0;
+               wpa_msg(wpa_s->parent, MSG_INFO,
+                       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
+                       wpa_s->ifname, wpa_s->cross_connect_uplink);
+       }
        wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_REMOVED "%s %s",
                wpa_s->ifname, gtype);
        if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
@@ -441,6 +448,7 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
                        "%s GO ssid=\"%s\" psk=%s go_dev_addr=" MACSTR "%s",
                        wpa_s->ifname, ssid_txt, psk, MAC2STR(go_dev_addr),
                        persistent ? " [PERSISTENT]" : "");
+               wpas_p2p_cross_connect_setup(wpa_s);
        } else {
                wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
                        "%s GO ssid=\"%s\" passphrase=\"%s\" go_dev_addr="
@@ -449,6 +457,7 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
                        ssid && ssid->passphrase ? ssid->passphrase : "",
                        MAC2STR(go_dev_addr),
                        persistent ? " [PERSISTENT]" : "");
+               wpas_p2p_cross_connect_setup(wpa_s);
        }
 
        if (persistent)
@@ -717,6 +726,7 @@ static void p2p_go_configured(void *ctx, void *data)
                        wpas_p2p_store_persistent_group(
                                wpa_s->parent, ssid,
                                wpa_s->parent->own_addr);
+               wpas_p2p_cross_connect_setup(wpa_s);
                return;
        }
 
@@ -3307,3 +3317,135 @@ int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
        return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
                                   duration);
 }
+
+
+int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
+{
+       if (wpa_s->global->p2p_disabled)
+               return -1;
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
+               return -1;
+
+       wpa_s->global->cross_connection = enabled;
+       p2p_set_cross_connect(wpa_s->global->p2p, enabled);
+
+       if (!enabled) {
+               struct wpa_supplicant *iface;
+
+               for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
+               {
+                       if (iface->cross_connect_enabled == 0)
+                               continue;
+
+                       iface->cross_connect_enabled = 0;
+                       iface->cross_connect_in_use = 0;
+                       wpa_msg(iface->parent, MSG_INFO,
+                               P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
+                               iface->ifname, iface->cross_connect_uplink);
+               }
+       }
+
+       return 0;
+}
+
+
+static void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink)
+{
+       struct wpa_supplicant *iface;
+
+       if (!uplink->global->cross_connection)
+               return;
+
+       for (iface = uplink->global->ifaces; iface; iface = iface->next) {
+               if (!iface->cross_connect_enabled)
+                       continue;
+               if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
+                   0)
+                       continue;
+               if (iface->ap_iface == NULL)
+                       continue;
+               if (iface->cross_connect_in_use)
+                       continue;
+
+               iface->cross_connect_in_use = 1;
+               wpa_msg(iface->parent, MSG_INFO,
+                       P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
+                       iface->ifname, iface->cross_connect_uplink);
+       }
+}
+
+
+static void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink)
+{
+       struct wpa_supplicant *iface;
+
+       for (iface = uplink->global->ifaces; iface; iface = iface->next) {
+               if (!iface->cross_connect_enabled)
+                       continue;
+               if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
+                   0)
+                       continue;
+               if (!iface->cross_connect_in_use)
+                       continue;
+
+               wpa_msg(iface->parent, MSG_INFO,
+                       P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
+                       iface->ifname, iface->cross_connect_uplink);
+               iface->cross_connect_in_use = 0;
+       }
+}
+
+
+void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
+{
+       if (wpa_s->ap_iface || wpa_s->current_ssid == NULL ||
+           wpa_s->current_ssid->mode != WPAS_MODE_INFRA ||
+           wpa_s->cross_connect_disallowed)
+               wpas_p2p_disable_cross_connect(wpa_s);
+       else
+               wpas_p2p_enable_cross_connect(wpa_s);
+}
+
+
+void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
+{
+       wpas_p2p_disable_cross_connect(wpa_s);
+}
+
+
+static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s)
+{
+       struct wpa_supplicant *iface;
+
+       if (!wpa_s->global->cross_connection)
+               return;
+
+       for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+               if (iface == wpa_s)
+                       continue;
+               if (iface->drv_flags &
+                   WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)
+                       continue;
+               if (iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)
+                       continue;
+
+               wpa_s->cross_connect_enabled = 1;
+               os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname,
+                          sizeof(wpa_s->cross_connect_uplink));
+               wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from "
+                          "%s to %s whenever uplink is available",
+                          wpa_s->ifname, wpa_s->cross_connect_uplink);
+
+               if (iface->ap_iface || iface->current_ssid == NULL ||
+                   iface->current_ssid->mode != WPAS_MODE_INFRA ||
+                   iface->cross_connect_disallowed ||
+                   iface->wpa_state != WPA_COMPLETED)
+                       break;
+
+               wpa_s->cross_connect_in_use = 1;
+               wpa_msg(wpa_s->parent, MSG_INFO,
+                       P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
+                       wpa_s->ifname, wpa_s->cross_connect_uplink);
+               break;
+       }
+}
index e1578fca9074efd48a977a38e83c880b25d54275..11674e0dbcf7cb62d842c4f815f8da8fa00c8772 100644 (file)
@@ -108,5 +108,8 @@ void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
 void wpas_p2p_update_config(struct wpa_supplicant *wpa_s);
 int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
                     int duration);
+int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled);
+void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s);
+void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s);
 
 #endif /* P2P_SUPPLICANT_H */
index d062fab1d65099cb9629fb167d7189ad29366776..af6377783f2671f1823d4d2a5a1aaa832e8943ac 100644 (file)
@@ -2548,6 +2548,10 @@ static void wpa_cli_action_process(const char *msg)
                wpa_cli_exec(action_file, ctrl_ifname, pos);
        } else if (str_match(pos, P2P_EVENT_GROUP_REMOVED)) {
                wpa_cli_exec(action_file, ctrl_ifname, pos);
+       } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_ENABLE)) {
+               wpa_cli_exec(action_file, ctrl_ifname, pos);
+       } else if (str_match(pos, P2P_EVENT_CROSS_CONNECT_DISABLE)) {
+               wpa_cli_exec(action_file, ctrl_ifname, pos);
        } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
                printf("wpa_supplicant is terminating - stop monitoring\n");
                wpa_cli_quit = 1;
index 177fe5bb5eea0c14ac496bedbec1ca5f0e4b555c..8536b455870231cf96da4d8abc85c68be0a73c64 100644 (file)
@@ -36,6 +36,7 @@
 #include "common/wpa_ctrl.h"
 #include "mlme.h"
 #include "common/ieee802_11_defs.h"
+#include "p2p/p2p.h"
 #include "blacklist.h"
 #include "wpas_glue.h"
 #include "wps_supplicant.h"
@@ -1169,6 +1170,21 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                if (res >= 0)
                        wpa_ie_len += res;
        }
+
+       wpa_s->cross_connect_disallowed = 0;
+       if (bss) {
+               struct wpabuf *p2p;
+               p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
+               if (p2p) {
+                       wpa_s->cross_connect_disallowed =
+                               p2p_get_cross_connect_disallowed(p2p);
+                       wpabuf_free(p2p);
+                       wpa_printf(MSG_DEBUG, "P2P: WLAN AP %s cross "
+                                  "connection",
+                                  wpa_s->cross_connect_disallowed ?
+                                  "disallows" : "allows");
+               }
+       }
 #endif /* CONFIG_P2P */
 
        wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
index 534ce942ebb0e5eaae122109b89131242dbb239b..fb1b955fff83a1a8b33a8e28268628ad3d3f7a1a 100644 (file)
@@ -214,6 +214,7 @@ struct wpa_global {
        struct dl_list p2p_srv_bonjour; /* struct p2p_srv_bonjour */
        struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
        int p2p_disabled;
+       int cross_connection;
 };
 
 
@@ -486,6 +487,27 @@ struct wpa_supplicant {
        int pending_join_wps_method;
        unsigned int roc_waiting_drv_freq;
        int force_long_sd;
+
+       /*
+        * Whether cross connection is disallowed by the AP to which this
+        * interface is associated (only valid if there is an association).
+        */
+       int cross_connect_disallowed;
+
+       /*
+        * Whether this P2P group is configured to use cross connection (only
+        * valid if this is P2P GO interface). The actual cross connect packet
+        * forwarding may not be configured depending on the uplink status.
+        */
+       int cross_connect_enabled;
+
+       /* Whether cross connection forwarding is in use at the moment. */
+       int cross_connect_in_use;
+
+       /*
+        * Uplink interface name for cross connection
+        */
+       char cross_connect_uplink[100];
 #endif /* CONFIG_P2P */
 
        struct wpa_ssid *bgscan_ssid;