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 default_proto_attach(const struct proto_handler *h,
45 struct interface *iface, struct blob_attr *attr)
47 struct interface_proto_state *proto;
49 proto = calloc(1, sizeof(*proto));
50 proto->free = default_proto_free;
51 proto->flags = PROTO_FLAG_IMMEDIATE;
52 proto->handler = no_proto_handler;
57 static const struct proto_handler no_proto = {
59 .attach = default_proto_attach,
62 static const struct proto_handler *
63 get_proto_handler(const char *name)
65 struct proto_handler *proto;
67 if (!strcmp(name, "none"))
73 return avl_find_element(&handlers, name, proto, avl);
77 proto_init_interface(struct interface *iface, struct blob_attr *attr)
79 const struct proto_handler *proto = iface->proto_handler;
80 struct interface_proto_state *state = NULL;
83 state = proto->attach(proto, iface, attr);
86 state = no_proto.attach(&no_proto, iface, attr);
87 state->handler = invalid_proto_handler;
90 interface_set_proto_state(iface, state);
94 proto_attach_interface(struct interface *iface, const char *proto_name)
96 const struct proto_handler *proto = NULL;
99 interface_add_error(iface, "proto", "NO_PROTO", NULL, 0);
103 proto = get_proto_handler(proto_name);
105 interface_add_error(iface, "proto", "INVALID_PROTO", NULL, 0);
107 iface->proto_handler = proto;
111 interface_proto_event(struct interface_proto_state *proto,
112 enum interface_proto_cmd cmd, bool force)
114 enum interface_event ev;
117 ret = proto->handler(proto, cmd, force);
118 if (ret || !(proto->flags & PROTO_FLAG_IMMEDIATE))
122 case PROTO_CMD_SETUP:
125 case PROTO_CMD_TEARDOWN:
131 proto->proto_event(proto, ev);