10 #include "interface.h"
11 #include "interface-ip.h"
26 static const struct blobmsg_policy route_attr
[__ROUTE_MAX
] = {
27 [ROUTE_INTERFACE
] = { .name
= "interface", .type
= BLOBMSG_TYPE_STRING
},
28 [ROUTE_TARGET
] = { .name
= "target", .type
= BLOBMSG_TYPE_STRING
},
29 [ROUTE_MASK
] = { .name
= "netmask", .type
= BLOBMSG_TYPE_STRING
},
30 [ROUTE_GATEWAY
] = { .name
= "gateway", .type
= BLOBMSG_TYPE_STRING
},
31 [ROUTE_METRIC
] = { .name
= "metric", .type
= BLOBMSG_TYPE_INT32
},
32 [ROUTE_MTU
] = { .name
= "mtu", .type
= BLOBMSG_TYPE_INT32
},
35 const struct config_param_list route_attr_list
= {
36 .n_params
= __ROUTE_MAX
,
41 interface_ip_add_route(struct interface
*iface
, struct blob_attr
*attr
, bool v6
)
43 struct interface_ip_settings
*ip
;
44 struct blob_attr
*tb
[__ROUTE_MAX
], *cur
;
45 struct device_route
*route
;
46 int af
= v6
? AF_INET6
: AF_INET
;
48 blobmsg_parse(route_attr
, __ROUTE_MAX
, tb
, blobmsg_data(attr
), blobmsg_data_len(attr
));
51 if ((cur
= tb
[ROUTE_INTERFACE
]) == NULL
)
54 iface
= vlist_find(&interfaces
, blobmsg_data(cur
), iface
, node
);
58 ip
= &iface
->config_ip
;
60 ip
= &iface
->proto_ip
;
63 route
= calloc(1, sizeof(*route
));
67 route
->flags
= v6
? DEVADDR_INET6
: DEVADDR_INET4
;
68 route
->mask
= v6
? 128 : 32;
69 if ((cur
= tb
[ROUTE_MASK
]) != NULL
) {
70 route
->mask
= parse_netmask_string(blobmsg_data(cur
), v6
);
71 if (route
->mask
> (v6
? 128 : 32))
75 if ((cur
= tb
[ROUTE_TARGET
]) != NULL
) {
76 if (!inet_pton(af
, blobmsg_data(cur
), &route
->addr
)) {
77 DPRINTF("Failed to parse route target: %s\n", (char *) blobmsg_data(cur
));
82 if ((cur
= tb
[ROUTE_GATEWAY
]) != NULL
) {
83 if (!inet_pton(af
, blobmsg_data(cur
), &route
->nexthop
)) {
84 DPRINTF("Failed to parse route gateway: %s\n", (char *) blobmsg_data(cur
));
89 if ((cur
= tb
[ROUTE_METRIC
]) != NULL
) {
90 route
->metric
= blobmsg_get_u32(cur
);
91 route
->flags
|= DEVROUTE_METRIC
;
94 if ((cur
= tb
[ROUTE_MTU
]) != NULL
)
95 route
->mtu
= blobmsg_get_u32(cur
);
97 vlist_add(&ip
->route
, &route
->node
, &route
->flags
);
105 addr_cmp(const void *k1
, const void *k2
, void *ptr
)
107 return memcmp(k1
, k2
, sizeof(struct device_addr
) -
108 offsetof(struct device_addr
, flags
));
112 route_cmp(const void *k1
, const void *k2
, void *ptr
)
114 return memcmp(k1
, k2
, sizeof(struct device_route
) -
115 offsetof(struct device_route
, flags
));
119 interface_update_proto_addr(struct vlist_tree
*tree
,
120 struct vlist_node
*node_new
,
121 struct vlist_node
*node_old
)
123 struct interface_ip_settings
*ip
;
124 struct interface
*iface
;
126 struct device_addr
*a_new
= NULL
, *a_old
= NULL
;
129 ip
= container_of(tree
, struct interface_ip_settings
, addr
);
131 dev
= iface
->l3_dev
.dev
;
134 a_new
= container_of(node_new
, struct device_addr
, node
);
136 if ((a_new
->flags
& DEVADDR_FAMILY
) == DEVADDR_INET4
&&
140 uint32_t *a
= (uint32_t *) &a_new
->addr
;
142 mask
>>= a_new
->mask
;
143 a_new
->broadcast
= *a
| mask
;
148 a_old
= container_of(node_old
, struct device_addr
, node
);
150 if (a_new
&& a_old
) {
153 if (a_old
->flags
!= a_new
->flags
)
156 if ((a_new
->flags
& DEVADDR_FAMILY
) == DEVADDR_INET4
&&
157 a_new
->broadcast
!= a_old
->broadcast
)
162 if (!(a_old
->flags
& DEVADDR_EXTERNAL
) && a_old
->enabled
&& !keep
)
163 system_del_address(dev
, a_old
);
168 if (!(a_new
->flags
& DEVADDR_EXTERNAL
) && !keep
)
169 system_add_address(dev
, a_new
);
170 a_new
->enabled
= true;
175 enable_route(struct interface_ip_settings
*ip
, struct device_route
*route
)
177 if (ip
->no_defaultroute
&& !route
->mask
)
184 interface_update_proto_route(struct vlist_tree
*tree
,
185 struct vlist_node
*node_new
,
186 struct vlist_node
*node_old
)
188 struct interface_ip_settings
*ip
;
189 struct interface
*iface
;
191 struct device_route
*route_old
, *route_new
;
194 ip
= container_of(tree
, struct interface_ip_settings
, route
);
196 dev
= iface
->l3_dev
.dev
;
198 route_old
= container_of(node_old
, struct device_route
, node
);
199 route_new
= container_of(node_new
, struct device_route
, node
);
201 if (node_old
&& node_new
)
202 keep
= !memcmp(&route_old
->nexthop
, &route_new
->nexthop
, sizeof(route_old
->nexthop
));
205 if (!(route_old
->flags
& DEVADDR_EXTERNAL
) && route_old
->enabled
&& !keep
)
206 system_del_route(dev
, route_old
);
211 bool _enabled
= enable_route(ip
, route_new
);
213 if (!(route_new
->flags
& DEVADDR_EXTERNAL
) && !keep
&& _enabled
)
214 system_add_route(dev
, route_new
);
216 route_new
->iface
= iface
;
217 route_new
->enabled
= _enabled
;
222 interface_add_dns_server(struct interface_ip_settings
*ip
, const char *str
)
224 struct dns_server
*s
;
226 s
= calloc(1, sizeof(*s
));
228 if (inet_pton(s
->af
, str
, &s
->addr
.in
))
232 if (inet_pton(s
->af
, str
, &s
->addr
.in
))
239 D(INTERFACE
, "Add IPv%c DNS server: %s\n",
240 s
->af
== AF_INET6
? '6' : '4', str
);
241 vlist_simple_add(&ip
->dns_servers
, &s
->node
);
245 interface_add_dns_server_list(struct interface_ip_settings
*ip
, struct blob_attr
*list
)
247 struct blob_attr
*cur
;
250 blobmsg_for_each_attr(cur
, list
, rem
) {
251 if (blobmsg_type(cur
) != BLOBMSG_TYPE_STRING
)
254 if (!blobmsg_check_attr(cur
, NULL
))
257 interface_add_dns_server(ip
, blobmsg_data(cur
));
262 interface_add_dns_search_domain(struct interface_ip_settings
*ip
, const char *str
)
264 struct dns_search_domain
*s
;
265 int len
= strlen(str
);
267 s
= calloc(1, sizeof(*s
) + len
+ 1);
271 D(INTERFACE
, "Add DNS search domain: %s\n", str
);
272 memcpy(s
->name
, str
, len
);
273 vlist_simple_add(&ip
->dns_search
, &s
->node
);
277 interface_add_dns_search_list(struct interface_ip_settings
*ip
, struct blob_attr
*list
)
279 struct blob_attr
*cur
;
282 blobmsg_for_each_attr(cur
, list
, rem
) {
283 if (blobmsg_type(cur
) != BLOBMSG_TYPE_STRING
)
286 if (!blobmsg_check_attr(cur
, NULL
))
289 interface_add_dns_search_domain(ip
, blobmsg_data(cur
));
294 write_resolv_conf_entries(FILE *f
, struct interface_ip_settings
*ip
)
296 struct dns_server
*s
;
297 struct dns_search_domain
*d
;
301 vlist_simple_for_each_element(&ip
->dns_servers
, s
, node
) {
302 str
= inet_ntop(s
->af
, &s
->addr
, buf
, sizeof(buf
));
306 fprintf(f
, "nameserver %s\n", str
);
309 vlist_simple_for_each_element(&ip
->dns_search
, d
, node
) {
310 fprintf(f
, "search %s\n", d
->name
);
315 interface_write_resolv_conf(void)
317 struct interface
*iface
;
318 char *path
= alloca(strlen(resolv_conf
) + 5);
321 sprintf(path
, "%s.tmp", resolv_conf
);
323 f
= fopen(path
, "w");
325 D(INTERFACE
, "Failed to open %s for writing\n", path
);
329 vlist_for_each_element(&interfaces
, iface
, node
) {
330 if (iface
->state
!= IFS_UP
)
333 if (vlist_simple_empty(&iface
->proto_ip
.dns_search
) &&
334 vlist_simple_empty(&iface
->proto_ip
.dns_servers
) &&
335 vlist_simple_empty(&iface
->config_ip
.dns_search
) &&
336 vlist_simple_empty(&iface
->config_ip
.dns_servers
))
339 fprintf(f
, "# Interface %s\n", iface
->name
);
340 write_resolv_conf_entries(f
, &iface
->config_ip
);
341 write_resolv_conf_entries(f
, &iface
->proto_ip
);
344 if (rename(path
, resolv_conf
) < 0) {
345 D(INTERFACE
, "Failed to replace %s\n", resolv_conf
);
350 void interface_ip_set_enabled(struct interface_ip_settings
*ip
, bool enabled
)
352 struct device_addr
*addr
;
353 struct device_route
*route
;
356 ip
->enabled
= enabled
;
357 dev
= ip
->iface
->l3_dev
.dev
;
361 vlist_for_each_element(&ip
->addr
, addr
, node
) {
362 if (addr
->enabled
== enabled
)
366 system_add_address(dev
, addr
);
368 system_del_address(dev
, addr
);
369 addr
->enabled
= enabled
;
372 vlist_for_each_element(&ip
->route
, route
, node
) {
373 bool _enabled
= enabled
;
375 if (!enable_route(ip
, route
))
378 if (route
->enabled
== _enabled
)
382 if (!(route
->flags
& DEVROUTE_METRIC
))
383 route
->metric
= ip
->iface
->metric
;
385 system_add_route(dev
, route
);
387 system_del_route(dev
, route
);
388 route
->enabled
= _enabled
;
393 interface_ip_update_start(struct interface_ip_settings
*ip
)
395 vlist_simple_update(&ip
->dns_servers
);
396 vlist_simple_update(&ip
->dns_search
);
397 vlist_update(&ip
->route
);
398 vlist_update(&ip
->addr
);
402 interface_ip_update_complete(struct interface_ip_settings
*ip
)
404 vlist_simple_flush(&ip
->dns_servers
);
405 vlist_simple_flush(&ip
->dns_search
);
406 vlist_flush(&ip
->route
);
407 vlist_flush(&ip
->addr
);
411 interface_ip_flush(struct interface_ip_settings
*ip
)
413 vlist_simple_flush_all(&ip
->dns_servers
);
414 vlist_simple_flush_all(&ip
->dns_search
);
415 vlist_flush_all(&ip
->route
);
416 vlist_flush_all(&ip
->addr
);
420 interface_ip_init(struct interface_ip_settings
*ip
, struct interface
*iface
)
424 vlist_simple_init(&ip
->dns_search
, struct dns_search_domain
, node
);
425 vlist_simple_init(&ip
->dns_servers
, struct dns_server
, node
);
426 vlist_init(&ip
->route
, route_cmp
, interface_update_proto_route
);
427 vlist_init(&ip
->addr
, addr_cmp
, interface_update_proto_addr
);