]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-manager.c
network: save DNS servers specified by DBus interface
[thirdparty/systemd.git] / src / network / networkd-manager.c
index 1348fcb9b3e2b9bd130c7f2b40f95bcf61448199..273c00c36b91de469684a4450de38fabb8d7196d 100644 (file)
@@ -11,6 +11,7 @@
 #include "sd-netlink.h"
 
 #include "alloc-util.h"
+#include "bus-log-control-api.h"
 #include "bus-polkit.h"
 #include "bus-util.h"
 #include "conf-parser.h"
@@ -23,6 +24,7 @@
 #include "local-addresses.h"
 #include "netlink-util.h"
 #include "network-internal.h"
+#include "networkd-dhcp-server-bus.h"
 #include "networkd-dhcp6.h"
 #include "networkd-link-bus.h"
 #include "networkd-manager-bus.h"
@@ -102,7 +104,7 @@ static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_b
 
         r = sd_bus_message_read(message, "b", &b);
         if (r < 0) {
-                log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
+                bus_log_parse_error(r);
                 return 0;
         }
 
@@ -153,6 +155,10 @@ int manager_connect_bus(Manager *m) {
         if (r < 0)
                return log_error_errno(r, "Failed to add link object vtable: %m");
 
+        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.DHCPServer", dhcp_server_vtable, link_object_find, m);
+        if (r < 0)
+               return log_error_errno(r, "Failed to add link object vtable: %m");
+
         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
         if (r < 0)
                 return log_error_errno(r, "Failed to add link enumerator: %m");
@@ -165,6 +171,10 @@ int manager_connect_bus(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to add network enumerator: %m");
 
+        r = bus_log_control_api_register(m->bus);
+        if (r < 0)
+                return r;
+
         r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to request name: %m");
@@ -495,7 +505,8 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo
 
                 log_link_debug(link,
                                "%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s",
-                               (!route && !link->manager->manage_foreign_routes) || type == RTM_DELROUTE ? "Forgetting" :
+                               (!route && !link->manager->manage_foreign_routes) ? "Ignoring received foreign" :
+                               type == RTM_DELROUTE ? "Forgetting" :
                                route ? "Received remembered" : "Remembering",
                                strna(buf_dst), strempty(buf_dst_prefixlen),
                                strna(buf_src), strna(buf_gw), strna(buf_prefsrc),
@@ -1262,6 +1273,9 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
         if (r < 0 && r != -ENODATA) {
                 log_warning_errno(r, "rtnl: could not get NHA_OIF attribute, ignoring: %m");
                 return 0;
+        } else if (tmp->oif <= 0) {
+                log_warning("rtnl: received nexthop message with invalid ifindex %d, ignoring.", tmp->oif);
+                return 0;
         }
 
         r = link_get(m, tmp->oif, &link);
@@ -1411,33 +1425,36 @@ static int manager_connect_rtnl(Manager *m) {
         return 0;
 }
 
-static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
-        char *p;
+static int ordered_set_put_dns_server(OrderedSet *s, int ifindex, struct in_addr_full *dns) {
+        const char *p;
         int r;
 
         assert(s);
-        assert(address);
+        assert(dns);
 
-        r = in_addr_to_string(address->family, &address->address, &p);
-        if (r < 0)
-                return r;
+        if (dns->ifindex != 0 && dns->ifindex != ifindex)
+                return 0;
 
-        r = ordered_set_consume(s, p);
+        p = in_addr_full_to_string(dns);
+        if (!p)
+                return 0;
+
+        r = ordered_set_put_strdup(s, p);
         if (r == -EEXIST)
                 return 0;
 
         return r;
 }
 
-static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
+static int ordered_set_put_dns_servers(OrderedSet *s, int ifindex, struct in_addr_full **dns, unsigned n) {
         int r, c = 0;
         unsigned i;
 
         assert(s);
-        assert(addresses || n == 0);
+        assert(dns || n == 0);
 
         for (i = 0; i < n; i++) {
-                r = ordered_set_put_in_addr_data(s, addresses+i);
+                r = ordered_set_put_dns_server(s, ifindex, dns[i]);
                 if (r < 0)
                         return r;
 
@@ -1489,8 +1506,7 @@ static int ordered_set_put_in4_addrv(OrderedSet *s,
 }
 
 static int manager_save(Manager *m) {
-        _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL,
-                *smtp = NULL, *search_domains = NULL, *route_domains = NULL;
+        _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
         const char *operstate_str, *carrier_state_str, *address_state_str;
         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
         LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
@@ -1498,7 +1514,6 @@ static int manager_save(Manager *m) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_strv_free_ char **p = NULL;
         _cleanup_fclose_ FILE *f = NULL;
-        const struct in_addr *addresses;
         Link *link;
         Iterator i;
         int r;
@@ -1519,14 +1534,6 @@ static int manager_save(Manager *m) {
         if (!sip)
                 return -ENOMEM;
 
-        pop3 = ordered_set_new(&string_hash_ops);
-        if (!pop3)
-                return -ENOMEM;
-
-        smtp = ordered_set_new(&string_hash_ops);
-       if (!smtp)
-               return -ENOMEM;
-
         search_domains = ordered_set_new(&dns_name_hash_ops);
         if (!search_domains)
                 return -ENOMEM;
@@ -1536,6 +1543,8 @@ static int manager_save(Manager *m) {
                 return -ENOMEM;
 
         HASHMAP_FOREACH(link, m->links, i) {
+                const struct in_addr *addresses;
+
                 if (link->flags & IFF_LOOPBACK)
                         continue;
 
@@ -1552,7 +1561,10 @@ static int manager_save(Manager *m) {
                         continue;
 
                 /* First add the static configured entries */
-                r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
+                if (link->n_dns != (unsigned) -1)
+                        r = ordered_set_put_dns_servers(dns, link->ifindex, link->dns, link->n_dns);
+                else
+                        r = ordered_set_put_dns_servers(dns, link->ifindex, link->network->dns, link->network->n_dns);
                 if (r < 0)
                         return r;
 
@@ -1602,22 +1614,6 @@ static int manager_save(Manager *m) {
                                 return r;
                 }
 
-                r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses);
-                if (r > 0) {
-                        r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local);
-                        if (r < 0)
-                                return r;
-                } else if (r < 0 && r != -ENODATA)
-                        return r;
-
-                r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses);
-                if (r > 0) {
-                        r = ordered_set_put_in4_addrv(smtp, addresses, r, in4_addr_is_non_local);
-                        if (r < 0)
-                                return r;
-                } else if (r < 0 && r != -ENODATA)
-                        return r;
-
                 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
                         const char *domainname;
                         char **domains = NULL;
@@ -1669,8 +1665,6 @@ static int manager_save(Manager *m) {
         ordered_set_print(f, "DNS=", dns);
         ordered_set_print(f, "NTP=", ntp);
         ordered_set_print(f, "SIP=", sip);
-        ordered_set_print(f, "POP3_SERVERS=", pop3);
-        ordered_set_print(f, "SMTP_SERVERS=", smtp);
         ordered_set_print(f, "DOMAINS=", search_domains);
         ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
 
@@ -1772,6 +1766,7 @@ int manager_new(Manager **ret) {
         *m = (Manager) {
                 .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
                 .manage_foreign_routes = true,
+                .ethtool_fd = -1,
         };
 
         m->state_file = strdup("/run/systemd/netif/state");
@@ -1882,6 +1877,8 @@ void manager_free(Manager *m) {
         free(m->dynamic_timezone);
         free(m->dynamic_hostname);
 
+        safe_close(m->ethtool_fd);
+
         free(m);
 }
 
@@ -2041,6 +2038,9 @@ int manager_rtnl_enumerate_routes(Manager *m) {
         assert(m);
         assert(m->rtnl);
 
+        if (!m->manage_foreign_routes)
+                return 0;
+
         r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
         if (r < 0)
                 return r;
@@ -2215,7 +2215,7 @@ void manager_dirty(Manager *manager) {
 }
 
 static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
-        Manager *manager = userdata;
+        _unused_ Manager *manager = userdata;
         const sd_bus_error *e;
 
         assert(m);
@@ -2261,7 +2261,7 @@ int manager_set_hostname(Manager *m, const char *hostname) {
 }
 
 static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
-        Manager *manager = userdata;
+        _unused_ Manager *manager = userdata;
         const sd_bus_error *e;
 
         assert(m);
@@ -2322,23 +2322,15 @@ int manager_request_product_uuid(Manager *m, Link *link) {
 
                 assert_se(duid = link_get_duid(link));
 
-                r = set_ensure_allocated(&m->links_requesting_uuid, NULL);
-                if (r < 0)
-                        return log_oom();
-
-                r = set_ensure_allocated(&m->duids_requesting_uuid, NULL);
+                r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
                 if (r < 0)
                         return log_oom();
+                if (r > 0)
+                        link_ref(link);
 
-                r = set_put(m->links_requesting_uuid, link);
+                r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
                 if (r < 0)
                         return log_oom();
-
-                r = set_put(m->duids_requesting_uuid, duid);
-                if (r < 0)
-                        return log_oom();
-
-                link_ref(link);
         }
 
         if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {