Module Name: src Committed By: roy Date: Wed Mar 23 09:31:58 UTC 2016
Modified Files: src/external/bsd/wpa/dist/wpa_supplicant: Makefile README defconfig events.c main.c wpa_supplicant.c wpa_supplicant_i.h Log Message: Add interface matching support with -M, guarded by CONFIG_MATCH_IFACE The new wpa_supplicant command line argument -M can be used to describe matching rules with a wildcard name (e.g., "wlan*"). This is very useful for systems without uev (Linux) or devd (FreeBSD). To generate a diff of this commit: cvs rdiff -u -r1.1.1.6 -r1.2 \ src/external/bsd/wpa/dist/wpa_supplicant/Makefile cvs rdiff -u -r1.1.1.5 -r1.2 src/external/bsd/wpa/dist/wpa_supplicant/README \ src/external/bsd/wpa/dist/wpa_supplicant/defconfig cvs rdiff -u -r1.4 -r1.5 src/external/bsd/wpa/dist/wpa_supplicant/events.c cvs rdiff -u -r1.2 -r1.3 src/external/bsd/wpa/dist/wpa_supplicant/main.c cvs rdiff -u -r1.5 -r1.6 \ src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant.c cvs rdiff -u -r1.1.1.7 -r1.2 \ src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant_i.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/wpa/dist/wpa_supplicant/Makefile diff -u src/external/bsd/wpa/dist/wpa_supplicant/Makefile:1.1.1.6 src/external/bsd/wpa/dist/wpa_supplicant/Makefile:1.2 --- src/external/bsd/wpa/dist/wpa_supplicant/Makefile:1.1.1.6 Wed Apr 1 19:24:39 2015 +++ src/external/bsd/wpa/dist/wpa_supplicant/Makefile Wed Mar 23 09:31:58 2016 @@ -274,6 +274,10 @@ CFLAGS += -DCONFIG_IBSS_RSN OBJS += ibss_rsn.o endif +ifdef CONFIG_MATCH_IFACE +CFLAGS += -DCONFIG_MATCH_IFACE +endif + ifdef CONFIG_P2P OBJS += p2p_supplicant.o OBJS += ../src/p2p/p2p.o Index: src/external/bsd/wpa/dist/wpa_supplicant/README diff -u src/external/bsd/wpa/dist/wpa_supplicant/README:1.1.1.5 src/external/bsd/wpa/dist/wpa_supplicant/README:1.2 --- src/external/bsd/wpa/dist/wpa_supplicant/README:1.1.1.5 Wed Apr 1 19:24:40 2015 +++ src/external/bsd/wpa/dist/wpa_supplicant/README Wed Mar 23 09:31:58 2016 @@ -412,7 +412,7 @@ usage: wpa_supplicant [-BddfhKLqqtuvwW] [-P<pid file>] [-g<global ctrl>] \ [-G<group>] \ -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \ - [-b<br_ifname> [-N -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \ + [-b<br_ifname> [-MN -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \ [-p<driver_param>] [-b<br_ifname>] [-m<P2P Device config file>] ... options: @@ -437,6 +437,7 @@ options: -v = show version -w = wait for interface to be added, if needed -W = wait for a control interface monitor before starting + -M = start describing matching interface -N = start describing new interface -m = Configuration file for the P2P Device @@ -479,6 +480,22 @@ wpa_supplicant \ -c wpa2.conf -i wlan1 -D wext +If the interfaces on which wpa_supplicant is to run are not known or do +not exist, wpa_supplicant can match an interface when it arrives. Each +matched interface is separated with -M argument and the -i argument now +allows for pattern matching. + +As an example, the following command would start wpa_supplicant for a +specific wired interface called lan0, any interface starting with wlan +and lastly any other interface. Each match has its own configuration +file, and for the wired interface a specific driver has also been given. + +wpa_supplicant \ + -M -c wpa_wired.conf -ilan0 -D wired \ + -M -c wpa1.conf -iwlan* \ + -M -c wpa2.conf + + If the interface is added in a Linux bridge (e.g., br0), the bridge interface needs to be configured to wpa_supplicant in addition to the main interface: Index: src/external/bsd/wpa/dist/wpa_supplicant/defconfig diff -u src/external/bsd/wpa/dist/wpa_supplicant/defconfig:1.1.1.5 src/external/bsd/wpa/dist/wpa_supplicant/defconfig:1.2 --- src/external/bsd/wpa/dist/wpa_supplicant/defconfig:1.1.1.5 Wed Apr 1 19:24:38 2015 +++ src/external/bsd/wpa/dist/wpa_supplicant/defconfig Wed Mar 23 09:31:58 2016 @@ -455,6 +455,9 @@ CONFIG_PEERKEY=y # Hotspot 2.0 #CONFIG_HS20=y +# Enable interface matching in wpa_supplicant +#CONFIG_MATCH_IFACE=y + # Disable roaming in wpa_supplicant #CONFIG_NO_ROAMING=y Index: src/external/bsd/wpa/dist/wpa_supplicant/events.c diff -u src/external/bsd/wpa/dist/wpa_supplicant/events.c:1.4 src/external/bsd/wpa/dist/wpa_supplicant/events.c:1.5 --- src/external/bsd/wpa/dist/wpa_supplicant/events.c:1.4 Wed Mar 23 08:48:43 2016 +++ src/external/bsd/wpa/dist/wpa_supplicant/events.c Wed Mar 23 09:31:58 2016 @@ -2451,6 +2451,14 @@ wpa_supplicant_event_interface_status(st wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED); l2_packet_deinit(wpa_s->l2); wpa_s->l2 = NULL; + +#ifdef CONFIG_MATCH_IFACE + if (wpa_s->matched) { + wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0); + break; + } +#endif /* CONFIG_MATCH_IFACE */ + #ifdef CONFIG_TERMINATE_ONLASTIF /* check if last interface */ if (!any_interfaces(wpa_s->global->ifaces)) @@ -3684,6 +3692,20 @@ void wpa_supplicant_event_global(void *c return; } } +#ifdef CONFIG_MATCH_IFACE + else if (data->interface_status.ievent == EVENT_INTERFACE_ADDED) { + struct wpa_interface *wpa_i; + + wpa_i = wpa_supplicant_match_iface( + ctx, data->interface_status.ifname); + if (!wpa_i) + return; + wpa_s = wpa_supplicant_add_iface(ctx, wpa_i, NULL); + os_free(wpa_i); + if (wpa_s) + wpa_s->matched = 1; + } +#endif /* CONFIG_MATCH_IFACE */ if (wpa_s) wpa_supplicant_event(wpa_s, event, data); Index: src/external/bsd/wpa/dist/wpa_supplicant/main.c diff -u src/external/bsd/wpa/dist/wpa_supplicant/main.c:1.2 src/external/bsd/wpa/dist/wpa_supplicant/main.c:1.3 --- src/external/bsd/wpa/dist/wpa_supplicant/main.c:1.2 Fri Jan 15 20:34:35 2016 +++ src/external/bsd/wpa/dist/wpa_supplicant/main.c Wed Mar 23 09:31:58 2016 @@ -80,6 +80,9 @@ static void usage(void) #ifdef CONFIG_P2P " -m = Configuration file for the P2P Device interface\n" #endif /* CONFIG_P2P */ +#ifdef CONFIG_MATCH_IFACE + " -M = start describing new matching interface\n" +#endif /* CONFIG_MATCH_IFACE */ " -N = start describing new interface\n" " -o = override driver parameter for new interfaces\n" " -O = override ctrl_interface parameter for new interfaces\n" @@ -153,6 +156,28 @@ static void wpa_supplicant_fd_workaround } +#ifdef CONFIG_MATCH_IFACE +static int wpa_supplicant_init_match(struct wpa_global *global) +{ + /* + * The assumption is that the first driver is the primary driver and + * will handle the arrival / departure of interfaces. + */ + if (wpa_drivers[0]->global_init && !global->drv_priv[0]) { + global->drv_priv[0] = wpa_drivers[0]->global_init(global); + if (!global->drv_priv[0]) { + wpa_printf(MSG_ERROR, + "Failed to initialize driver '%s'", + wpa_drivers[0]->name); + return -1; + } + } + + return 0; +} +#endif /* CONFIG_MATCH_IFACE */ + + int main(int argc, char *argv[]) { int c, i; @@ -176,7 +201,7 @@ int main(int argc, char *argv[]) for (;;) { c = getopt(argc, argv, - "b:Bc:C:D:de:f:g:G:hi:I:KLm:No:O:p:P:qsTtuvW"); + "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); if (c < 0) break; switch (c) { @@ -282,6 +307,20 @@ int main(int argc, char *argv[]) case 'W': params.wait_for_monitor++; break; +#ifdef CONFIG_MATCH_IFACE + case 'M': + params.match_iface_count++; + iface = os_realloc_array(params.match_ifaces, + params.match_iface_count, + sizeof(struct wpa_interface)); + if (!iface) + goto out; + params.match_ifaces = iface; + iface = ¶ms.match_ifaces[params.match_iface_count - + 1]; + os_memset(iface, 0, sizeof(*iface)); + break; +#endif /* CONFIG_MATCH_IFACE */ case 'N': iface_count++; iface = os_realloc_array(ifaces, iface_count, @@ -317,6 +356,9 @@ int main(int argc, char *argv[]) ifaces[i].ctrl_interface == NULL) || ifaces[i].ifname == NULL) { if (iface_count == 1 && (params.ctrl_interface || +#ifdef CONFIG_MATCH_IFACE + params.match_iface_count || +#endif /* CONFIG_MATCH_IFACE */ params.dbus_ctrl_interface)) break; usage(); @@ -330,6 +372,11 @@ int main(int argc, char *argv[]) } } +#ifdef CONFIG_MATCH_IFACE + if (exitcode == 0) + exitcode = wpa_supplicant_init_match(global); +#endif /* CONFIG_MATCH_IFACE */ + if (exitcode == 0) exitcode = wpa_supplicant_run(global); @@ -338,6 +385,9 @@ int main(int argc, char *argv[]) out: wpa_supplicant_fd_workaround(0); os_free(ifaces); +#ifdef CONFIG_MATCH_IFACE + os_free(params.match_ifaces); +#endif /* CONFIG_MATCH_IFACE */ os_free(params.pid_file); os_program_deinit(); Index: src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant.c diff -u src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant.c:1.5 src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant.c:1.6 --- src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant.c:1.5 Wed Mar 23 08:48:43 2016 +++ src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant.c Wed Mar 23 09:31:58 2016 @@ -11,6 +11,10 @@ */ #include "includes.h" +#ifdef CONFIG_MATCH_IFACE +#include <net/if.h> +#include <fnmatch.h> +#endif /* CONFIG_MATCH_IFACE */ #include "common.h" #include "crypto/random.h" @@ -4291,6 +4295,74 @@ static void wpa_supplicant_deinit_iface( } +#ifdef CONFIG_MATCH_IFACE + +/** + * wpa_supplicant_match_iface - Match an interface description to a name + * @global: Pointer to global data from wpa_supplicant_init() + * @ifname: Name of the interface to match + * Returns: Pointer to the created interface description or %NULL on failure + */ +struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global, + const char *ifname) +{ + int i; + struct wpa_interface *iface, *miface; + + for (i = 0; i < global->params.match_iface_count; i++) { + miface = &global->params.match_ifaces[i]; + if (!miface->ifname || + fnmatch(miface->ifname, ifname, 0) == 0) { + iface = os_zalloc(sizeof(*iface)); + if (!iface) + return NULL; + *iface = *miface; + iface->ifname = ifname; + return iface; + } + } + + return NULL; +} + + +/** + * wpa_supplicant_match_existing - Match existing interfaces + * @global: Pointer to global data from wpa_supplicant_init() + * Returns: 0 on success, -1 on failure + */ +static int wpa_supplicant_match_existing(struct wpa_global *global) +{ + struct if_nameindex *ifi, *ifp; + struct wpa_supplicant *wpa_s; + struct wpa_interface *iface; + + ifp = if_nameindex(); + if (!ifp) { + wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno)); + return -1; + } + + for (ifi = ifp; ifi->if_name; ifi++) { + wpa_s = wpa_supplicant_get_iface(global, ifi->if_name); + if (wpa_s) + continue; + iface = wpa_supplicant_match_iface(global, ifi->if_name); + if (iface) { + wpa_s = wpa_supplicant_add_iface(global, iface, NULL); + os_free(iface); + if (wpa_s) + wpa_s->matched = 1; + } + } + + if_freenameindex(ifp); + return 0; +} + +#endif /* CONFIG_MATCH_IFACE */ + + /** * wpa_supplicant_add_iface - Add a new network interface * @global: Pointer to global data from wpa_supplicant_init() @@ -4563,6 +4635,18 @@ struct wpa_global * wpa_supplicant_init( if (params->override_ctrl_interface) global->params.override_ctrl_interface = os_strdup(params->override_ctrl_interface); +#ifdef CONFIG_MATCH_IFACE + global->params.match_iface_count = params->match_iface_count; + if (params->match_iface_count) { + global->params.match_ifaces = + os_calloc(params->match_iface_count, + sizeof(struct wpa_interface)); + os_memcpy(global->params.match_ifaces, + params->match_ifaces, + params->match_iface_count * + sizeof(struct wpa_interface)); + } +#endif /* CONFIG_MATCH_IFACE */ wpa_debug_level = global->params.wpa_debug_level = params->wpa_debug_level; wpa_debug_show_keys = global->params.wpa_debug_show_keys = @@ -4634,6 +4718,11 @@ int wpa_supplicant_run(struct wpa_global eloop_sock_requeue())) return -1; +#ifdef CONFIG_MATCH_IFACE + if (wpa_supplicant_match_existing(global)) + return -1; +#endif + if (global->params.wait_for_monitor) { for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) if (wpa_s->ctrl_iface) @@ -4700,6 +4789,9 @@ void wpa_supplicant_deinit(struct wpa_gl os_free(global->params.ctrl_interface_group); os_free(global->params.override_driver); os_free(global->params.override_ctrl_interface); +#ifdef CONFIG_MATCH_IFACE + os_free(global->params.match_ifaces); +#endif /* CONFIG_MATCH_IFACE */ os_free(global->p2p_disallow_freq.range); os_free(global->p2p_go_avoid_freq.range); Index: src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant_i.h diff -u src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant_i.h:1.1.1.7 src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant_i.h:1.2 --- src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant_i.h:1.1.1.7 Wed Apr 1 19:24:38 2015 +++ src/external/bsd/wpa/dist/wpa_supplicant/wpa_supplicant_i.h Wed Mar 23 09:31:58 2016 @@ -227,6 +227,18 @@ struct wpa_params { * its internal entropy store over restarts. */ char *entropy_file; + +#ifdef CONFIG_MATCH_IFACE + /** + * match_ifaces - Interface descriptions to match + */ + struct wpa_interface *match_ifaces; + + /** + * match_iface_count - Number of defined matching interfaces + */ + int match_iface_count; +#endif /* CONFIG_MATCH_IFACE */ }; struct p2p_srv_bonjour { @@ -430,6 +442,9 @@ struct wpa_supplicant { unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; +#ifdef CONFIG_MATCH_IFACE + int matched; +#endif /* CONFIG_MATCH_IFACE */ #ifdef CONFIG_CTRL_IFACE_DBUS char *dbus_path; #endif /* CONFIG_CTRL_IFACE_DBUS */ @@ -1034,6 +1049,8 @@ void free_hw_features(struct wpa_supplic void wpa_show_license(void); +struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global, + const char *ifname); struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, struct wpa_interface *iface, struct wpa_supplicant *parent);