Connecting the device to a wifi behind a captive

@majorz , i want to update shortly.
the solution seems to work, but.
the issues:
when a WIFI_AP is created, when the device is up, the network manager starts the WIFI_AP automatically, but this time using wlan0, and then i’m unable to add vap0 using iw because wlan0 is active - the workaround for this is deleting WIFI_AP and restarting it after adding vap0, with the right interface.

this also makes me to have a service using network_mode host for adding the vap0, and now i cant communicate with this service from services that are not on host mode.

do you have a suggestion how to approach this?

You can try setting interface-name=vap0 in the NetworkManager profile. autoconnect=false could be of help as well. Please let me know whether that will work for you. Can you also please explain more about the second question you have for communicating between those services - what you are trying to achieve more specifically?

My goal is to make vap0 available all the time, i couldnt do it through UDEV rules, so my container (connectionservice) is on network_mode host, and it is doing on startup iw dev wlan0 interface add vap0 type __ap addr 12:34:56:78:ab:cd
i would like to avoid him having to be on host mode, and have the vap0 constant( UDEV rules didnt work for me)

i’ve added this to UDEV:
“os”: {
“udevRules”: {
“12”: “ACTION==“add”, SUBSYSTEM==“net”, ENV{INTERFACE}==“wlan0”, RUN+=“iw dev wlan0 interface add vap0 type __ap addr 12:34:56:78:ab:cd””
}
},

the functionality i need basically, is having vap0 always available on startup, before the containers start.

this is the output of the udev:
root@b7cc5d3:~# udevadm test /sys/class/net/wlan0
calling: test
version 237
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

