[systemd-commits] 8 commits - src/libsystemd src/network src/shared src/systemd
Tom Gundersen
tomegun at kemper.freedesktop.org
Tue Dec 2 01:50:22 PST 2014
src/libsystemd/sd-rtnl/rtnl-message.c | 122 ++++++++++++++--
src/libsystemd/sd-rtnl/rtnl-types.c | 22 ++
src/libsystemd/sd-rtnl/rtnl-util.c | 11 +
src/libsystemd/sd-rtnl/rtnl-util.h | 1
src/network/networkctl.c | 253 +++++++++++++++++++++++++++++++++-
src/shared/udev-util.h | 2
src/systemd/sd-rtnl.h | 6
7 files changed, 403 insertions(+), 14 deletions(-)
New commits:
commit c09da72900b03fcddade06643f24c6357f3e0482
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 01:05:52 2014 +0100
networkctl: print the Gateway in the status output
This is the IP address of the default route on the link, if present. A
description is printed when available (the manufacturer of the gateway NIC based
on its MAC address).
In the future we should prefer LLDP information over MAC info.
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 5351663..91eb635 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -247,6 +247,251 @@ static int list_links(char **args, unsigned n) {
return 0;
}
+/* IEEE Organizationally Unique Identifier vendor string */
+static int ieee_oui(struct udev_hwdb *hwdb, struct ether_addr *mac, char **ret) {
+ struct udev_list_entry *entry;
+ char *description;
+ char str[32];
+
+ /* skip commonly misused 00:00:00 (Xerox) prefix */
+ if (memcmp(mac, "\0\0\0", 3) == 0)
+ return -EINVAL;
+
+ snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X", mac->ether_addr_octet[0], mac->ether_addr_octet[1], mac->ether_addr_octet[2],
+ mac->ether_addr_octet[3], mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
+
+ udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, str, 0))
+ if (strcmp(udev_list_entry_get_name(entry), "ID_OUI_FROM_DATABASE") == 0) {
+ description = strdup(udev_list_entry_get_value(entry));
+ if (!description)
+ return -ENOMEM;
+
+ *ret = description;
+ return 0;
+ }
+
+ return -ENODATA;
+}
+
+static int get_gateway_description(sd_rtnl *rtnl, struct udev_hwdb *hwdb, int ifindex, int family,
+ union in_addr_union *gateway, char **gateway_description) {
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+ sd_rtnl_message *m;
+ int r;
+
+ assert(rtnl);
+ assert(ifindex >= 0);
+ assert(family == AF_INET || family == AF_INET6);
+ assert(gateway);
+ assert(gateway_description);
+
+ r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_GETNEIGH, ifindex, family);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_request_dump(req, true);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_call(rtnl, req, 0, &reply);
+ if (r < 0)
+ return r;
+
+ for (m = reply; m; m = sd_rtnl_message_next(m)) {
+ union in_addr_union gw = {};
+ struct ether_addr mac = {};
+ uint16_t type;
+ int ifi, fam;
+
+ r = sd_rtnl_message_get_errno(m);
+ if (r < 0) {
+ log_error_errno(r, "got error: %m");
+ continue;
+ }
+
+ r = sd_rtnl_message_get_type(m, &type);
+ if (r < 0) {
+ log_error_errno(r, "could not get type: %m");
+ continue;
+ }
+
+ if (type != RTM_NEWNEIGH) {
+ log_error("type is not RTM_NEWNEIGH");
+ continue;
+ }
+
+ r = sd_rtnl_message_neigh_get_family(m, &fam);
+ if (r < 0) {
+ log_error_errno(r, "could not get family: %m");
+ continue;
+ }
+
+ if (fam != family) {
+ log_error("family is not correct");
+ continue;
+ }
+
+ r = sd_rtnl_message_neigh_get_ifindex(m, &ifi);
+ if (r < 0) {
+ log_error_errno(r, "colud not get ifindex: %m");
+ continue;
+ }
+
+ if (ifindex > 0 && ifi != ifindex)
+ continue;
+
+ switch (fam) {
+ case AF_INET:
+ r = sd_rtnl_message_read_in_addr(m, NDA_DST, &gw.in);
+ if (r < 0)
+ continue;
+
+ break;
+ case AF_INET6:
+ r = sd_rtnl_message_read_in6_addr(m, NDA_DST, &gw.in6);
+ if (r < 0)
+ continue;
+
+ break;
+ default:
+ continue;
+ }
+
+ if (!in_addr_equal(fam, &gw, gateway))
+ continue;
+
+ r = sd_rtnl_message_read_ether_addr(m, NDA_LLADDR, &mac);
+ if (r < 0)
+ continue;
+
+ r = ieee_oui(hwdb, &mac, gateway_description);
+ if (r < 0)
+ continue;
+
+ return 0;
+ }
+
+ return -ENODATA;
+}
+
+static int dump_gateways(sd_rtnl *rtnl, struct udev_hwdb *hwdb, const char *prefix, int ifindex) {
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+ sd_rtnl_message *m;
+ bool first = true;
+ int r;
+
+ assert(rtnl);
+ assert(ifindex >= 0);
+
+ r = sd_rtnl_message_new_route(rtnl, &req, RTM_GETROUTE, AF_UNSPEC, RTPROT_UNSPEC);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_request_dump(req, true);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_call(rtnl, req, 0, &reply);
+ if (r < 0)
+ return r;
+
+ for (m = reply; m; m = sd_rtnl_message_next(m)) {
+ _cleanup_free_ char *gateway = NULL, *gateway_description = NULL;
+ union in_addr_union gw = {};
+ uint16_t type;
+ uint32_t ifi;
+ int family;
+
+ r = sd_rtnl_message_get_errno(m);
+ if (r < 0) {
+ log_error_errno(r, "got error: %m");
+ continue;
+ }
+
+ r = sd_rtnl_message_get_type(m, &type);
+ if (r < 0) {
+ log_error_errno(r, "could not get type: %m");
+ continue;
+ }
+
+ if (type != RTM_NEWROUTE) {
+ log_error("type is not RTM_NEWROUTE");
+ continue;
+ }
+
+ r = sd_rtnl_message_route_get_family(m, &family);
+ if (r < 0) {
+ log_error_errno(r, "could not get family: %m");
+ continue;
+ }
+
+ r = sd_rtnl_message_read_u32(m, RTA_OIF, &ifi);
+ if (r < 0) {
+ log_error_errno(r, "colud not get RTA_OIF: %m");
+ continue;
+ }
+
+ if (ifindex > 0 && ifi != (unsigned) ifindex)
+ continue;
+
+ switch (family) {
+ case AF_INET:
+ r = sd_rtnl_message_read_in_addr(m, RTA_GATEWAY, &gw.in);
+ if (r < 0)
+ continue;
+
+ r = sd_rtnl_message_read_in_addr(m, RTA_DST, NULL);
+ if (r >= 0)
+ continue;
+
+ r = sd_rtnl_message_read_in_addr(m, RTA_SRC, NULL);
+ if (r >= 0)
+ continue;
+
+ break;
+ case AF_INET6:
+ r = sd_rtnl_message_read_in6_addr(m, RTA_GATEWAY, &gw.in6);
+ if (r < 0)
+ continue;
+
+ r = sd_rtnl_message_read_in6_addr(m, RTA_DST, NULL);
+ if (r >= 0)
+ continue;
+
+ r = sd_rtnl_message_read_in6_addr(m, RTA_SRC, NULL);
+ if (r >= 0)
+ continue;
+
+ break;
+ default:
+ continue;
+ }
+
+ r = in_addr_to_string(family, &gw, &gateway);
+ if (r < 0)
+ continue;
+
+ r = get_gateway_description(rtnl, hwdb, ifi, family, &gw, &gateway_description);
+ if (r < 0)
+ log_debug("could not get description of gateway: %s", strerror(-r));
+
+ if (gateway_description)
+ printf("%*s%s (%s)\n",
+ (int) strlen(prefix),
+ first ? prefix : "",
+ gateway, gateway_description);
+ else
+ printf("%*s%s\n",
+ (int) strlen(prefix),
+ first ? prefix : "",
+ gateway);
+
+ first = false;
+ }
+
+ return 0;
+}
+
static int dump_addresses(sd_rtnl *rtnl, const char *prefix, int ifindex) {
_cleanup_free_ struct local_address *local = NULL;
int r, n, i;
@@ -284,9 +529,11 @@ static void dump_list(const char *prefix, char **l) {
static int link_status_one(sd_rtnl *rtnl, struct udev *udev, const char *name) {
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
- _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
+ _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *gateway = NULL, *gateway_description = NULL,
+ *gateway6 = NULL, *gateway6_description = NULL;
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
_cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_udev_hwdb_unref_ struct udev_hwdb *hwdb = NULL;
char devid[2 + DECIMAL_STR_MAX(int)];
_cleanup_free_ char *t = NULL, *network = NULL;
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
@@ -420,6 +667,10 @@ static int link_status_one(sd_rtnl *rtnl, struct udev *udev, const char *name) {
if (mtu > 0)
printf(" MTU: %u\n", mtu);
+ hwdb = udev_hwdb_new(udev);
+
+ dump_gateways(rtnl, hwdb, " Gateway: ", ifindex);
+
dump_addresses(rtnl, " Address: ", ifindex);
if (!strv_isempty(dns))
commit 722f7cc95cdc0532f3226aae796ef446d2eea722
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 10:46:14 2014 +0100
sd-rtnl: route - allow GETROUTE with AF_UNSPEC
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 84ebf65..7ec6143 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -150,7 +150,8 @@ int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
int r;
assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
- assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
+ assert_return((nlmsg_type == RTM_GETROUTE && rtm_family == AF_UNSPEC) ||
+ rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
assert_return(ret, -EINVAL);
r = message_new(rtnl, ret, nlmsg_type);
commit 1e30c94f745814d495c0dc3f91c4f52d27e2a3e0
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 10:19:14 2014 +0100
shared: udev-util - add hwdb cleanup macro
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index 5f09ce1..5e0e1a9 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -27,6 +27,7 @@
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_device*, udev_device_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_enumerate*, udev_enumerate_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_hwdb*, udev_hwdb_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_event*, udev_event_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_rules*, udev_rules_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl*, udev_ctrl_unref);
@@ -35,6 +36,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_monitor*, udev_monitor_unref);
#define _cleanup_udev_unref_ _cleanup_(udev_unrefp)
#define _cleanup_udev_device_unref_ _cleanup_(udev_device_unrefp)
#define _cleanup_udev_enumerate_unref_ _cleanup_(udev_enumerate_unrefp)
+#define _cleanup_udev_hwdb_unref_ _cleanup_(udev_hwdb_unrefp)
#define _cleanup_udev_event_unref_ _cleanup_(udev_event_unrefp)
#define _cleanup_udev_rules_unref_ _cleanup_(udev_rules_unrefp)
#define _cleanup_udev_ctrl_unref_ _cleanup_(udev_ctrl_unrefp)
commit 20dff6c4ff4f6e1b88c841e523ce9cff0e150fdf
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 01:35:11 2014 +0100
sd-rtnl: add sd_rtnl_message_{new_neigh,neigh_get_{family,ifindex}}
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index e5c72e7..84ebf65 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -171,6 +171,59 @@ int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
return 0;
}
+int sd_rtnl_message_neigh_get_family(sd_rtnl_message *m, int *family) {
+ struct ndmsg *ndm;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
+ assert_return(family, -EINVAL);
+
+ ndm = NLMSG_DATA(m->hdr);
+
+ *family = ndm->ndm_family;
+
+ return 0;
+}
+
+int sd_rtnl_message_neigh_get_ifindex(sd_rtnl_message *m, int *index) {
+ struct ndmsg *ndm;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
+ assert_return(index, -EINVAL);
+
+ ndm = NLMSG_DATA(m->hdr);
+
+ *index = ndm->ndm_ifindex;
+
+ return 0;
+}
+
+int sd_rtnl_message_new_neigh(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlmsg_type, int index, int ndm_family) {
+ struct ndmsg *ndm;
+ int r;
+
+ assert_return(rtnl_message_type_is_neigh(nlmsg_type), -EINVAL);
+ assert_return(ndm_family == AF_INET || ndm_family == AF_INET6, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ r = message_new(rtnl, ret, nlmsg_type);
+ if (r < 0)
+ return r;
+
+ if (nlmsg_type == RTM_NEWNEIGH)
+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
+
+ ndm = NLMSG_DATA((*ret)->hdr);
+
+ ndm->ndm_family = ndm_family;
+ ndm->ndm_ifindex = index;
+
+ return 0;
+}
+
int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
struct ifinfomsg *ifi;
@@ -242,9 +295,10 @@ int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret,
int sd_rtnl_message_request_dump(sd_rtnl_message *m, int dump) {
assert_return(m, -EINVAL);
assert_return(m->hdr, -EINVAL);
- assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
- m->hdr->nlmsg_type == RTM_GETADDR ||
- m->hdr->nlmsg_type == RTM_GETROUTE,
+ assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
+ m->hdr->nlmsg_type == RTM_GETADDR ||
+ m->hdr->nlmsg_type == RTM_GETROUTE ||
+ m->hdr->nlmsg_type == RTM_GETNEIGH,
-EINVAL);
if (dump)
diff --git a/src/libsystemd/sd-rtnl/rtnl-util.c b/src/libsystemd/sd-rtnl/rtnl-util.c
index 4521742..194a267 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.c
+++ b/src/libsystemd/sd-rtnl/rtnl-util.c
@@ -122,6 +122,17 @@ int rtnl_message_new_synthetic_error(int error, uint32_t serial, sd_rtnl_message
return 0;
}
+bool rtnl_message_type_is_neigh(uint16_t type) {
+ switch (type) {
+ case RTM_NEWNEIGH:
+ case RTM_GETNEIGH:
+ case RTM_DELNEIGH:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool rtnl_message_type_is_route(uint16_t type) {
switch (type) {
case RTM_NEWROUTE:
diff --git a/src/libsystemd/sd-rtnl/rtnl-util.h b/src/libsystemd/sd-rtnl/rtnl-util.h
index fa3592d..ca9fbd4 100644
--- a/src/libsystemd/sd-rtnl/rtnl-util.h
+++ b/src/libsystemd/sd-rtnl/rtnl-util.h
@@ -33,6 +33,7 @@ void rtnl_message_seal(sd_rtnl_message *m);
bool rtnl_message_type_is_link(uint16_t type);
bool rtnl_message_type_is_addr(uint16_t type);
bool rtnl_message_type_is_route(uint16_t type);
+bool rtnl_message_type_is_neigh(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);
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 14eb9b8..15eaa26 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -75,6 +75,7 @@ int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_
int family);
int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlmsg_type,
int rtm_family, unsigned char rtm_protocol);
+int sd_rtnl_message_new_neigh(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index, int nda_family);
sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);
@@ -104,6 +105,9 @@ int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char pr
int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope);
int sd_rtnl_message_route_get_family(sd_rtnl_message *m, int *family);
+int sd_rtnl_message_neigh_get_family(sd_rtnl_message *m, int *family);
+int sd_rtnl_message_neigh_get_ifindex(sd_rtnl_message *m, int *family);
+
int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data);
int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data);
int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data);
commit e559b38493e6e0bc0214af2bce5aa940a8a15006
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 01:23:47 2014 +0100
sd-rtnl: add typesystem for RTM_*NEIGH
diff --git a/src/libsystemd/sd-rtnl/rtnl-types.c b/src/libsystemd/sd-rtnl/rtnl-types.c
index b6c483c..a1db2ab 100644
--- a/src/libsystemd/sd-rtnl/rtnl-types.c
+++ b/src/libsystemd/sd-rtnl/rtnl-types.c
@@ -329,6 +329,25 @@ static const NLTypeSystem rtnl_route_type_system = {
.types = rtnl_route_types,
};
+static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
+ [NDA_DST] = { .type = NLA_IN_ADDR },
+ [NDA_LLADDR] = { .type = NLA_ETHER_ADDR },
+/*
+ NDA_CACHEINFO,
+ NDA_PROBES,
+ NDA_VLAN,
+ NDA_PORT
+ NDA_VNI
+ NDA_IFINDEX
+ NDA_MASTER
+*/
+};
+
+static const NLTypeSystem rtnl_neigh_type_system = {
+ .max = ELEMENTSOF(rtnl_neigh_types) - 1,
+ .types = rtnl_neigh_types,
+};
+
static const NLType rtnl_types[RTM_MAX + 1] = {
[NLMSG_ERROR] = { .type = NLA_META, .size = sizeof(struct nlmsgerr) },
[RTM_NEWLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
@@ -341,6 +360,9 @@ static const NLType rtnl_types[RTM_MAX + 1] = {
[RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
[RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
[RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_NEWNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_DELNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_GETNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
};
const NLTypeSystem rtnl_type_system = {
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 0d17b16..14eb9b8 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -26,6 +26,7 @@
#include <netinet/in.h>
#include <netinet/ether.h>
#include <linux/rtnetlink.h>
+#include <linux/neighbour.h>
#include "sd-event.h"
#include "_sd-common.h"
commit 64918838d566058b7cec72d13f4524de0a64a8e3
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 00:59:34 2014 +0100
sd-rtnl: add a bit more debugging in case a message is dropped
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index e7238d5..e5c72e7 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -1306,8 +1306,10 @@ int socket_read_message(sd_rtnl *rtnl) {
}
/* check that the size matches the message type */
- if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size))
+ if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size)) {
+ log_debug("sd-rtnl: message larger than expected, dropping");
continue;
+ }
r = message_new_empty(rtnl, &m);
if (r < 0)
commit 73ae2b7dade339c8a258dcf4fa2b302e238117e1
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 00:59:02 2014 +0100
sd-rtnl: message - allow checking for attributes without reading out their contents
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 22ee4c5..e7238d5 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -830,6 +830,8 @@ int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, const c
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_STRING);
if (r < 0)
return r;
@@ -840,7 +842,8 @@ int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, const c
else if (strnlen(attr_data, r) >= (size_t) r)
return -EIO;
- *data = (const char *) attr_data;
+ if (data)
+ *data = (const char *) attr_data;
return 0;
}
@@ -849,6 +852,8 @@ int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *da
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_U8);
if (r < 0)
return r;
@@ -859,7 +864,8 @@ int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *da
else if ((size_t) r < sizeof(uint8_t))
return -EIO;
- *data = *(uint8_t *) attr_data;
+ if (data)
+ *data = *(uint8_t *) attr_data;
return 0;
}
@@ -868,6 +874,8 @@ int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_U16);
if (r < 0)
return r;
@@ -878,7 +886,8 @@ int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *
else if ((size_t) r < sizeof(uint16_t))
return -EIO;
- *data = *(uint16_t *) attr_data;
+ if (data)
+ *data = *(uint16_t *) attr_data;
return 0;
}
@@ -887,6 +896,8 @@ int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_U32);
if (r < 0)
return r;
@@ -897,7 +908,8 @@ int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *
else if ((size_t)r < sizeof(uint32_t))
return -EIO;
- *data = *(uint32_t *) attr_data;
+ if (data)
+ *data = *(uint32_t *) attr_data;
return 0;
}
@@ -906,6 +918,8 @@ int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, str
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
if (r < 0)
return r;
@@ -916,7 +930,8 @@ int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, str
else if ((size_t)r < sizeof(struct ether_addr))
return -EIO;
- memcpy(data, attr_data, sizeof(struct ether_addr));
+ if (data)
+ memcpy(data, attr_data, sizeof(struct ether_addr));
return 0;
}
@@ -925,6 +940,8 @@ int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, str
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
if (r < 0)
return r;
@@ -935,7 +952,8 @@ int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, str
else if ((size_t)r < sizeof(struct ifa_cacheinfo))
return -EIO;
- memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
+ if (info)
+ memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
return 0;
}
@@ -944,6 +962,8 @@ int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_IN_ADDR);
if (r < 0)
return r;
@@ -954,7 +974,8 @@ int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct
else if ((size_t)r < sizeof(struct in_addr))
return -EIO;
- memcpy(data, attr_data, sizeof(struct in_addr));
+ if (data)
+ memcpy(data, attr_data, sizeof(struct in_addr));
return 0;
}
@@ -963,6 +984,8 @@ int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struc
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_IN_ADDR);
if (r < 0)
return r;
@@ -973,7 +996,8 @@ int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struc
else if ((size_t)r < sizeof(struct in6_addr))
return -EIO;
- memcpy(data, attr_data, sizeof(struct in6_addr));
+ if (data)
+ memcpy(data, attr_data, sizeof(struct in6_addr));
return 0;
}
commit dae4de9d42debf448bf667e0e4fd4606dfcfae0c
Author: Tom Gundersen <teg at jklm.no>
Date: Tue Dec 2 00:58:17 2014 +0100
sd-rtnl: add sd_rtnl_message_route_get_family
diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
index 44ad303..22ee4c5 100644
--- a/src/libsystemd/sd-rtnl/rtnl-message.c
+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
@@ -128,6 +128,21 @@ int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
return 0;
}
+int sd_rtnl_message_route_get_family(sd_rtnl_message *m, int *family) {
+ struct rtmsg *rtm;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
+ assert_return(family, -EINVAL);
+
+ rtm = NLMSG_DATA(m->hdr);
+
+ *family = rtm->rtm_family;
+
+ return 0;
+}
+
int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
uint16_t nlmsg_type, int rtm_family,
unsigned char rtm_protocol) {
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 95bdb1d..0d17b16 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -101,6 +101,7 @@ int sd_rtnl_message_link_get_type(sd_rtnl_message *m, unsigned *type);
int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen);
int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope);
+int sd_rtnl_message_route_get_family(sd_rtnl_message *m, int *family);
int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data);
int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data);
More information about the systemd-commits
mailing list