[systemd-commits] 8 commits - src/core src/libsystemd-rtnl src/network src/systemd

Tom Gundersen tomegun at kemper.freedesktop.org
Mon Dec 16 08:23:09 PST 2013


 src/core/loopback-setup.c           |   24 +
 src/libsystemd-rtnl/rtnl-internal.h |    7 
 src/libsystemd-rtnl/rtnl-message.c  |  537 +++++++++++++++++++++++++-----------
 src/libsystemd-rtnl/rtnl-util.c     |   12 
 src/libsystemd-rtnl/sd-rtnl.c       |   16 -
 src/libsystemd-rtnl/test-rtnl.c     |   58 +--
 src/network/networkd-address.c      |    9 
 src/network/networkd-bridge.c       |   10 
 src/network/networkd-link.c         |   12 
 src/network/networkd-route.c        |   26 +
 src/systemd/sd-rtnl.h               |   21 +
 11 files changed, 500 insertions(+), 232 deletions(-)

New commits:
commit 0f49a5f75185bb358ee142f3c1c9f029a588435b
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon Dec 16 14:37:51 2013 +0100

    network: use SETLINK to bring up interfaces

diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c
index 1999959..a1b3847 100644
--- a/src/core/loopback-setup.c
+++ b/src/core/loopback-setup.c
@@ -89,7 +89,7 @@ static int start_interface(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_
         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
-        r = sd_rtnl_message_link_new(RTM_NEWLINK, if_loopback, &req);
+        r = sd_rtnl_message_link_new(RTM_SETLINK, if_loopback, &req);
         if (r < 0)
                 return r;
 
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 16255f9..7684d65 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -301,9 +301,9 @@ static int link_up(Link *link) {
         assert(link->manager);
         assert(link->manager->rtnl);
 
-        r = sd_rtnl_message_link_new(RTM_NEWLINK, link->ifindex, &req);
+        r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
         if (r < 0) {
-                log_error("Could not allocate RTM_NEWLINK message");
+                log_error("Could not allocate RTM_SETLINK message");
                 return r;
         }
 

commit 0a0dc69b655cfb10cab39133f5d521e7b35ce3d5
Author: Tom Gundersen <teg at jklm.no>
Date:   Sun Dec 15 14:00:20 2013 +0100

    rtnl: replace message_append by typesafe versions

diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c
index 7bb20ec..1999959 100644
--- a/src/core/loopback-setup.c
+++ b/src/core/loopback-setup.c
@@ -47,7 +47,7 @@ static int pipe_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
         return r == -EEXIST ? 0 : r;
 }
 
-static int add_adresses(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address, int *counter) {
+static int add_addresses(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_address, int *counter) {
         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *ipv4 = NULL, *ipv6 = NULL;
         int r;
 
@@ -55,7 +55,7 @@ static int add_adresses(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address, i
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_message_append(ipv4, IFA_LOCAL, &ipv4_address);
+        r = sd_rtnl_message_append_in_addr(ipv4, IFA_LOCAL, ipv4_address);
         if (r < 0)
                 return r;
 
@@ -72,7 +72,7 @@ static int add_adresses(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address, i
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_message_append(ipv6, IFA_LOCAL, &in6addr_loopback);
+        r = sd_rtnl_message_append_in6_addr(ipv6, IFA_LOCAL, &in6addr_loopback);
         if (r < 0)
                 return r;
 
@@ -85,7 +85,7 @@ static int add_adresses(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address, i
         return 0;
 }
 
-static int start_interface(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address, int *counter) {
+static int start_interface(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_address, int *counter) {
         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
@@ -97,7 +97,7 @@ static int start_interface(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_message_append(req, IFA_LOCAL, &ipv4_address);
+        r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, ipv4_address);
         if (r < 0)
                 return r;
 
@@ -140,22 +140,24 @@ int loopback_setup(void) {
         _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
         int r, if_loopback, counter = 0;
         bool eperm = false;
-        uint32_t ipv4_address = htonl(INADDR_LOOPBACK);
+        struct in_addr ipv4_address;
 
         errno = 0;
         if_loopback = (int) if_nametoindex("lo");
         if (if_loopback <= 0)
                 return errno ? -errno : -ENODEV;
 
+        ipv4_address.s_addr = htonl(INADDR_LOOPBACK);
+
         r = sd_rtnl_open(0, &rtnl);
         if (r < 0)
                 return r;
 
-        r = add_adresses(rtnl, if_loopback, ipv4_address, &counter);
+        r = add_addresses(rtnl, if_loopback, &ipv4_address, &counter);
         if (r < 0)
                 return r;
 
-        r = start_interface(rtnl, if_loopback, ipv4_address, &counter);
+        r = start_interface(rtnl, if_loopback, &ipv4_address, &counter);
         if (r < 0)
                 return r;
 
diff --git a/src/libsystemd-rtnl/rtnl-message.c b/src/libsystemd-rtnl/rtnl-message.c
index 8940d21..264cca0 100644
--- a/src/libsystemd-rtnl/rtnl-message.c
+++ b/src/libsystemd-rtnl/rtnl-message.c
@@ -356,109 +356,256 @@ static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data,
         return 0;
 }
 
-int sd_rtnl_message_append(sd_rtnl_message *m, unsigned short type, const void *data) {
+int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
         uint16_t rtm_type;
-        struct ifaddrmsg *ifa;
-        struct rtmsg *rtm;
+        int r;
 
         assert_return(m, -EINVAL);
         assert_return(data, -EINVAL);
 
-        sd_rtnl_message_get_type(m, &rtm_type);
+        r = sd_rtnl_message_get_type(m, &rtm_type);
+        if (r < 0)
+                return r;
 
-        if (m->current_container) {
-                switch (rtm_type) {
-                        case RTM_NEWLINK:
-                        case RTM_SETLINK:
-                        case RTM_GETLINK:
-                        case RTM_DELLINK:
-                                switch (m->current_container->rta_type) {
-                                        case IFLA_LINKINFO:
-                                                switch (type) {
-                                                        case IFLA_INFO_KIND:
-                                                                return add_rtattr(m, type, data, strlen(data) + 1);
-                                                        default:
-                                                                return -ENOTSUP;
-                                                }
+        /* check that the type is correct */
+        switch (rtm_type) {
+                case RTM_NEWLINK:
+                case RTM_SETLINK:
+                case RTM_GETLINK:
+                case RTM_DELLINK:
+                        if (m->current_container) {
+                                if (m->current_container->rta_type != IFLA_LINKINFO ||
+                                    type != IFLA_INFO_KIND)
+                                        return -ENOTSUP;
+                        } else {
+                                switch (type) {
+                                        case IFLA_IFNAME:
+                                        case IFLA_IFALIAS:
+                                        case IFLA_QDISC:
+                                                break;
                                         default:
                                                 return -ENOTSUP;
                                 }
-                        default:
+                        }
+                        break;
+                case RTM_NEWADDR:
+                case RTM_GETADDR:
+                case RTM_DELADDR:
+                        if (type != IFA_LABEL)
                                 return -ENOTSUP;
-                }
+                        break;
+                default:
+                        return -ENOTSUP;
         }
 
+        r = add_rtattr(m, type, data, strlen(data) + 1);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
+        uint16_t rtm_type;
+        int r;
+
+        assert_return(m, -EINVAL);
+
+        r = sd_rtnl_message_get_type(m, &rtm_type);
+        if (r < 0)
+                return r;
+
+        /* check that the type is correct */
         switch (rtm_type) {
                 case RTM_NEWLINK:
                 case RTM_SETLINK:
-                case RTM_DELLINK:
                 case RTM_GETLINK:
+                case RTM_DELLINK:
                         switch (type) {
-                                case IFLA_IFNAME:
-                                case IFLA_IFALIAS:
-                                case IFLA_QDISC:
-                                        return add_rtattr(m, type, data, strlen(data) + 1);
                                 case IFLA_MASTER:
                                 case IFLA_MTU:
                                 case IFLA_LINK:
-                                        return add_rtattr(m, type, data, sizeof(uint32_t));
-                                case IFLA_STATS:
-                                        return add_rtattr(m, type, data, sizeof(struct rtnl_link_stats));
-                                case IFLA_ADDRESS:
-                                case IFLA_BROADCAST:
-                                        return add_rtattr(m, type, data, ETH_ALEN);
+                                        break;
                                 default:
                                         return -ENOTSUP;
                         }
+                        break;
+                case RTM_NEWROUTE:
+                case RTM_GETROUTE:
+                case RTM_DELROUTE:
+                        switch (type) {
+                                case RTA_TABLE:
+                                case RTA_PRIORITY:
+                                case RTA_IIF:
+                                case RTA_OIF:
+                                        break;
+                                default:
+                                        return -ENOTSUP;
+                        }
+                        break;
+                default:
+                        return -ENOTSUP;
+        }
+
+        r = add_rtattr(m, type, &data, sizeof(&data));
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
+        struct ifaddrmsg *ifa;
+        struct rtmsg *rtm;
+        uint16_t rtm_type;
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(data, -EINVAL);
+
+        r = sd_rtnl_message_get_type(m, &rtm_type);
+        if (r < 0)
+                return r;
+
+        /* check that the type is correct */
+        switch (rtm_type) {
                 case RTM_NEWADDR:
-                case RTM_DELADDR:
                 case RTM_GETADDR:
+                case RTM_DELADDR:
                         switch (type) {
-                                case IFA_LABEL:
-                                        return add_rtattr(m, type, data, strlen(data) + 1);
                                 case IFA_ADDRESS:
                                 case IFA_LOCAL:
                                 case IFA_BROADCAST:
                                 case IFA_ANYCAST:
                                         ifa = NLMSG_DATA(m->hdr);
-                                        switch (ifa->ifa_family) {
-                                                case AF_INET:
-                                                        return add_rtattr(m, type, data, sizeof(struct in_addr));
-                                                case AF_INET6:
-                                                        return add_rtattr(m, type, data, sizeof(struct in6_addr));
-                                                default:
-                                                        return -EINVAL;
-                                        }
+
+                                        if (ifa->ifa_family != AF_INET)
+                                                return -EINVAL;
+
+                                        break;
                                 default:
                                         return -ENOTSUP;
                         }
+                        break;
                 case RTM_NEWROUTE:
+                case RTM_GETROUTE:
                 case RTM_DELROUTE:
+                        switch (type) {
+                                case RTA_DST:
+                                case RTA_SRC:
+                                case RTA_GATEWAY:
+                                        rtm = NLMSG_DATA(m->hdr);
+
+                                        if (rtm->rtm_family != AF_INET)
+                                                return -EINVAL;
+
+                                        break;
+                                default:
+                                        return -ENOTSUP;
+                        }
+                        break;
+                default:
+                        return -ENOTSUP;
+        }
+
+        r = add_rtattr(m, type, data, sizeof(data));
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
+        struct ifaddrmsg *ifa;
+        struct rtmsg *rtm;
+        uint16_t rtm_type;
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(data, -EINVAL);
+
+        r = sd_rtnl_message_get_type(m, &rtm_type);
+        if (r < 0)
+                return r;
+
+        /* check that the type is correct */
+        switch (rtm_type) {
+                case RTM_NEWADDR:
+                case RTM_GETADDR:
+                case RTM_DELADDR:
+                        switch (type) {
+                                case IFA_ADDRESS:
+                                case IFA_LOCAL:
+                                case IFA_BROADCAST:
+                                case IFA_ANYCAST:
+                                        ifa = NLMSG_DATA(m->hdr);
+
+                                        if (ifa->ifa_family != AF_INET6)
+                                                return -EINVAL;
+
+                                        break;
+                                default:
+                                        return -ENOTSUP;
+                        }
+                        break;
+                case RTM_NEWROUTE:
                 case RTM_GETROUTE:
+                case RTM_DELROUTE:
                         switch (type) {
                                 case RTA_DST:
                                 case RTA_SRC:
                                 case RTA_GATEWAY:
                                         rtm = NLMSG_DATA(m->hdr);
-                                        switch (rtm->rtm_family) {
-                                                case AF_INET:
-                                                        return add_rtattr(m, type, data, sizeof(struct in_addr));
-                                                case AF_INET6:
-                                                        return add_rtattr(m, type, data, sizeof(struct in6_addr));
-                                                default:
-                                                        return -EINVAL;
-                                        }
-                                case RTA_TABLE:
-                                case RTA_PRIORITY:
-                                case RTA_IIF:
-                                case RTA_OIF:
-                                        return add_rtattr(m, type, data, sizeof(uint32_t));
+
+                                        if (rtm->rtm_family != AF_INET6)
+                                                return -EINVAL;
+
+                                        break;
                                 default:
                                         return -ENOTSUP;
                         }
                 default:
                         return -ENOTSUP;
         }
+
+        r = add_rtattr(m, type, data, sizeof(data));
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
+        uint16_t rtm_type;
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(data, -EINVAL);
+
+        sd_rtnl_message_get_type(m, &rtm_type);
+
+        switch (rtm_type) {
+                case RTM_NEWLINK:
+                case RTM_SETLINK:
+                case RTM_DELLINK:
+                case RTM_GETLINK:
+                        switch (type) {
+                                case IFLA_ADDRESS:
+                                case IFLA_BROADCAST:
+                                        break;
+                                default:
+                                        return -ENOTSUP;
+                        }
+                        break;
+                default:
+                        return -ENOTSUP;
+        }
+
+        r = add_rtattr(m, type, data, sizeof(data));
+        if (r < 0)
+                return r;
+
+        return 0;
 }
 
 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
diff --git a/src/libsystemd-rtnl/rtnl-util.c b/src/libsystemd-rtnl/rtnl-util.c
index 264b72e..dfc0050 100644
--- a/src/libsystemd-rtnl/rtnl-util.c
+++ b/src/libsystemd-rtnl/rtnl-util.c
@@ -38,7 +38,7 @@ int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name) {
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_message_append(message, IFLA_IFNAME, name);
+        r = sd_rtnl_message_append_string(message, IFLA_IFNAME, name);
         if (r < 0)
                 return r;
 
@@ -66,7 +66,7 @@ int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias,
                 return r;
 
         if (alias) {
-                r = sd_rtnl_message_append(message, IFLA_IFALIAS, alias);
+                r = sd_rtnl_message_append_string(message, IFLA_IFALIAS, alias);
                 if (r < 0)
                         return r;
 
@@ -75,7 +75,7 @@ int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias,
         }
 
         if (mac) {
-                r = sd_rtnl_message_append(message, IFLA_ADDRESS, mac);
+                r = sd_rtnl_message_append_ether_addr(message, IFLA_ADDRESS, mac);
                 if (r < 0)
                         return r;
 
@@ -83,7 +83,7 @@ int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias,
         }
 
         if (mtu > 0) {
-                r = sd_rtnl_message_append(message, IFLA_MTU, &mtu);
+                r = sd_rtnl_message_append_u32(message, IFLA_MTU, mtu);
                 if (r < 0)
                         return r;
 
diff --git a/src/libsystemd-rtnl/test-rtnl.c b/src/libsystemd-rtnl/test-rtnl.c
index d7a243a..58654e9 100644
--- a/src/libsystemd-rtnl/test-rtnl.c
+++ b/src/libsystemd-rtnl/test-rtnl.c
@@ -38,9 +38,9 @@ static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
 
         /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
         assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, &message) >= 0);
-        assert(sd_rtnl_message_append(message, IFLA_IFNAME, name) >= 0);
-        assert(sd_rtnl_message_append(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
-        assert(sd_rtnl_message_append(message, IFLA_MTU, &mtu) >= 0);
+        assert(sd_rtnl_message_append_string(message, IFLA_IFNAME, name) >= 0);
+        assert(sd_rtnl_message_append_ether_addr(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
+        assert(sd_rtnl_message_append_u32(message, IFLA_MTU, mtu) >= 0);
 
         assert(sd_rtnl_message_read(message, &type, &data) > 0);
         assert(type == IFLA_IFNAME);
@@ -59,7 +59,7 @@ static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
 
 static void test_route(void) {
         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req;
-        uint32_t addr = htonl(INADDR_LOOPBACK);
+        struct in_addr addr;
         uint32_t index = 2;
         uint16_t type;
         void *data;
@@ -71,13 +71,15 @@ static void test_route(void) {
                 return;
         }
 
-        r = sd_rtnl_message_append(req, RTA_GATEWAY, &addr);
+        addr.s_addr = htonl(INADDR_LOOPBACK);
+
+        r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &addr);
         if (r < 0) {
                 log_error("Could not append RTA_GATEWAY attribute: %s", strerror(-r));
                 return;
         }
 
-        r = sd_rtnl_message_append(req, RTA_OIF, &index);
+        r = sd_rtnl_message_append_u32(req, RTA_OIF, index);
         if (r < 0) {
                 log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
                 return;
@@ -85,7 +87,7 @@ static void test_route(void) {
 
         assert(sd_rtnl_message_read(req, &type, &data) > 0);
         assert(type == RTA_GATEWAY);
-        assert(*(uint32_t *) data == addr);
+        assert(((struct in_addr *)data)->s_addr == addr.s_addr);
 
         assert(sd_rtnl_message_read(req, &type, &data) > 0);
         assert(type == RTA_OIF);
@@ -213,7 +215,7 @@ static void test_container(void) {
 
         assert(sd_rtnl_message_open_container(m, IFLA_LINKINFO) >= 0);
         assert(sd_rtnl_message_open_container(m, IFLA_LINKINFO) == -EINVAL);
-        assert(sd_rtnl_message_append(m, IFLA_INFO_KIND, "kind") >= 0);
+        assert(sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "kind") >= 0);
         assert(sd_rtnl_message_close_container(m) >= 0);
         assert(sd_rtnl_message_close_container(m) == -EINVAL);
 
@@ -295,7 +297,7 @@ int main(void) {
         assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, &m) >= 0);
         assert(m);
 
-        assert(sd_rtnl_message_append(m, IFLA_MTU, &mtu) >= 0);
+        assert(sd_rtnl_message_append_u32(m, IFLA_MTU, mtu) >= 0);
         assert(sd_rtnl_message_read(m, &type, (void **) &mtu_reply) == 1);
 
         assert(type == IFLA_MTU);
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 8f16a8c..63ba33e 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -95,7 +95,10 @@ int address_configure(Address *address, Link *link,
                 return r;
         }
 
-        r = sd_rtnl_message_append(req, IFA_LOCAL, &address->in_addr);
+        if (address->family == AF_INET)
+                r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in);
+        else if (address->family == AF_INET6)
+                r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6);
         if (r < 0) {
                 log_error("Could not append IFA_LOCAL attribute: %s",
                           strerror(-r));
@@ -107,7 +110,7 @@ int address_configure(Address *address, Link *link,
 
                 broadcast.s_addr = address->in_addr.in.s_addr | address->netmask.s_addr;
 
-                r = sd_rtnl_message_append(req, IFA_BROADCAST, &broadcast);
+                r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &broadcast);
                 if (r < 0) {
                         log_error("Could not append IFA_BROADCAST attribute: %s",
                                   strerror(-r));
@@ -116,7 +119,7 @@ int address_configure(Address *address, Link *link,
         }
 
         if (address->label) {
-                r = sd_rtnl_message_append(req, IFA_LABEL, address->label);
+                r = sd_rtnl_message_append_string(req, IFA_LABEL, address->label);
                 if (r < 0) {
                         log_error("Could not append IFA_LABEL attribute: %s",
                                   strerror(-r));
diff --git a/src/network/networkd-bridge.c b/src/network/networkd-bridge.c
index b764b7d..2c54146 100644
--- a/src/network/networkd-bridge.c
+++ b/src/network/networkd-bridge.c
@@ -91,7 +91,7 @@ static int bridge_join_ready(Bridge *bridge, Link* link, sd_rtnl_message_handler
                 return r;
         }
 
-        r = sd_rtnl_message_append(req, IFLA_MASTER, &bridge->link->ifindex);
+        r = sd_rtnl_message_append_u32(req, IFLA_MASTER, bridge->link->ifindex);
         if (r < 0) {
                 log_error("Could not append IFLA_MASTER attribute: %s",
                           strerror(-r));
@@ -162,7 +162,7 @@ static int bridge_create(Bridge *bridge) {
                 return r;
         }
 
-        r = sd_rtnl_message_append(req, IFLA_IFNAME, bridge->name);
+        r = sd_rtnl_message_append_string(req, IFLA_IFNAME, bridge->name);
         if (r < 0) {
                 log_error("Could not append IFLA_IFNAME attribute: %s",
                           strerror(-r));
@@ -176,7 +176,7 @@ static int bridge_create(Bridge *bridge) {
                 return r;
         }
 
-        r = sd_rtnl_message_append(req, IFLA_INFO_KIND, "bridge");
+        r = sd_rtnl_message_append_string(req, IFLA_INFO_KIND, "bridge");
         if (r < 0) {
                 log_error("Could not append IFLA_INFO_KIND attribute: %s",
                           strerror(-r));
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index f8580e9..22604b3 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -92,16 +92,24 @@ int route_configure(Route *route, Link *link,
                 return r;
         }
 
-        r = sd_rtnl_message_append(req, RTA_GATEWAY, &route->in_addr);
+        if (route->family == AF_INET)
+                r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &route->in_addr.in);
+        else if (route->family == AF_INET6)
+                r = sd_rtnl_message_append_in6_addr(req, RTA_GATEWAY, &route->in_addr.in6);
         if (r < 0) {
                 log_error("Could not append RTA_GATEWAY attribute: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_rtnl_message_append(req, RTA_DST, &route->dst_addr);
-        if (r < 0) {
-                log_error("Could not append RTA_DST attribute: %s", strerror(-r));
-                return r;
+        if (route->dst_prefixlen) {
+                if (route->family == AF_INET)
+                        r = sd_rtnl_message_append_in_addr(req, RTA_DST, &route->dst_addr.in);
+                else if (route->family == AF_INET6)
+                        r = sd_rtnl_message_append_in6_addr(req, RTA_DST, &route->dst_addr.in6);
+                if (r < 0) {
+                        log_error("Could not append RTA_DST attribute: %s", strerror(-r));
+                        return r;
+                }
         }
 
         r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
@@ -110,7 +118,7 @@ int route_configure(Route *route, Link *link,
                 return r;
         }
 
-        r = sd_rtnl_message_append(req, RTA_OIF, &link->ifindex);
+        r = sd_rtnl_message_append_u32(req, RTA_OIF, link->ifindex);
         if (r < 0) {
                 log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
                 return r;
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index fcd09a0..7d626b8 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -23,6 +23,8 @@
 ***/
 
 #include <inttypes.h>
+#include <netinet/in.h>
+#include <netinet/ether.h>
 
 #include "sd-event.h"
 #include "_sd-common.h"
@@ -89,7 +91,12 @@ int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags);
 
 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen);
 
-int sd_rtnl_message_append(sd_rtnl_message *m, unsigned short type, const void *data);
+int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data);
+int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data);
+int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data);
+int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data);
+int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data);
+
 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type);
 int sd_rtnl_message_close_container(sd_rtnl_message *m);
 

commit 0fc7531b40225475fed4ca8219b075bbdb54c5e0
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri Dec 6 17:19:55 2013 +0100

    rtnl: support interleaved reading and writing, and rewind

diff --git a/src/libsystemd-rtnl/rtnl-message.c b/src/libsystemd-rtnl/rtnl-message.c
index f8f2bcd..8940d21 100644
--- a/src/libsystemd-rtnl/rtnl-message.c
+++ b/src/libsystemd-rtnl/rtnl-message.c
@@ -39,7 +39,6 @@ struct sd_rtnl_message {
         struct rtattr *current_container;
 
         struct rtattr *next_rta;
-        size_t remaining_size;
 
         bool sealed:1;
 };
@@ -155,6 +154,8 @@ int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family,
 
         rtm = NLMSG_DATA((*ret)->hdr);
 
+        (*ret)->next_rta = RTM_RTA(rtm);
+
         rtm->rtm_family = rtm_family;
         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
         rtm->rtm_type = RTN_UNICAST;
@@ -207,6 +208,8 @@ int sd_rtnl_message_link_new(uint16_t nlmsg_type, int index, sd_rtnl_message **r
         ifi->ifi_index = index;
         ifi->ifi_change = 0xffffffff;
 
+        (*ret)->next_rta = IFLA_RTA(ifi);
+
         return 0;
 }
 
@@ -233,6 +236,8 @@ int sd_rtnl_message_addr_new(uint16_t nlmsg_type, int index, unsigned char famil
         ifa->ifa_scope = scope;
         ifa->ifa_index = index;
 
+        (*ret)->next_rta = IFA_RTA(ifa);
+
         return 0;
 }
 
@@ -314,6 +319,10 @@ static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data,
         new_hdr = realloc(m->hdr, message_length);
         if (!new_hdr)
                 return -ENOMEM;
+        /* update the location of the next rta for reading */
+        m->next_rta = (struct rtattr *) ((uint8_t *) m->next_rta +
+                                         ((uint8_t *) new_hdr -
+                                          (uint8_t *) m->hdr));
         m->hdr = new_hdr;
 
         /* get pointer to the attribute we are about to add */
@@ -323,9 +332,9 @@ static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data,
 
         /* we are inside a container, extend it */
         if (m->current_container)
-                m->current_container->rta_len = (unsigned char *) m->hdr +
+                m->current_container->rta_len = (uint8_t *) m->hdr +
                                                 m->hdr->nlmsg_len -
-                                                (unsigned char *) m->current_container;
+                                                (uint8_t *) m->current_container;
 
         /* fill in the attribute */
         rta->rta_type = type;
@@ -339,9 +348,9 @@ static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data,
                 */
                 padding = mempcpy(RTA_DATA(rta), data, data_length);
                 /* make sure also the padding at the end of the message is initialized */
-                memset(padding, '\0', (unsigned char *) m->hdr +
+                memset(padding, '\0', (uint8_t *) m->hdr +
                                       m->hdr->nlmsg_len -
-                                      (unsigned char *) padding);
+                                      (uint8_t *) padding);
         }
 
         return 0;
@@ -480,7 +489,8 @@ int sd_rtnl_message_close_container(sd_rtnl_message *m) {
         return 0;
 }
 
-static int message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
+int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
+        size_t remaining_size;
         uint16_t rtm_type;
         int r;
 
@@ -489,7 +499,9 @@ static int message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
         assert(type);
         assert(data);
 
-        if (!RTA_OK(m->next_rta, m->remaining_size))
+        remaining_size = (uint8_t *) m->hdr + m->hdr->nlmsg_len - (uint8_t *) m->next_rta;
+
+        if (!RTA_OK(m->next_rta, remaining_size))
                 return 0;
 
         /* make sure we don't try to read a container
@@ -498,74 +510,18 @@ static int message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
         if (r < 0)
                 return r;
 
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_GETLINK:
-                case RTM_SETLINK:
-                case RTM_DELLINK:
-                        if (m->next_rta->rta_type == IFLA_LINKINFO) {
-                                return -EINVAL;
-                        }
-        }
+        if (message_type_is_link(rtm_type) &&
+            m->next_rta->rta_type == IFLA_LINKINFO)
+               return -EINVAL;
 
         *data = RTA_DATA(m->next_rta);
         *type = m->next_rta->rta_type;
 
-        m->next_rta = RTA_NEXT(m->next_rta, m->remaining_size);
+        m->next_rta = RTA_NEXT(m->next_rta, remaining_size);
 
         return 1;
 }
 
-int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
-        uint16_t rtm_type;
-        int r;
-
-        assert_return(m, -EINVAL);
-        assert_return(data, -EINVAL);
-
-        r = sd_rtnl_message_get_type(m, &rtm_type);
-        if (r < 0)
-                return r;
-
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_DELLINK:
-                case RTM_GETLINK:
-                        if (!m->next_rta) {
-                                struct ifinfomsg *ifi = NLMSG_DATA(m->hdr);
-
-                                m->next_rta = IFLA_RTA(ifi);
-                                m->remaining_size = IFLA_PAYLOAD(m->hdr);
-                        }
-                        break;
-                case RTM_NEWADDR:
-                case RTM_DELADDR:
-                case RTM_GETADDR:
-                        if (!m->next_rta) {
-                                struct ifaddrmsg *ifa = NLMSG_DATA(m->hdr);
-
-                                m->next_rta = IFA_RTA(ifa);
-                                m->remaining_size = IFA_PAYLOAD(m->hdr);
-                        }
-                        break;
-                case RTM_NEWROUTE:
-                case RTM_DELROUTE:
-                case RTM_GETROUTE:
-                        if (!m->next_rta) {
-                                struct rtmesg *rtm = NLMSG_DATA(m->hdr);
-
-                                m->next_rta = RTM_RTA(rtm);
-                                m->remaining_size = RTM_PAYLOAD(m->hdr);
-                        }
-                        break;
-                default:
-                        return -ENOTSUP;
-        }
-
-        return message_read(m, type, data);
-}
-
 uint32_t message_get_serial(sd_rtnl_message *m) {
         assert(m);
         assert(m->hdr);
@@ -691,6 +647,10 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
 
         if (k > 0)
                 switch (m->hdr->nlmsg_type) {
+                        struct ifinfomsg *ifi;
+                        struct ifaddrmsg *ifa;
+                        struct rtmsg *rtm;
+
                         /* check that the size matches the message type */
                         case NLMSG_ERROR:
                                 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
@@ -702,18 +662,30 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
                         case RTM_GETLINK:
                                 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg)))
                                         k = -EIO;
+                                else {
+                                        ifi = NLMSG_DATA(m->hdr);
+                                        m->next_rta = IFLA_RTA(ifi);
+                                }
                                 break;
                         case RTM_NEWADDR:
                         case RTM_DELADDR:
                         case RTM_GETADDR:
                                 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifaddrmsg)))
                                         k = -EIO;
+                                else {
+                                        ifa = NLMSG_DATA(m->hdr);
+                                        m->next_rta = IFA_RTA(ifa);
+                                }
                                 break;
                         case RTM_NEWROUTE:
                         case RTM_DELROUTE:
                         case RTM_GETROUTE:
                                 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg)))
                                         k = -EIO;
+                                else {
+                                        rtm = NLMSG_DATA(m->hdr);
+                                        m->next_rta = RTM_RTA(rtm);
+                                }
                                 break;
                         case NLMSG_NOOP:
                                 k = 0;
@@ -732,3 +704,41 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
 
         return k;
 }
+
+int sd_rtnl_message_rewind(sd_rtnl_message *m) {
+        struct ifinfomsg *ifi;
+        struct ifaddrmsg *ifa;
+        struct rtmsg *rtm;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+
+        switch(m->hdr->nlmsg_type) {
+                case RTM_NEWLINK:
+                case RTM_SETLINK:
+                case RTM_GETLINK:
+                case RTM_DELLINK:
+                        ifi = NLMSG_DATA(m->hdr);
+
+                        m->next_rta = IFLA_RTA(ifi);
+                        break;
+                case RTM_NEWADDR:
+                case RTM_GETADDR:
+                case RTM_DELADDR:
+                        ifa = NLMSG_DATA(m->hdr);
+
+                        m->next_rta = IFA_RTA(ifa);
+                        break;
+                case RTM_NEWROUTE:
+                case RTM_GETROUTE:
+                case RTM_DELROUTE:
+                        rtm = NLMSG_DATA(m->hdr);
+
+                        m->next_rta = RTM_RTA(rtm);
+                        break;
+                default:
+                        return -ENOTSUP;
+        }
+
+        return 0;
+}
diff --git a/src/libsystemd-rtnl/test-rtnl.c b/src/libsystemd-rtnl/test-rtnl.c
index bfcfc85..d7a243a 100644
--- a/src/libsystemd-rtnl/test-rtnl.c
+++ b/src/libsystemd-rtnl/test-rtnl.c
@@ -42,15 +42,15 @@ static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
         assert(sd_rtnl_message_append(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
         assert(sd_rtnl_message_append(message, IFLA_MTU, &mtu) >= 0);
 
-        assert(sd_rtnl_message_read(message, &type, &data) >= 0);
+        assert(sd_rtnl_message_read(message, &type, &data) > 0);
         assert(type == IFLA_IFNAME);
         assert(streq(name, (char *) data));
 
-        assert(sd_rtnl_message_read(message, &type, &data) >= 0);
+        assert(sd_rtnl_message_read(message, &type, &data) > 0);
         assert(type == IFLA_ADDRESS);
         assert(streq(mac, ether_ntoa(data)));
 
-        assert(sd_rtnl_message_read(message, &type, &data) >= 0);
+        assert(sd_rtnl_message_read(message, &type, &data) > 0);
         assert(type == IFLA_MTU);
         assert(mtu == *(unsigned int *) data);
 
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index f851afa..fcd09a0 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -95,6 +95,8 @@ int sd_rtnl_message_close_container(sd_rtnl_message *m);
 
 int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data);
 
+int sd_rtnl_message_rewind(sd_rtnl_message *m);
+
 _SD_END_DECLARATIONS;
 
 #endif

commit 1f01fb4f29bbe6aff952331a538fb3cc7f52dab4
Author: Tom Gundersen <teg at jklm.no>
Date:   Sat Dec 7 21:18:44 2013 +0100

    rtnl: simplify route_new()
    
    Drop most of the arguments and instead introduce set_dst_prefixlen().

diff --git a/src/libsystemd-rtnl/rtnl-message.c b/src/libsystemd-rtnl/rtnl-message.c
index 8a3aa63..f8f2bcd 100644
--- a/src/libsystemd-rtnl/rtnl-message.c
+++ b/src/libsystemd-rtnl/rtnl-message.c
@@ -125,15 +125,23 @@ bool message_type_is_addr(uint16_t type) {
         }
 }
 
+int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
+        struct rtmsg *rtm;
+
+        rtm = NLMSG_DATA(m->hdr);
+
+        rtm->rtm_dst_len = prefixlen;
+
+        return 0;
+}
+
 int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family,
-                              unsigned char rtm_dst_len, unsigned char rtm_src_len,
-                              unsigned char rtm_tos, unsigned char rtm_table,
-                              unsigned char rtm_scope, unsigned char rtm_protocol,
-                              unsigned char rtm_type, unsigned rtm_flags, sd_rtnl_message **ret) {
+                              sd_rtnl_message **ret) {
         struct rtmsg *rtm;
         int r;
 
         assert_return(message_type_is_route(nlmsg_type), -EINVAL);
+        assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
         assert_return(ret, -EINVAL);
 
         r = message_new(ret, NLMSG_SPACE(sizeof(struct rtmsg)));
@@ -148,14 +156,10 @@ int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family,
         rtm = NLMSG_DATA((*ret)->hdr);
 
         rtm->rtm_family = rtm_family;
-        rtm->rtm_dst_len = rtm_dst_len;
-        rtm->rtm_src_len = rtm_src_len;
-        rtm->rtm_tos = rtm_tos;
-        rtm->rtm_table = rtm_table;
-        rtm->rtm_protocol = rtm_protocol;
-        rtm->rtm_scope = rtm_scope;
-        rtm->rtm_type = rtm_type;
-        rtm->rtm_flags = rtm_flags;
+        rtm->rtm_scope = RT_SCOPE_UNIVERSE;
+        rtm->rtm_type = RTN_UNICAST;
+        rtm->rtm_table = RT_TABLE_MAIN;
+        rtm->rtm_protocol = RTPROT_BOOT;
 
         return 0;
 }
