6 #include <netinet/in.h>
10 #include "interface-ip.h"
13 static struct avl_tree handlers;
16 split_netmask(char *str, unsigned int *netmask)
18 char *delim, *err = NULL;
20 delim = strchr(str, '/');
24 *netmask = strtoul(delim, &err, 10);
32 parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netmask)
34 char *astr = alloca(strlen(str) + 1);
37 if (!split_netmask(astr, netmask))
48 return inet_pton(af, astr, addr);
52 proto_parse_ip_addr_string(const char *str, bool v6, int mask)
54 struct device_addr *addr;
55 int af = v6 ? AF_INET6 : AF_INET;
57 addr = calloc(1, sizeof(*addr));
58 addr->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4;
60 if (!parse_ip_and_netmask(af, str, &addr->addr, &addr->mask)) {
68 void add_proto_handler(struct proto_handler *p)
71 avl_init(&handlers, avl_strcmp, false, NULL);
77 avl_insert(&handlers, &p->avl);
81 default_proto_free(struct interface_proto_state *proto)
87 invalid_proto_handler(struct interface_proto_state *proto,
88 enum interface_proto_cmd cmd, bool force)
94 no_proto_handler(struct interface_proto_state *proto,
95 enum interface_proto_cmd cmd, bool force)
100 static struct interface_proto_state *
101 default_proto_attach(const struct proto_handler *h,
102 struct interface *iface, struct blob_attr *attr)
104 struct interface_proto_state *proto;
106 proto = calloc(1, sizeof(*proto));
107 proto->free = default_proto_free;
108 proto->cb = no_proto_handler;
113 static const struct proto_handler no_proto = {
115 .flags = PROTO_FLAG_IMMEDIATE,
116 .attach = default_proto_attach,
119 static const struct proto_handler *
120 get_proto_handler(const char *name)
122 struct proto_handler *proto;
124 if (!strcmp(name, "none"))
130 return avl_find_element(&handlers, name, proto, avl);
134 proto_init_interface(struct interface *iface, struct blob_attr *attr)
136 const struct proto_handler *proto = iface->proto_handler;
137 struct interface_proto_state *state = NULL;
140 state = proto->attach(proto, iface, attr);
143 state = no_proto.attach(&no_proto, iface, attr);
144 state->cb = invalid_proto_handler;
147 state->handler = proto;
148 interface_set_proto_state(iface, state);
152 proto_attach_interface(struct interface *iface, const char *proto_name)
154 const struct proto_handler *proto = NULL;
157 interface_add_error(iface, "proto", "NO_PROTO", NULL, 0);
161 proto = get_proto_handler(proto_name);
163 interface_add_error(iface, "proto", "INVALID_PROTO", NULL, 0);
165 iface->proto_handler = proto;
169 interface_proto_event(struct interface_proto_state *proto,
170 enum interface_proto_cmd cmd, bool force)
172 enum interface_proto_event ev;
175 ret = proto->cb(proto, cmd, force);
176 if (ret || !(proto->handler->flags & PROTO_FLAG_IMMEDIATE))
180 case PROTO_CMD_SETUP:
183 case PROTO_CMD_TEARDOWN:
189 proto->proto_event(proto, ev);