Load module index
Skipping empty file: /etc/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /etc/udev/rules.d/10-camera1-a.rules
Reading rules file: /etc/udev/rules.d/10-camera1-c.rules
Reading rules file: /etc/udev/rules.d/10-camera2-a.rules
Reading rules file: /etc/udev/rules.d/10-camera2-c.rules
Reading rules file: /lib/udev/rules.d/10-local-bt-hci-up.rules
Reading rules file: /etc/udev/rules.d/12.rules
Reading rules file: /lib/udev/rules.d/40-usb_modeswitch.rules
Reading rules file: /lib/udev/rules.d/49-teensy.rules
Reading rules file: /lib/udev/rules.d/50-firmware.rules
Reading rules file: /lib/udev/rules.d/50-udev-default.rules
Specified group ‘render’ unknown
Specified group ‘kvm’ unknown
Reading rules file: /lib/udev/rules.d/60-block.rules
Reading rules file: /lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /lib/udev/rules.d/60-drm.rules
Reading rules file: /lib/udev/rules.d/60-evdev.rules
Reading rules file: /lib/udev/rules.d/60-input-id.rules
Reading rules file: /lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /lib/udev/rules.d/60-resin-update-state.rules
Reading rules file: /lib/udev/rules.d/60-sensor.rules
Reading rules file: /lib/udev/rules.d/60-serial.rules
Reading rules file: /lib/udev/rules.d/64-btrfs.rules
Reading rules file: /lib/udev/rules.d/70-joystick.rules
Reading rules file: /lib/udev/rules.d/70-mouse.rules
Reading rules file: /lib/udev/rules.d/70-power-switch.rules
Reading rules file: /lib/udev/rules.d/70-touchpad.rules
Reading rules file: /lib/udev/rules.d/70-uaccess.rules
Reading rules file: /lib/udev/rules.d/71-seat.rules
Reading rules file: /lib/udev/rules.d/73-seat-late.rules
Reading rules file: /lib/udev/rules.d/75-net-description.rules
Reading rules file: /lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /lib/udev/rules.d/77-mm-cinterion-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-dell-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-dlink-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-ericsson-mbm.rules
Reading rules file: /lib/udev/rules.d/77-mm-fibocom-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-haier-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-huawei-configuration.rules
Reading rules file: /lib/udev/rules.d/77-mm-huawei-net-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-longcheer-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-mtk-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-nokia-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-pcmcia-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-quectel-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-sierra.rules
Reading rules file: /lib/udev/rules.d/77-mm-simtech-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-telit-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-tplink-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-ublox-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-usb-device-blacklist.rules
Reading rules file: /lib/udev/rules.d/77-mm-usb-serial-adapters-greylist.rules
Reading rules file: /lib/udev/rules.d/77-mm-x22x-port-types.rules
Reading rules file: /lib/udev/rules.d/77-mm-zte-port-types.rules
Reading rules file: /lib/udev/rules.d/78-sound-card.rules
Reading rules file: /lib/udev/rules.d/80-drivers.rules
Reading rules file: /lib/udev/rules.d/80-mm-candidate.rules
Reading rules file: /lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /lib/udev/rules.d/84-nm-drivers.rules
Reading rules file: /lib/udev/rules.d/85-nm-unmanaged.rules
Reading rules file: /lib/udev/rules.d/85-regulatory.rules
Reading rules file: /lib/udev/rules.d/90-nm-thunderbolt.rules
Reading rules file: /lib/udev/rules.d/90-vconsole.rules
Reading rules file: /lib/udev/rules.d/97-hid2hci.rules
Reading rules file: /lib/udev/rules.d/99-misc.rules
Reading rules file: /lib/udev/rules.d/99-systemd.rules
Reading rules file: /lib/udev/rules.d/touchscreen.rules
rules contain 98304 bytes tokens (8192 * 12 bytes), 18749 bytes strings
8389 strings (81430 bytes), 6971 de-duplicated (64100 bytes), 1419 trie nodes used
RUN ‘iw dev wlan0 interface add vap0 type __ap addr 12:34:56:78:ab:cd’ /etc/udev/rules.d/12.rules:1
IMPORT builtin ‘net_id’ /lib/udev/rules.d/75-net-description.rules:6
IMPORT builtin ‘path_id’ /lib/udev/rules.d/80-net-setup-link.rules:5
IMPORT builtin ‘net_setup_link’ /lib/udev/rules.d/80-net-setup-link.rules:9
No matching link configuration found.
RUN ‘/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/$name --prefix=/net/ipv4/neigh/$name --prefix=/net/ipv6/conf/$name --prefix=/net/ipv6/neigh/$name’ /lib/udev/rules.d/99-systemd.rules:60
ACTION=add
DEVPATH=/devices/platform/30b40000.mmc/mmc_host/mmc0/mmc0:0001/mmc0:0001:1/net/wlan0
DEVTYPE=wlan
ID_MM_CANDIDATE=1
ID_NET_DRIVER=brcmfmac
ID_PATH=platform-30b40000.mmc
ID_PATH_TAG=platform-30b40000_mmc
IFINDEX=4
INTERFACE=wlan0
SUBSYSTEM=net
SYSTEMD_ALIAS=/sys/subsystem/net/devices/wlan0
TAGS=:systemd:
USEC_INITIALIZED=8450378
run: ‘iw dev wlan0 interface add vap0 type __ap addr 12:34:56:78:ab:cd’
run: ‘/lib/systemd/systemd-sysctl --prefix=/net/ipv4/conf/wlan0 --prefix=/net/ipv4/neigh/wlan0 --prefix=/net/ipv6/conf/wlan0 --prefix=/net/ipv6/neigh/wlan0’
Unload module index
Unloaded link configuration context.

Hi @mellerdaniel ,
Can you also clarify that the inner quotes of the configuration were properly escaped?
I mean something like:

"os": {
  "udevRules": {
    "12": "ACTION==\"add\", SUBSYSTEM==\"net\", ENV{INTERFACE}==\"wlan0\", RUN+=\"iw dev wlan0 interface add vap0 type __ap addr 12:34:56:78:ab:cd\""
  }
}

If that does not work also try making the rule with a higher number, e.g. 99, not 12, so that all other rules have been run at the time it is executed.

tried with 99, not working.
i now have a service that runs iw dev wlan0 interface add vap0 type __ap addr 12:34:56:78:ab:cd and adds a AP with dbus API (python).
that works fine, BUT :confused:
it causes conflict with a WIFI that was already connected, and it makes that connection not work.
i will add also, that sometimes when the system starts, the network manager thinks that hot spot should be used by wlan0, and actually deletes all the other connections that were connected to my home router.
so it cant automatically reconnect to defined routers

