[systemd-commits] 6 commits - Makefile.am src/bus-proxyd src/network TODO

Tom Gundersen tomegun at kemper.freedesktop.org
Sun Jan 12 06:32:16 PST 2014


 Makefile.am                      |    2 +
 TODO                             |    8 +---
 src/bus-proxyd/bus-proxyd.c      |    2 +
 src/network/networkd-address.c   |   37 +++++++++++++++++++
 src/network/networkd-bridge.c    |   25 +++++--------
 src/network/networkd-gperf.gperf |    1 
 src/network/networkd-link.c      |   15 ++++++-
 src/network/networkd-manager.c   |   75 +++++++++++++++++++++++++++++++++++++++
 src/network/networkd-network.c   |   11 ++++-
 src/network/networkd.c           |    7 +++
 src/network/networkd.h           |    9 ++++
 11 files changed, 167 insertions(+), 25 deletions(-)

New commits:
commit c74ecd718229e15b42ea5c00c5a171a08f616e51
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat Jan 11 20:19:10 2014 +0000

    TODO: update rtnl/network sections

diff --git a/TODO b/TODO
index 521ba8d..5d6fd30 100644
--- a/TODO
+++ b/TODO
@@ -667,15 +667,13 @@ Features:
    - Check if Driver= is broken, or just my driver (bcma)
 
 * sd-rtnl:
-   - replace sd_rtnl_message_append() by type-safe versions
    - improve container support, and add support for entering containers when reading
    - add support for more attribute types
 
 * networkd:
-   - unify and clarify logging, also use proper structured log messages
-   - add [Route] sections
-   - add more keys to [Address] sections
-   - add DHCPv4 support (and, longer term, other kinds of dynamic config)
+   - add more keys to [Route] and [Address] sections
+   - add support for more DHCPv4 options (and, longer term, other kinds of dynamic config)
+   - allow opting out of receiving DNS servers over DHCPv4
    - add proper initrd support (in particular generate .network/.link files based on /proc/cmdline)
 
 External:

commit 3bef724f7e7f7eaca69881548b06e221b77d7031
Author: Tom Gundersen <teg at jklm.no>
Date:   Sun Jan 5 23:01:10 2014 +0100

    networkd: generate resolv.conf
    
    This adds support to generate a basic resolv.conf in /run/systemd/network.
    This file will not take any effect unless a symlink is created from
    /etc/resolv.conf.
    
    Nameservers received over DHCP takes precedence over statically configured ones.
    
    Note: /etc/resolv.conf is severely limited, so in the future we will likely
    rather provide a much more powerfull nss plugin (or something to that effect),
    but this should allow current users to function without any loss of
    functionality.

diff --git a/Makefile.am b/Makefile.am
index 65b445e..b4bb6e1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4107,6 +4107,7 @@ systemd_networkd_LDADD = \
 	libsystemd-id128-internal.la \
 	libsystemd-rtnl.la \
 	libsystemd-dhcp.la \
+	libsystemd-label.la \
 	libsystemd-shared.la
 
 nodist_systemunit_DATA += \
@@ -4133,6 +4134,7 @@ test_network_LDADD = \
 	libsystemd-daemon-internal.la \
 	libsystemd-rtnl.la \
 	libsystemd-dhcp.la \
+	libsystemd-label.la \
 	libsystemd-shared.la
 
 tests += \
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 8a71630..7d06cf8 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -190,6 +190,43 @@ int address_configure(Address *address, Link *link,
         return 0;
 }
 
