move immediate protocol state transitions to a wrapper function
authorFelix Fietkau <nbd@openwrt.org>
Sun, 3 Apr 2011 17:05:48 +0000 (19:05 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 3 Apr 2011 17:05:51 +0000 (19:05 +0200)
interface.c
proto.c
proto.h

index ba7b5e52740162ecbc8dfaa1a39255cc17bc7bbe..a947cf6c7c5173f772260f8640fd389f61e56ca3 100644 (file)
@@ -81,7 +81,7 @@ __set_interface_up(struct interface *iface)
                return ret;
 
        iface->state = IFS_SETUP;
-       ret = iface->proto->handler(iface->proto, PROTO_CMD_SETUP, false);
+       ret = interface_proto_event(iface->proto, PROTO_CMD_SETUP, false);
        if (ret) {
                mark_interface_down(iface);
                return ret;
@@ -103,7 +103,7 @@ __set_interface_down(struct interface *iface, bool force)
        iface->state = IFS_TEARDOWN;
        interface_event(iface, IFEV_DOWN);
 
-       iface->proto->handler(iface->proto, PROTO_CMD_TEARDOWN, force);
+       interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, force);
        release_device(iface->main_dev.dev);
 }
 
@@ -162,7 +162,7 @@ interface_proto_cb(struct interface_proto_state *state, enum interface_proto_eve
 void interface_set_proto_state(struct interface *iface, struct interface_proto_state *state)
 {
        if (iface->proto) {
-               iface->proto->handler(iface->proto, PROTO_CMD_TEARDOWN, true);
+               interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, true);
                iface->proto->free(iface->proto);
                iface->proto = NULL;
        }
diff --git a/proto.c b/proto.c
index 287eae5f95fe2f807e54a26b51b192e786f72323..b16600ce749ab06ed2bbce301faddc99049d4d5a 100644 (file)
--- a/proto.c
+++ b/proto.c
@@ -15,8 +15,31 @@ default_proto_free(struct interface_proto_state *proto)
 static int
 default_proto_handler(struct interface_proto_state *proto,
                      enum interface_proto_cmd cmd, bool force)
+{
+       return 0;
+}
+
+struct interface_proto_state *get_default_proto(void)
+{
+       struct interface_proto_state *proto;
+
+       proto = calloc(1, sizeof(*proto));
+       proto->handler = default_proto_handler;
+       proto->free = default_proto_free;
+       proto->flags = PROTO_FLAG_IMMEDIATE;
+
+       return proto;
+}
+
+int interface_proto_event(struct interface_proto_state *proto,
+                         enum interface_proto_cmd cmd, bool force)
 {
        enum interface_event ev;
+       int ret;
+
+       ret = proto->handler(proto, cmd, force);
+       if (ret || !(proto->flags & PROTO_FLAG_IMMEDIATE))
+               goto out;
 
        switch(cmd) {
        case PROTO_CMD_SETUP:
@@ -29,15 +52,7 @@ default_proto_handler(struct interface_proto_state *proto,
                return -EINVAL;
        }
        proto->proto_event(proto, ev);
-       return 0;
-}
 
-struct interface_proto_state *get_default_proto(void)
-{
-       struct interface_proto_state *proto;
-
-       proto = calloc(1, sizeof(*proto));
-       proto->handler = default_proto_handler;
-       proto->free = default_proto_free;
-       return proto;
+out:
+       return ret;
 }
diff --git a/proto.h b/proto.h
index 92cef0162432d58c57023c92654ce9c991d37625..d94b992e67a5109c7e9ed199d44d41c6e879e162 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -13,8 +13,13 @@ enum interface_proto_cmd {
        PROTO_CMD_TEARDOWN,
 };
 
+enum {
+       PROTO_FLAG_IMMEDIATE = (1 << 0),
+};
+
 struct interface_proto_state {
        struct interface *iface;
+       unsigned int flags;
 
        /* filled in by the protocol user */
        void (*proto_event)(struct interface_proto_state *, enum interface_proto_event ev);
@@ -25,5 +30,7 @@ struct interface_proto_state {
 };
 
 struct interface_proto_state *get_default_proto(void);
+int interface_proto_event(struct interface_proto_state *proto,
+                         enum interface_proto_cmd cmd, bool force);
 
 #endif