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
);