diff --git a/src/libsystemd-rtnl/test-rtnl.c b/src/libsystemd-rtnl/test-rtnl.c
index 409a0fa..bfcfc85 100644
--- a/src/libsystemd-rtnl/test-rtnl.c
+++ b/src/libsystemd-rtnl/test-rtnl.c
@@ -65,9 +65,7 @@ static void test_route(void) {
         void *data;
         int r;
 
-        r = sd_rtnl_message_route_new(RTM_NEWROUTE, AF_INET, 0, 0, 0,
-                                      RT_TABLE_MAIN, RT_SCOPE_UNIVERSE, RTPROT_BOOT,
-                                      RTN_UNICAST, 0, &req);
+        r = sd_rtnl_message_route_new(RTM_NEWROUTE, AF_INET, &req);
         if (r < 0) {
                 log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
                 return;
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 1ea6237..f8580e9 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -86,9 +86,7 @@ int route_configure(Route *route, Link *link,
         assert(link->ifindex > 0);
         assert(route->family == AF_INET || route->family == AF_INET6);
 
-        r = sd_rtnl_message_route_new(RTM_NEWROUTE, route->family, route->dst_prefixlen,
-                                      0, 0, RT_TABLE_MAIN, RT_SCOPE_UNIVERSE,
-                                      RTPROT_BOOT, RTN_UNICAST, 0, &req);
+        r = sd_rtnl_message_route_new(RTM_NEWROUTE, route->family, &req);
         if (r < 0) {
                 log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
                 return r;
@@ -106,6 +104,12 @@ int route_configure(Route *route, Link *link,
                 return r;
         }
 
+        r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
+        if (r < 0) {
+                log_error("Could not set destination prefix length: %s", strerror(-r));
+                return r;
+        }
+
         r = sd_rtnl_message_append(req, RTA_OIF, &link->ifindex);
         if (r < 0) {
                 log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 066d778..f851afa 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -69,10 +69,13 @@ int sd_rtnl_message_addr_new(uint16_t msg_type, int index, unsigned char family,
                              unsigned char prefixlen, unsigned char flags,
                              unsigned char scope, sd_rtnl_message **ret);
 int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family,
+                              sd_rtnl_message **ret);
+/*
                               unsigned char rtm_dst_len, unsigned char rtm_src_len,
                               unsigned char rtm_tos, unsigned char rtm_table,
                               unsigned char rtm_scope, unsigned char rtm_protocol,
                               unsigned char rtm_type, unsigned flags, sd_rtnl_message **ret);
+*/
 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);
 
@@ -84,6 +87,8 @@ int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type);
 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex);
 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags);
 
