99f083c60025c045897387c9febd29c8249667f0
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
, str
, 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_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
);