chiark / gitweb /
sd-bus: get rid of PID starttime concept
[elogind.git] / src / network / networkd-link.c
index b46ac5c3c308005aaafea8503df05fcb17af8d13..b9f1b992d31e71e5ce35a1387d8a8a83d2f701b6 100644 (file)
@@ -515,12 +515,7 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0 && r != -EEXIST)
-                log_link_struct(LOG_WARNING, link,
-                                "MESSAGE=%-*s: could not set route: %s",
-                                IFNAMSIZ,
-                                link->ifname, strerror(-r),
-                                "ERRNO=%d", -r,
-                                NULL);
+                log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
 
         if (link->link_messages == 0) {
                 log_link_debug(link, "routes set");
@@ -576,38 +571,7 @@ int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0 && r != -ESRCH)
-                log_link_struct(LOG_WARNING, link,
-                                "MESSAGE=%-*s: could not drop route: %s",
-                                IFNAMSIZ,
-                                link->ifname, strerror(-r),
-                                "ERRNO=%d", -r,
-                                NULL);
-
-        return 1;
-}
-
-int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        _cleanup_link_unref_ Link *link = userdata;
-        int r;
-
-        assert(rtnl);
-        assert(m);
-        assert(link);
-        assert(link->manager);
-
-        for (; m; m = sd_rtnl_message_next(m)) {
-                r = sd_rtnl_message_get_errno(m);
-                if (r < 0) {
-                        log_link_debug(link, "getting address failed: %s",
-                                       strerror(-r));
-                        continue;
-                }
-
-                r = link_rtnl_process_address(rtnl, m, link->manager);
-                if (r < 0)
-                        log_link_warning(link, "could not process address: %s",
-                                         strerror(-r));
-        }
+                log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
 
         return 1;
 }
@@ -631,17 +595,9 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0 && r != -EEXIST)
-                log_link_struct(LOG_WARNING, link,
-                                "MESSAGE=%-*s: could not set address: %s",
-                                IFNAMSIZ,
-                                link->ifname, strerror(-r),
-                                "ERRNO=%d", -r,
-                                NULL);
-        else if (r >= 0) {
-                /* calling handler directly so take a ref */
-                link_ref(link);
-                link_get_address_handler(rtnl, m, link);
-        }
+                log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
+        else if (r >= 0)
+                link_rtnl_process_address(rtnl, m, link->manager);
 
         if (link->link_messages == 0) {
                 log_link_debug(link, "addresses set");
@@ -695,14 +651,30 @@ int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata)
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0 && r != -EADDRNOTAVAIL)
-                log_link_struct(LOG_WARNING, link,
-                                "MESSAGE=%-*s: could not drop address: %s",
+                log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
+
+        return 1;
+}
+
+static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        int r;
+
+        log_link_debug(link, "set link");
+
+        r = sd_rtnl_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_link_struct(link, LOG_ERR,
+                                "MESSAGE=%-*s: could not join netdev: %s",
                                 IFNAMSIZ,
                                 link->ifname, strerror(-r),
                                 "ERRNO=%d", -r,
                                 NULL);
+                link_enter_failed(link);
+                return 1;
+        }
 
-        return 1;
+        return 0;
 }
 
 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
@@ -780,11 +752,7 @@ static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0)
-                log_link_struct(LOG_WARNING, link,
-                                "MESSAGE=%-*s: could not set MTU: %s",
-                                IFNAMSIZ, link->ifname, strerror(-r),
-                                "ERRNO=%d", -r,
-                                NULL);
+                log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
 
         return 1;
 }
@@ -826,6 +794,69 @@ int link_set_mtu(Link *link, uint32_t mtu) {
         return 0;
 }
 