+int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen);
+
 int sd_rtnl_message_append(sd_rtnl_message *m, unsigned short type, const void *data);
 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type);
 int sd_rtnl_message_close_container(sd_rtnl_message *m);

commit fc25d7f8050f262fa6cafeb2a1032e6eb3e7b412
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri Dec 6 18:16:16 2013 +0100

    rtnl: simplify link_new()
    
    Drop most of the arguments and instead introduce link_set_{flags,type}.

diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c
index 5172a69..7bb20ec 100644
--- a/src/core/loopback-setup.c
+++ b/src/core/loopback-setup.c
@@ -89,7 +89,11 @@ static int start_interface(sd_rtnl *rtnl, int if_loopback, uint32_t ipv4_address
         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
-        r = sd_rtnl_message_link_new(RTM_NEWLINK, if_loopback, 0, IFF_UP, &req);
+        r = sd_rtnl_message_link_new(RTM_NEWLINK, if_loopback, &req);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_link_set_flags(req, IFF_UP);
         if (r < 0)
                 return r;
 
diff --git a/src/libsystemd-rtnl/rtnl-message.c b/src/libsystemd-rtnl/rtnl-message.c
index 870fdcd..8a3aa63 100644
--- a/src/libsystemd-rtnl/rtnl-message.c
+++ b/src/libsystemd-rtnl/rtnl-message.c
@@ -160,7 +160,27 @@ int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family,
         return 0;
 }
 
