[systemd-commits] 12 commits - src/libsystemd src/network src/shared src/systemd

Tom Gundersen tomegun at kemper.freedesktop.org
Sat May 10 11:57:01 PDT 2014


 src/libsystemd/sd-rtnl/rtnl-message.c |  121 +++++++++++++++++---------
 src/libsystemd/sd-rtnl/sd-rtnl.c      |   35 +++++++
 src/network/networkd-link.c           |  111 ++++++++++--------------
 src/network/networkd-manager.c        |  153 +++++++++++++++++++++++++++++-----
 src/network/networkd-netdev.c         |    2 
 src/network/networkd-network.c        |    3 
 src/shared/missing.h                  |    4 
 src/systemd/sd-rtnl.h                 |    3 
 8 files changed, 297 insertions(+), 135 deletions(-)

New commits:
commit 2e9f08eaf11fdb9c702058524f634eb13298a966
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 19:39:03 2014 +0200

    networkd: listen for address changes
    
    This is proof-of-concept only, as we only log the changes but don't do anything
    with it.

diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 61be347..effa93c 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -217,6 +217,97 @@ static int manager_udev_process_link(Manager *m, struct udev_device *device) {
         return 0;
 }
 
+static int manager_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
+        Manager *m = userdata;
+        Link *link = NULL;
+        uint16_t type;
+        _cleanup_address_free_ Address *address = NULL;
+        char buf[INET6_ADDRSTRLEN];
+        int r, ifindex;
+
+        assert(rtnl);
+        assert(message);
+        assert(m);
+
+        r = sd_rtnl_message_get_type(message, &type);
+        if (r < 0) {
+                log_warning("rtnl: could not get message type");
+                return 0;
+        }
+
+        r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
+        if (r < 0 || ifindex <= 0) {
+                log_warning("rtnl: received address message without valid ifindix, ignoring");
+                return 0;
+        } else {
+                r = link_get(m, ifindex, &link);
+                if (r < 0 || !link) {
+                        log_warning("rtnl: received address for non-existing link, ignoring");
+                        return 0;
+                }
+        }
+
+        r = address_new_dynamic(&address);
+        if (r < 0)
+                return 0;
+
+        r = sd_rtnl_message_addr_get_family(message, &address->family);
+        if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
+                log_warning("rtnl: received address with invalid family, ignoring");
+                return 0;
+        }
+
+        r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
+        if (r < 0) {
+                log_warning("rtnl: recevied address with invalid prefixlen, ignoring");
+                return 0;
+        }
+
+        switch (address->family) {
+        case AF_INET:
+                r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
+                if (r < 0) {
+                        log_warning("rtnl: received address without valid address, ignoring");
+                        return 0;
+                }
+
+                break;
+
+        case AF_INET6:
+                r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
+                if (r < 0) {
+                        log_warning("rtnl: received address without valid address, ignoring");
+                        return 0;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("invalid address family");
+        }
+
+        if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
+                log_warning("could not print address");
+                return 0;
+        }
+
+        switch (type) {
+        case RTM_NEWADDR:
+                log_info("added address: %s/%u to ifindex %d", buf,
+                         address->prefixlen, ifindex);
+                break;
+
+        case RTM_DELADDR:
+                log_info("removed address: %s/%u from ifindex %d", buf,
+                         address->prefixlen, ifindex);
+                break;
+        default:
+                assert_not_reached("Received invalid RTNL message type");
+        }
+
+        return 1;
+}
+
 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
         Manager *m = userdata;
         Link *link = NULL;
@@ -385,6 +476,14 @@ int manager_rtnl_listen(Manager *m) {
         if (r < 0)
                 return r;
 
+        r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &manager_rtnl_process_address, m);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &manager_rtnl_process_address, m);
+        if (r < 0)
+                return r;
+
         return 0;
 }
 

commit 8fe65c03fce8739c0799231e46a3ad99ec53deb3
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 20:16:10 2014 +0200

    rtnl: message - fix check for broadcast messages

diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 84b46af..4d1b6fb 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1214,7 +1214,7 @@ int socket_read_message(sd_rtnl *rtnl) {
                 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
                 const NLType *nl_type;
 
-                if (new_msg->nlmsg_pid && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
+                if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
                         /* not broadcast and not for us */
                         continue;
 

commit 66269b05cf31ef5d8f83a7150c314bf35ee8a35e
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 20:15:52 2014 +0200

    rtnl: message - read group membership of incoming messages

diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 9558e11..84b46af 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1098,8 +1098,9 @@ int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
         return k;
 }
 
-static int socket_recv_message(int fd, struct iovec *iov, bool peek) {
-        uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred))];
+static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool peek) {
+        uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred)) +
+                            CMSG_SPACE(sizeof(struct nl_pktinfo))];
         struct msghdr msg = {
                 .msg_iov = iov,
                 .msg_iovlen = 1,
@@ -1107,6 +1108,7 @@ static int socket_recv_message(int fd, struct iovec *iov, bool peek) {
                 .msg_controllen = sizeof(cred_buffer),
         };
         struct cmsghdr *cmsg;
+        uint32_t group = 0;
         bool auth = false;
         int r;
 
@@ -1128,10 +1130,15 @@ static int socket_recv_message(int fd, struct iovec *iov, bool peek) {
                         struct ucred *ucred = (void *)CMSG_DATA(cmsg);
 
                         /* from the kernel */
-                        if (ucred->uid == 0 && ucred->pid == 0) {
+                        if (ucred->uid == 0 && ucred->pid == 0)
                                 auth = true;
-                                break;
-                        }
+                } else if (cmsg->cmsg_level == SOL_NETLINK &&
+                           cmsg->cmsg_type == NETLINK_PKTINFO &&
+                           cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
+                        struct nl_pktinfo *pktinfo = (void *)CMSG_DATA(cmsg);
+
+                        /* multi-cast group */
+                        group = pktinfo->group;
                 }
         }
 
@@ -1139,6 +1146,9 @@ static int socket_recv_message(int fd, struct iovec *iov, bool peek) {
                 /* not from the kernel, ignore */
                 return 0;
 
+        if (group)
+                *_group = group;
+
         return r;
 }
 
