return 0;
}
+int sd_rtnl_message_route_set_src_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) {
+ struct rtmsg *rtm;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
+
+ rtm = NLMSG_DATA(m->hdr);
+
+ if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
+ (rtm->rtm_family == AF_INET6 && prefixlen > 128))
+ return -ERANGE;
+
+ rtm->rtm_src_len = prefixlen;
+
+ return 0;
+}
+
int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
struct rtmsg *rtm;
return 0;
}
+int sd_rtnl_message_route_get_dst_prefixlen(sd_rtnl_message *m, unsigned char *dst_len) {
+ 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(dst_len, -EINVAL);
+
+ rtm = NLMSG_DATA(m->hdr);
+
+ *dst_len = rtm->rtm_dst_len;
+
+ return 0;
+}
+
+int sd_rtnl_message_route_get_src_prefixlen(sd_rtnl_message *m, unsigned char *src_len) {
+ 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(src_len, -EINVAL);
+
+ rtm = NLMSG_DATA(m->hdr);
+
+ *src_len = rtm->rtm_src_len;
+
+ 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) {
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);
return m->hdr->nlmsg_seq;
}
+int sd_rtnl_message_is_error(sd_rtnl_message *m) {
+ assert_return(m, 0);
+ assert_return(m->hdr, 0);
+
+ return m->hdr->nlmsg_type == NLMSG_ERROR;
+}
+
int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
struct nlmsgerr *err;
assert_return(m, -EINVAL);
assert_return(m->hdr, -EINVAL);
- if (m->hdr->nlmsg_type != NLMSG_ERROR)
+ if (!sd_rtnl_message_is_error(m))
return 0;
err = NLMSG_DATA(m->hdr);
}
}
- for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len); new_msg = NLMSG_NEXT(new_msg, len)) {
+ for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) {
_cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
const NLType *nl_type;
if (new_msg->nlmsg_type == NLMSG_DONE) {
/* finished reading multi-part message */
done = true;
- break;
+
+ continue;
}
/* check that we support this message type */