X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fnetwork.c;h=4b9e4f10958f733df1f661c8e8f5b087d4f8a16a;hp=4a4f93252f5a1f02693222e2ca1d6560d2a0995b;hb=f6d419d22a4c69af185201b30f78b5a88da51219;hpb=c75acc64833eb7263b340079e7ba3153ebc60aec diff --git a/discover/network.c b/discover/network.c index 4a4f932..4b9e4f1 100644 --- a/discover/network.c +++ b/discover/network.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include +#include "file.h" #include "network.h" #define HWADDR_SIZE 6 @@ -53,7 +55,7 @@ struct network { bool dry_run; }; -static const struct network_config *find_config_by_hwaddr( +static const struct interface_config *find_config_by_hwaddr( uint8_t *hwaddr) { const struct config *config; @@ -63,11 +65,11 @@ static const struct network_config *find_config_by_hwaddr( if (!config) return NULL; - for (i = 0; i < config->n_network_configs; i++) { - struct network_config *netconf = config->network_configs[i]; + for (i = 0; i < config->network.n_interfaces; i++) { + struct interface_config *ifconf = config->network.interfaces[i]; - if (!memcmp(netconf->hwaddr, hwaddr, HWADDR_SIZE)) - return netconf; + if (!memcmp(ifconf->hwaddr, hwaddr, HWADDR_SIZE)) + return ifconf; } return NULL; @@ -134,26 +136,42 @@ static int network_send_link_query(struct network *network) return 0; } -static int interface_up(struct network *network, struct interface *interface) +static int interface_change(struct network *network, + struct interface *interface, + bool up) { int rc; + const char *statestr = up ? "up" : "down"; const char *argv[] = { pb_system_apps.ip, "link", "set", interface->name, - "up", + statestr, NULL, }; rc = pb_run_cmd(argv, 1, network->dry_run); if (rc) { - pb_log("failed to bring interface %s up\n", interface->name); + pb_log("failed to bring interface %s %s\n", interface->name, + statestr); return -1; } return 0; } +static int interface_up(struct network *network, + struct interface *interface) +{ + return interface_change(network, interface, true); +} + +static int interface_down(struct network *network, + struct interface *interface) +{ + return interface_change(network, interface, false); +} + static void configure_interface_dhcp(struct network *network, struct interface *interface) { @@ -175,7 +193,7 @@ static void configure_interface_dhcp(struct network *network, static void configure_interface_static(struct network *network, struct interface *interface, - const struct network_config *config) + const struct interface_config *config) { const char *addr_argv[] = { pb_system_apps.ip, @@ -226,7 +244,7 @@ static void configure_interface_static(struct network *network, static void configure_interface(struct network *network, struct interface *interface, bool up, bool link) { - const struct network_config *config = NULL; + const struct interface_config *config = NULL; if (interface->state == IFSTATE_IGNORED) return; @@ -383,6 +401,60 @@ static int network_netlink_process(void *arg) return 0; } +static void network_init_dns(struct network *network) +{ + const struct config *config; + int i, rc, len; + bool modified; + char *buf; + + if (network->dry_run) + return; + + config = config_get(); + if (!config || !config->network.n_dns_servers) + return; + + rc = read_file(network, "/etc/resolv.conf", &buf, &len); + + if (rc) { + buf = talloc_strdup(network, ""); + len = 0; + } + + modified = false; + + for (i = 0; i < config->network.n_dns_servers; i++) { + int dns_conf_len; + char *dns_conf; + + dns_conf = talloc_asprintf(network, "nameserver %s\n", + config->network.dns_servers[i]); + + if (strstr(buf, dns_conf)) { + talloc_free(dns_conf); + continue; + } + + dns_conf_len = strlen(dns_conf); + buf = talloc_realloc(network, buf, char, len + dns_conf_len); + memcpy(buf + len, dns_conf, dns_conf_len); + len += dns_conf_len; + modified = true; + + talloc_free(dns_conf); + } + + if (modified) { + rc = replace_file("/etc/resolv.conf", buf, len); + if (rc) + pb_log("error replacing resolv.conf: %s\n", + strerror(errno)); + } + + talloc_free(buf); +} + struct network *network_init(void *ctx, struct waitset *waitset, bool dry_run) { struct network *network; @@ -393,6 +465,8 @@ struct network *network_init(void *ctx, struct waitset *waitset, bool dry_run) network->manual_config = false; network->dry_run = dry_run; + network_init_dns(network); + rc = network_init_netlink(network); if (rc) goto err; @@ -417,9 +491,14 @@ err: int network_shutdown(struct network *network) { + struct interface *interface; + if (network->waiter) waiter_remove(network->waiter); + list_for_each_entry(&network->interfaces, interface, list) + interface_down(network, interface); + close(network->netlink_sd); talloc_free(network); return 0;