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_add_dns_search_domain(struct interface
*iface
, const char *str
)
125 struct dns_search_domain
*s
;
126 int len
= strlen(str
);
128 s
= calloc(1, sizeof(*s
) + len
+ 1);
132 D(INTERFACE
, "Add DNS search domain: %s\n", str
);
133 memcpy(s
->name
, str
, len
);
134 list_add_tail(&s
->list
, &iface
->proto_dns_search
);
138 interface_add_dns_search_list(struct interface
*iface
, struct blob_attr
*list
)
140 struct blob_attr
*cur
;
143 blobmsg_for_each_attr(cur
, list
, rem
) {
144 if (blobmsg_type(cur
) != BLOBMSG_TYPE_STRING
)
147 if (!blobmsg_check_attr(cur
, NULL
))
150 interface_add_dns_server(iface
, blobmsg_data(cur
));
155 interface_clear_dns_servers(struct interface
*iface
)
157 struct dns_server
*s
, *tmp
;
159 list_for_each_entry_safe(s
, tmp
, &iface
->proto_dns_servers
, list
) {
166 interface_clear_dns_search(struct interface
*iface
)
168 struct dns_search_domain
*s
, *tmp
;
170 list_for_each_entry_safe(s
, tmp
, &iface
->proto_dns_search
, list
) {
177 interface_clear_dns(struct interface
*iface
)
179 interface_clear_dns_servers(iface
);
180 interface_clear_dns_search(iface
);
184 interface_write_resolv_conf(void)
186 struct interface
*iface
;
187 struct dns_server
*s
;
188 struct dns_search_domain
*d
;
189 char *path
= alloca(strlen(resolv_conf
) + 5);
194 sprintf(path
, "%s.tmp", resolv_conf
);
196 f
= fopen(path
, "w");
198 D(INTERFACE
, "Failed to open %s for writing\n", path
);
202 vlist_for_each_element(&interfaces
, iface
, node
) {
203 if (iface
->state
!= IFS_UP
)
206 if (list_empty(&iface
->proto_dns_search
) &&
207 list_empty(&iface
->proto_dns_servers
))
210 fprintf(f
, "# Interface %s\n", iface
->name
);
211 list_for_each_entry(s
, &iface
->proto_dns_servers
, list
) {
212 str
= inet_ntop(s
->af
, &s
->addr
, buf
, sizeof(buf
));
216 fprintf(f
, "nameserver %s\n", str
);
219 list_for_each_entry(d
, &iface
->proto_dns_search
, list
) {
220 fprintf(f
, "search %s\n", d
->name
);
224 if (rename(path
, resolv_conf
) < 0) {
225 D(INTERFACE
, "Failed to replace %s\n", resolv_conf
);
231 interface_ip_update_start(struct interface
*iface
)
233 interface_clear_dns(iface
);
234 vlist_update(&iface
->proto_route
);
235 vlist_update(&iface
->proto_addr
);
239 interface_ip_update_complete(struct interface
*iface
)
241 vlist_flush(&iface
->proto_route
);
242 vlist_flush(&iface
->proto_addr
);
246 interface_ip_init(struct interface
*iface
)
248 vlist_init(&iface
->proto_route
, route_cmp
, interface_update_proto_route
,
249 struct device_route
, node
, mask
);
250 vlist_init(&iface
->proto_addr
, addr_cmp
, interface_update_proto_addr
,
251 struct device_addr
, node
, mask
);