[pkg-wpa-devel] Fwd: PATCH RFC: wpa_supplicant influencing device
operstate
Reinhard Tartler
siretart at tauware.de
Fri Mar 10 20:40:34 UTC 2006
FYI: I found this email from the hostap mailing list very interesting. I
think this is great news and a step in the right direction to modern
networking configuration!
regards,
Reinhard
From: Stefan Rompf <stefan at loplof.de>
Newsgroups: gmane.linux.drivers.hostap
Subject: PATCH RFC: wpa_supplicant influencing device operstate
Date: Sat, 4 Mar 2006 00:04:54 +0100
--Boundary-00=_XuMCExQpBMlTz0O
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Hi,
some weeks ago, there has been a quite heated discussion on linux-netdev about
extending functionality of netif_carrier_on()/off(). In the end, a patch
written by me has been applied for 2.6.17. For an overview, see the
documentation at http://www.flamewarmaster.de/software/operstates.txt . The
patch itself (applies to 2.6.14+) can be found on this site too. Main point
concerning this list is that it allows an userspace supplicant to signal the
kernel when the interface is ready for user traffic after authentication, and
afterwards, kernel notifies other programs via the existing IFF_RUNNING
interface.
The quagga routing daemon, vrrpd and my new dhcp client
(http://www.flamewarmaster.de/software/dhcpclient/) can act on these
messages.
I have attached a patch against wpa_supplicant 0.5.1 to this mail that
implements signalling functionality in the WEXT driver. Note that I haven't
tested how this affects drivers that rely on WEXT functionality - this is a
very first version.
With this extension, I can start wpa_supplicant and my DHCP client in
parallel. Whenever the supplicant has completed association, and WPA
authentication if needed, the DHCP client will automatically update the
interface IP configuration. Together with a graphical wpa_cli (will try
wpa_gui), this increases usability of wireless LANs a lot. In the long run,
I'd like this feature to be added to wpa_supplicant.
Thoughts?
Stefan
--Boundary-00=_XuMCExQpBMlTz0O
Content-Type: text/x-diff;
charset="us-ascii";
name="wpa_supplicant.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="wpa_supplicant.diff"
diff -x '*.o' -x '*.d' -x '*~' -x wpa_cli -x wpa_passphrase -x wpa_supplicant -upr wpa_supplicant-0.5.1.orig/driver.h wpa_supplicant-0.5.1/driver.h
--- wpa_supplicant-0.5.1.orig/driver.h 2005-10-15 17:36:32.000000000 +0200
+++ wpa_supplicant-0.5.1/driver.h 2006-03-03 20:03:44.000000000 +0100
@@ -554,6 +554,13 @@ struct wpa_driver_ops {
*/
int (*send_eapol)(void *priv, const u8 *dest, u16 proto,
const u8 *data, size_t data_len);
+
+ /**
+ * set_operstate - Sets device operating state to DORMANT or UP
+ * @priv: private driver interface data
+ * @state: 0 = dormant, 1 = up
+ */
+ void (*set_operstate)(void *priv, int state);
};
#endif /* DRIVER_H */
diff -x '*.o' -x '*.d' -x '*~' -x wpa_cli -x wpa_passphrase -x wpa_supplicant -upr wpa_supplicant-0.5.1.orig/driver_wext.c wpa_supplicant-0.5.1/driver_wext.c
--- wpa_supplicant-0.5.1.orig/driver_wext.c 2006-01-30 05:11:48.000000000 +0100
+++ wpa_supplicant-0.5.1/driver_wext.c 2006-03-03 23:48:09.000000000 +0100
@@ -47,11 +47,14 @@ struct wpa_driver_wext_data {
struct wpa_driver_capa capa;
int has_capability;
int we_version_compiled;
+ int operstate;
};
static int wpa_driver_wext_flush_pmkid(void *priv);
static int wpa_driver_wext_get_range(void *priv);
+static void wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
+ char linkmode, char operstate);
static int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv,
@@ -559,6 +562,15 @@ static void wpa_driver_wext_event_rtm_ne
return;
}
+ /* some drivers send the association event before the operup event -
+ in this case, lifting operstate in wpa_driver_wext_set_operstate()
+ fails. This will hit us when wpa_supplicant doesn't need to do
+ 802.1X authentication */
+ if (drv->ifindex == ifi->ifi_index && drv->operstate == 1 &&
+ (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
+ !(ifi->ifi_flags & IFF_RUNNING))
+ wpa_driver_wext_send_oper_ifla(drv, -1, IF_OPER_UP);
+
nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
attrlen = h->nlmsg_len - nlmsg_len;
@@ -794,6 +806,8 @@ void * wpa_driver_wext_init(void *ctx, c
wpa_driver_wext_alternative_ifindex(drv, ifname2);
}
+ wpa_driver_wext_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
+
return drv;
}
@@ -816,6 +830,8 @@ void wpa_driver_wext_deinit(void *priv)
*/
wpa_driver_wext_set_bssid(drv, (u8 *) "\x00\x00\x00\x00\x00\x00");
+ wpa_driver_wext_send_oper_ifla(priv, 0, IF_OPER_UP);
+
eloop_unregister_read_sock(drv->event_sock);
if (wpa_driver_wext_get_ifflags(drv, &flags) == 0)
@@ -1759,6 +1775,57 @@ int wpa_driver_wext_alternative_ifindex(
}
+static void wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
+ char linkmode, char operstate) {
+ struct {
+ struct nlmsghdr hdr;
+ struct ifinfomsg ifinfo;
+ char opts[16];
+ } req;
+ struct rtattr *rta;
+ static int nl_seq;
+
+ req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.hdr.nlmsg_type = RTM_SETLINK;
+ req.hdr.nlmsg_flags = NLM_F_REQUEST;
+ req.hdr.nlmsg_seq = ++nl_seq;
+ req.hdr.nlmsg_pid = 0;
+
+ req.ifinfo.ifi_family = AF_UNSPEC;
+ req.ifinfo.ifi_type = 0;
+ req.ifinfo.ifi_index = drv->ifindex;
+ req.ifinfo.ifi_flags = 0;
+ req.ifinfo.ifi_change = 0;
+
+ if (linkmode != -1) {
+ rta = (struct rtattr *)((char *)&req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+ rta->rta_type = IFLA_LINKMODE;
+ rta->rta_len = RTA_LENGTH(sizeof(char));
+ *((char *)RTA_DATA(rta)) = linkmode;
+ req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char));
+ }
+ if (operstate != -1) {
+ rta = (struct rtattr *)((char *)&req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+ rta->rta_type = IFLA_OPERSTATE;
+ rta->rta_len = RTA_LENGTH(sizeof(char));
+ *((char *)RTA_DATA(rta)) = operstate;
+ req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + RTA_LENGTH(sizeof(char));
+ }
+
+ printf("Operstate: linkmode=%d, operstate=%d\n", linkmode, operstate);
+
+ (void)send(drv->event_sock, &req, req.hdr.nlmsg_len, 0);
+}
+
+
+static void wpa_driver_wext_set_operstate(void *priv, int state) {
+ struct wpa_driver_wext_data *drv = priv;
+
+ drv->operstate = state;
+ wpa_driver_wext_send_oper_ifla(drv, -1, state?IF_OPER_UP:IF_OPER_DORMANT);
+}
+
+
const struct wpa_driver_ops wpa_driver_wext_ops = {
.name = "wext",
.desc = "Linux wireless extensions (generic)",
@@ -1780,4 +1847,5 @@ const struct wpa_driver_ops wpa_driver_w
.remove_pmkid = wpa_driver_wext_remove_pmkid,
.flush_pmkid = wpa_driver_wext_flush_pmkid,
.get_capa = wpa_driver_wext_get_capa,
+ .set_operstate = wpa_driver_wext_set_operstate,
};
diff -x '*.o' -x '*.d' -x '*~' -x wpa_cli -x wpa_passphrase -x wpa_supplicant -upr wpa_supplicant-0.5.1.orig/priv_netlink.h wpa_supplicant-0.5.1/priv_netlink.h
--- wpa_supplicant-0.5.1.orig/priv_netlink.h 2005-06-18 19:39:36.000000000 +0200
+++ wpa_supplicant-0.5.1/priv_netlink.h 2006-03-03 23:26:45.000000000 +0100
@@ -20,18 +20,36 @@
* library, etc..
*/
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
+#endif
+#ifndef IFF_DORMANT
+#define IFF_DORMANT 0x20000 /* driver signals dormant */
+#endif
+
#ifndef IFLA_IFNAME
#define IFLA_IFNAME 3
#endif
#ifndef IFLA_WIRELESS
#define IFLA_WIRELESS 11
#endif
+#ifndef IFLA_OPERSTATE
+#define IFLA_OPERSTATE 16
+#endif
+#ifndef IFLA_LINKMODE
+#define IFLA_LINKMODE 17
+#define IF_OPER_DORMANT 5
+#define IF_OPER_UP 6
+#endif
+
+#define NLM_F_REQUEST 1
#define NETLINK_ROUTE 0
#define RTMGRP_LINK 1
#define RTM_BASE 0x10
#define RTM_NEWLINK (RTM_BASE + 0)
#define RTM_DELLINK (RTM_BASE + 1)
+#define RTM_SETLINK (RTM_BASE + 3)
#define NLMSG_ALIGNTO 4
#define NLMSG_ALIGN(len) (((len) + NLMSG_ALIGNTO - 1) & ~(NLMSG_ALIGNTO - 1))
@@ -46,6 +64,9 @@
#define RTA_NEXT(rta,attrlen) \
((attrlen) -= RTA_ALIGN((rta)->rta_len), \
(struct rtattr *) (((char *)(rta)) + RTA_ALIGN((rta)->rta_len)))
+#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
+#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
+
struct sockaddr_nl
diff -x '*.o' -x '*.d' -x '*~' -x wpa_cli -x wpa_passphrase -x wpa_supplicant -upr wpa_supplicant-0.5.1.orig/wpa_supplicant.c wpa_supplicant-0.5.1/wpa_supplicant.c
--- wpa_supplicant-0.5.1.orig/wpa_supplicant.c 2006-01-30 05:24:58.000000000 +0100
+++ wpa_supplicant-0.5.1/wpa_supplicant.c 2006-03-03 20:20:15.000000000 +0100
@@ -706,9 +706,11 @@ void wpa_supplicant_set_state(struct wpa
MAC2STR(wpa_s->bssid), wpa_s->reassociated_connection ?
"(reauth)" : "(auth)");
wpa_s->reassociated_connection = 1;
+ wpa_drv_set_operstate(wpa_s, 1);
} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
state == WPA_ASSOCIATED) {
wpa_s->new_connection = 1;
+ wpa_drv_set_operstate(wpa_s, 0);
}
wpa_s->wpa_state = state;
}
diff -x '*.o' -x '*.d' -x '*~' -x wpa_cli -x wpa_passphrase -x wpa_supplicant -upr wpa_supplicant-0.5.1.orig/wpa_supplicant_i.h wpa_supplicant-0.5.1/wpa_supplicant_i.h
--- wpa_supplicant-0.5.1.orig/wpa_supplicant_i.h 2005-11-28 05:44:50.000000000 +0100
+++ wpa_supplicant-0.5.1/wpa_supplicant_i.h 2006-03-03 20:05:17.000000000 +0100
@@ -484,4 +484,10 @@ static inline int wpa_drv_send_eapol(str
return -1;
}
+static inline void wpa_drv_set_operstate(struct wpa_supplicant *wpa_s,
+ int state)
+{
+ if (wpa_s->driver->set_operstate)
+ wpa_s->driver->set_operstate(wpa_s->drv_priv, state);
+}
#endif /* WPA_SUPPLICANT_I_H */
--Boundary-00=_XuMCExQpBMlTz0O
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
HostAP mailing list
HostAP at shmoo.com
http://lists.shmoo.com/mailman/listinfo/hostap
--Boundary-00=_XuMCExQpBMlTz0O--
More information about the Pkg-wpa-devel
mailing list