OpenWrt Forum Archive

Topic: How does hotplug work for network interfaces?

The content of this topic has been archived on 3 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I'm trying to wrap my mind around the full sequence of events from an interface coming up (or its address changing) to the scripts in /etc/hotplug.d/iface being called. I'm specifically interested in this for ddns purposes (ddns-scripts packages drops a 25-ddns script there), but the discussion should apply more generally.

I start in the kernel, where subsystems can inject a uevent using kobject_uevent:
http://lxr.linux.no/linux+v3.12.6/lib/k … ent.c#L322

That takes an enum for the action, which is stringified according to this LUT for inclusion in the netlink message as "ACTION=":
http://lxr.linux.no/linux+v3.12.6/lib/k … vent.c#L45
The possible values are: add, remove, change, move, online, offline.

I looked around linux/net/ for call sites of kobject_uevent and it seems like net only delivers add/remove for devices as a whole, plus change for a few protocol/driver specific cases like rfkill. No interface address change events? Anyway, let's continue..

From here procd appears to create a netlink socket and pump events out of it:
http://nbd.name/gitweb.cgi?p=luci2/proc … =HEAD#l451

There doesn't seem to be much event-specific handling in C code, but there is a mini domain-specific language (why a new language instead of bash or lua?) expressed in JSON that takes care of certain subsystems specially:
https://dev.openwrt.org/browser/trunk/p … ?rev=36994

netifd *also* creates a netlink socket and pumps events out of it:
http://nbd.name/gitweb.cgi?p=luci2/neti … =HEAD#l141

netifd seems to handle "add" and "remove" events only, using them to update internal state about device presence and to rebroadcast state changes to internal subscribers. I see calls to device_claim in alias.c, bridge.c, vlan.c, a few others. Do these events somehow end up on ubus? Are there any bash scripts (ala /etc/hotplug.d) executed as a result of these events? examples/hotplug-cmd seems to be a hotplug script, when does this come into play?

Going back to procd, the openwrt hotplug.json, for "net" events, runs /sbin/hotplug-call %SUBSYSTEM%. This runs the scripts in /etc/hotplug.d/net with environment from the uevent:
https://dev.openwrt.org/browser/trunk/p … =36994#L71

hotplug.json has no configuration for SUBSYSTEM=iface. Are these events swallowed? What about the "ifup" and "ifdown" values for ACTION? (these are documented on the wiki: http://wiki.openwrt.org/doc/techref/hotplug and used by the scripts in /etc/hotplug.d/iface) I'm starting to think SUBSYSTEM=iface may not actually exist..

Does uevent deliver events only for device add/remove, or also when an interface alias is created? What about when the addresses of an interface change? I tried answering some of these questions by running 'strace -f -p 1' (stracing procd) and bringing up an alias of lo (ifconfig lo:1 1.1.1.1 netmask 255.255.255.0) but it didn't seem to get any events. I also tried stracing netifd, again with no visible effects. I can't easily play with the other interface on this router because it's in active use.

The reason I'm doing this is I suspect ddns-scripts is not being triggered when my WAN interface gets an IP. It has the following script in /etc/hotplug.d/iface/25-ddns:
#!/bin/sh

. /usr/lib/ddns/dynamic_dns_functions.sh

if [ "$ACTION" = "ifup" ]; then
    start_daemon_for_all_ddns_sections "$INTERFACE"
fi


In my case the WAN proto is DHCP - I want an event when WAN gets an IP (*after* the underlying network device has come up). What is the best hook to trigger for this? I have another router that uses PPP on wan so I'm looking for a generic solution.

Thanks.

(Last edited by eigma on 26 Dec 2013, 04:01)

While I was away my router did a renew of its wan lease:

Thu Dec 26 23:24:20 2013 daemon.notice netifd: wan (833): Sending renew...
Thu Dec 26 23:24:20 2013 daemon.notice netifd: wan (833): Lease of 174.112.209.141 obtained, lease time 3600
Thu Dec 26 23:24:20 2013 user.notice firewall: Reloading firewall due to ifup of wan ()

That last log from firewall is from /etc/hotplug.d/iface/20-firewall so it looks like netifd does call those scripts.

[strike]It also looks like ACTION=ifup gets emitted for lease renews as well (when the interface already has an address).[/strike] EDIT: ACTION=ifupdate on dhcp renews

(Last edited by eigma on 27 Dec 2013, 08:15)

Aha, from netifd interface-event.c:

    char *eventnames[] = {"ifdown", "ifup", "ifupdate"};
    setenv("ACTION", eventnames[event], 1);
    setenv("INTERFACE", ifname, 1);
    if (device)
        setenv("DEVICE", device, 1);
    argv[0] = hotplug_cmd_path;
    argv[1] = "iface";
    argv[2] = NULL;
    execvp(argv[0], argv);
    exit(127);

netifd's cycle appears to be:
- Start some proto-specific mechanism for acquiring interface configuration. For DHCP this is driven by proto-shell.c, which spawns /lib/netifd/proto/dhcp.sh, which is a thin wrapper around udhcpc. udhcpc is long-lived and set up to call back into /lib/netifd/dhcp.script for dhcp events:
  833 root      1488 S    udhcpc -p /var/run/udhcpc-eth1.pid -s /lib/netifd/dhcp.script -f -t 0 -i eth1 -C

- dhcp.script packages variables from udhcpc into json and end up doing 'ubus call network.interface notify_proto <json>'. This in turn is handled by netifd in proto-shell.c, in proto_shell_notify. Action is 0, which leads into proto_shell_update_link.

- proto_shell_update_link delivers an event to the interface through state->proto.proto_event (interface_proto_cb), which calls interface_event, which leads to the snippet above, calling into /sbin/hotplug-call with ACTION=ifupdate.

Hi eigma -

thanks for the analysis -

i do run in the same circles for a while now.

Still now clue why not getting event-actions on wan up or other interfaces coming up/down

Do you have some more insight to help me out ?

Wondering abt these json "script" containers also -seems quite wierd to me - is there any infor for the concept behind this ?

regards
3zl

Sorry to open up this old thread but I have the same problem: no hotplug events when wan or other interface comes up.

Has anyone found a solution to these problems?

I need a hook that fires when a non-DHCP interface has come up.

Thanks

(Last edited by danielcra on 3 Jun 2015, 08:46)

For anyone who is having issues for interface up and down events for Attitude Adjustment (AA), you might want to check out the patches provided by Hans Dedecker which don't appear to have been incorporated into AA. Here is a link to the mailing list thread where these patches can be found (check out patch 7 and 8).
https://lists.openwrt.org/pipermail/ope … 22538.html

Perhaps someone could get them added to AA to allow for this capability?

It would appear that the Hans Dedecker patches _did_ make it into the upstream netifd sources, but the default commit used by the tip of AA for the netifd package is old. You should be able to pick up these changes by changing which netifd commit hash you use (edit the package/netifd/Makefile in your copy of AA). I can't promise this won't break something, nor can I suggest which commit hash would be a stable hash to go with.  The netifd commit hash that includes the Han patches is:
7335c3e19ea09674245dda3653d3f40705e68d6b

Hopefully someone with more experience can comment on more stable commit hash that includes these patches that should be used for AA. Thanks.

The discussion might have continued from here.