-int sd_rtnl_message_link_new(uint16_t nlmsg_type, int index, unsigned type, unsigned flags, sd_rtnl_message **ret) {
+int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags) {
+        struct ifinfomsg *ifi;
+
+        ifi = NLMSG_DATA(m->hdr);
+
+        ifi->ifi_flags = flags;
+
+        return 0;
+}
+
+int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) {
+        struct ifinfomsg *ifi;
+
+        ifi = NLMSG_DATA(m->hdr);
+
+        ifi->ifi_type = type;
+
+        return 0;
+}
+
+int sd_rtnl_message_link_new(uint16_t nlmsg_type, int index, sd_rtnl_message **ret) {
         struct ifinfomsg *ifi;
         int r;
 
@@ -181,8 +201,6 @@ int sd_rtnl_message_link_new(uint16_t nlmsg_type, int index, unsigned type, unsi
 
         ifi->ifi_family = AF_UNSPEC;
         ifi->ifi_index = index;
-        ifi->ifi_type = type;
-        ifi->ifi_flags = flags;
         ifi->ifi_change = 0xffffffff;
 
         return 0;
diff --git a/src/libsystemd-rtnl/rtnl-util.c b/src/libsystemd-rtnl/rtnl-util.c
index 4e7661b..264b72e 100644
--- a/src/libsystemd-rtnl/rtnl-util.c
+++ b/src/libsystemd-rtnl/rtnl-util.c
@@ -34,7 +34,7 @@ int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name) {
         assert(ifindex > 0);
         assert(name);
 
-        r = sd_rtnl_message_link_new(RTM_SETLINK, ifindex, 0, 0, &message);
+        r = sd_rtnl_message_link_new(RTM_SETLINK, ifindex, &message);
         if (r < 0)
                 return r;
 
@@ -61,7 +61,7 @@ int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias,
         if (!alias && !mac && mtu == 0)
                 return 0;
 
-        r = sd_rtnl_message_link_new(RTM_SETLINK, ifindex, 0, 0, &message);
+        r = sd_rtnl_message_link_new(RTM_SETLINK, ifindex, &message);
         if (r < 0)
                 return r;
 
diff --git a/src/libsystemd-rtnl/test-rtnl.c b/src/libsystemd-rtnl/test-rtnl.c
index 6c34a85..409a0fa 100644
--- a/src/libsystemd-rtnl/test-rtnl.c
+++ b/src/libsystemd-rtnl/test-rtnl.c
@@ -37,7 +37,7 @@ static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
         void *data;
 
         /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
-        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &message) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, &message) >= 0);
         assert(sd_rtnl_message_append(message, IFLA_IFNAME, name) >= 0);
         assert(sd_rtnl_message_append(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
         assert(sd_rtnl_message_append(message, IFLA_MTU, &mtu) >= 0);
@@ -142,7 +142,7 @@ static void test_event_loop(int ifindex) {
         assert(ifname);
 
         assert(sd_rtnl_open(0, &rtnl) >= 0);
-        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, &m) >= 0);
 
         assert(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, NULL) >= 0);
 
