- 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);
+ /* no hotplug.d calls for link up */
+ if (ev == IFEV_LINK_UP)
+ return;
+
+ 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);
+ }
+ }