Hi, some more log information could help debug what is happening - could you try accessing the device and running udevadm monitor to capture log output, and then in another tab run udevadm trigger to replay the system events. Once you’ve done this, please post the output of udevadm monitor here and hopefully this will provide more insight into the problem.

i have a suspect about the way i connect to a SSID using the python dbus API.

i use this example:
https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/dbus/add-wifi-psk-connection.py

with the addition of ‘interface-name’ : ‘wlan0’ in the connection.

when i use just nmcli dev wifi connect SSID password PASS it looks like it works perfectly and acts as expected.

Hi Daniel

Thanks for sharing the example link.
Can you share the log information that lucian requested above?

@majorz maybe you know the answer from your experience.
We are trying to achieve that our device will serve as a hotspot, and phones will connect the device, but we want to make sure that the devices will keep using their 4g and use the internet from our device.
is that easy to get using network manager? i’ve googled quite a lot and didnt find a solution yet.

So when a phone connects to the access point of the device, it will receive an IP address from dnsmasq. You would like the 4G Internet of the phone to be shared through that WiFi connection with the device. This is kind of reversed case of the usual share internet through a hotspot. While not possible with NetworkManager directly, I think you can achieve that in the following way:

Use the dnsmasq DBus API to find out what the assigned phone address is: https://github.com/liquidm/dnsmasq/blob/master/dbus/DBus-interface#L266-L282.

Add a default route with ip route add default via to this IP address.

Both of those should be enough for the device to try to reach the Internet through the phone.

Next will be setting up the phone to share the 4G internet through the WiFi without creating a hotspot as the default Internet sharing involves creating a hotspot. I do not have experience those phone APIs and I am not sure how easy that would be.

i actually was looking for something more simple, sorry for the misunderstanding.
i’m looking for a way to make the phone, not using the device internet.
our device is connected through Ethernet and also serves as a hotspot.
my goal is that the internet of the mobile phone will keep being used by 4g, and it will be connected to the wifi of the device (so they can talk to each other)

Ah, so when the phone connects to the WiFi hotspot, it will detect the captive portal, and will expect this to be the Internet connection with higher priority, so it will stop using the 4G connection. You would like to continue using the 4G Internet from the cellular connection on your phone.

This again falls into the responsibility of the phone OS. What you need is to set somehow the phone to use higher route metrics (lower priority) for routes that are behind a captive portal. NetworkManager has a connectivity check feature, which can do that, and you will need to see whether the phone OS has a corresponding feature which could be configured.

Actually what you can do from the device side is to disable the captive portal feature on top of the hotspot, and also tell dnsmasq to not push a gateway record to the phone through DHCP (this I think could be done through --dhcp-option). This way the phone will know that the device does not provide Internet access, so it will not create a default route for reaching the Internet. But then again the captive portal feature will have to be disabled, so when you connect from your phone to the device, you will not have the automatic pop-up displayed, so you will have to open the browser manually and enter the IP address of the device to reach it. If you are using some phone app for reaching the phone and not rely on the phone captive portal detection and auto pop-up display, then this will fit your use-case well.

this is exactly what i need.
the solution without regards to the captive or not, we want this to be our permanent solution for every phone that will connect to our device.

how can this be done technically using network manager?

This won’t involve NetworkManager, only dnsmasq. When you currently start dnsmasq, you probably do it with this parameter added: --dhcp-option=option:router,<GATEWAY_IP>. This defines a gateway IP that is passed to the phone when it acquires DHCP information from the device. Since we do not want the phone to receive a gateway then this option should be omitted. If that does not work, try omitting only the IP like so ``–dhcp-option=option:router`. You may check for more information on this parameter the dnsmasq man page as it had some quirks.

i actually dont start dnmsq, it is probably started by NetworkManager.
i only use python-dbus API to start the wifi hot spot.

How do you assign IP addresses to the connected phones then?

its automaticly done by Network manager i guess.