@@ -176,7 +176,7 @@ static void test_async(int ifindex) {
 
         assert(sd_rtnl_open(0, &rtnl) >= 0);
 
-        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, &m) >= 0);
 
         assert(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, &serial) >= 0);
 
@@ -191,8 +191,8 @@ static void test_pipe(int ifindex) {
 
         assert(sd_rtnl_open(0, &rtnl) >= 0);
 
-        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m1) >= 0);
-        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &m2) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, &m1) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, &m2) >= 0);
 
         counter ++;
         assert(sd_rtnl_call_async(rtnl, m1, &pipe_handler, &counter, 0, NULL) >= 0);
@@ -211,7 +211,7 @@ static void test_container(void) {
         uint16_t type;
         void *data;
 
-        assert(sd_rtnl_message_link_new(RTM_NEWLINK, 0, 0, 0, &m) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_NEWLINK, 0, &m) >= 0);
 
         assert(sd_rtnl_message_open_container(m, IFLA_LINKINFO) >= 0);
         assert(sd_rtnl_message_open_container(m, IFLA_LINKINFO) == -EINVAL);
@@ -275,7 +275,7 @@ int main(void) {
 
         test_link_configure(rtnl, if_loopback);
 
-        assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, 0, 0, &m) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, &m) >= 0);
         assert(m);
 
         assert(sd_rtnl_message_get_type(m, &type) >= 0);
