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 *
44 get_default_proto(void)
46 struct interface_proto_state *proto;
48 proto = calloc(1, sizeof(*proto));
49 proto->free = default_proto_free;
50 proto->flags = PROTO_FLAG_IMMEDIATE;
55 struct proto_handler *
56 get_proto_handler(const char *name)
58 struct proto_handler *proto;
63 return avl_find_element(&handlers, name, proto, avl);
67 proto_attach_interface(struct interface *iface, struct uci_section *s)
69 struct interface_proto_state *state = NULL;
70 struct proto_handler *proto = NULL;
71 const char *proto_name;
72 const char *error = NULL;
74 proto_name = uci_lookup_option_string(uci_ctx, s, "proto");
80 if (!strcmp(proto_name, "none")) {
81 state = get_default_proto();
82 state->handler = no_proto_handler;
86 proto = get_proto_handler(proto_name);
88 error = "INVALID_PROTO";
92 state = proto->attach(proto, iface, s);
96 interface_add_error(iface, "proto", error, NULL, 0);
97 state = get_default_proto();
98 state->handler = invalid_proto_handler;
102 interface_set_proto_state(iface, state);
107 interface_proto_event(struct interface_proto_state *proto,
108 enum interface_proto_cmd cmd, bool force)
110 enum interface_event ev;
113 ret = proto->handler(proto, cmd, force);
114 if (ret || !(proto->flags & PROTO_FLAG_IMMEDIATE))
118 case PROTO_CMD_SETUP:
121 case PROTO_CMD_TEARDOWN:
127 proto->proto_event(proto, ev);