netlink-message.c revision 0610939d6bd21873cd2a8d945daff86c477a5015
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
fff87a35d9e26c0d4ea41273a963c0eb20e18da4Zbigniew Jędrzejewski-Szmek Copyright 2013 Tom Gundersen <teg@jklm.no>
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier systemd is free software; you can redistribute it and/or modify it
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer under the terms of the GNU Lesser General Public License as published by
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer the Free Software Foundation; either version 2.1 of the License, or
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer (at your option) any later version.
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier systemd is distributed in the hope that it will be useful, but
278d5115470919319c514ea37d7b14e3f7d0580bEvgeny Vereshchagin WITHOUT ANY WARRANTY; without even the implied warranty of
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier Lesser General Public License for more details.
32d965851d8cbb39f8ee0eeaf76a89e8f5fc174fLennart Poettering You should have received a copy of the GNU Lesser General Public License
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer along with systemd; If not, see <http://www.gnu.org/licenses/>.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier#define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer#define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer#define RTA_FLAGS(rta) ((rta)->rta_type & ~NLA_TYPE_MASK)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Note that 'rtnl' is currently unused, if we start using it internally
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer we must take care to avoid problems due to mutual references between
6b197f2a03fa03a2a853cf726d47be2ea4c623b6Harald Hoyer buses and their queued messages. See sd-bus.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = type_system_get_type(&type_system_root, &nl_type, type);
return -EINVAL;
if (!m->hdr)
return -ENOMEM;
*ret = m;
m = NULL;
-EINVAL);
if (dump)
for (i = 0; i <= m->n_containers; i++)
free(m);
return NULL;
return m->broadcast;
static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *data, size_t data_length) {
char *padding;
int offset;
assert(m);
if (!new_hdr)
return -ENOMEM;
for (i = 0; i < m->n_containers; i++)
if (data)
return offset;
static int message_attribute_has_type(sd_netlink_message *m, size_t *out_size, uint16_t attribute_type, uint16_t data_type) {
assert(m);
return -EINVAL;
if (out_size)
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data) {
if (size) {
return -EINVAL;
int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type, const struct in_addr *data) {
int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short type, const struct in6_addr *data) {
int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short type, const struct ether_addr *data) {
int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
int family;
r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
family);
type);
int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned short type, const char *key) {
r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
key);
m->n_containers --;
static int netlink_message_read_internal(sd_netlink_message *m, unsigned short type, void **data, bool *net_byteorder) {
return -ENODATA;
if (net_byteorder)
void *attr_data;
return -EIO;
if (data)
void *attr_data;
return -EIO;
if (data)
void *attr_data;
bool net_byteorder;
return -EIO;
if (data) {
if (net_byteorder)
void *attr_data;
bool net_byteorder;
return -EIO;
if (data) {
if (net_byteorder)
int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short type, struct ether_addr *data) {
void *attr_data;
return -EIO;
if (data)
int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short type, struct ifa_cacheinfo *info) {
void *attr_data;
return -EIO;
if (info)
int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, struct in_addr *data) {
void *attr_data;
return -EIO;
if (data)
int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, struct in6_addr *data) {
void *attr_data;
return -EIO;
if (data)
int count,
unsigned int rt_len) {
if(!attributes)
return -ENOMEM;
unsigned short type;
void *container;
&nl_type,
type_id);
type_id);
type_id);
case NL_MATCH_SIBLING:
const char *key;
key);
case NL_MATCH_PROTOCOL:
int family;
family);
return -EINVAL;
m->n_containers ++;
r = netlink_container_parse(m,
size);
m->n_containers --;
m->n_containers --;
assert(m);
assert_return(m, 0);
if (!sd_netlink_message_is_error(m))
if (!m->sealed)
m->n_containers = 0;
r = netlink_container_parse(m,
assert(m);
m->sealed = true;
return m->next;