Add protocol update notifications and hotplug legacy calls
authorSteven Barth <steven@midlink.org>
Thu, 17 Oct 2013 14:51:49 +0000 (16:51 +0200)
committerSteven Barth <steven@midlink.org>
Thu, 17 Oct 2013 14:51:49 +0000 (16:51 +0200)
interface-event.c
interface.c
interface.h
proto-shell.c
ubus.c
ubus.h

index c6fe1cab877f0faa185a61e7ae81244e13d470b3..fe4759e6b5161c7742546cf78d78e20a354f46f8 100644 (file)
@@ -33,7 +33,7 @@ static struct uloop_process task = {
 };
 
 static void
-run_cmd(const char *ifname, const char *device, bool up)
+run_cmd(const char *ifname, const char *device, enum interface_event event)
 {
        char *argv[3];
        int pid;
@@ -48,7 +48,8 @@ run_cmd(const char *ifname, const char *device, bool up)
                return;
        }
 
-       setenv("ACTION", up ? "ifup" : "ifdown", 1);
+       char *eventnames[] = {"ifdown", "ifup", "ifupdate"};
+       setenv("ACTION", eventnames[event], 1);
        setenv("INTERFACE", ifname, 1);
        if (device)
                setenv("DEVICE", device, 1);
@@ -74,7 +75,7 @@ call_hotplug(void)
                device = current->l3_dev.dev->ifname;
 
        D(SYSTEM, "Call hotplug handler for interface '%s' (%s)\n", current->name, device ? device : "none");
-       run_cmd(current->name, device, current_ev == IFEV_UP);
+       run_cmd(current->name, device, current_ev);
 }
 
 static void
@@ -99,7 +100,11 @@ interface_queue_event(struct interface *iface, enum interface_event ev)
        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 (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)
                last_ev = current_ev;
        else
@@ -130,6 +135,7 @@ static void interface_event_cb(struct interface_user *dep, struct interface *ifa
 {
        switch (ev) {
                case IFEV_UP:
+               case IFEV_UPDATE:
                case IFEV_DOWN:
                        interface_queue_event(iface, ev);
                        break;
index 49fc830cc065c94ba79c85c10fdac009b9a0a9a1..a79de4a999977a64ce9de47bf4625ca985b24c57 100644 (file)
@@ -378,6 +378,7 @@ interface_alias_cb(struct interface_user *dep, struct interface *iface, enum int
                interface_remove_user(dep);
                break;
        case IFEV_RELOAD:
+       case IFEV_UPDATE:
                break;
        }
 }
@@ -483,8 +484,10 @@ interface_proto_cb(struct interface_proto_state *state, enum interface_proto_eve
 
        switch (ev) {
        case IFPEV_UP:
-               if (iface->state != IFS_SETUP)
+               if (iface->state != IFS_SETUP) {
+                       interface_event(iface, IFEV_UPDATE);
                        return;
+               }
 
                interface_ip_set_enabled(&iface->config_ip, true);
                system_flush_routes();
index e4d92aa22b93b626b4b4da134582bc58f90396e5..8c69958fa8edc78df18cb1a66476122843f385bf 100644 (file)
@@ -23,6 +23,7 @@ struct interface_proto_state;
 enum interface_event {
        IFEV_DOWN,
        IFEV_UP,
+       IFEV_UPDATE,
        IFEV_FREE,
        IFEV_RELOAD,
 };
index 4bb07446b8a1650c9bfe6548e4c442aca4c257dd..38d3871ff6f95858064e7f15b8c1576e30bcb0d2 100644 (file)
@@ -225,7 +225,7 @@ proto_shell_if_down_cb(struct interface_user *dep, struct interface *iface,
        struct proto_shell_dependency *pdep;
        struct proto_shell_state *state;
 
-       if (ev == IFEV_UP)
+       if (ev == IFEV_UP || ev == IFEV_UPDATE)
                return;
 
        pdep = container_of(dep, struct proto_shell_dependency, dep);
diff --git a/ubus.c b/ubus.c
index d24554198897ef6bb713d529e640a76227e93b91..a26c3dd276fe6ec55011e6caffc2ec2e5bf852fc 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -630,7 +630,6 @@ netifd_dump_status(struct interface *iface)
        struct device *dev;
        void *a, *inactive;
 
-       blobmsg_add_string(&b, "name", iface->name);
        blobmsg_add_u8(&b, "up", iface->state == IFS_UP);
        blobmsg_add_u8(&b, "pending", iface->state == IFS_SETUP);
        blobmsg_add_u8(&b, "available", iface->available);
@@ -739,6 +738,7 @@ netifd_handle_dump(struct ubus_context *ctx, struct ubus_object *obj,
        struct interface *iface;
        vlist_for_each_element(&interfaces, iface, node) {
                void *i = blobmsg_open_table(&b, NULL);
+               blobmsg_add_string(&b, "interface", iface->name);
                netifd_dump_status(iface);
                blobmsg_close_table(&b, i);
        }
@@ -996,6 +996,17 @@ netifd_ubus_interface_event(struct interface *iface, bool up)
        ubus_send_event(ctx, "network.interface", b.head);
 }
 
+void
+netifd_ubus_interface_notify(struct interface *iface, bool up)
+{
+       const char *event = (up) ? "update" : "down";
+       blob_buf_init(&b, 0);
+       blobmsg_add_string(&b, "interface", iface->name);
+       netifd_dump_status(iface);
+       ubus_notify(ctx, &iface_object, event, b.head, -1);
+       ubus_notify(ctx, &iface->ubus, event, b.head, -1);
+}
+
 void
 netifd_ubus_add_interface(struct interface *iface)
 {
diff --git a/ubus.h b/ubus.h
index 05bf39110c18fb2dd4e33c5a36e14c7060cb056d..553faef99764dd6175da6fb33e268225c37a3fa5 100644 (file)
--- a/ubus.h
+++ b/ubus.h
@@ -19,5 +19,6 @@ void netifd_ubus_done(void);
 void netifd_ubus_add_interface(struct interface *iface);
 void netifd_ubus_remove_interface(struct interface *iface);
 void netifd_ubus_interface_event(struct interface *iface, bool up);
+void netifd_ubus_interface_notify(struct interface *iface, bool up);
 
 #endif