From: Felix Fietkau Date: Wed, 19 Oct 2011 16:46:53 +0000 (+0200) Subject: add support for keeping multiple ip addr/route/dns lists X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=commitdiff_plain;h=a0dedf26ed338ef420784541da0676ad91e181a7 add support for keeping multiple ip addr/route/dns lists --- diff --git a/interface-ip.c b/interface-ip.c index a5efad5..b875f50 100644 --- a/interface-ip.c +++ b/interface-ip.c @@ -32,11 +32,13 @@ interface_update_proto_addr(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old) { + struct interface_ip_settings *ip; struct interface *iface; struct device *dev; struct device_addr *addr; - iface = container_of(tree, struct interface, proto_addr); + ip = container_of(tree, struct interface_ip_settings, addr); + iface = ip->iface; dev = iface->l3_dev->dev; if (node_old) { @@ -58,11 +60,13 @@ interface_update_proto_route(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old) { + struct interface_ip_settings *ip; struct interface *iface; struct device *dev; struct device_route *route; - iface = container_of(tree, struct interface, proto_route); + ip = container_of(tree, struct interface_ip_settings, route); + iface = ip->iface; dev = iface->l3_dev->dev; if (node_old) { @@ -80,7 +84,7 @@ interface_update_proto_route(struct vlist_tree *tree, } void -interface_add_dns_server(struct interface *iface, const char *str) +interface_add_dns_server(struct interface_ip_settings *ip, const char *str) { struct dns_server *s; @@ -99,11 +103,11 @@ interface_add_dns_server(struct interface *iface, const char *str) add: D(INTERFACE, "Add IPv%c DNS server: %s\n", s->af == AF_INET6 ? '6' : '4', str); - list_add_tail(&s->list, &iface->proto_dns_servers); + list_add_tail(&s->list, &ip->dns_servers); } void -interface_add_dns_server_list(struct interface *iface, struct blob_attr *list) +interface_add_dns_server_list(struct interface_ip_settings *ip, struct blob_attr *list) { struct blob_attr *cur; int rem; @@ -115,12 +119,12 @@ interface_add_dns_server_list(struct interface *iface, struct blob_attr *list) if (!blobmsg_check_attr(cur, NULL)) continue; - interface_add_dns_server(iface, blobmsg_data(cur)); + interface_add_dns_server(ip, blobmsg_data(cur)); } } void -interface_add_dns_search_domain(struct interface *iface, const char *str) +interface_add_dns_search_domain(struct interface_ip_settings *ip, const char *str) { struct dns_search_domain *s; int len = strlen(str); @@ -131,11 +135,11 @@ interface_add_dns_search_domain(struct interface *iface, const char *str) D(INTERFACE, "Add DNS search domain: %s\n", str); memcpy(s->name, str, len); - list_add_tail(&s->list, &iface->proto_dns_search); + list_add_tail(&s->list, &ip->dns_search); } void -interface_add_dns_search_list(struct interface *iface, struct blob_attr *list) +interface_add_dns_search_list(struct interface_ip_settings *ip, struct blob_attr *list) { struct blob_attr *cur; int rem; @@ -147,40 +151,33 @@ interface_add_dns_search_list(struct interface *iface, struct blob_attr *list) if (!blobmsg_check_attr(cur, NULL)) continue; - interface_add_dns_server(iface, blobmsg_data(cur)); + interface_add_dns_server(ip, blobmsg_data(cur)); } } static void -interface_clear_dns_servers(struct interface *iface) +interface_clear_dns_servers(struct interface_ip_settings *ip) { struct dns_server *s, *tmp; - list_for_each_entry_safe(s, tmp, &iface->proto_dns_servers, list) { + list_for_each_entry_safe(s, tmp, &ip->dns_servers, list) { list_del(&s->list); free(s); } } static void -interface_clear_dns_search(struct interface *iface) +interface_clear_dns_search(struct interface_ip_settings *ip) { struct dns_search_domain *s, *tmp; - list_for_each_entry_safe(s, tmp, &iface->proto_dns_search, list) { + list_for_each_entry_safe(s, tmp, &ip->dns_search, list) { list_del(&s->list); free(s); } } void -interface_clear_dns(struct interface *iface) -{ - interface_clear_dns_servers(iface); - interface_clear_dns_search(iface); -} - -void interface_write_resolv_conf(void) { struct interface *iface; @@ -203,12 +200,12 @@ interface_write_resolv_conf(void) if (iface->state != IFS_UP) continue; - if (list_empty(&iface->proto_dns_search) && - list_empty(&iface->proto_dns_servers)) + if (list_empty(&iface->proto_ip.dns_search) && + list_empty(&iface->proto_ip.dns_servers)) continue; fprintf(f, "# Interface %s\n", iface->name); - list_for_each_entry(s, &iface->proto_dns_servers, list) { + list_for_each_entry(s, &iface->proto_ip.dns_servers, list) { str = inet_ntop(s->af, &s->addr, buf, sizeof(buf)); if (!str) continue; @@ -216,7 +213,7 @@ interface_write_resolv_conf(void) fprintf(f, "nameserver %s\n", str); } - list_for_each_entry(d, &iface->proto_dns_search, list) { + list_for_each_entry(d, &iface->proto_ip.dns_search, list) { fprintf(f, "search %s\n", d->name); } } @@ -228,25 +225,38 @@ interface_write_resolv_conf(void) } void -interface_ip_update_start(struct interface *iface) +interface_ip_update_start(struct interface_ip_settings *ip) +{ + interface_clear_dns_servers(ip); + interface_clear_dns_search(ip); + vlist_update(&ip->route); + vlist_update(&ip->addr); +} + +void +interface_ip_update_complete(struct interface_ip_settings *ip) { - interface_clear_dns(iface); - vlist_update(&iface->proto_route); - vlist_update(&iface->proto_addr); + vlist_flush(&ip->route); + vlist_flush(&ip->addr); } void -interface_ip_update_complete(struct interface *iface) +interface_ip_flush(struct interface_ip_settings *ip) { - vlist_flush(&iface->proto_route); - vlist_flush(&iface->proto_addr); + interface_clear_dns_servers(ip); + interface_clear_dns_search(ip); + vlist_flush_all(&ip->route); + vlist_flush_all(&ip->addr); } void -interface_ip_init(struct interface *iface) +interface_ip_init(struct interface_ip_settings *ip, struct interface *iface) { - vlist_init(&iface->proto_route, route_cmp, interface_update_proto_route, + ip->iface = iface; + INIT_LIST_HEAD(&ip->dns_search); + INIT_LIST_HEAD(&ip->dns_servers); + vlist_init(&ip->route, route_cmp, interface_update_proto_route, struct device_route, node, mask); - vlist_init(&iface->proto_addr, addr_cmp, interface_update_proto_addr, + vlist_init(&ip->addr, addr_cmp, interface_update_proto_addr, struct device_addr, node, mask); } diff --git a/interface-ip.h b/interface-ip.h index 6ad9b42..4a1776d 100644 --- a/interface-ip.h +++ b/interface-ip.h @@ -1,6 +1,8 @@ #ifndef __INTERFACE_IP_H #define __INTERFACE_IP_H +#include "interface.h" + enum device_addr_flags { /* address family for routes and addresses */ DEVADDR_INET4 = (0 << 0), @@ -54,15 +56,15 @@ struct dns_search_domain { char name[]; }; -void interface_ip_init(struct interface *iface); -void interface_add_dns_server(struct interface *iface, const char *str); -void interface_add_dns_server_list(struct interface *iface, struct blob_attr *list); -void interface_add_dns_search_list(struct interface *iface, struct blob_attr *list); -void interface_clear_dns(struct interface *iface); +void interface_ip_init(struct interface_ip_settings *ip, struct interface *iface); +void interface_add_dns_server(struct interface_ip_settings *ip, const char *str); +void interface_add_dns_server_list(struct interface_ip_settings *ip, struct blob_attr *list); +void interface_add_dns_search_list(struct interface_ip_settings *ip, struct blob_attr *list); void interface_write_resolv_conf(void); -void interface_ip_update_start(struct interface *iface); -void interface_ip_update_complete(struct interface *iface); +void interface_ip_update_start(struct interface_ip_settings *ip); +void interface_ip_update_complete(struct interface_ip_settings *ip); +void interface_ip_flush(struct interface_ip_settings *ip); #endif diff --git a/interface.c b/interface.c index befb194..11b629a 100644 --- a/interface.c +++ b/interface.c @@ -90,9 +90,7 @@ interface_event(struct interface *iface, enum interface_event ev) static void interface_flush_state(struct interface *iface) { - interface_clear_dns(iface); - vlist_flush_all(&iface->proto_addr); - vlist_flush_all(&iface->proto_route); + interface_ip_flush(&iface->proto_ip); if (iface->main_dev.dev) device_release(&iface->main_dev); } @@ -219,7 +217,7 @@ interface_cleanup(struct interface *iface) list_for_each_entry_safe(dep, tmp, &iface->users, list) interface_remove_user(dep); - interface_clear_dns(iface); + interface_flush_state(iface); interface_clear_errors(iface); if (iface->main_dev.dev) device_remove_user(&iface->main_dev); @@ -332,8 +330,7 @@ interface_init(struct interface *iface, const char *name, INIT_LIST_HEAD(&iface->errors); INIT_LIST_HEAD(&iface->users); INIT_LIST_HEAD(&iface->hotplug_list); - INIT_LIST_HEAD(&iface->proto_dns_search); - INIT_LIST_HEAD(&iface->proto_dns_servers); + interface_ip_init(&iface->proto_ip, iface); iface->main_dev.cb = interface_cb; iface->l3_dev = &iface->main_dev; @@ -509,7 +506,6 @@ interface_update(struct vlist_tree *tree, struct vlist_node *node_new, D(INTERFACE, "Create interface '%s'\n", if_new->name); interface_claim_device(if_new); proto_init_interface(if_new, if_new->config); - interface_ip_init(if_new); netifd_ubus_add_interface(if_new); } } diff --git a/interface.h b/interface.h index 8a00900..598774b 100644 --- a/interface.h +++ b/interface.h @@ -39,6 +39,16 @@ struct interface_user { void (*cb)(struct interface_user *dep, enum interface_event ev); }; +struct interface_ip_settings { + struct interface *iface; + + struct vlist_tree addr; + struct vlist_tree route; + + struct list_head dns_servers; + struct list_head dns_search; +}; + /* * interface configuration */ @@ -72,11 +82,7 @@ struct interface { const struct proto_handler *proto_handler; struct interface_proto_state *proto; - struct vlist_tree proto_addr; - struct vlist_tree proto_route; - - struct list_head proto_dns_servers; - struct list_head proto_dns_search; + struct interface_ip_settings proto_ip; /* errors/warnings while trying to bring up the interface */ struct list_head errors; diff --git a/proto-shell.c b/proto-shell.c index 415eb74..ae4ebd3 100644 --- a/proto-shell.c +++ b/proto-shell.c @@ -161,7 +161,7 @@ proto_shell_free(struct interface_proto_state *proto) } static void -proto_shell_parse_addr_list(struct interface *iface, struct blob_attr *attr, +proto_shell_parse_addr_list(struct interface_ip_settings *ip, struct blob_attr *attr, bool v6, bool external) { struct device_addr *addr; @@ -183,7 +183,7 @@ proto_shell_parse_addr_list(struct interface *iface, struct blob_attr *attr, if (external) addr->flags |= DEVADDR_EXTERNAL; - vlist_add(&iface->proto_addr, &addr->node); + vlist_add(&ip->addr, &addr->node); } } @@ -203,7 +203,7 @@ static const struct blobmsg_policy route_attr[__ROUTE_LAST] = { }; static void -parse_route(struct interface *iface, struct blob_attr *attr, bool v6) +parse_route(struct interface_ip_settings *ip, struct blob_attr *attr, bool v6) { struct blob_attr *tb[__ROUTE_LAST], *cur; struct device_route *route; @@ -242,7 +242,7 @@ parse_route(struct interface *iface, struct blob_attr *attr, bool v6) if ((cur = tb[ROUTE_DEVICE]) != NULL) route->device = device_get(blobmsg_data(cur), true); - vlist_add(&iface->proto_route, &route->node); + vlist_add(&ip->route, &route->node); return; error: @@ -250,7 +250,7 @@ error: } static void -proto_shell_parse_route_list(struct interface *iface, struct blob_attr *attr, +proto_shell_parse_route_list(struct interface_ip_settings *ip, struct blob_attr *attr, bool v6) { struct blob_attr *cur; @@ -262,7 +262,7 @@ proto_shell_parse_route_list(struct interface *iface, struct blob_attr *attr, continue; } - parse_route(iface, cur, v6); + parse_route(ip, cur, v6); } } @@ -302,6 +302,7 @@ static const struct blobmsg_policy notify_attr[__NOTIFY_LAST] = { static int proto_shell_update_link(struct proto_shell_state *state, struct blob_attr **tb) { + struct interface_ip_settings *ip; struct blob_attr *cur; bool addr_ext = false; bool up; @@ -328,30 +329,31 @@ proto_shell_update_link(struct proto_shell_state *state, struct blob_attr **tb) device_claim(&state->l3_dev); } - interface_ip_update_start(state->proto.iface); + ip = &state->proto.iface->proto_ip; + interface_ip_update_start(ip); if ((cur = tb[NOTIFY_ADDR_EXT]) != NULL) addr_ext = blobmsg_get_bool(cur); if ((cur = tb[NOTIFY_IPADDR]) != NULL) - proto_shell_parse_addr_list(state->proto.iface, cur, false, addr_ext); + proto_shell_parse_addr_list(ip, cur, false, addr_ext); if ((cur = tb[NOTIFY_IP6ADDR]) != NULL) - proto_shell_parse_addr_list(state->proto.iface, cur, true, addr_ext); + proto_shell_parse_addr_list(ip, cur, true, addr_ext); if ((cur = tb[NOTIFY_ROUTES]) != NULL) - proto_shell_parse_route_list(state->proto.iface, cur, false); + proto_shell_parse_route_list(ip, cur, false); if ((cur = tb[NOTIFY_ROUTES6]) != NULL) - proto_shell_parse_route_list(state->proto.iface, cur, true); + proto_shell_parse_route_list(ip, cur, true); if ((cur = tb[NOTIFY_DNS]) != NULL) - interface_add_dns_server_list(state->proto.iface, cur); + interface_add_dns_server_list(ip, cur); if ((cur = tb[NOTIFY_DNS_SEARCH]) != NULL) - interface_add_dns_search_list(state->proto.iface, cur); + interface_add_dns_search_list(ip, cur); - interface_ip_update_complete(state->proto.iface); + interface_ip_update_complete(ip); state->proto.proto_event(&state->proto, IFPEV_UP); diff --git a/proto-static.c b/proto-static.c index b8f3412..a7d75ec 100644 --- a/proto-static.c +++ b/proto-static.c @@ -58,7 +58,7 @@ parse_addr(struct interface *iface, const char *str, bool v6, int mask) interface_add_error(iface, "proto-static", "INVALID_ADDRESS", &str, 1); return false; } - vlist_add(&iface->proto_addr, &addr->node); + vlist_add(&iface->proto_ip.addr, &addr->node); return true; } @@ -94,7 +94,7 @@ parse_gateway_option(struct interface *iface, struct blob_attr *attr, bool v6) } route->mask = 0; route->flags = DEVADDR_DEVICE | (v6 ? DEVADDR_INET6 : DEVADDR_INET4); - vlist_add(&iface->proto_route, &route->node); + vlist_add(&iface->proto_ip.route, &route->node); return true; } @@ -142,7 +142,7 @@ proto_apply_static_settings(struct interface *iface, struct blob_attr *attr) } if (tb[OPT_DNS]) - interface_add_dns_server_list(iface, tb[OPT_DNS]); + interface_add_dns_server_list(&iface->proto_ip, tb[OPT_DNS]); return 0;