[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