9 static struct avl_tree handlers;
11 void add_proto_handler(struct proto_handler *p)
14 avl_init(&handlers, avl_strcmp, false, NULL);
20 avl_insert(&handlers, &p->avl);
24 default_proto_free(struct interface_proto_state *proto)
30 invalid_proto_handler(struct interface_proto_state *proto,
31 enum interface_proto_cmd cmd, bool force)
37 no_proto_handler(struct interface_proto_state *proto,
38 enum interface_proto_cmd cmd, bool force)
43 static struct interface_proto_state *get_default_proto(void)
45 struct interface_proto_state *proto;
47 proto = calloc(1, sizeof(*proto));
48 proto->free = default_proto_free;
49 proto->flags = PROTO_FLAG_IMMEDIATE;
54 void proto_attach_interface(struct interface *iface, struct uci_section *s)
56 struct interface_proto_state *state = NULL;
57 struct proto_handler *proto = NULL;
58 const char *proto_name;
59 const char *error = NULL;
61 proto_name = uci_lookup_option_string(uci_ctx, s, "proto");
67 if (!strcmp(proto_name, "none")) {
68 state = get_default_proto();
69 state->handler = no_proto_handler;
74 proto = avl_find_element(&handlers, proto_name, proto, avl);
77 error = "INVALID_PROTO";
81 state = proto->attach(proto, iface);
85 interface_add_error(iface, "proto", error, NULL, 0);
86 state = get_default_proto();
87 state->handler = invalid_proto_handler;
91 interface_set_proto_state(iface, state);
95 int interface_proto_event(struct interface_proto_state *proto,
96 enum interface_proto_cmd cmd, bool force)
98 enum interface_event ev;
101 ret = proto->handler(proto, cmd, force);
102 if (ret || !(proto->flags & PROTO_FLAG_IMMEDIATE))
106 case PROTO_CMD_SETUP:
109 case PROTO_CMD_TEARDOWN:
115 proto->proto_event(proto, ev);