Support for User-Defined Wpa-Supplicant Config

Goal:
I'd like to use a user-defined wpa_supplicant.conf file when using wifi in STA mode. I want to accomplish this by adding an 'option' field to the wireless config file that, when in STA mode, lets me point to a custom wpa_supplicant.conf file to use. I need some guidance on how to do this (perhaps through netifd)

Why?
I will be frequently moving my LEDE device and it will be connecting to multiple different wifi AP's depending on where I am with it. Right now, there appears to be no way to configure in /etc/config/wireless to connect to one of multiple different wifi AP's when they become available to the OS.

Background
I can configure multiple wifi AP's in the wireless file for a single wlan device. However, LEDE creates an instance of wpa_Supplicant for every AP entry. This results in LEDE attempting to connect to every wifi ap simultaneously if they are available. I want it to connect to only one AP at a time (based on priority) not all of them.

You can configure wpa_supplicant to do exactly that with the "priority" field in the wpa_supplicant.conf file but it looks like there's no way to use my own conf file.

My attempts at getting control of wpa_supplicant are being negated by netifd. Anytime I want to make a change or restart wifi, netifd wipes out my wpa_supplicant.conf and generates its own. If i try to kill wpa_supplicant, netifd simply restarts it and regenerates its wpa_supplicant.conf. I suppose it is possible to accomplish this by not using /etc/config/wireless and managing the wifi device completely separately. But then it's being managed outside of the LEDE config system / uci and it'd be nice to keep it within that if possible.

It appears that netifd allows for "plugins" and extensions by reading in scripts located in the /lib/netifd directory, but I have no idea how these scripts work, how they are called by netifd and what their interdpendencies are. The best documentation I can find on it (LEDE wiki and git ) gives a general overview at best.

Again, I am looking for any guidance on how to accomplish this or to where i can find better details/documentation on netifd. Thank you for your time!

Maybe what you want can be achieved by extending/modifying travelmate package?

This is true. You can do it purely with wpa_supplicant and if you need dhcp also with udhcpc.

I know this because I have my own setup, that I personally use. It's not controlled by luci (or /etc/config/wireless), though the radio i am using is added in (/etc/config/wireless) without a 'wifi-iface'. I can use it to scan that radio with luci. It's controlled with scripts for a connection: wpad wpa_supplicant to connect and udhcpc for dhcp.

Tad bit more info: udhcpc uses a script (/usr/share/udhcpc/default.script) by default but netifd starts udhcpc with a custom script for dhcp (/lib/netifd/dhcp.script).

This is the route I chose to go. I used iw to manually create a "wlan" VIF and then start a standalone wpa_supplicant instance with a multi-network wpa_supplicant.conf file. udhcpc also appears to successfully acquire a lease and associate it with the VIF.

Now there are problems with DNS and netifd. I modified the /usr/share/udhcpc/default.script to write the dhcp server's dns servers to /etc/resolve.conf once a lease is acquired. However, if I happen to plug in or remove an ethernet cable, this triggers netifd to overwrite resolve.conf. Since I'd like the ability to use ethernet when available this could turn out to be a real pain.

Perhaps the best solution will be to try to create the wlan VIF through calls to netifd using ubus. Then associate that VIF with one of the networks defined in the /etc/config/networks file. This would allow netifd to become aware of events on the VIF while associating a network with it for acquiring an ip address. This yields the following questions:

  • How do you create a wireless virtual interface by using ubus calls to netifd?
  • How do you associate a wireless virtual interface with a network interface using ubus?

Looking at the scripts in /lib/netifd and /lib/netifd/wireless, I can gather that I need to call ubus object methods such as network.wireless.notify and network.add_dynamic, but I'm having a very hard time figuring out what parameters those scripts are calling ubus with. Will keep digging.

dns part: this is what i do. sorry if i knew you were actually still going to go through with it, i would've said more.
(TRY THIS /tmp/resolv.conf.auto INSTEAD OF /etc/resolve.conf)

