- enum interface_event last_ev;
-
- D(SYSTEM, "Queue hotplug handler for interface '%s'\n", iface->name);
- netifd_ubus_interface_event(iface, ev == IFEV_UP);
- if (current == iface)
- last_ev = current_ev;
- else
- last_ev = iface->hotplug_ev;
-
- iface->hotplug_ev = ev;
- if (last_ev == ev && !list_empty(&iface->hotplug_list))
- list_del(&iface->hotplug_list);
- else if (last_ev != ev && list_empty(&iface->hotplug_list))
- list_add(&iface->hotplug_list, &pending);
+ D(SYSTEM, "Queue hotplug handler for interface '%s', event '%s'\n",
+ iface->name, eventnames[ev]);
+ if (ev == IFEV_UP || ev == IFEV_DOWN)
+ netifd_ubus_interface_event(iface, ev == IFEV_UP);
+
+ netifd_ubus_interface_notify(iface, ev != IFEV_DOWN);
+
+ if (current == iface) {
+ /* an event for iface is being processed */
+ if (!list_empty(&iface->hotplug_list)) {
+ /* an additional event for iface is pending */
+ /* overwrite pending event if it differs from */
+ /* an update */
+ if (ev != IFEV_UPDATE)
+ iface->hotplug_ev = ev;
+ }
+ else {
+ /* no additional event for iface is pending */
+ if (ev != current_ev || ev == IFEV_UPDATE) {
+ /* only add the interface to the pending list if
+ * the event is different from the one being
+ * handled or if it is an update */
+ iface->hotplug_ev = ev;
+ /* Handle hotplug calls FIFO */
+ list_add_tail(&iface->hotplug_list, &pending);
+ }
+ }
+ }
+ else {
+ /* currently not handling an event or handling an event
+ * for another interface */
+ if (!list_empty(&iface->hotplug_list)) {
+ /* an event for iface is pending */
+ if (!(iface->hotplug_ev == IFEV_UP &&
+ ev == IFEV_UPDATE)) {
+ /* overwrite pending event, unless the incoming
+ * event is an ifupdate while the pending one
+ * is an ifup */
+ iface->hotplug_ev = ev;
+ }
+ }
+ else {
+ /* an event for the interface is not yet pending,
+ * queue it */
+ iface->hotplug_ev = ev;
+ /* Handle hotplug calls FIFO */
+ list_add_tail(&iface->hotplug_list, &pending);
+ }
+ }