From cafbc790d1affec2c9524c5ee1915485a1ac6879 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 09:56:59 +0200 Subject: sd-netlink: rename NLA_ to NETLINK_TYPE_ The NLA_ names are used to name real datatypes we extract out of netlink messages. The kernel has an internal enum with the same names (NLA_foobar), which is *NOT* binary compatible to our types. Furthermore, we support a different set of types than the kernel (as we try to treat some kernel peculiarities as our own types to simplify the API). Rename NLA_ to NETLINK_TYPE_ to make clear that this is our own set of types. --- src/libsystemd/sd-netlink/netlink-message.c | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 87324fc2f7..601124cc05 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -236,7 +236,7 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_STRING); + r = message_attribute_has_type(m, type, NETLINK_TYPE_STRING); if (r < 0) return r; else @@ -262,7 +262,7 @@ int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uin assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NLA_U8); + r = message_attribute_has_type(m, type, NETLINK_TYPE_U8); if (r < 0) return r; @@ -280,7 +280,7 @@ int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, ui assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NLA_U16); + r = message_attribute_has_type(m, type, NETLINK_TYPE_U16); if (r < 0) return r; @@ -297,7 +297,7 @@ int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, ui assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NLA_U32); + r = message_attribute_has_type(m, type, NETLINK_TYPE_U32); if (r < 0) return r; @@ -315,7 +315,7 @@ int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -333,7 +333,7 @@ int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short typ assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -351,7 +351,7 @@ int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short t assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_ETHER_ADDR); + r = message_attribute_has_type(m, type, NETLINK_TYPE_ETHER_ADDR); if (r < 0) return r; @@ -369,7 +369,7 @@ int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short t assert_return(!m->sealed, -EPERM); assert_return(info, -EINVAL); - r = message_attribute_has_type(m, type, NLA_CACHE_INFO); + r = message_attribute_has_type(m, type, NETLINK_TYPE_CACHE_INFO); if (r < 0) return r; @@ -388,12 +388,12 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type assert_return(!m->sealed, -EPERM); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE); - r = message_attribute_has_type(m, type, NLA_NESTED); + r = message_attribute_has_type(m, type, NETLINK_TYPE_NESTED); if (r < 0) { const NLTypeSystemUnion *type_system_union; int family; - r = message_attribute_has_type(m, type, NLA_UNION); + r = message_attribute_has_type(m, type, NETLINK_TYPE_UNION); if (r < 0) return r; size = (size_t) r; @@ -499,7 +499,7 @@ int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, c assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_STRING); + r = message_attribute_has_type(m, type, NETLINK_TYPE_STRING); if (r < 0) return r; @@ -521,7 +521,7 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8 assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_U8); + r = message_attribute_has_type(m, type, NETLINK_TYPE_U8); if (r < 0) return r; @@ -543,7 +543,7 @@ int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_U16); + r = message_attribute_has_type(m, type, NETLINK_TYPE_U16); if (r < 0) return r; @@ -565,7 +565,7 @@ int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_U32); + r = message_attribute_has_type(m, type, NETLINK_TYPE_U32); if (r < 0) return r; @@ -587,7 +587,7 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_ETHER_ADDR); + r = message_attribute_has_type(m, type, NETLINK_TYPE_ETHER_ADDR); if (r < 0) return r; @@ -609,7 +609,7 @@ int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short typ assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_CACHE_INFO); + r = message_attribute_has_type(m, type, NETLINK_TYPE_CACHE_INFO); if (r < 0) return r; @@ -631,7 +631,7 @@ int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -653,7 +653,7 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -685,13 +685,13 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - if (nl_type->type == NLA_NESTED) { + if (nl_type->type == NETLINK_TYPE_NESTED) { r = type_system_get_type_system(m->container_type_system[m->n_containers], &type_system, type); if (r < 0) return r; - } else if (nl_type->type == NLA_UNION) { + } else if (nl_type->type == NETLINK_TYPE_UNION) { const NLTypeSystemUnion *type_system_union; r = type_system_get_type_system_union(m->container_type_system[m->n_containers], @@ -871,7 +871,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { if (r < 0) return r; - if (type->type == NLA_NESTED) { + if (type->type == NETLINK_TYPE_NESTED) { const NLTypeSystem *type_system = type->type_system; assert(type_system); -- cgit v1.2.3-54-g00ecf From c658008f50fdbc617e6f7ad321c058f3a6f175f5 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 10:51:25 +0200 Subject: sd-netlink: don't access type->type_system[_union] directly Make sure we never access type->type_system or type->type_system_union directly. This is an implementation detail of the type-system and we should always use the accessors. Right now, they only exist for 2-level accesses (type-system to type-system). This patch introduces the 1-level accessors (type to type-system) and makes use of it. This patch makes sure the proper assertions are in place, so we never accidentally access sub-type-systems for non-nested/union types. Note that this places hard-asserts on the accessors. This should be fine, as we expect callers to only access sub type-systems if they *know* they're dealing with nested types. --- src/libsystemd/sd-netlink/netlink-message.c | 7 ++++--- src/libsystemd/sd-netlink/netlink-types.c | 30 +++++++++++++++++++---------- src/libsystemd/sd-netlink/netlink-types.h | 2 ++ 3 files changed, 26 insertions(+), 13 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 601124cc05..887327c9ae 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -85,7 +85,8 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - m->container_type_system[0] = nl_type->type_system; + if (nl_type->type == NETLINK_TYPE_NESTED) + type_get_type_system(nl_type, &m->container_type_system[0]); m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; @@ -872,9 +873,9 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { return r; if (type->type == NETLINK_TYPE_NESTED) { - const NLTypeSystem *type_system = type->type_system; + const NLTypeSystem *type_system; - assert(type_system); + type_get_type_system(type, &type_system); m->container_type_system[0] = type_system; diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 72799da887..fe9e5f9826 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -460,6 +460,24 @@ const NLTypeSystem rtnl_type_system = { .types = rtnl_types, }; +void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) { + assert(nl_type); + assert(ret); + assert(nl_type->type == NETLINK_TYPE_NESTED); + assert(nl_type->type_system); + + *ret = nl_type->type_system; +} + +void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion **ret) { + assert(nl_type); + assert(ret); + assert(nl_type->type == NETLINK_TYPE_UNION); + assert(nl_type->type_system_union); + + *ret = nl_type->type_system_union; +} + int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { const NLType *nl_type; @@ -493,11 +511,7 @@ int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSys if (r < 0) return r; - assert(nl_type->type == NETLINK_TYPE_NESTED); - assert(nl_type->type_system); - - *ret = nl_type->type_system; - + type_get_type_system(nl_type, ret); return 0; } @@ -511,11 +525,7 @@ int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLT if (r < 0) return r; - assert(nl_type->type == NETLINK_TYPE_UNION); - assert(nl_type->type_system_union); - - *ret = nl_type->type_system_union; - + type_get_type_system_union(nl_type, ret); return 0; } diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 1bb1b21da9..74a59bb7c2 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -65,6 +65,8 @@ struct NLType { const NLTypeSystemUnion *type_system_union; }; +void type_get_type_system(const NLType *type, const NLTypeSystem **ret); +void type_get_type_system_union(const NLType *type, const NLTypeSystemUnion **ret); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); -- cgit v1.2.3-54-g00ecf From 817d1cd824bedba8feeef24c9724ec8bd160a7b2 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 11:03:10 +0200 Subject: sd-netlink: make NLType internal If we extend NLType to support arrays and further extended types, we really want to avoid hard-coding the type-layout outside of netlink-types.c. We already avoid accessing nl_type->type_system outside of netlink-types.c, extend this to also avoid accessing any other fields. Provide accessor functions for nl_type->type and nl_type->size and then move NLType away from the type-system header. With this in place, follow-up patches can safely turn "type_system" and "type_system_union" into a real "union { }", and then add another type for arrays. --- src/libsystemd/sd-netlink/netlink-message.c | 43 +++++++++++++++++------------ src/libsystemd/sd-netlink/netlink-socket.c | 2 +- src/libsystemd/sd-netlink/netlink-types.c | 17 ++++++++++++ src/libsystemd/sd-netlink/netlink-types.h | 9 ++---- 4 files changed, 45 insertions(+), 26 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 887327c9ae..1780585f08 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -76,7 +76,7 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { if (r < 0) return r; - size = NLMSG_SPACE(nl_type->size); + size = NLMSG_SPACE(type_get_size(nl_type)); assert(size >= sizeof(struct nlmsghdr)); m->hdr = malloc0(size); @@ -85,7 +85,7 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - if (nl_type->type == NETLINK_TYPE_NESTED) + if (type_get_type(nl_type) == NETLINK_TYPE_NESTED) type_get_type_system(nl_type, &m->container_type_system[0]); m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; @@ -223,10 +223,10 @@ static int message_attribute_has_type(sd_netlink_message *m, uint16_t attribute_ if (r < 0) return r; - if (type->type != data_type) + if (type_get_type(type) != data_type) return -EINVAL; - return type->size; + return type_get_size(type); } int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data) { @@ -670,10 +670,11 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, return 0; } -int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type) { +int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type_id) { const NLType *nl_type; const NLTypeSystem *type_system; void *container; + uint16_t type; size_t size; int r; @@ -682,22 +683,24 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ r = type_system_get_type(m->container_type_system[m->n_containers], &nl_type, - type); + type_id); if (r < 0) return r; - if (nl_type->type == NETLINK_TYPE_NESTED) { + type = type_get_type(nl_type); + + if (type == NETLINK_TYPE_NESTED) { r = type_system_get_type_system(m->container_type_system[m->n_containers], &type_system, - type); + type_id); if (r < 0) return r; - } else if (nl_type->type == NETLINK_TYPE_UNION) { + } else if (type == NETLINK_TYPE_UNION) { const NLTypeSystemUnion *type_system_union; r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, - type); + type_id); if (r < 0) return r; @@ -740,7 +743,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ } else return -EINVAL; - r = rtnl_message_read_internal(m, type, &container); + r = rtnl_message_read_internal(m, type_id, &container); if (r < 0) return r; else @@ -842,7 +845,9 @@ int rtnl_message_parse(sd_netlink_message *m, } int sd_netlink_message_rewind(sd_netlink_message *m) { - const NLType *type; + const NLType *nl_type; + uint16_t type; + size_t size; unsigned i; int r; @@ -868,14 +873,17 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { assert(m->hdr); - r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type); + r = type_system_get_type(NULL, &nl_type, m->hdr->nlmsg_type); if (r < 0) return r; - if (type->type == NETLINK_TYPE_NESTED) { + type = type_get_type(nl_type); + size = type_get_size(nl_type); + + if (type == NETLINK_TYPE_NESTED) { const NLTypeSystem *type_system; - type_get_type_system(type, &type_system); + type_get_type_system(nl_type, &type_system); m->container_type_system[0] = type_system; @@ -883,9 +891,8 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { &m->rta_offset_tb[m->n_containers], &m->rta_tb_size[m->n_containers], type_system->max, - (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + - NLMSG_ALIGN(type->size)), - NLMSG_PAYLOAD(m->hdr, type->size)); + (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), + NLMSG_PAYLOAD(m->hdr, size)); if (r < 0) return r; } diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 8136cf36ae..db4efb58d4 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -253,7 +253,7 @@ int socket_read_message(sd_netlink *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(type_get_size(nl_type))) { log_debug("sd-netlink: message larger than expected, dropping"); continue; } diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index fe9e5f9826..7715ff8a44 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -39,6 +39,13 @@ #include "netlink-types.h" #include "missing.h" +struct NLType { + uint16_t type; + size_t size; + const NLTypeSystem *type_system; + const NLTypeSystemUnion *type_system_union; +}; + static const NLTypeSystem rtnl_link_type_system; static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = { @@ -460,6 +467,16 @@ const NLTypeSystem rtnl_type_system = { .types = rtnl_types, }; +uint16_t type_get_type(const NLType *type) { + assert(type); + return type->type; +} + +size_t type_get_size(const NLType *type) { + assert(type); + return type->size; +} + void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) { assert(nl_type); assert(ret); diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 74a59bb7c2..cb6a78fb3e 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -58,13 +58,8 @@ struct NLTypeSystem { const NLType *types; }; -struct NLType { - uint16_t type; - size_t size; - const NLTypeSystem *type_system; - const NLTypeSystemUnion *type_system_union; -}; - +uint16_t type_get_type(const NLType *type); +size_t type_get_size(const NLType *type); void type_get_type_system(const NLType *type, const NLTypeSystem **ret); void type_get_type_system_union(const NLType *type, const NLTypeSystemUnion **ret); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); -- cgit v1.2.3-54-g00ecf From 435bbb0233018bbafc6d80d2935adb151d187d97 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 11:07:59 +0200 Subject: sd-netlink: make NLTypeSystem internal Same as NLType, move NLTypeSystem into netlink-types.c and hide it from the outside. Provide an accessor function for the 'max' field that is used to allocate suitable array sizes. Note that this will probably be removed later on, anyway. Once we support bigger type-systems, it just seems impractical to allocate such big arrays for each container entry. An RBTree would probably do just fine. --- src/libsystemd/sd-netlink/netlink-message.c | 4 ++-- src/libsystemd/sd-netlink/netlink-types.c | 10 ++++++++++ src/libsystemd/sd-netlink/netlink-types.h | 7 ++----- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 1780585f08..1245371f7b 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -754,7 +754,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ r = rtnl_message_parse(m, &m->rta_offset_tb[m->n_containers], &m->rta_tb_size[m->n_containers], - type_system->max, + type_system_get_max(type_system), container, size); if (r < 0) { @@ -890,7 +890,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { r = rtnl_message_parse(m, &m->rta_offset_tb[m->n_containers], &m->rta_tb_size[m->n_containers], - type_system->max, + type_system_get_max(type_system), (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), NLMSG_PAYLOAD(m->hdr, size)); if (r < 0) diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 7715ff8a44..70dbd4f8dc 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -46,6 +46,11 @@ struct NLType { const NLTypeSystemUnion *type_system_union; }; +struct NLTypeSystem { + uint16_t max; + const NLType *types; +}; + static const NLTypeSystem rtnl_link_type_system; static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = { @@ -495,6 +500,11 @@ void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion * *ret = nl_type->type_system_union; } +uint16_t type_system_get_max(const NLTypeSystem *type_system) { + assert(type_system); + return type_system->max; +} + int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { const NLType *nl_type; diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index cb6a78fb3e..c11bdbdf4c 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -53,15 +53,12 @@ struct NLTypeSystemUnion { const NLTypeSystem *type_systems; }; -struct NLTypeSystem { - uint16_t max; - const NLType *types; -}; - uint16_t type_get_type(const NLType *type); size_t type_get_size(const NLType *type); void type_get_type_system(const NLType *type, const NLTypeSystem **ret); void type_get_type_system_union(const NLType *type, const NLTypeSystemUnion **ret); + +uint16_t type_system_get_max(const NLTypeSystem *type_system); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); -- cgit v1.2.3-54-g00ecf From 6c14ad61db68e24932329c4137198ef7f46e35e8 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 11:18:53 +0200 Subject: sd-netlink: avoid casting size_t into int size_t is usually 64bit and int 32bit on a 64bit machine. This probably does not matter for netlink message sizes, but nevertheless, avoid hard-coding it anywhere. --- src/libsystemd/sd-netlink/netlink-message.c | 49 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 1245371f7b..a41d7f9670 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -215,10 +215,12 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da return offset; } -static int message_attribute_has_type(sd_netlink_message *m, uint16_t attribute_type, uint16_t data_type) { +static int message_attribute_has_type(sd_netlink_message *m, size_t *out_size, uint16_t attribute_type, uint16_t data_type) { const NLType *type; int r; + assert(m); + r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type); if (r < 0) return r; @@ -226,7 +228,9 @@ static int message_attribute_has_type(sd_netlink_message *m, uint16_t attribute_ if (type_get_type(type) != data_type) return -EINVAL; - return type_get_size(type); + if (out_size) + *out_size = type_get_size(type); + return 0; } int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data) { @@ -237,11 +241,9 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_STRING); + r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING); if (r < 0) return r; - else - size = (size_t)r; if (size) { length = strnlen(data, size+1); @@ -263,7 +265,7 @@ int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uin assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NETLINK_TYPE_U8); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U8); if (r < 0) return r; @@ -281,7 +283,7 @@ int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, ui assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NETLINK_TYPE_U16); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U16); if (r < 0) return r; @@ -298,7 +300,7 @@ int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, ui assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NETLINK_TYPE_U32); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U32); if (r < 0) return r; @@ -316,7 +318,7 @@ int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -334,7 +336,7 @@ int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short typ assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -352,7 +354,7 @@ int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short t assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_ETHER_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR); if (r < 0) return r; @@ -370,7 +372,7 @@ int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short t assert_return(!m->sealed, -EPERM); assert_return(info, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_CACHE_INFO); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_CACHE_INFO); if (r < 0) return r; @@ -389,15 +391,14 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type assert_return(!m->sealed, -EPERM); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE); - r = message_attribute_has_type(m, type, NETLINK_TYPE_NESTED); + r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED); if (r < 0) { const NLTypeSystemUnion *type_system_union; int family; - r = message_attribute_has_type(m, type, NETLINK_TYPE_UNION); + r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_UNION); if (r < 0) return r; - size = (size_t) r; r = sd_rtnl_message_get_family(m, &family); if (r < 0) @@ -413,8 +414,6 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type if (r < 0) return r; } else { - size = (size_t)r; - r = type_system_get_type_system(m->container_type_system[m->n_containers], &m->container_type_system[m->n_containers + 1], type); @@ -500,7 +499,7 @@ int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, c assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_STRING); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_STRING); if (r < 0) return r; @@ -522,7 +521,7 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8 assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_U8); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U8); if (r < 0) return r; @@ -544,7 +543,7 @@ int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_U16); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U16); if (r < 0) return r; @@ -566,7 +565,7 @@ int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_U32); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U32); if (r < 0) return r; @@ -588,7 +587,7 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_ETHER_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR); if (r < 0) return r; @@ -610,7 +609,7 @@ int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short typ assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_CACHE_INFO); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_CACHE_INFO); if (r < 0) return r; @@ -632,7 +631,7 @@ int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -654,7 +653,7 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NETLINK_TYPE_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From c1df8dee2811e76ec2f7306f13b7559044a88842 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 11:46:48 +0200 Subject: sd-netlink: turn 'max' into 'count' to support empty type-systems Right now we store the maximum type-ID of a type-system. This prevents us from creating empty type-systems. Store the "count" instead, which should be treated as max+1. Note that type_system_union_protocol_get_type_system() currently has a nasty hack to treat empty type-systems as invalid. This might need some modification later on as well. --- src/libsystemd/sd-netlink/netlink-message.c | 12 +++--- src/libsystemd/sd-netlink/netlink-types.c | 62 ++++++++++++++--------------- src/libsystemd/sd-netlink/netlink-types.h | 2 +- 3 files changed, 38 insertions(+), 38 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index a41d7f9670..bfbc0e6c95 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -753,7 +753,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ r = rtnl_message_parse(m, &m->rta_offset_tb[m->n_containers], &m->rta_tb_size[m->n_containers], - type_system_get_max(type_system), + type_system_get_count(type_system), container, size); if (r < 0) { @@ -811,17 +811,17 @@ int sd_netlink_message_get_errno(sd_netlink_message *m) { int rtnl_message_parse(sd_netlink_message *m, size_t **rta_offset_tb, unsigned short *rta_tb_size, - int max, + int count, struct rtattr *rta, unsigned int rt_len) { unsigned short type; size_t *tb; - tb = new0(size_t, max + 1); + tb = new0(size_t, count); if(!tb) return -ENOMEM; - *rta_tb_size = max + 1; + *rta_tb_size = count; for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) { type = RTA_TYPE(rta); @@ -829,7 +829,7 @@ int rtnl_message_parse(sd_netlink_message *m, /* if the kernel is newer than the headers we used when building, we ignore out-of-range attributes */ - if (type > max) + if (type >= count) continue; if (tb[type]) @@ -889,7 +889,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { r = rtnl_message_parse(m, &m->rta_offset_tb[m->n_containers], &m->rta_tb_size[m->n_containers], - type_system_get_max(type_system), + type_system_get_count(type_system), (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), NLMSG_PAYLOAD(m->hdr, size)); if (r < 0) diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 70dbd4f8dc..4ee0e6148e 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -47,7 +47,7 @@ struct NLType { }; struct NLTypeSystem { - uint16_t max; + uint16_t count; const NLType *types; }; @@ -122,7 +122,7 @@ static const NLType rtnl_bond_arp_target_types[BOND_ARP_TARGETS_MAX + 1] = { }; static const NLTypeSystem rtnl_bond_arp_type_system = { - .max = ELEMENTSOF(rtnl_bond_arp_target_types) - 1, + .count = ELEMENTSOF(rtnl_bond_arp_target_types), .types = rtnl_bond_arp_target_types, }; @@ -223,37 +223,37 @@ static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_ DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = { - [NL_UNION_LINK_INFO_DATA_BOND] = { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1, + [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), .types = rtnl_link_info_data_bond_types }, - [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1, + [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), .types = rtnl_link_info_data_bridge_types }, - [NL_UNION_LINK_INFO_DATA_VLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), .types = rtnl_link_info_data_vlan_types }, - [NL_UNION_LINK_INFO_DATA_VETH] = { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1, + [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), .types = rtnl_link_info_data_veth_types }, - [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), .types = rtnl_link_info_data_vxlan_types }, - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1, + [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1, + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1, + [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types) - 1, + [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), .types = rtnl_link_info_data_ip6tnl_types }, }; @@ -277,7 +277,7 @@ static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = { }; static const NLTypeSystem rtnl_link_info_type_system = { - .max = ELEMENTSOF(rtnl_link_info_types) - 1, + .count = ELEMENTSOF(rtnl_link_info_types), .types = rtnl_link_info_types, }; @@ -293,7 +293,7 @@ static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] }; static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = { - [AF_BRIDGE] = { .max = ELEMENTSOF(rtnl_prot_info_bridge_port_types) - 1, + [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), .types = rtnl_prot_info_bridge_port_types }, }; @@ -317,7 +317,7 @@ static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = { }; static const NLTypeSystem rtnl_af_spec_inet6_type_system = { - .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1, + .count = ELEMENTSOF(rtnl_af_spec_inet6_types), .types = rtnl_af_spec_inet6_types, }; @@ -326,7 +326,7 @@ static const NLType rtnl_af_spec_types[AF_MAX + 1] = { }; static const NLTypeSystem rtnl_af_spec_type_system = { - .max = ELEMENTSOF(rtnl_af_spec_types) - 1, + .count = ELEMENTSOF(rtnl_af_spec_types), .types = rtnl_af_spec_types, }; @@ -383,7 +383,7 @@ static const NLType rtnl_link_types[IFLA_MAX + 1 ] = { }; static const NLTypeSystem rtnl_link_type_system = { - .max = ELEMENTSOF(rtnl_link_types) - 1, + .count = ELEMENTSOF(rtnl_link_types), .types = rtnl_link_types, }; @@ -403,7 +403,7 @@ static const NLType rtnl_address_types[CONST_MAX(IFA_MAX, IFA_FLAGS) + 1] = { }; static const NLTypeSystem rtnl_address_type_system = { - .max = ELEMENTSOF(rtnl_address_types) - 1, + .count = ELEMENTSOF(rtnl_address_types), .types = rtnl_address_types, }; @@ -429,7 +429,7 @@ static const NLType rtnl_route_types[RTA_MAX + 1] = { }; static const NLTypeSystem rtnl_route_type_system = { - .max = ELEMENTSOF(rtnl_route_types) - 1, + .count = ELEMENTSOF(rtnl_route_types), .types = rtnl_route_types, }; @@ -445,7 +445,7 @@ static const NLType rtnl_neigh_types[NDA_MAX + 1] = { }; static const NLTypeSystem rtnl_neigh_type_system = { - .max = ELEMENTSOF(rtnl_neigh_types) - 1, + .count = ELEMENTSOF(rtnl_neigh_types), .types = rtnl_neigh_types, }; @@ -468,7 +468,7 @@ static const NLType rtnl_types[RTM_MAX + 1] = { }; const NLTypeSystem rtnl_type_system = { - .max = ELEMENTSOF(rtnl_types) - 1, + .count = ELEMENTSOF(rtnl_types), .types = rtnl_types, }; @@ -500,9 +500,9 @@ void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion * *ret = nl_type->type_system_union; } -uint16_t type_system_get_max(const NLTypeSystem *type_system) { +uint16_t type_system_get_count(const NLTypeSystem *type_system) { assert(type_system); - return type_system->max; + return type_system->count; } int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { @@ -515,7 +515,7 @@ int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, ui assert(type_system->types); - if (type > type_system->max) + if (type >= type_system->count) return -EOPNOTSUPP; nl_type = &type_system->types[type]; @@ -589,7 +589,7 @@ int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_sys return -EOPNOTSUPP; type_system = &type_system_union->type_systems[protocol]; - if (type_system->max == 0) + if (type_system->count == 0) return -EOPNOTSUPP; *ret = type_system; diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index c11bdbdf4c..91f6a1d1c2 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -58,7 +58,7 @@ size_t type_get_size(const NLType *type); void type_get_type_system(const NLType *type, const NLTypeSystem **ret); void type_get_type_system_union(const NLType *type, const NLTypeSystemUnion **ret); -uint16_t type_system_get_max(const NLTypeSystem *type_system); +uint16_t type_system_get_count(const NLTypeSystem *type_system); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); -- cgit v1.2.3-54-g00ecf From 12b7dff45b0e2442355008a1e53f1211bd227147 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 10:47:44 +0200 Subject: sd-netlink: make sure the root-level type is nested In sd-netlink-message, we always guarantee that the currently selected type-system is non-NULL. Otherwise, we would be unable to parse any types in the current container level. Hence, this assertion must be true: message->container_type_system[m->n_containers] != NULL During message_new() we currently do not verify that this assertion is true. Instead, we blindly access nl_type->type_system and use it (which might be NULL for basic types and unions). Fix this, by explicitly checking that the root-level type is nested. Note that this is *not* a strict requirement of netlink, but it's a strict requirement for all message types we currently support. Furthermore, all the callers of message_new() already verify that only supported types are passed, therefore, this is a pure cosmetic check. However, it might be needed on the future, so make sure we don't trap into this once we change the type-system. --- src/libsystemd/sd-netlink/netlink-message.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index bfbc0e6c95..e39e4c646c 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -72,6 +72,9 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { if (r < 0) return r; + if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) + return -EINVAL; + r = message_new_empty(rtnl, &m); if (r < 0) return r; @@ -85,8 +88,7 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - if (type_get_type(nl_type) == NETLINK_TYPE_NESTED) - type_get_type_system(nl_type, &m->container_type_system[0]); + type_get_type_system(nl_type, &m->container_type_system[0]); m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; -- cgit v1.2.3-54-g00ecf From 846a6b3d89aaf4ee2cece0f10148f675c4796841 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 23 Jun 2015 12:10:38 +0200 Subject: sd-netlink: don't treat NULL as root type-system Explicitly export the root type-system to the type-system callers. This avoids treating NULL as root, which for one really looks backwards (NULL is usually a leaf, not root), and secondly prevents us from properly debugging calling into non-nested types. Also rename the root to "type_system_root". Once we support more than rtnl, well will have to revisit that, anyway. --- src/libsystemd/sd-netlink/netlink-message.c | 4 ++-- src/libsystemd/sd-netlink/netlink-socket.c | 2 +- src/libsystemd/sd-netlink/netlink-types.c | 7 ++----- src/libsystemd/sd-netlink/netlink-types.h | 2 ++ 4 files changed, 7 insertions(+), 8 deletions(-) (limited to 'src/libsystemd/sd-netlink/netlink-message.c') diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index e39e4c646c..a935b821f6 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -68,7 +68,7 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { size_t size; int r; - r = type_system_get_type(NULL, &nl_type, type); + r = type_system_get_type(&type_system_root, &nl_type, type); if (r < 0) return r; @@ -874,7 +874,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { assert(m->hdr); - r = type_system_get_type(NULL, &nl_type, m->hdr->nlmsg_type); + r = type_system_get_type(&type_system_root, &nl_type, m->hdr->nlmsg_type); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index db4efb58d4..84ff7c38c9 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -243,7 +243,7 @@ int socket_read_message(sd_netlink *rtnl) { } /* check that we support this message type */ - r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type); + r = type_system_get_type(&type_system_root, &nl_type, new_msg->nlmsg_type); if (r < 0) { if (r == -EOPNOTSUPP) log_debug("sd-netlink: ignored message with unknown type: %i", diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index d22194ad71..40548dcbc0 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -476,7 +476,7 @@ static const NLType rtnl_types[RTM_MAX + 1] = { [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, }; -const NLTypeSystem rtnl_type_system = { +const NLTypeSystem type_system_root = { .count = ELEMENTSOF(rtnl_types), .types = rtnl_types, }; @@ -518,10 +518,7 @@ int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, ui const NLType *nl_type; assert(ret); - - if (!type_system) - type_system = &rtnl_type_system; - + assert(type_system); assert(type_system->types); if (type >= type_system->count) diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index d642295464..b1ef7af421 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -52,6 +52,8 @@ struct NLTypeSystemUnion { const NLTypeSystem *type_systems; }; +extern const NLTypeSystem type_system_root; + uint16_t type_get_type(const NLType *type); size_t type_get_size(const NLType *type); void type_get_type_system(const NLType *type, const NLTypeSystem **ret); -- cgit v1.2.3-54-g00ecf