summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-rtnl
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-08-12 01:41:42 +0200
committerLennart Poettering <lennart@poettering.net>2014-08-12 01:54:40 +0200
commitee8c45689526ca973407cbb77bce7b96a062c40b (patch)
tree789e44a352ce3a0a5a88af6339117e8deaff0950 /src/libsystemd/sd-rtnl
parent1cb5d1f31909c731d93568eb4838cb86e033d783 (diff)
networkd: add minimal client tool "networkd" to query network status
In the long run this should become a full fledged client to networkd (but not before networkd learns bus support). For now, just pull interesting data out of networkd, udev, and rtnl and present it to the user, in a simple but useful output.
Diffstat (limited to 'src/libsystemd/sd-rtnl')
-rw-r--r--src/libsystemd/sd-rtnl/local-addresses.c26
-rw-r--r--src/libsystemd/sd-rtnl/local-addresses.h3
-rw-r--r--src/libsystemd/sd-rtnl/rtnl-message.c15
-rw-r--r--src/libsystemd/sd-rtnl/rtnl-util.c10
-rw-r--r--src/libsystemd/sd-rtnl/rtnl-util.h3
5 files changed, 48 insertions, 9 deletions
diff --git a/src/libsystemd/sd-rtnl/local-addresses.c b/src/libsystemd/sd-rtnl/local-addresses.c
index dd5ccedc9d..c5508856c8 100644
--- a/src/libsystemd/sd-rtnl/local-addresses.c
+++ b/src/libsystemd/sd-rtnl/local-addresses.c
@@ -48,7 +48,7 @@ static int address_compare(const void *_a, const void *_b) {
return 0;
}
-int local_addresses(struct local_address **ret) {
+int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
_cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
_cleanup_free_ struct local_address *list = NULL;
@@ -58,9 +58,13 @@ int local_addresses(struct local_address **ret) {
assert(ret);
- r = sd_rtnl_open(&rtnl, 0);
- if (r < 0)
- return r;
+ if (context)
+ rtnl = sd_rtnl_ref(context);
+ else {
+ r = sd_rtnl_open(&rtnl, 0);
+ if (r < 0)
+ return r;
+ }
r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
if (r < 0)
@@ -74,6 +78,7 @@ int local_addresses(struct local_address **ret) {
struct local_address *a;
unsigned char flags;
uint16_t type;
+ int ifi;
r = sd_rtnl_message_get_errno(m);
if (r < 0)
@@ -86,6 +91,13 @@ int local_addresses(struct local_address **ret) {
if (type != RTM_NEWADDR)
continue;
+ r = sd_rtnl_message_addr_get_ifindex(m, &ifi);
+ if (r < 0)
+ return r;
+
+ if (ifindex != 0 && ifi != ifindex)
+ continue;
+
r = sd_rtnl_message_addr_get_flags(m, &flags);
if (r < 0)
return r;
@@ -102,7 +114,7 @@ int local_addresses(struct local_address **ret) {
if (r < 0)
return r;
- if (a->scope == RT_SCOPE_HOST || a->scope == RT_SCOPE_NOWHERE)
+ if (ifindex == 0 && (a->scope == RT_SCOPE_HOST || a->scope == RT_SCOPE_NOWHERE))
continue;
r = sd_rtnl_message_addr_get_family(m, &a->family);
@@ -133,9 +145,7 @@ int local_addresses(struct local_address **ret) {
continue;
}
- r = sd_rtnl_message_addr_get_ifindex(m, &a->ifindex);
- if (r < 0)
- return r;
+ a->ifindex = ifi;
n_list++;
};
diff --git a/src/libsystemd/sd-rtnl/local-addresses.h b/src/libsystemd/sd-rtnl/local-addresses.h
index c6e3559bf1..b1ed6341f6 100644
--- a/src/libsystemd/sd-rtnl/local-addresses.h
+++ b/src/libsystemd/sd-rtnl/local-addresses.h
@@ -26,6 +26,7 @@
#include <assert.h>
#include <sys/socket.h>
+#include "sd-rtnl.h"
#include "in-addr-util.h"
struct local_address {
@@ -34,4 +35,4 @@ struct local_address {
union in_addr_union address;
};
-int local_addresses(struct local_address **ret);
+int local_addresses(sd_rtnl *rtnl, int ifindex, struct local_address **ret);
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index c50d0ea982..1f596ca10c 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -465,6 +465,21 @@ int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
return 0;
}
+int sd_rtnl_message_link_get_type(sd_rtnl_message *m, unsigned *type) {
+ struct ifinfomsg *ifi;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
+ assert_return(type, -EINVAL);
+
+ ifi = NLMSG_DATA(m->hdr);
+
+ *type = ifi->ifi_type;
+
+ return 0;
+}
+
/* If successful the updated message will be correctly aligned, if
unsuccessful the old message is untouched. */
static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
diff --git a/src/libsystemd/sd-rtnl/rtnl-util.c b/src/libsystemd/sd-rtnl/rtnl-util.c
index c8b20d109e..0bc2c9b1f5 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.c
+++ b/src/libsystemd/sd-rtnl/rtnl-util.c
@@ -153,3 +153,13 @@ bool rtnl_message_type_is_addr(uint16_t type) {
return false;
}
}
+
+int rtnl_log_parse_error(int r) {
+ log_error("Failed to parse netlink message: %s", strerror(-r));
+ return r;
+}
+
+int rtnl_log_create_error(int r) {
+ log_error("Failed to create netlink message: %s", strerror(-r));
+ return r;
+}
diff --git a/src/libsystemd/sd-rtnl/rtnl-util.h b/src/libsystemd/sd-rtnl/rtnl-util.h
index 06d5699c3a..2963f02d3e 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.h
+++ b/src/libsystemd/sd-rtnl/rtnl-util.h
@@ -37,6 +37,9 @@ bool rtnl_message_type_is_route(uint16_t type);
int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
+int rtnl_log_parse_error(int r);
+int rtnl_log_create_error(int r);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_rtnl*, sd_rtnl_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_rtnl_message*, sd_rtnl_message_unref);