10 #include "interface.h"
11 #include "interface-ip.h"
17 addr_cmp(const void *k1
, const void *k2
, void *ptr
)
19 return memcmp(k1
, k2
, sizeof(struct device_addr
) -
20 offsetof(struct device_addr
, mask
));
24 route_cmp(const void *k1
, const void *k2
, void *ptr
)
26 return memcmp(k1
, k2
, sizeof(struct device_route
) -
27 offsetof(struct device_route
, mask
));
31 interface_update_proto_addr(struct vlist_tree
*tree
,
32 struct vlist_node
*node_new
,
33 struct vlist_node
*node_old
)
35 struct interface
*iface
;
37 struct device_addr
*addr
;
39 iface
= container_of(tree
, struct interface
, proto_addr
);
40 dev
= iface
->l3_dev
->dev
;
43 addr
= container_of(node_old
, struct device_addr
, node
);
44 if (!(addr
->flags
& DEVADDR_EXTERNAL
))
45 system_del_address(dev
, addr
);
50 addr
= container_of(node_new
, struct device_addr
, node
);
51 if (!(addr
->flags
& DEVADDR_EXTERNAL
))
52 system_add_address(dev
, addr
);
57 interface_update_proto_route(struct vlist_tree
*tree
,
58 struct vlist_node
*node_new
,
59 struct vlist_node
*node_old
)
61 struct interface
*iface
;
63 struct device_route
*route
;
65 iface
= container_of(tree
, struct interface
, proto_route
);
66 dev
= iface
->l3_dev
->dev
;
69 route
= container_of(node_old
, struct device_route
, node
);
70 if (!(route
->flags
& DEVADDR_EXTERNAL
))
71 system_del_route(dev
, route
);
76 route
= container_of(node_new
, struct device_route
, node
);
77 if (!(route
->flags
& DEVADDR_EXTERNAL
))
78 system_add_route(dev
, route
);
83 interface_add_dns_server(struct interface
*iface
, const char *str
)
87 s
= calloc(1, sizeof(*s
));
89 if (inet_pton(s
->af
, str
, &s
->addr
.in
))
93 if (inet_pton(s
->af
, str
, &s
->addr
.in
))
100 D(INTERFACE
, "Add IPv%c DNS server: %s\n",
101 s
->af
== AF_INET6
? '6' : '4', str
);
102 list_add_tail(&s
->list
, &iface
->proto_dns_servers
);
106 interface_add_dns_server_list(struct interface
*iface
, struct blob_attr
*list
)
108 struct blob_attr
*cur
;
111 blobmsg_for_each_attr(cur
, list
, rem
) {
112 if (blobmsg_type(cur
) != BLOBMSG_TYPE_STRING
)
115 if (!blobmsg_check_attr(cur
, NULL
))
118 interface_add_dns_server(iface
, blobmsg_data(cur
));
123 interface_clear_dns_servers(struct interface
*iface
)
125 struct dns_server
*s
, *tmp
;
127 list_for_each_entry_safe(s
, tmp
, &iface
->proto_dns_servers
, list
) {
134 interface_clear_dns_search(struct interface
*iface
)
136 struct dns_search_domain
*s
, *tmp
;
138 list_for_each_entry_safe(s
, tmp
, &iface
->proto_dns_search
, list
) {
145 interface_clear_dns(struct interface
*iface
)
147 interface_clear_dns_servers(iface
);
148 interface_clear_dns_search(iface
);
152 interface_write_resolv_conf(void)
154 struct interface
*iface
;
155 struct dns_server
*s
;
156 struct dns_search_domain
*d
;
157 char *path
= alloca(strlen(resolv_conf
) + 5);
162 sprintf(path
, "%s.tmp", resolv_conf
);
164 f
= fopen(path
, "w");
166 D(INTERFACE
, "Failed to open %s for writing\n", path
);
170 vlist_for_each_element(&interfaces
, iface
, node
) {
171 if (iface
->state
!= IFS_UP
)
174 if (list_empty(&iface
->proto_dns_search
) &&
175 list_empty(&iface
->proto_dns_servers
))
178 fprintf(f
, "# Interface %s\n", iface
->name
);
179 list_for_each_entry(s
, &iface
->proto_dns_servers
, list
) {
180 str
= inet_ntop(s
->af
, &s
->addr
, buf
, sizeof(buf
));
184 fprintf(f
, "nameserver %s\n", str
);
187 list_for_each_entry(d
, &iface
->proto_dns_search
, list
) {
188 fprintf(f
, "search %s\n", d
->name
);
192 if (rename(path
, resolv_conf
) < 0) {
193 D(INTERFACE
, "Failed to replace %s\n", resolv_conf
);
199 interface_ip_update_start(struct interface
*iface
)
201 interface_clear_dns(iface
);
202 vlist_update(&iface
->proto_route
);
203 vlist_update(&iface
->proto_addr
);
207 interface_ip_update_complete(struct interface
*iface
)
209 vlist_flush(&iface
->proto_route
);
210 vlist_flush(&iface
->proto_addr
);
214 interface_ip_init(struct interface
*iface
)
216 vlist_init(&iface
->proto_route
, route_cmp
, interface_update_proto_route
,
217 struct device_route
, node
, mask
);
218 vlist_init(&iface
->proto_addr
, addr_cmp
, interface_update_proto_addr
,
219 struct device_addr
, node
, mask
);