+int config_parse_dns(const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+        Address **dns = data;
+        _cleanup_address_free_ Address *n = NULL;
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = address_new_dynamic(&n);
+        if (r < 0)
+                return r;
+
+        r = net_parse_inaddr(rvalue, &n->family, &n->in_addr);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "DNS address is invalid, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+
+        *dns = n;
+        n = NULL;
+
+        return 0;
+}
+
 int config_parse_address(const char *unit,
                 const char *filename,
                 unsigned line,
diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf
index f1594d5..92954a8 100644
--- a/src/network/networkd-gperf.gperf
+++ b/src/network/networkd-gperf.gperf
@@ -25,6 +25,7 @@ Network.Bridge,          config_parse_bridge,           0,       offsetof(Networ
 Network.DHCP,            config_parse_bool,             0,       offsetof(Network, dhcp)
 Network.Address,         config_parse_address,          0,       0
 Network.Gateway,         config_parse_gateway,          0,       0
+Network.DNS,             config_parse_dns,              0,       offsetof(Network, dns)
 Address.Address,         config_parse_address,          0,       0
 Address.Label,           config_parse_label,            0,       0
 Route.Gateway,           config_parse_gateway,          0,       0
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 25d92c8..5dd8e91 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -378,6 +378,7 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
         if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
                 _cleanup_address_free_ Address *addr = NULL;
                 _cleanup_route_free_ Route *rt = NULL;
+                struct in_addr **nameservers;
 
                 log_struct_link(LOG_INFO, link,
                                 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
@@ -420,6 +421,13 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
                 addr = NULL;
                 rt = NULL;
 
+                r = sd_dhcp_client_get_dns(client, &nameservers);
+                if (r >= 0) {
+                        r = manager_update_resolv_conf(link->manager);
+                        if (r < 0)
+                                log_error("Failed to update resolv.conf");
+                }
+
                 link_enter_set_addresses(link);
         }
 
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index c9ce1d6..f02eed1 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -19,10 +19,13 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
  ***/
 
+#include <resolv.h>
+
 #include "path-util.h"
 #include "networkd.h"
 #include "libudev-private.h"
 #include "udev-util.h"
+#include "mkdir.h"
 
 const char* const network_dirs[] = {
         "/etc/systemd/network",
@@ -276,3 +279,75 @@ int manager_rtnl_listen(Manager *m) {
 
         return 0;
 }
+
+static void append_dns(FILE *f, struct in_addr *dns, unsigned char family, unsigned *count) {
+        char buf[INET6_ADDRSTRLEN];
+        const char *address;
+
+        address = inet_ntop(family, dns, buf, INET6_ADDRSTRLEN);
+        if (!address) {
+                log_warning("Invalid DNS address. Ignoring.");
+                return;
+        }
+
+        if (*count == MAXNS)
+                fputs("# Too many dynamic name servers configured, the "
+                      "following entries will be ignored\n", f);
+
+        fprintf(f, "nameserver %s\n", address);
+
+        (*count) ++;
+}
+
+int manager_update_resolv_conf(Manager *m) {
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        Link *link;
+        Iterator i;
+        unsigned count = 0;
+        int r;
+
+        assert(m);
+
+        r = mkdir_safe_label("/run/systemd/network", 0755, 0, 0);
+        if (r < 0)
+                return r;
+
+        r = fopen_temporary("/run/systemd/network/resolv.conf", &f, &temp_path);
+        if (r < 0)
+                return r;
+
+        fchmod(fileno(f), 0644);
+
+        fputs("# This file is managed by systemd-networkd(8). Do not edit.\n", f);
+
+        HASHMAP_FOREACH(link, m->links, i) {
+                if (link->dhcp) {
+                        struct in_addr **nameservers;
+
+                        r = sd_dhcp_client_get_dns(link->dhcp, &nameservers);
+                        if (r >= 0) {
+                                unsigned j;
+
+                                for (j = 0; nameservers[j]; j++)
+                                        append_dns(f, nameservers[j], AF_INET, &count);
+                        }
+                }
+        }
+
+        HASHMAP_FOREACH(link, m->links, i)
+                if (link->network && link->network->dns)
+                        append_dns(f, &link->network->dns->in_addr.in,
+                                   link->network->dns->family, &count);
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, "/run/systemd/network/resolv.conf") < 0) {
+                r = -errno;
+                unlink("/run/systemd/network/resolv.conf");
+                unlink(temp_path);
+                return r;
+        }
+
+        return 0;
+}
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index f254644..f987310 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -144,6 +144,8 @@ void network_free(Network *network) {
 
         free(network->description);
 
+        address_free(network->dns);
+
         while ((route = network->static_routes))
                 route_free(route);
 
@@ -197,6 +199,12 @@ int network_apply(Manager *manager, Network *network, Link *link) {
         if (r < 0)
                 return r;
 
+        if (network->dns) {
+                r = manager_update_resolv_conf(manager);
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 }
 
diff --git a/src/network/networkd.c b/src/network/networkd.c
index 360afba..055200c 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -60,6 +60,13 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto out;
 
+
+        /* write out empty resolv.conf to avoid a
+         * dangling symlink */
+        r = manager_update_resolv_conf(m);
+        if (r < 0)
+                goto out;
+
         sd_notify(false,
                   "READY=1\n"
                   "STATUS=Processing requests...");
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 55181f2..607feba 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -88,6 +88,7 @@ struct Network {
 
         LIST_HEAD(Address, static_addresses);
         LIST_HEAD(Route, static_routes);
+        Address *dns;
 
         Hashmap *addresses_by_section;
         Hashmap *routes_by_section;
@@ -157,6 +158,7 @@ struct Link {
 
         Route *dhcp_route;
         Address *dhcp_address;
+        Address *dns;
 
         LinkState state;
 
@@ -195,6 +197,8 @@ int manager_udev_listen(Manager *m);
 
 int manager_rtnl_listen(Manager *m);
 
+int manager_update_resolv_conf(Manager *m);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
 #define _cleanup_manager_free_ _cleanup_(manager_freep)
 
@@ -258,6 +262,10 @@ int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callbac
 DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
 #define _cleanup_address_free_ _cleanup_(address_freep)
 
+int config_parse_dns(const char *unit, const char *filename, unsigned line,
+                     const char *section, unsigned section_line, const char *lvalue,
+                     int ltype, const char *rvalue, void *data, void *userdata);
+
 int config_parse_address(const char *unit, const char *filename, unsigned line,
                          const char *section, unsigned section_line, const char *lvalue,
                          int ltype, const char *rvalue, void *data, void *userdata);

commit 924fe4304af981ffd849346b4a1d415f11e9dd79
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat Jan 11 20:20:14 2014 +0000

    networkd: bridge - remove redundant state
    
    We will not insist on getting the reply from rtnl that the bridge
    was created before considering the bridge ready, as we will be
    notified about that via udev. We will listen for the rtnl response
    however, in case the creation of the bridge failed.

diff --git a/src/network/networkd-bridge.c b/src/network/networkd-bridge.c
index 7de7546..ce48878 100644
--- a/src/network/networkd-bridge.c
+++ b/src/network/networkd-bridge.c
@@ -113,6 +113,9 @@ static int bridge_join_ready(Bridge *bridge, Link* link, sd_rtnl_message_handler
 static int bridge_enter_ready(Bridge *bridge) {
         bridge_join_callback *callback;
 
+        assert(bridge);
+        assert(bridge->name);
+
         bridge->state = BRIDGE_STATE_READY;
 
         log_info_bridge(bridge, "bridge ready");
@@ -130,7 +133,7 @@ static int bridge_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda
         Bridge *bridge = userdata;
         int r;
 
-        assert(bridge->state == BRIDGE_STATE_CREATING);
+        assert(bridge->state != _BRIDGE_STATE_INVALID);
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0) {
@@ -140,11 +143,6 @@ static int bridge_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda
                 return 1;
         }
 
-        if (bridge->link)
-                bridge_enter_ready(bridge);
-        else
-                bridge->state = BRIDGE_STATE_CREATED;
-
         return 1;
 }
 
@@ -234,18 +232,18 @@ int bridge_join(Bridge *bridge, Link *link, sd_rtnl_message_handler_t callback)
 
 int bridge_set_link(Manager *m, Link *link) {
         Bridge *bridge;
+        int r;
 
-        bridge = hashmap_get(m->bridges, link->ifname);
-        if (!bridge)
-                return -ENOENT;
+        r = bridge_get(m, link->ifname, &bridge);
+        if (r < 0)
+                return r;
 
         if (bridge->link && bridge->link != link)
                 return -EEXIST;
 
         bridge->link = link;
 
-        if (bridge->state == BRIDGE_STATE_CREATED)
-                bridge_enter_ready(bridge);
+        bridge_enter_ready(bridge);
 
         return 0;
 }
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 4f44f78..55181f2 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -52,7 +52,6 @@ struct bridge_join_callback {
 typedef enum BridgeState {
         BRIDGE_STATE_FAILED,
         BRIDGE_STATE_CREATING,
-        BRIDGE_STATE_CREATED,
         BRIDGE_STATE_READY,
         _BRIDGE_STATE_MAX,
         _BRIDGE_STATE_INVALID = -1,

commit f46685a4c0780173e5291fb7c3caa1c35cb1d0af
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat Jan 11 20:16:13 2014 +0000

    networkd: don't automatically reload config at runtime
    
    We don't know if the config will be consistent, so do as systemd itself and only
    load config when the daemon starts (and possibly, in the future, when explicitly requested).

diff --git a/src/network/networkd-bridge.c b/src/network/networkd-bridge.c
index 430b5c5..7de7546 100644
--- a/src/network/networkd-bridge.c
+++ b/src/network/networkd-bridge.c
@@ -55,9 +55,6 @@ int bridge_get(Manager *manager, const char *name, Bridge **ret) {
         assert(name);
         assert(ret);
 
-        if (manager_should_reload(manager))
-                manager_load_config(manager);
-
         bridge = hashmap_get(manager->bridges, name);
         if (!bridge) {
                 *ret = NULL;
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 1606042..f254644 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -166,9 +166,6 @@ int network_get(Manager *manager, struct udev_device *device, Network **ret) {
         assert(device);
         assert(ret);
 
-        if (manager_should_reload(manager))
-                manager_load_config(manager);
-
         LIST_FOREACH(networks, network, manager->networks) {
                 if (net_match_config(network->match_mac, network->match_path,
                                         network->match_driver, network->match_type,

commit ab47d620b459ce45774237ca1a38b5218426c897
Author: Tom Gundersen <teg at jklm.no>
Date:   Sun Jan 12 15:24:11 2014 +0100

    networkd: improve logging a bit

diff --git a/src/network/networkd-bridge.c b/src/network/networkd-bridge.c
index fa87d3e..430b5c5 100644
--- a/src/network/networkd-bridge.c
+++ b/src/network/networkd-bridge.c
@@ -108,6 +108,8 @@ static int bridge_join_ready(Bridge *bridge, Link* link, sd_rtnl_message_handler
                 return r;
         }
 
+        log_debug_bridge(bridge, "joining link %s to bridge", link->ifname);
+
         return 0;
 }
 
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 52b023c..25d92c8 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -453,6 +453,8 @@ static int link_acquire_conf(Link *link) {
                         return r;
         }
 
+        log_debug_link(link, "acquiring DHCPv4 lease");
+
         r = sd_dhcp_client_start(link->dhcp);
         if (r < 0)
                 return r;
@@ -470,7 +472,7 @@ static int link_update_flags(Link *link, unsigned flags) {
                 return 0;
 
         if (link->flags == flags) {
-                log_debug_link(link, "link status unchanged: %#x", flags);
+                log_debug_link(link, "link status unchanged: %#.8x", flags);
                 return 0;
         }
 
@@ -503,7 +505,7 @@ static int link_update_flags(Link *link, unsigned flags) {
         }
 
         log_debug_link(link,
-                       "link status updated: %#x -> %#x", link->flags, flags);
+                       "link status updated: %#.8x -> %#.8x", link->flags, flags);
 
         link->flags = flags;
 
@@ -609,6 +611,7 @@ static int bridge_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
                         link->network->bridge->name,
                         BRIDGE(link->network->bridge),
                         NULL);
+
         link_bridge_joined(link);
 
         return 1;

commit 920e2957be7730596a80b1b64f133cbb080e4955
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri Jan 10 20:40:19 2014 +0000

    bus-proxyd: add some more debugging
    
    Make sure we print a message when exiting with an error.

diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index f4d6fab..d085598 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -644,6 +644,7 @@ int main(int argc, char *argv[]) {
                         k = process_hello(a, b, m, &got_hello);
                         if (k < 0) {
                                 r = k;
+                                log_error("Failed to process HELLO: %s", strerror(-r));
                                 goto finish;
                         }
 
@@ -653,6 +654,7 @@ int main(int argc, char *argv[]) {
                                 k = process_policy(a, b, m);
                                 if (k < 0) {
                                         r = k;
+                                        log_error("Failed to process policy: %s", strerror(-r));
                                         goto finish;
                                 }
 



More information about the systemd-commits mailing list