From 8224fd466a845e40723e37c225eadaf37766b822 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 26 Jun 2015 00:02:55 +0200 Subject: netlink: rework containers Instead of representing containers as several arrays, make a new netlink_container struct and keep one array of these structs. We also introduce netlink_attribute structs that in the future will hold meta-information about each atribute. --- src/libsystemd/sd-netlink/netlink-internal.h | 19 +++++++---- src/libsystemd/sd-netlink/netlink-message.c | 48 ++++++++++------------------ 2 files changed, 29 insertions(+), 38 deletions(-) (limited to 'src/libsystemd') diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 4aa7583d0..6b83764e5 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -72,6 +72,10 @@ struct sd_netlink { unsigned rqueue_partial_size; size_t rqueue_partial_allocated; + sd_netlink_message **wqueue; + unsigned wqueue_size; + size_t wqueue_allocated; + struct nlmsghdr *rbuffer; size_t rbuffer_allocated; @@ -94,8 +98,6 @@ struct sd_netlink { struct netlink_attribute { size_t offset; /* offset from hdr to attirubte */ - bool nested:1; - bool net_byteorder:1; }; struct netlink_container { @@ -113,6 +115,7 @@ struct sd_netlink_message { struct nlmsghdr *hdr; struct netlink_container containers[RTNL_CONTAINER_DEPTH]; unsigned n_containers; /* number of containers */ + size_t next_rta_offset; /* offset from hdr to next rta */ bool sealed:1; bool broadcast:1; @@ -120,17 +123,21 @@ struct sd_netlink_message { }; int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type); -int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret); -int socket_open(int family); -int socket_bind(sd_netlink *nl); -int socket_join_broadcast_group(sd_netlink *nl, unsigned group); int socket_write_message(sd_netlink *nl, sd_netlink_message *m); int socket_read_message(sd_netlink *nl); int rtnl_rqueue_make_room(sd_netlink *rtnl); int rtnl_rqueue_partial_make_room(sd_netlink *rtnl); +int rtnl_message_read_internal(sd_netlink_message *m, unsigned short type, void **data); +int rtnl_message_parse(sd_netlink_message *m, + size_t **rta_offset_tb, + unsigned short *rta_tb_size, + int max, + struct rtattr *rta, + unsigned int rt_len); + /* Make sure callbacks don't destroy the rtnl connection */ #define RTNL_DONT_DESTROY(rtnl) \ _cleanup_netlink_unref_ _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index b0ed2f288..13573dcea 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -38,7 +38,6 @@ #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr; #define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK) -#define RTA_FLAGS(rta) ((rta)->rta_type & ~NLA_TYPE_MASK) int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) { sd_netlink_message *m; @@ -476,7 +475,7 @@ int sd_netlink_message_close_container(sd_netlink_message *m) { return 0; } -static int netlink_message_read_internal(sd_netlink_message *m, unsigned short type, void **data, bool *net_byteorder) { +static int netlink_message_read_internal(sd_netlink_message *m, unsigned short type, void **data) { struct netlink_attribute *attribute; struct rtattr *rta; @@ -496,9 +495,6 @@ static int netlink_message_read_internal(sd_netlink_message *m, unsigned short t *data = RTA_DATA(rta); - if (net_byteorder) - *net_byteorder = attribute->net_byteorder; - return RTA_PAYLOAD(rta); } @@ -512,7 +508,7 @@ int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, c if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, NULL); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if (strnlen(attr_data, r) >= (size_t) r) @@ -534,7 +530,7 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8 if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, NULL); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t) r < sizeof(uint8_t)) @@ -547,9 +543,8 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8 } int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data) { - void *attr_data; - bool net_byteorder; int r; + void *attr_data; assert_return(m, -EINVAL); @@ -557,26 +552,21 @@ int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, &net_byteorder); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t) r < sizeof(uint16_t)) return -EIO; - if (data) { - if (net_byteorder) - *data = be16toh(*(uint16_t *) attr_data); - else - *data = *(uint16_t *) attr_data; - } + if (data) + *data = *(uint16_t *) attr_data; return 0; } int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data) { - void *attr_data; - bool net_byteorder; int r; + void *attr_data; assert_return(m, -EINVAL); @@ -584,18 +574,14 @@ int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, &net_byteorder); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(uint32_t)) return -EIO; - if (data) { - if (net_byteorder) - *data = be32toh(*(uint32_t *) attr_data); - else - *data = *(uint32_t *) attr_data; - } + if (data) + *data = *(uint32_t *) attr_data; return 0; } @@ -610,7 +596,7 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, NULL); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct ether_addr)) @@ -632,7 +618,7 @@ int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, NULL); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct ifa_cacheinfo)) @@ -654,7 +640,7 @@ int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, NULL); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct in_addr)) @@ -676,7 +662,7 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, if (r < 0) return r; - r = netlink_message_read_internal(m, type, &attr_data, NULL); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct in6_addr)) @@ -713,8 +699,6 @@ static int netlink_container_parse(sd_netlink_message *m, log_debug("rtnl: message parse - overwriting repeated attribute"); attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr; - attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED; - attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER; } container->attributes = attributes; @@ -797,7 +781,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ } else return -EINVAL; - r = netlink_message_read_internal(m, type_id, &container, NULL); + r = netlink_message_read_internal(m, type_id, &container); if (r < 0) return r; else -- cgit v1.2.3