@@ -1150,6 +1160,7 @@ static int socket_recv_message(int fd, struct iovec *iov, bool peek) {
 int socket_read_message(sd_rtnl *rtnl) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
         struct iovec iov = {};
+        uint32_t group = 0;
         bool multi_part = false, done = false;
         struct nlmsghdr *new_msg;
         size_t len;
@@ -1161,7 +1172,7 @@ int socket_read_message(sd_rtnl *rtnl) {
         assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
 
         /* read nothing, just get the pending message size */
-        r = socket_recv_message(rtnl->fd, &iov, true);
+        r = socket_recv_message(rtnl->fd, &iov, &group, true);
         if (r <= 0)
                 return r;
         else
@@ -1177,7 +1188,7 @@ int socket_read_message(sd_rtnl *rtnl) {
         iov.iov_len = rtnl->rbuffer_allocated;
 
         /* read the pending message */
-        r = socket_recv_message(rtnl->fd, &iov, false);
+        r = socket_recv_message(rtnl->fd, &iov, &group, false);
         if (r <= 0)
                 return r;
         else
diff --git a/src/libsystemd/sd-rtnl/sd-rtnl.c b/src/libsystemd/sd-rtnl/sd-rtnl.c
index 4ee360c..b91d080 100644
--- a/src/libsystemd/sd-rtnl/sd-rtnl.c
+++ b/src/libsystemd/sd-rtnl/sd-rtnl.c
@@ -22,6 +22,7 @@
 #include <sys/socket.h>
 #include <poll.h>
 
+#include "missing.h"
 #include "macro.h"
 #include "util.h"
 #include "hashmap.h"
@@ -109,7 +110,12 @@ int sd_rtnl_open(sd_rtnl **ret, unsigned n_groups, ...) {
         if (rtnl->fd < 0)
                 return -errno;
 
-        if (setsockopt(rtnl->fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+        r = setsockopt(rtnl->fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(rtnl->fd, SOL_NETLINK, NETLINK_PKTINFO, &one, sizeof(one));
+        if (r < 0)
                 return -errno;
 
         va_start(ap, n_groups);
diff --git a/src/shared/missing.h b/src/shared/missing.h
index d5ec2f8..716d3b8 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -105,6 +105,10 @@
   #endif
 #endif
 
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
 #if !HAVE_DECL_PIVOT_ROOT
 static inline int pivot_root(const char *new_root, const char *put_old) {
         return syscall(SYS_pivot_root, new_root, put_old);

commit 26349add97c8e9bfd26f2f16d61dd80a324f504e
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 19:55:00 2014 +0200

    rtnl: message - verify that we read the pending message size from the kernel
    
    Reuse the auth-checking for both the peek and the real read.

diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index fb42986..9558e11 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1098,61 +1098,28 @@ int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
         return k;
 }
 
-/* On success, the number of bytes received is returned and *ret points to the received message
- * which has a valid header and the correct size.
- * If nothing useful was received 0 is returned.
- * On failure, a negative error code is returned.
- */
-int socket_read_message(sd_rtnl *rtnl) {
-        _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
+static int socket_recv_message(int fd, struct iovec *iov, bool peek) {
         uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred))];
-        struct iovec iov = {};
         struct msghdr msg = {
-                .msg_iov = &iov,
+                .msg_iov = iov,
                 .msg_iovlen = 1,
                 .msg_control = cred_buffer,
                 .msg_controllen = sizeof(cred_buffer),
         };
         struct cmsghdr *cmsg;
-        bool auth = false, multi_part = false, done = false;
-        struct nlmsghdr *new_msg;
-        size_t len;
+        bool auth = false;
         int r;
-        unsigned i = 0;
-
-        assert(rtnl);
-        assert(rtnl->rbuffer);
-        assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
-
-        /* read nothing, just get the pending message size */
-        r = recvmsg(rtnl->fd, &msg, MSG_PEEK | MSG_TRUNC);
-        if (r < 0)
-                /* no data */
-                return (errno == EAGAIN) ? 0 : -errno;
-        else if (r == 0)
-                /* connection was closed by the kernel */
-                return -ECONNRESET;
-        else
-                len = (size_t)r;
-
-        /* make room for the pending message */
-        if (!greedy_realloc((void **)&rtnl->rbuffer,
-                            &rtnl->rbuffer_allocated,
-                            len, sizeof(uint8_t)))
-                return -ENOMEM;
 
-        iov.iov_base = rtnl->rbuffer;
-        iov.iov_len = rtnl->rbuffer_allocated;
+        assert(fd >= 0);
+        assert(iov);
 
-        r = recvmsg(rtnl->fd, &msg, MSG_TRUNC);
+        r = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
         if (r < 0)
                 /* no data */
                 return (errno == EAGAIN) ? 0 : -errno;
         else if (r == 0)
                 /* connection was closed by the kernel */
                 return -ECONNRESET;
-        else
-                len = (size_t)r;
 
         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
                 if (cmsg->cmsg_level == SOL_SOCKET &&
@@ -1172,6 +1139,50 @@ int socket_read_message(sd_rtnl *rtnl) {
                 /* not from the kernel, ignore */
                 return 0;
 
+        return r;
+}
+
+/* On success, the number of bytes received is returned and *ret points to the received message
+ * which has a valid header and the correct size.
+ * If nothing useful was received 0 is returned.
+ * On failure, a negative error code is returned.
+ */
+int socket_read_message(sd_rtnl *rtnl) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
+        struct iovec iov = {};
+        bool multi_part = false, done = false;
+        struct nlmsghdr *new_msg;
+        size_t len;
+        int r;
+        unsigned i = 0;
+
+        assert(rtnl);
+        assert(rtnl->rbuffer);
+        assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
+
+        /* read nothing, just get the pending message size */
+        r = socket_recv_message(rtnl->fd, &iov, true);
+        if (r <= 0)
+                return r;
+        else
+                len = (size_t)r;
+
+        /* make room for the pending message */
+        if (!greedy_realloc((void **)&rtnl->rbuffer,
+                            &rtnl->rbuffer_allocated,
+                            len, sizeof(uint8_t)))
+                return -ENOMEM;
+
+        iov.iov_base = rtnl->rbuffer;
+        iov.iov_len = rtnl->rbuffer_allocated;
+
+        /* read the pending message */
+        r = socket_recv_message(rtnl->fd, &iov, false);
+        if (r <= 0)
+                return r;
+        else
+                len = (size_t)r;
+
         if (len > rtnl->rbuffer_allocated)
                 /* message did not fit in read buffer */
                 return -EIO;

commit 127dc4ea9487397b1ab70447e2f44d091e44ab5f
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 19:40:11 2014 +0200

    rtnl: message - move code around
    
    No functional change.

diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index d611207..fb42986 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1154,10 +1154,6 @@ int socket_read_message(sd_rtnl *rtnl) {
         else
                 len = (size_t)r;
 
-        if (len > rtnl->rbuffer_allocated)
-                /* message did not fit in read buffer */
-                return -EIO;
-
         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
                 if (cmsg->cmsg_level == SOL_SOCKET &&
                     cmsg->cmsg_type == SCM_CREDENTIALS &&
@@ -1176,6 +1172,10 @@ int socket_read_message(sd_rtnl *rtnl) {
                 /* not from the kernel, ignore */
                 return 0;
 
+        if (len > rtnl->rbuffer_allocated)
+                /* message did not fit in read buffer */
+                return -EIO;
+
         if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
                 multi_part = true;
 

commit 897e184c7d54156357fd204beafe06ab9bd0341a
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 19:38:32 2014 +0200

    rtnl: change from bitmask to enum for rtnl groups
    
    The bitmask is deprecated in the kernel, so move to the new interface. At the moment
    this does not make a difference for us, but it avoids having to change the API in the future.

diff --git a/src/libsystemd/sd-rtnl/sd-rtnl.c b/src/libsystemd/sd-rtnl/sd-rtnl.c
index 543bad9..4ee360c 100644
--- a/src/libsystemd/sd-rtnl/sd-rtnl.c
+++ b/src/libsystemd/sd-rtnl/sd-rtnl.c
@@ -75,8 +75,27 @@ static bool rtnl_pid_changed(sd_rtnl *rtnl) {
         return rtnl->original_pid != getpid();
 }
 
-int sd_rtnl_open(sd_rtnl **ret, uint32_t groups) {
+static int rtnl_compute_groups_ap(uint32_t *_groups, unsigned n_groups, va_list ap) {
+        uint32_t groups = 0;
+        unsigned i;
+
+        for (i = 0; i < n_groups; i++) {
+                unsigned group;
+
+                group = va_arg(ap, unsigned);
+                assert_return(group < 32, -EINVAL);
+
+                groups |= group ? (1 << (group - 1)) : 0;
+        }
+
+        *_groups = groups;
+
+        return 0;
+}
+
+int sd_rtnl_open(sd_rtnl **ret, unsigned n_groups, ...) {
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        va_list ap;
         socklen_t addrlen;
         int r, one = 1;
 
@@ -93,7 +112,11 @@ int sd_rtnl_open(sd_rtnl **ret, uint32_t groups) {
         if (setsockopt(rtnl->fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
                 return -errno;
 
-        rtnl->sockaddr.nl.nl_groups = groups;
+        va_start(ap, n_groups);
+        r = rtnl_compute_groups_ap(&rtnl->sockaddr.nl.nl_groups, n_groups, ap);
+        va_end(ap);
+        if (r < 0)
+                return r;
 
         addrlen = sizeof(rtnl->sockaddr);
 
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 0456eef..61be347 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -91,7 +91,8 @@ int manager_new(Manager **ret) {
 
         sd_event_set_watchdog(m->event, true);
 
-        r = sd_rtnl_open(&m->rtnl, RTMGRP_LINK | RTMGRP_IPV4_IFADDR);
+        r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
+                         RTNLGRP_IPV6_IFADDR);
         if (r < 0)
                 return r;
 
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 9059ed4..b5aa634 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -40,7 +40,7 @@ typedef struct sd_rtnl_message sd_rtnl_message;
 typedef int (*sd_rtnl_message_handler_t)(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
 
 /* bus */
-int sd_rtnl_open(sd_rtnl **nl, uint32_t groups);
+int sd_rtnl_open(sd_rtnl **nl, unsigned n_groups, ...);
 
 sd_rtnl *sd_rtnl_ref(sd_rtnl *nl);
 sd_rtnl *sd_rtnl_unref(sd_rtnl *nl);

commit 389cc5f74368a18fd5991e4647e7ba86319c473f
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 16:08:03 2014 +0200

    networkd: link - redo flag change logging
    
    Make the logging less verbose by only printing all the changed flags on one line,
    at the same time make it more complete by supporting all flags currently supported
    by the kernel.
    
    We still fall back to printing the raw flags in case we get something we do not recognize
    This may be useful when running on new kernels.

diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index f1f04a3..3bc9c0e 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1226,8 +1226,13 @@ bool link_has_carrier(unsigned flags, uint8_t operstate) {
         return false;
 }
 
+#define FLAG_STRING(string, flag, old, new) \
+        (((old ^ new) & flag) \
+                ? ((old & flag) ? (" -" string) : (" +" string)) \
+                : "")
+
 static int link_update_flags(Link *link, sd_rtnl_message *m) {
-        unsigned flags, flags_added, flags_removed, generic_flags;
+        unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
         uint8_t operstate;
         bool carrier_gained = false, carrier_lost = false;
         int r;
@@ -1249,70 +1254,46 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) {
         if ((link->flags == flags) && (link->operstate == operstate))
                 return 0;
 
-        flags_added = (link->flags ^ flags) & flags;
-        flags_removed = (link->flags ^ flags) & link->flags;
-        generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
-                          IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
-                          IFF_NOARP | IFF_MASTER | IFF_SLAVE | IFF_RUNNING);
-
-        if (flags_added & IFF_UP)
-                log_debug_link(link, "link is up");
-        else if (flags_removed & IFF_UP)
-                log_debug_link(link, "link is down");
-
-        if (flags_added & IFF_LOWER_UP)
-                log_debug_link(link, "link is lower up");
-        else if (flags_removed & IFF_LOWER_UP)
-                log_debug_link(link, "link is lower down");
-
-        if (flags_added & IFF_DORMANT)
-                log_debug_link(link, "link is dormant");
-        else if (flags_removed & IFF_DORMANT)
-                log_debug_link(link, "link is not dormant");
-
-        if (flags_added & IFF_DEBUG)
-                log_debug_link(link, "debugging enabled in the kernel");
-        else if (flags_removed & IFF_DEBUG)
-                log_debug_link(link, "debugging disabled in the kernel");
-
-        if (flags_added & IFF_MULTICAST)
-                log_debug_link(link, "multicast enabled");
-        else if (flags_removed & IFF_MULTICAST)
-                log_debug_link(link, "multicast disabled");
-
-        if (flags_added & IFF_BROADCAST)
-                log_debug_link(link, "broadcast enabled");
-        else if (flags_removed & IFF_BROADCAST)
-                log_debug_link(link, "broadcast disabled");
-
-        if (flags_added & IFF_PROMISC)
-                log_debug_link(link, "promiscuous mode enabled");
-        else if (flags_removed & IFF_PROMISC)
-                log_debug_link(link, "promiscuous mode disabled");
-
-        if (flags_added & IFF_NOARP)
-                log_debug_link(link, "ARP protocol disabled");
-        else if (flags_removed & IFF_NOARP)
-                log_debug_link(link, "ARP protocol enabled");
-
-        if (flags_added & IFF_MASTER)
-                log_debug_link(link, "link is master");
-        else if (flags_removed & IFF_MASTER)
-                log_debug_link(link, "link is no longer master");
-
-        if (flags_added & IFF_SLAVE)
-                log_debug_link(link, "link is slave");
-        else if (flags_removed & IFF_SLAVE)
-                log_debug_link(link, "link is no longer slave");
-
-        /* link flags are currently at most 18 bits, let's default to printing 20 */
-        if (flags_added & generic_flags)
-                log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
-                               flags_added & generic_flags);
-
-        if (flags_removed & generic_flags)
-                log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
-                               flags_removed & generic_flags);
+        if (link->flags != flags) {
+                log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+                               FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
+                               FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
+                               FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
+                               FLAG_STRING("UP", IFF_UP, link->flags, flags),
+                               FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
+                               FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
+                               FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
+                               FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
+                               FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
+                               FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
+                               FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
+                               FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
+                               FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
+                               FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
+                               FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
+                               FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
+                               FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
+                               FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
+                               FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
+
+                unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
+                                  IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
+                                  IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
+                                  IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
+                                  IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
+                                  IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
+                unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
+                unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
+
+                /* link flags are currently at most 18 bits, let's align to printing 20 */
+                if (unknown_flags_added)
+                        log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
+                                       unknown_flags_added);
+
+                if (unknown_flags_removed)
+                        log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
+                                       unknown_flags_removed);
+        }
 
         carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
                        link_has_carrier(flags, operstate);

commit f4e884dd1c4cc4bc6d5f068f96b14ceda46f3962
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat May 10 16:06:23 2014 +0200

    sd-rtnl: message - add support for getting prefixlen from address messages

diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 9043c67..d611207 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -290,6 +290,21 @@ int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, unsigned char *family) {
         return 0;
 }
 
+int sd_rtnl_message_addr_get_prefixlen(sd_rtnl_message *m, unsigned char *prefixlen) {
+        struct ifaddrmsg *ifa;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
+        assert_return(prefixlen, -EINVAL);
+
+        ifa = NLMSG_DATA(m->hdr);
+
+        *prefixlen = ifa->ifa_prefixlen;
+
+        return 0;
+}
+
 int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope) {
         struct ifaddrmsg *ifa;
 
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 93f5ab9..9059ed4 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -86,6 +86,7 @@ int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixl
 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope);
 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags);
 int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, unsigned char *family);
+int sd_rtnl_message_addr_get_prefixlen(sd_rtnl_message *m, unsigned char *prefixlen);
 int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope);
 int sd_rtnl_message_addr_get_flags(sd_rtnl_message *m, unsigned char *flags);
 int sd_rtnl_message_addr_get_ifindex(sd_rtnl_message *m, int *ifindex);

commit 31d0ac36c62c9ed9646fb478b9d71cc2ecc3e55c
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri May 9 18:05:42 2014 +0200

    networkd: network - fix leak

diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index a452096..5d7ce1c 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -257,7 +257,8 @@ int config_parse_netdev(const char *unit,
                 void *data,
                 void *userdata) {
         Network *network = userdata;
-        char *kind_string, *p;
+        _cleanup_free_ char *kind_string = NULL;
+        char *p;
         NetDev *netdev;
         NetDevKind kind;
         int r;

commit 86e6e5d1b4e78d62d1a45539c1de141bc5e839aa
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri May 9 18:02:14 2014 +0200

    networkd: manager - initialize variables

diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index d4b05bb..0456eef 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -497,7 +497,7 @@ int manager_save(Manager *m) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         const char *oper_state = "unknown";
-        bool dormant, carrier;
+        bool dormant = false, carrier = false;
         int r;
 
         assert(m);

commit 5e273efec5fcf60ddb55e6bc0aaa850cb1be86c6
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri May 9 18:00:20 2014 +0200

    networkd: netdev - rephrase logging message a bit
    
    Make it fit with what is logged from the link.

diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 7962cc6..f742e39 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -114,7 +114,7 @@ void netdev_drop(NetDev *netdev) {
 
         netdev->state = NETDEV_STATE_LINGER;
 
-        log_debug_netdev(netdev, "dropped");
+        log_debug_netdev(netdev, "netdev removed");
 
         netdev_cancel_callbacks(netdev);
 

commit 4d473d5dded03d3b682dc389d610bb6b2db6e5f7
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri May 9 17:59:20 2014 +0200

    networkd: manager - refactor link tracking a bit

diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 40a088b..d4b05bb 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -219,6 +219,7 @@ static int manager_udev_process_link(Manager *m, struct udev_device *device) {
 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
         Manager *m = userdata;
         Link *link = NULL;
+        NetDev *netdev = NULL;
         uint16_t type;
         char *name;
         int r, ifindex;
@@ -237,42 +238,50 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
         if (r < 0 || ifindex <= 0) {
                 log_warning("rtnl: received link message without valid ifindex");
                 return 0;
-        }
-
-        link_get(m, ifindex, &link);
-        if (type == RTM_DELLINK)
-                link_drop(link);
-        else if (!link) {
-                /* link is new, so add it */
-                r = link_add(m, message, &link);
-                if (r < 0) {
-                        log_debug("could not add new link");
-                        return 0;
-                }
-        }
+        } else
+                link_get(m, ifindex, &link);
 
         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
-        if (r < 0)
+        if (r < 0 || !name) {
                 log_warning("rtnl: received link message without valid ifname");
-        else {
-                NetDev *netdev = NULL;
-
+                return 0;
+        } else
                 netdev_get(m, name, &netdev);
-                if (type == RTM_DELLINK)
-                        netdev_drop(netdev);
-                else if (netdev) {
+
+        switch (type) {
+        case RTM_NEWLINK:
+                if (!link) {
+                        /* link is new, so add it */
+                        r = link_add(m, message, &link);
+                        if (r < 0) {
+                                log_debug("could not add new link");
+                                return 0;
+                        }
+                }
+
+                if (netdev) {
+                        /* netdev exists, so make sure the ifindex matches */
                         r = netdev_set_ifindex(netdev, message);
                         if (r < 0) {
                                 log_debug("could not set ifindex on netdev");
                                 return 0;
                         }
                 }
-        }
 
-        if (type == RTM_NEWLINK) {
                 r = link_update(link, message);
                 if (r < 0)
                         return 0;
+
+                break;
+
+        case RTM_DELLINK:
+                link_drop(link);
+                netdev_drop(netdev);
+
+                break;
+
+        default:
+                assert_not_reached("Received invalid RTNL message type.");
         }
 
         return 1;



More information about the systemd-commits mailing list