@@ -294,7 +294,7 @@ int main(void) {
         assert((m = sd_rtnl_message_unref(m)) == NULL);
         assert((r = sd_rtnl_message_unref(r)) == NULL);
 
-        assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, 0, 0, &m) >= 0);
+        assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, &m) >= 0);
         assert(m);
 
         assert(sd_rtnl_message_append(m, IFLA_MTU, &mtu) >= 0);
diff --git a/src/network/networkd-bridge.c b/src/network/networkd-bridge.c
index 1704f65..b764b7d 100644
--- a/src/network/networkd-bridge.c
+++ b/src/network/networkd-bridge.c
@@ -84,7 +84,7 @@ static int bridge_join_ready(Bridge *bridge, Link* link, sd_rtnl_message_handler
         assert(link);
         assert(callback);
 
-        r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, 0, 0, &req);
+        r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
         if (r < 0) {
                 log_error("Could not allocate RTM_SETLINK message: %s",
                           strerror(-r));
@@ -155,7 +155,7 @@ static int bridge_create(Bridge *bridge) {
         assert(bridge->manager);
         assert(bridge->manager->rtnl);
 
-        r = sd_rtnl_message_link_new(RTM_NEWLINK, 0, 0, 0, &req);
+        r = sd_rtnl_message_link_new(RTM_NEWLINK, 0, &req);
         if (r < 0) {
                 log_error("Could not allocate RTM_NEWLINK message: %s",
                           strerror(-r));
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 8c7b0fc..16255f9 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -264,7 +264,7 @@ static int link_get(Link *link) {
         assert(link->manager);
         assert(link->manager->rtnl);
 
-        r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, 0, 0, &req);
+        r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
         if (r < 0) {
                 log_error("Could not allocate RTM_GETLINK message");
                 return r;
@@ -301,12 +301,18 @@ static int link_up(Link *link) {
         assert(link->manager);
         assert(link->manager->rtnl);
 
-        r = sd_rtnl_message_link_new(RTM_NEWLINK, link->ifindex, 0, IFF_UP, &req);
+        r = sd_rtnl_message_link_new(RTM_NEWLINK, link->ifindex, &req);
         if (r < 0) {
                 log_error("Could not allocate RTM_NEWLINK message");
                 return r;
         }
 
+        r = sd_rtnl_message_link_set_flags(req, IFF_UP);
+        if (r < 0) {
+                log_error("Could not set link flags");
+                return r;
+        }
+
         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
         if (r < 0) {
                 log_error("Could not send rtnetlink message: %s", strerror(-r));
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 0a63b28..066d778 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -64,8 +64,7 @@ int sd_rtnl_attach_event(sd_rtnl *nl, sd_event *e, int priority);
 int sd_rtnl_detach_event(sd_rtnl *nl);
 
 /* messages */
-int sd_rtnl_message_link_new(uint16_t msg_type, int index, unsigned int type,
-                             unsigned int flags, sd_rtnl_message **ret);
+int sd_rtnl_message_link_new(uint16_t msg_type, int index, sd_rtnl_message **ret);
 int sd_rtnl_message_addr_new(uint16_t msg_type, int index, unsigned char family,
                              unsigned char prefixlen, unsigned char flags,
                              unsigned char scope, sd_rtnl_message **ret);
@@ -80,6 +79,8 @@ sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);
 int sd_rtnl_message_get_errno(sd_rtnl_message *m);
 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type);
 
+int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags);
+int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type);
 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex);
 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags);
 

