1a260cc166b8b72521470adb34130771fee9651e
6 #include <netinet/in.h>
10 #include "interface-ip.h"
13 static struct avl_tree handlers
;
16 parse_netmask_string(const char *str
, bool v6
)
22 if (!strchr(str
, '.')) {
23 ret
= strtoul(str
, &err
, 0);
33 if (inet_aton(str
, &addr
) != 1)
36 return 32 - fls(~(ntohl(addr
.s_addr
)));
43 split_netmask(char *str
, unsigned int *netmask
, bool v6
)
45 char *delim
= strchr(str
, '/');
50 *netmask
= parse_netmask_string(delim
, v6
);
56 parse_ip_and_netmask(int af
, const char *str
, void *addr
, unsigned int *netmask
)
58 char *astr
= alloca(strlen(str
) + 1);
61 if (!split_netmask(astr
, netmask
, af
== AF_INET6
))
72 return inet_pton(af
, astr
, addr
);
76 proto_parse_ip_addr_string(const char *str
, bool v6
, int mask
)
78 struct device_addr
*addr
;
79 int af
= v6
? AF_INET6
: AF_INET
;
81 addr
= calloc(1, sizeof(*addr
));
82 addr
->flags
= v6
? DEVADDR_INET6
: DEVADDR_INET4
;
84 if (!parse_ip_and_netmask(af
, str
, &addr
->addr
, &addr
->mask
)) {
92 void add_proto_handler(struct proto_handler
*p
)
95 avl_init(&handlers
, avl_strcmp
, false, NULL
);
100 p
->avl
.key
= p
->name
;
101 avl_insert(&handlers
, &p
->avl
);
105 default_proto_free(struct interface_proto_state
*proto
)
111 invalid_proto_handler(struct interface_proto_state
*proto
,
112 enum interface_proto_cmd cmd
, bool force
)
118 no_proto_handler(struct interface_proto_state
*proto
,
119 enum interface_proto_cmd cmd
, bool force
)
124 static struct interface_proto_state
*
125 default_proto_attach(const struct proto_handler
*h
,
126 struct interface
*iface
, struct blob_attr
*attr
)
128 struct interface_proto_state
*proto
;
130 proto
= calloc(1, sizeof(*proto
));
131 proto
->free
= default_proto_free
;
132 proto
->cb
= no_proto_handler
;
137 static const struct proto_handler no_proto
= {
139 .flags
= PROTO_FLAG_IMMEDIATE
,
140 .attach
= default_proto_attach
,
143 static const struct proto_handler
*
144 get_proto_handler(const char *name
)
146 struct proto_handler
*proto
;
148 if (!strcmp(name
, "none"))
154 return avl_find_element(&handlers
, name
, proto
, avl
);
158 proto_init_interface(struct interface
*iface
, struct blob_attr
*attr
)
160 const struct proto_handler
*proto
= iface
->proto_handler
;
161 struct interface_proto_state
*state
= NULL
;
166 state
= proto
->attach(proto
, iface
, attr
);
168 state
= no_proto
.attach(&no_proto
, iface
, attr
);
169 state
->cb
= invalid_proto_handler
;
172 state
->handler
= proto
;
173 interface_set_proto_state(iface
, state
);
177 proto_attach_interface(struct interface
*iface
, const char *proto_name
)
179 const struct proto_handler
*proto
= &no_proto
;
182 proto
= get_proto_handler(proto_name
);
184 interface_add_error(iface
, "proto", "INVALID_PROTO", NULL
, 0);
189 iface
->proto_handler
= proto
;
193 interface_proto_event(struct interface_proto_state
*proto
,
194 enum interface_proto_cmd cmd
, bool force
)
196 enum interface_proto_event ev
;
199 ret
= proto
->cb(proto
, cmd
, force
);
200 if (ret
|| !(proto
->handler
->flags
& PROTO_FLAG_IMMEDIATE
))
204 case PROTO_CMD_SETUP
:
207 case PROTO_CMD_TEARDOWN
:
213 proto
->proto_event(proto
, ev
);