Make 'ifconfig nwid' override 'ifconfig join'.
authorstsp <stsp@openbsd.org>
Sat, 1 Sep 2018 08:20:56 +0000 (08:20 +0000)
committerstsp <stsp@openbsd.org>
Sat, 1 Sep 2018 08:20:56 +0000 (08:20 +0000)
There was no way to override a decision made by join's network
selection algorithm (apart from disabling the feature by clearing
the join list). Automatic selection is based on heuristics which
cannot always guess correctly so we need to provide an override.

One specific problem was that if 'nwid foo' and 'nwid bar' were
both visible in the scan and only 'nwid foo' was a member of the
join list, then there was no way at all to connect to 'nwid bar'.
The wireless stack would keep selecting 'nwid foo' instead.

'ifconfig iwm0 nwid bar' command will now disable automatic
network selection and force the use of ESSID 'bar'.
Any of these commands will re-enable automatic network selection:
   ifconfig iwm0 -nwid
   ifconfig iwm0 nwid ''
   ifconfig iwm0 join some-network-id

ok phessler@ deraadt@

sys/net80211/ieee80211_ioctl.c
sys/net80211/ieee80211_node.c
sys/net80211/ieee80211_var.h

index 2ff4c10..f144979 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_ioctl.c,v 1.63 2018/08/06 11:42:18 benno Exp $      */
+/*     $OpenBSD: ieee80211_ioctl.c,v 1.64 2018/09/01 08:20:56 stsp Exp $       */
 /*     $NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung Exp $      */
 
 /*-
@@ -429,6 +429,13 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN);
                ic->ic_des_esslen = nwid.i_len;
                memcpy(ic->ic_des_essid, nwid.i_nwid, nwid.i_len);
+               if (ic->ic_des_esslen > 0) {
+                       /* 'nwid' disables auto-join magic */
+                       ic->ic_flags &= ~IEEE80211_F_AUTO_JOIN;
+               } else {
+                       /* '-nwid' re-enables auto-join */
+                       ic->ic_flags |= IEEE80211_F_AUTO_JOIN;
+               }
                /* disable WPA/WEP */
                ieee80211_disable_rsn(ic);
                ieee80211_disable_wep(ic);
@@ -467,8 +474,10 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                ieee80211_disable_rsn(ic);
                ieee80211_disable_wep(ic);
                /* save nwid for auto-join */
-               if (!(join.i_flags & IEEE80211_JOIN_DEL))
-                       ieee80211_add_ess(ic, 0, 0);
+               if (!(join.i_flags & IEEE80211_JOIN_DEL)) {
+                       if (ieee80211_add_ess(ic, 0, 0) == 0)
+                               ic->ic_flags |= IEEE80211_F_AUTO_JOIN;
+               }
                ieee80211_set_ess(ic, ic->ic_des_essid);
                error = ENETRESET;
                break;
@@ -483,7 +492,8 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                                join.i_len = ic->ic_bss->ni_esslen;
                                memcpy(join.i_nwid, ic->ic_bss->ni_essid,
                                    join.i_len);
-                               join.i_flags = IEEE80211_JOIN_FOUND;
+                               if (ic->ic_flags & IEEE80211_F_AUTO_JOIN)
+                                       join.i_flags = IEEE80211_JOIN_FOUND;
                                error = copyout(&join, ifr->ifr_data,
                                    sizeof(join));
                                break;
index 191fcfc..718576b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_node.c,v 1.142 2018/08/15 18:45:43 stsp Exp $       */
+/*     $OpenBSD: ieee80211_node.c,v 1.143 2018/09/01 08:20:56 stsp Exp $       */
 /*     $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $       */
 
 /*-
@@ -485,6 +485,20 @@ ieee80211_switch_ess(struct ieee80211com *ic)
                if (ess == NULL)
                        continue;
 
+               /*
+                * Operate only on ic_des_essid if auto-join is disabled.
+                * We might have a password stored for this network.
+                */
+               if (!ISSET(ic->ic_flags, IEEE80211_F_AUTO_JOIN)) {
+                       if (ic->ic_des_esslen == ess->esslen &&
+                           memcmp(ic->ic_des_essid, ess->essid,
+                           ess->esslen) == 0) {
+                               ieee80211_set_ess(ic, ess->essid);
+                               return;
+                       }
+                       continue;
+               }
+
                if (selni == NULL) {
                        seless = ess;
                        selni = ni;
index 406b160..c5a1bd3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ieee80211_var.h,v 1.87 2018/08/06 11:28:01 stsp Exp $ */
+/*     $OpenBSD: ieee80211_var.h,v 1.88 2018/09/01 08:20:56 stsp Exp $ */
 /*     $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */
 
 /*-
@@ -392,7 +392,8 @@ struct ieee80211_ess {
 #define        IEEE80211_F_HTON        0x02000000      /* CONF: HT enabled */
 #define        IEEE80211_F_PBAR        0x04000000      /* CONF: PBAC required */
 #define        IEEE80211_F_BGSCAN      0x08000000      /* STATUS: background scan */
-#define IEEE80211_F_USERMASK   0xf0000000      /* CONF: ioctl flag mask */
+#define IEEE80211_F_AUTO_JOIN  0x10000000      /* CONF: auto-join active */
+#define IEEE80211_F_USERMASK   0xe0000000      /* CONF: ioctl flag mask */
 
 /* ic_xflags */
 #define        IEEE80211_F_TX_MGMT_ONLY 0x00000001     /* leave data frames on ifq */