commit 23a7f0f721ff4e3b3fd4ed87f7d8e01ebad20093
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri Dec 6 15:20:36 2013 +0100

    rtnl: match - only match on one type at a time

diff --git a/src/libsystemd-rtnl/rtnl-internal.h b/src/libsystemd-rtnl/rtnl-internal.h
index 1e40427..2e0b7b8 100644
--- a/src/libsystemd-rtnl/rtnl-internal.h
+++ b/src/libsystemd-rtnl/rtnl-internal.h
@@ -39,7 +39,7 @@ struct reply_callback {
 
 struct match_callback {
         sd_rtnl_message_handler_t callback;
-        uint16_t types;
+        uint16_t type;
         void *userdata;
 
         LIST_FIELDS(struct match_callback, match_callbacks);
diff --git a/src/libsystemd-rtnl/sd-rtnl.c b/src/libsystemd-rtnl/sd-rtnl.c
index c933ac5..08b82ab 100644
--- a/src/libsystemd-rtnl/sd-rtnl.c
+++ b/src/libsystemd-rtnl/sd-rtnl.c
@@ -304,7 +304,7 @@ static int process_match(sd_rtnl *rtnl, sd_rtnl_message *m) {
                 return r;
 
         LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) {
-                if (type & c->types) {
+                if (type == c->type) {
                         r = c->callback(rtnl, m, c->userdata);
                         if (r != 0)
                                 return r;
@@ -825,22 +825,22 @@ int sd_rtnl_detach_event(sd_rtnl *rtnl) {
 }
 
 int sd_rtnl_add_match(sd_rtnl *rtnl,
-                      uint16_t types,
+                      uint16_t type,
                       sd_rtnl_message_handler_t callback,
                       void *userdata) {
         struct match_callback *c;
 
         assert_return(rtnl, -EINVAL);
         assert_return(callback, -EINVAL);
-        assert_return(types, -EINVAL);
         assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
+        assert_return(message_type_is_link(type) || message_type_is_addr(type) || message_type_is_route(type), -ENOTSUP);
 
         c = new0(struct match_callback, 1);
         if (!c)
                 return -ENOMEM;
 
         c->callback = callback;
-        c->types = types;
+        c->type = type;
         c->userdata = userdata;
 
         LIST_PREPEND(match_callbacks, rtnl->match_callbacks, c);
@@ -849,7 +849,7 @@ int sd_rtnl_add_match(sd_rtnl *rtnl,
 }
 
 int sd_rtnl_remove_match(sd_rtnl *rtnl,
-                         uint16_t types,
+                         uint16_t type,
                          sd_rtnl_message_handler_t callback,
                          void *userdata) {
         struct match_callback *c;
@@ -859,7 +859,7 @@ int sd_rtnl_remove_match(sd_rtnl *rtnl,
         assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
 
         LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks)
-                if (c->callback == callback && c->types == types && c->userdata == userdata) {
+                if (c->callback == callback && c->type == type && c->userdata == userdata) {
                         LIST_REMOVE(match_callbacks, rtnl->match_callbacks, c);
                         free(c);
 
diff --git a/src/libsystemd-rtnl/test-rtnl.c b/src/libsystemd-rtnl/test-rtnl.c
index a512a7b..6c34a85 100644
--- a/src/libsystemd-rtnl/test-rtnl.c
+++ b/src/libsystemd-rtnl/test-rtnl.c
@@ -235,14 +235,12 @@ static void test_match(void) {
 
         assert(sd_rtnl_open(0, &rtnl) >= 0);
 
-        assert(sd_rtnl_add_match(rtnl, 0, &link_handler, NULL) == -EINVAL);
+        assert(sd_rtnl_add_match(rtnl, RTM_NEWLINK, &link_handler, NULL) >= 0);
+        assert(sd_rtnl_add_match(rtnl, RTM_NEWLINK, &link_handler, NULL) >= 0);
 
-        assert(sd_rtnl_add_match(rtnl, RTMGRP_LINK, &link_handler, NULL) >= 0);
-        assert(sd_rtnl_add_match(rtnl, RTMGRP_LINK, &link_handler, NULL) >= 0);
-
-        assert(sd_rtnl_remove_match(rtnl, RTMGRP_LINK, &link_handler, NULL) == 1);
-        assert(sd_rtnl_remove_match(rtnl, RTMGRP_LINK, &link_handler, NULL) == 1);
-        assert(sd_rtnl_remove_match(rtnl, RTMGRP_LINK, &link_handler, NULL) == 0);
+        assert(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
+        assert(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
+        assert(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 0);
 }
 
 int main(void) {

commit 9d0db17836c867ab2b8f460f649a478bf9f291d2
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri Dec 6 15:13:34 2013 +0100

    rtnl: clean up/add asserts

diff --git a/src/libsystemd-rtnl/rtnl-internal.h b/src/libsystemd-rtnl/rtnl-internal.h
index a1050a0..1e40427 100644
--- a/src/libsystemd-rtnl/rtnl-internal.h
+++ b/src/libsystemd-rtnl/rtnl-internal.h
@@ -86,6 +86,11 @@ struct sd_rtnl {
 int message_new_synthetic_error(int error, uint32_t serial, sd_rtnl_message **ret);
 uint32_t message_get_serial(sd_rtnl_message *m);
 int message_seal(sd_rtnl *nl, sd_rtnl_message *m);
+
+bool message_type_is_link(uint16_t type);
+bool message_type_is_addr(uint16_t type);
+bool message_type_is_route(uint16_t type);
+
 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m);
 int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret);
 
diff --git a/src/libsystemd-rtnl/rtnl-message.c b/src/libsystemd-rtnl/rtnl-message.c
index 65cc501..870fdcd 100644
--- a/src/libsystemd-rtnl/rtnl-message.c
+++ b/src/libsystemd-rtnl/rtnl-message.c
@@ -91,6 +91,40 @@ int message_new_synthetic_error(int error, uint32_t serial, sd_rtnl_message **re
         return 0;
 }
 
+bool message_type_is_route(uint16_t type) {
+        switch (type) {
+                case RTM_NEWROUTE:
+                case RTM_GETROUTE:
+                case RTM_DELROUTE:
+                        return true;
+                default:
+                        return false;
+        }
+}
+
+bool message_type_is_link(uint16_t type) {
+        switch (type) {
+                case RTM_NEWLINK:
+                case RTM_SETLINK:
+                case RTM_GETLINK:
+                case RTM_DELLINK:
+                        return true;
+                default:
+                        return false;
+        }
+}
+
+bool message_type_is_addr(uint16_t type) {
+        switch (type) {
+                case RTM_NEWADDR:
+                case RTM_GETADDR:
+                case RTM_DELADDR:
+                        return true;
+                default:
+                        return false;
+        }
+}
+
 int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family,
                               unsigned char rtm_dst_len, unsigned char rtm_src_len,
                               unsigned char rtm_tos, unsigned char rtm_table,
@@ -99,8 +133,7 @@ int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family,
         struct rtmsg *rtm;
         int r;
 
-        assert_return(nlmsg_type == RTM_NEWROUTE || nlmsg_type == RTM_DELROUTE ||
-                      nlmsg_type == RTM_GETROUTE, -EINVAL);
+        assert_return(message_type_is_route(nlmsg_type), -EINVAL);
         assert_return(ret, -EINVAL);
 
         r = message_new(ret, NLMSG_SPACE(sizeof(struct rtmsg)));
@@ -131,8 +164,7 @@ int sd_rtnl_message_link_new(uint16_t nlmsg_type, int index, unsigned type, unsi
         struct ifinfomsg *ifi;
         int r;
 
-        assert_return(nlmsg_type == RTM_NEWLINK || nlmsg_type == RTM_DELLINK ||
-                      nlmsg_type == RTM_SETLINK || nlmsg_type == RTM_GETLINK, -EINVAL);
+        assert_return(message_type_is_link(nlmsg_type), -EINVAL);
         assert_return(nlmsg_type == RTM_NEWLINK || index > 0, -EINVAL);
         assert_return(ret, -EINVAL);
 
@@ -160,7 +192,7 @@ int sd_rtnl_message_addr_new(uint16_t nlmsg_type, int index, unsigned char famil
         struct ifaddrmsg *ifa;
         int r;
 
-        assert_return(nlmsg_type == RTM_NEWADDR || nlmsg_type == RTM_DELADDR || nlmsg_type == RTM_GETADDR, -EINVAL);
+        assert_return(message_type_is_addr(nlmsg_type), -EINVAL);
         assert_return(index > 0, -EINVAL);
         assert_return(ret, -EINVAL);
 
@@ -211,9 +243,9 @@ int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
         struct ifinfomsg *ifi;
 
         assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
         assert_return(ifindex, -EINVAL);
-        assert_return(m->hdr->nlmsg_type == RTM_NEWLINK || m->hdr->nlmsg_type == RTM_DELLINK ||
-                      m->hdr->nlmsg_type == RTM_GETLINK || m->hdr->nlmsg_type == RTM_SETLINK, -EINVAL);
 
         ifi = NLMSG_DATA(m->hdr);
 
@@ -226,9 +258,9 @@ int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
         struct ifinfomsg *ifi;
 
         assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
         assert_return(flags, -EINVAL);
-        assert_return(m->hdr->nlmsg_type == RTM_NEWLINK || m->hdr->nlmsg_type == RTM_DELLINK ||
-                      m->hdr->nlmsg_type == RTM_GETLINK || m->hdr->nlmsg_type == RTM_SETLINK, -EINVAL);
 
         ifi = NLMSG_DATA(m->hdr);
 
@@ -406,18 +438,13 @@ int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
 
         sd_rtnl_message_get_type(m, &rtm_type);
 
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_GETLINK:
-                case RTM_DELLINK:
-                        if (type == IFLA_LINKINFO)
-                                return add_rtattr(m, type, NULL, 0);
-                        else
-                                return -ENOTSUP;
-                default:
+        if (message_type_is_link(rtm_type)) {
+                if (type == IFLA_LINKINFO)
+                        return add_rtattr(m, type, NULL, 0);
+                else
                         return -ENOTSUP;
-        }
+        } else
+                return -ENOTSUP;
 
         return 0;
 }
@@ -519,6 +546,7 @@ int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data)
 
 uint32_t message_get_serial(sd_rtnl_message *m) {
         assert(m);
+        assert(m->hdr);
 
         return m->hdr->nlmsg_seq;
 }
@@ -527,6 +555,7 @@ int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
         struct nlmsgerr *err;
 
         assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
 
         if (m->hdr->nlmsg_type != NLMSG_ERROR)
                 return 0;
@@ -537,6 +566,10 @@ int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
 }
 
 int message_seal(sd_rtnl *nl, sd_rtnl_message *m) {
+        assert(nl);
+        assert(m);
+        assert(m->hdr);
+
         if (m->sealed)
                 return -EPERM;
 
@@ -547,8 +580,8 @@ int message_seal(sd_rtnl *nl, sd_rtnl_message *m) {
 }
 
 static int message_receive_need(sd_rtnl *rtnl, size_t *need) {
-        assert_return(rtnl, -EINVAL);
-        assert_return(need, -EINVAL);
+        assert(rtnl);
+        assert(need);
 
         /* ioctl(rtnl->fd, FIONREAD, &need)
            Does not appear to work on netlink sockets. libnl uses
@@ -576,8 +609,9 @@ int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
         };
         ssize_t k;
 
-        assert_return(nl, -EINVAL);
-        assert_return(m, -EINVAL);
+        assert(nl);
+        assert(m);
+        assert(m->hdr);
 
         k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
                         0, &addr.sa, sizeof(addr));
@@ -603,8 +637,8 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
         ssize_t k;
         size_t need;
 
-        assert_return(nl, -EINVAL);
-        assert_return(ret, -EINVAL);
+        assert(nl);
+        assert(ret);
 
         r = message_receive_need(nl, &need);
         if (r < 0)
diff --git a/src/libsystemd-rtnl/sd-rtnl.c b/src/libsystemd-rtnl/sd-rtnl.c
index 98d0f89..c933ac5 100644
--- a/src/libsystemd-rtnl/sd-rtnl.c
+++ b/src/libsystemd-rtnl/sd-rtnl.c
@@ -75,6 +75,8 @@ int sd_rtnl_open(uint32_t groups, sd_rtnl **ret) {
         socklen_t addrlen;
         int r;
 
+        assert_return(ret, -EINVAL);
+
         r = sd_rtnl_new(&rtnl);
         if (r < 0)
                 return r;
@@ -316,6 +318,8 @@ static int process_running(sd_rtnl *rtnl, sd_rtnl_message **ret) {
         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *m = NULL;
         int r;
 
+        assert(rtnl);
+
         r = process_timeout(rtnl);
         if (r != 0)
                 goto null_message;

commit 3e10a9f410da15a8c8384b2d7fcf29d138c6f327
Author: Tom Gundersen <teg at jklm.no>
Date:   Fri Dec 6 16:26:17 2013 +0100

    rtnl: add support for receiving route messages

diff --git a/src/libsystemd-rtnl/rtnl-message.c b/src/libsystemd-rtnl/rtnl-message.c
index 8d62df9..65cc501 100644
--- a/src/libsystemd-rtnl/rtnl-message.c
+++ b/src/libsystemd-rtnl/rtnl-message.c
@@ -653,6 +653,12 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
                                 if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifaddrmsg)))
                                         k = -EIO;
                                 break;
+                        case RTM_NEWROUTE:
+                        case RTM_DELROUTE:
+                        case RTM_GETROUTE:
+                                if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg)))
+                                        k = -EIO;
+                                break;
                         case NLMSG_NOOP:
                                 k = 0;
                                 break;



More information about the systemd-commits mailing list