+static int link_set_bridge(Link *link) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
+        int r;
+
+        assert(link);
+        assert(link->network);
+
+        if(link->network->cost == 0)
+                return 0;
+
+        r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
+                                     RTM_SETLINK, link->ifindex);
+        if (r < 0) {
+                log_link_error(link, "Could not allocate RTM_SETLINK message");
+                return r;
+        }
+
+        r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
+        if (r < 0) {
+                log_link_error(link,
+                               "Could not set message family %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_open_container(req, IFLA_PROTINFO);
+        if (r < 0) {
+                log_link_error(link,
+                               "Could not append IFLA_PROTINFO attribute: %s",
+                               strerror(-r));
+                return r;
+        }
+
+        if(link->network->cost != 0) {
+                r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
+                if (r < 0) {
+                        log_link_error(link,
+                                       "Could not append IFLA_BRPORT_COST attribute: %s",
+                                       strerror(-r));
+                        return r;
+                }
+        }
+
+        r = sd_rtnl_message_close_container(req);
+        if (r < 0) {
+                log_link_error(link,
+                               "Could not append IFLA_LINKINFO attribute: %s",
+                               strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
+        if (r < 0) {
+                log_link_error(link,
+                               "Could not send rtnetlink message: %s",
+                               strerror(-r));
+                return r;
+        }
+
+        link_ref(link);
+
+        return r;
+}
+
 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
         Link *link = userdata;
 
@@ -1003,12 +1034,7 @@ static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
         if (r < 0) {
                 /* we warn but don't fail the link, as it may
                    be brought up later */
-                log_link_struct(LOG_WARNING, link,
-                                "MESSAGE=%-*s: could not bring up interface: %s",
-                                IFNAMSIZ,
-                                link->ifname, strerror(-r),
-                                "ERRNO=%d", -r,
-                                NULL);
+                log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
         }
 
         return 1;
@@ -1019,6 +1045,7 @@ static int link_up(Link *link) {
         int r;
 
         assert(link);
+        assert(link->network);
         assert(link->manager);
         assert(link->manager->rtnl);
 
@@ -1038,6 +1065,22 @@ static int link_up(Link *link) {
                 return r;
         }
 
+        if (link->network->mac) {
+                r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
+                if (r < 0) {
+                        log_link_error(link, "Could not set MAC address: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        if (link->network->mtu) {
+                r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu);
+                if (r < 0) {
+                        log_link_error(link, "Could not set MTU: %s", strerror(-r));
+                        return r;
+                }
+        }
+
         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
                                0, NULL);
         if (r < 0) {
@@ -1066,6 +1109,15 @@ static int link_joined(Link *link) {
                 }
         }
 
+        if(link->network->bridge) {
+                r = link_set_bridge(link);
+                if (r < 0) {
+                        log_link_error(link,
+                                       "Could not set bridge message: %s",
+                                       strerror(-r));
+                }
+        }
+
         return link_enter_set_addresses(link);
 }
 
@@ -1084,12 +1136,7 @@ static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0 && r != -EEXIST) {
-                log_link_struct(LOG_ERR, link,
-                                "MESSAGE=%-*s: could not join netdev: %s",
-                                IFNAMSIZ,
-                                link->ifname, strerror(-r),
-                                "ERRNO=%d", -r,
-                                NULL);
+                log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
                 link_enter_failed(link);
                 return 1;
         } else
@@ -1120,7 +1167,7 @@ static int link_enter_join_netdev(Link *link) {
                 return link_joined(link);
 
         if (link->network->bond) {
-                log_link_struct(LOG_DEBUG, link,
+                log_link_struct(link, LOG_DEBUG,
                                 "MESSAGE=%-*s: enslaving by '%s'",
                                 IFNAMSIZ,
                                 link->ifname, link->network->bond->ifname,
@@ -1129,7 +1176,7 @@ static int link_enter_join_netdev(Link *link) {
 
                 r = netdev_join(link->network->bond, link, &netdev_join_handler);
                 if (r < 0) {
-                        log_link_struct(LOG_WARNING, link,
+                        log_link_struct(link, LOG_WARNING,
                                         "MESSAGE=%-*s: could not join netdev '%s': %s",
                                         IFNAMSIZ,
                                         link->ifname, link->network->bond->ifname,
@@ -1144,7 +1191,7 @@ static int link_enter_join_netdev(Link *link) {
         }
 
         if (link->network->bridge) {
-                log_link_struct(LOG_DEBUG, link,
+                log_link_struct(link, LOG_DEBUG,
                                 "MESSAGE=%-*s: enslaving by '%s'",
                                 IFNAMSIZ,
                                 link->ifname, link->network->bridge->ifname,
@@ -1154,7 +1201,7 @@ static int link_enter_join_netdev(Link *link) {
                 r = netdev_join(link->network->bridge, link,
                                 &netdev_join_handler);
                 if (r < 0) {
-                        log_link_struct(LOG_WARNING, link,
+                        log_link_struct(link, LOG_WARNING,
                                         "MESSAGE=%-*s: could not join netdev '%s': %s",
                                         IFNAMSIZ,
                                         link->ifname, link->network->bridge->ifname,
@@ -1169,7 +1216,7 @@ static int link_enter_join_netdev(Link *link) {
         }
 
         HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
-                log_link_struct(LOG_DEBUG, link,
+                log_link_struct(link, LOG_DEBUG,
                                 "MESSAGE=%-*s: enslaving by '%s'",
                                 IFNAMSIZ,
                                 link->ifname, netdev->ifname, NETDEVIF(netdev),
@@ -1177,7 +1224,7 @@ static int link_enter_join_netdev(Link *link) {
 
                 r = netdev_join(netdev, link, &netdev_join_handler);
                 if (r < 0) {
-                        log_link_struct(LOG_WARNING, link,
+                        log_link_struct(link, LOG_WARNING,
                                         "MESSAGE=%-*s: could not join netdev '%s': %s",
                                         IFNAMSIZ,
                                         link->ifname, netdev->ifname,
@@ -1341,8 +1388,7 @@ int link_initialized(Link *link, struct udev_device *device) {
         return 0;
 }
 
-int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
-                              void *userdata) {
+int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
         Manager *m = userdata;
         Link *link = NULL;
         uint16_t type;
@@ -1358,6 +1404,14 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
         assert(message);
         assert(m);
 
+        if (sd_rtnl_message_is_error(message)) {
+                r = sd_rtnl_message_get_errno(message);
+                if (r < 0)
+                        log_warning_errno(r, "rtnl: failed to receive address: %m");
+
+                return 0;
+        }
+
         r = sd_rtnl_message_get_type(message, &type);
         if (r < 0) {
                 log_warning("rtnl: could not get message type");
@@ -1365,13 +1419,16 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
         }
 
         r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
-        if (r < 0 || ifindex <= 0) {
-                log_warning("rtnl: received address message without valid ifindex, ignoring");
+        if (r < 0) {
+                log_warning_errno(r, "rtnl: could not get ifindex: %m");
+                return 0;
+        } else if (ifindex <= 0) {
+                log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
                 return 0;
         } else {
                 r = link_get(m, ifindex, &link);
                 if (r < 0 || !link) {
-                        log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
+                        log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
                         return 0;
                 }
         }
@@ -1518,18 +1575,6 @@ int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
 
         log_link_debug(link, "link %d added", link->ifindex);
 
-        r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
-                                     0);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
-                               NULL);
-        if (r < 0)
-                return r;
-
-        link_ref(link);
-
         if (detect_container(NULL) <= 0) {
                 /* not in a container, udev will be around */
                 sprintf(ifindex_str, "n%d", link->ifindex);