X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-rtnl%2Frtnl-message.c;h=dc749479939fc8b7d05c548f8243e23dab349c57;hb=bdd13f6be4b588568683a1ab54f421fc6a636dbb;hp=c780f71881abf407b447ab2ac30ec916fa363091;hpb=31a4e15384b3819621dd5648e18148c2edea72d3;p=elogind.git diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c index c780f7188..dc7494799 100644 --- a/src/libsystemd/sd-rtnl/rtnl-message.c +++ b/src/libsystemd/sd-rtnl/rtnl-message.c @@ -19,7 +19,6 @@ along with systemd; If not, see . ***/ -#include #include #include #include @@ -28,6 +27,7 @@ #include "util.h" #include "refcnt.h" +#include "missing.h" #include "sd-rtnl.h" #include "rtnl-util.h" @@ -38,7 +38,7 @@ #define UPDATE_RTA(m, new) (m)->next_rta_offset = (uint8_t*)(new) - (uint8_t*)(m)->hdr; #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr; -int message_new(sd_rtnl_message **ret, size_t initial_size) { +int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, size_t initial_size) { sd_rtnl_message *m; assert_return(ret, -EINVAL); @@ -59,6 +59,9 @@ int message_new(sd_rtnl_message **ret, size_t initial_size) { m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; m->sealed = false; + if (rtnl) + m->rtnl = sd_rtnl_ref(rtnl); + *ret = m; return 0; @@ -82,8 +85,8 @@ int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char pr return 0; } -int sd_rtnl_message_new_route(uint16_t nlmsg_type, unsigned char rtm_family, - sd_rtnl_message **ret) { +int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, + uint16_t nlmsg_type, unsigned char rtm_family) { struct rtmsg *rtm; int r; @@ -91,7 +94,7 @@ int sd_rtnl_message_new_route(uint16_t nlmsg_type, unsigned char rtm_family, assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL); assert_return(ret, -EINVAL); - r = message_new(ret, NLMSG_SPACE(sizeof(struct rtmsg))); + r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct rtmsg))); if (r < 0) return r; @@ -119,14 +122,12 @@ int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL); + assert_return(change, -EINVAL); ifi = NLMSG_DATA(m->hdr); ifi->ifi_flags = flags; - if (change) - ifi->ifi_change = change; - else - ifi->ifi_change = 0xffffffff; + ifi->ifi_change = change; return 0; } @@ -145,15 +146,17 @@ int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) { return 0; } -int sd_rtnl_message_new_link(uint16_t nlmsg_type, int index, sd_rtnl_message **ret) { +int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret, + uint16_t nlmsg_type, int index) { struct ifinfomsg *ifi; int r; assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL); - assert_return(nlmsg_type == RTM_NEWLINK || index > 0, -EINVAL); + assert_return(nlmsg_type == RTM_NEWLINK || + nlmsg_type == RTM_SETLINK || index > 0, -EINVAL); assert_return(ret, -EINVAL); - r = message_new(ret, NLMSG_SPACE(sizeof(struct ifinfomsg))); + r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifinfomsg))); if (r < 0) return r; @@ -218,8 +221,9 @@ int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) { return 0; } -int sd_rtnl_message_new_addr(uint16_t nlmsg_type, int index, unsigned char family, - sd_rtnl_message **ret) { +int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, + uint16_t nlmsg_type, int index, + unsigned char family) { struct ifaddrmsg *ifa; int r; @@ -228,12 +232,14 @@ int sd_rtnl_message_new_addr(uint16_t nlmsg_type, int index, unsigned char famil assert_return(family == AF_INET || family == AF_INET6, -EINVAL); assert_return(ret, -EINVAL); - r = message_new(ret, NLMSG_SPACE(sizeof(struct ifaddrmsg))); + r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifaddrmsg))); if (r < 0) return r; (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); (*ret)->hdr->nlmsg_type = nlmsg_type; + if (nlmsg_type == RTM_GETADDR && family == AF_INET) + (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP; ifa = NLMSG_DATA((*ret)->hdr); @@ -258,6 +264,7 @@ sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) { sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) { if (m && REFCNT_DEC(m->n_ref) <= 0) { + sd_rtnl_unref(m->rtnl); free(m->hdr); free(m); } @@ -473,7 +480,7 @@ int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t break; else return -ENOTSUP; - break; + default: return -ENOTSUP; } @@ -701,7 +708,7 @@ int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, c return 0; } -int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type, size_t extra) { +int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) { uint16_t rtm_type; assert_return(m, -EINVAL); @@ -712,9 +719,13 @@ int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type, size if (rtnl_message_type_is_link(rtm_type)) { if ((type == IFLA_LINKINFO && m->n_containers == 0) || - (type == IFLA_INFO_DATA && m->n_containers == 1 && GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO) || - (type == VETH_INFO_PEER && m->n_containers == 2 && GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA)) - return add_rtattr(m, type, NULL, extra); + (type == IFLA_INFO_DATA && m->n_containers == 1 && + GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO)) + return add_rtattr(m, type, NULL, 0); + else if (type == VETH_INFO_PEER && m->n_containers == 2 && + GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA && + GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO) + return add_rtattr(m, type, NULL, sizeof(struct ifinfomsg)); } return -ENOTSUP; @@ -893,7 +904,7 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) { if (r < 0) return r; - r = message_new(&m, need); + r = message_new(nl, &m, need); if (r < 0) return r; @@ -921,10 +932,6 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) { if (k > 0) switch (m->hdr->nlmsg_type) { - struct ifinfomsg *ifi; - struct ifaddrmsg *ifa; - struct rtmsg *rtm; - /* check that the size matches the message type */ case NLMSG_ERROR: if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) @@ -937,6 +944,8 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) { if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) k = -EIO; else { + struct ifinfomsg *ifi; + ifi = NLMSG_DATA(m->hdr); UPDATE_RTA(m, IFLA_RTA(ifi)); } @@ -947,6 +956,8 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) { if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifaddrmsg))) k = -EIO; else { + struct ifaddrmsg *ifa; + ifa = NLMSG_DATA(m->hdr); UPDATE_RTA(m, IFA_RTA(ifa)); } @@ -957,6 +968,8 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) { if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg))) k = -EIO; else { + struct rtmsg *rtm; + rtm = NLMSG_DATA(m->hdr); UPDATE_RTA(m, RTM_RTA(rtm)); }