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_ip_settings
*ip
;
36 struct interface
*iface
;
38 struct device_addr
*addr
;
40 ip
= container_of(tree
, struct interface_ip_settings
, addr
);
42 dev
= iface
->l3_dev
->dev
;
45 addr
= container_of(node_old
, struct device_addr
, node
);
46 if (!(addr
->flags
& DEVADDR_EXTERNAL
))
47 system_del_address(dev
, addr
);
52 addr
= container_of(node_new
, struct device_addr
, node
);
53 if (!(addr
->flags
& DEVADDR_EXTERNAL
))
54 system_add_address(dev
, addr
);
59 interface_update_proto_route(struct vlist_tree
*tree
,
60 struct vlist_node
*node_new
,
61 struct vlist_node
*node_old
)
63 struct interface_ip_settings
*ip
;
64 struct interface
*iface
;
66 struct device_route
*route
;
68 ip
= container_of(tree
, struct interface_ip_settings
, route
);
70 dev
= iface
->l3_dev
->dev
;
73 route
= container_of(node_old
, struct device_route
, node
);
74 if (!(route
->flags
& DEVADDR_EXTERNAL
))
75 system_del_route(dev
, route
);
80 route
= container_of(node_new
, struct device_route
, node
);
81 if (!(route
->flags
& DEVADDR_EXTERNAL
))
82 system_add_route(dev
, route
);
87 interface_add_dns_server(struct interface_ip_settings
*ip
, const char *str
)
91 s
= calloc(1, sizeof(*s
));
93 if (inet_pton(s
->af
, str
, &s
->addr
.in
))
97 if (inet_pton(s
->af
, str
, &s
->addr
.in
))
104 D(INTERFACE
, "Add IPv%c DNS server: %s\n",
105 s
->af
== AF_INET6
? '6' : '4', str
);
106 list_add_tail(&s
->list
, &ip
->dns_servers
);
110 interface_add_dns_server_list(struct interface_ip_settings
*ip
, struct blob_attr
*list
)
112 struct blob_attr
*cur
;
115 blobmsg_for_each_attr(cur
, list
, rem
) {
116 if (blobmsg_type(cur
) != BLOBMSG_TYPE_STRING
)
119 if (!blobmsg_check_attr(cur
, NULL
))
122 interface_add_dns_server(ip
, blobmsg_data(cur
));
127 interface_add_dns_search_domain(struct interface_ip_settings
*ip
, const char *str
)
129 struct dns_search_domain
*s
;
130 int len
= strlen(str
);
132 s
= calloc(1, sizeof(*s
) + len
+ 1);
136 D(INTERFACE
, "Add DNS search domain: %s\n", str
);
137 memcpy(s
->name
, str
, len
);
138 list_add_tail(&s
->list
, &ip
->dns_search
);
142 interface_add_dns_search_list(struct interface_ip_settings
*ip
, struct blob_attr
*list
)
144 struct blob_attr
*cur
;
147 blobmsg_for_each_attr(cur
, list
, rem
) {
148 if (blobmsg_type(cur
) != BLOBMSG_TYPE_STRING
)
151 if (!blobmsg_check_attr(cur
, NULL
))
154 interface_add_dns_server(ip
, blobmsg_data(cur
));
159 interface_clear_dns_servers(struct interface_ip_settings
*ip
)
161 struct dns_server
*s
, *tmp
;
163 list_for_each_entry_safe(s
, tmp
, &ip
->dns_servers
, list
) {
170 interface_clear_dns_search(struct interface_ip_settings
*ip
)
172 struct dns_search_domain
*s
, *tmp
;
174 list_for_each_entry_safe(s
, tmp
, &ip
->dns_search
, list
) {
181 interface_write_resolv_conf(void)
183 struct interface
*iface
;
184 struct dns_server
*s
;
185 struct dns_search_domain
*d
;
186 char *path
= alloca(strlen(resolv_conf
) + 5);
191 sprintf(path
, "%s.tmp", resolv_conf
);
193 f
= fopen(path
, "w");
195 D(INTERFACE
, "Failed to open %s for writing\n", path
);
199 vlist_for_each_element(&interfaces
, iface
, node
) {
200 if (iface
->state
!= IFS_UP
)
203 if (list_empty(&iface
->proto_ip
.dns_search
) &&
204 list_empty(&iface
->proto_ip
.dns_servers
))
207 fprintf(f
, "# Interface %s\n", iface
->name
);
208 list_for_each_entry(s
, &iface
->proto_ip
.dns_servers
, list
) {
209 str
= inet_ntop(s
->af
, &s
->addr
, buf
, sizeof(buf
));
213 fprintf(f
, "nameserver %s\n", str
);
216 list_for_each_entry(d
, &iface
->proto_ip
.dns_search
, list
) {
217 fprintf(f
, "search %s\n", d
->name
);
221 if (rename(path
, resolv_conf
) < 0) {
222 D(INTERFACE
, "Failed to replace %s\n", resolv_conf
);
228 interface_ip_update_start(struct interface_ip_settings
*ip
)
230 interface_clear_dns_servers(ip
);
231 interface_clear_dns_search(ip
);
232 vlist_update(&ip
->route
);
233 vlist_update(&ip
->addr
);
237 interface_ip_update_complete(struct interface_ip_settings
*ip
)
239 vlist_flush(&ip
->route
);
240 vlist_flush(&ip
->addr
);
244 interface_ip_flush(struct interface_ip_settings
*ip
)
246 interface_clear_dns_servers(ip
);
247 interface_clear_dns_search(ip
);
248 vlist_flush_all(&ip
->route
);
249 vlist_flush_all(&ip
->addr
);
253 interface_ip_init(struct interface_ip_settings
*ip
, struct interface
*iface
)
256 INIT_LIST_HEAD(&ip
->dns_search
);
257 INIT_LIST_HEAD(&ip
->dns_servers
);
258 vlist_init(&ip
->route
, route_cmp
, interface_update_proto_route
,
259 struct device_route
, node
, mask
);
260 vlist_init(&ip
->addr
, addr_cmp
, interface_update_proto_addr
,
261 struct device_addr
, node
, mask
);