## /usr/share/udhcpc/default.script :: setup_interface() needs this to add DNS from host
[ -n "$dns" ] && {
	echo "udhcpc: adding $dns to /tmp/resolv.conf.auto"
	> /tmp/resolv.conf.auto
	for dns in $dns; do
		echo "nameserver $dns" >> /tmp/resolv.conf.auto
	done
}

you can put udhcpc in the background with screen like this (this is the call i use exactly):

screen -d -S udhcpc -m udhcpc -p /var/run/udhcpc-wlan2.pid -f -t 0 -i wlan2 -x hostname:Edimax -C -O 121

this is the command i use for wpa_supplicant

wpad wpa_supplicant -B -P /var/run/wpa_supplicant-wlan2.pid -D nl80211 -i wlan2 -c /etc/config/wpad/sta.conf -C /var/run/wpa_supplicant/

to kill them you can:

kill -9 `cat /var/run/wpa_supplicant-wlan2.pid` && rm -f /var/run/wpa_supplicant-wlan2.pid
kill -9 `cat /var/run/udhcpc-wlan2.pid` && rm -f /var/run/udhcpc-wlan2.pid

also udhcpc can call a separate script instead of default: -s,--script PROG Run PROG at DHCP events (default /usr/share/udhcpc/default.script)

i actually have a bash script to control all of this for another driver (see: rtl8812AU and/or rtl8814AU drivers [whats after ~ on another note ~] and http://i.imgur.com/UVJzJfo.png), it's not finished yet but i've been working on it when i have time. :stuck_out_tongue:

as for the rest of what you said, i cant be much help. So i am sorry for this, but i hope you have a lovely day! :slight_smile:

This is all very nice indeed but feels like a massive hack. There are plenty of options that UCI simply does not support, while wpa_supplicant does. Also managing wifi devices manually makes it a total pain to manage interface names for things like firewall zones. So essentially it means that either UCI does everything you need, or you suddenly need to do everything manually, which feels somewhat backwards. I believe that there is a need to either
a) support custom wpa_suppicant.conf in /etc/config/wireless OR
b) allow interfaces to be attached to e.g. firewall config even if they are not managed by UCI directly

I have a similar issue, I'm building an AP that will move around and want to have it connect via wire if it's plugged in, and if not, through a series of different known wireless networks (ideally a list that can be added to, so it can add hotel networks easily)

I can sort of do it by scanning for a network and adding it, telling luci to replace the entire network config. But that doesn't allow it to remember networks and connect to them when available.

One thing that I've done is I've made the 'wan' interface a bridge, and put the dhcp client on interface. That handles one wifi and the wired network 'well enough' (odd things happen when both wired and wireless are connected, but it's mostly a matter of which one is used being a race condition)

But trying to extend the wifi to support multiple known networks is an issue.

Adding a sta varient mode that punts to a user-created wpa_supplicant instead of creating one doesn't sound like it should be that painful and would give a sane way to graft in this custom stuff without losing all integration with the rest of the openwrt infrastructure.

Hello devs,

Regarding this topic, I would like advice on whether I should submit a patch, or if that is anyway not in the philosophy of OpenWRT and I should not bother.

Same as those previous op, I needed to define my own wpa_supplicant.conf to include many options that are not manageable with uci (for EAP-SIM).

Basically the advice for that on forums is to manually configure a wpa_supplicant service with a dedicated conf file and add scripts to handle disconnection etc. This is quite complicated and prevents benefiting from OpenWRT integration, as pointed by alex.pyattaev here some years ago.

So my proposed solution is to just add a "conf_file" option under the uci wireless. When set, it prevents generating the wpa_supplicant.conf and instead takes the content of the provided file. Similar as suggested by [drschlock] in this old thread.
The change is a matter of adding 5 lines within the hostapd.sh script (package hostapd-common).
(I also added it to LuCI, through an additional "Manual conf file" option in the list of encryptions)

Thanks!