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;
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)
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_STRING);
if (r < 0)
return r;
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;
}
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_U8);
if (r < 0)
return r;
else if ((size_t) r < sizeof(uint8_t))
return -EIO;
- *data = *(uint8_t *) attr_data;
+ if (data)
+ *data = *(uint8_t *) attr_data;
return 0;
}
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_U16);
if (r < 0)
return r;
else if ((size_t) r < sizeof(uint16_t))
return -EIO;
- *data = *(uint16_t *) attr_data;
+ if (data)
+ *data = *(uint16_t *) attr_data;
return 0;
}
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_U32);
if (r < 0)
return r;
else if ((size_t)r < sizeof(uint32_t))
return -EIO;
- *data = *(uint32_t *) attr_data;
+ if (data)
+ *data = *(uint32_t *) attr_data;
return 0;
}
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
if (r < 0)
return r;
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;
}
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
if (r < 0)
return r;
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;
}
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_IN_ADDR);
if (r < 0)
return r;
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;
}
int r;
void *attr_data;
+ assert_return(m, -EINVAL);
+
r = message_attribute_has_type(m, type, NLA_IN_ADDR);
if (r < 0)
return r;
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;
}
}
/* 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)