diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 8d2269b54d..9c31105772 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -244,7 +244,7 @@ static int genl_message_new( if (!policy_set) return -EOPNOTSUPP; - r = message_new_full(nl, family->id, policy_set, + r = message_new_full(nl, family->id, NLM_F_REQUEST | NLM_F_ACK, policy_set, sizeof(struct genlmsghdr) + family->additional_header_size, &m); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 5b9ccb336e..7346902bdc 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -131,10 +131,11 @@ int message_new_empty(sd_netlink *nl, sd_netlink_message **ret); int message_new_full( sd_netlink *nl, uint16_t nlmsg_type, + uint16_t nlmsg_flags, const NLAPolicySet *policy_set, size_t header_size, sd_netlink_message **ret); -int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type); +int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type, uint16_t flags); int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret); static inline uint32_t message_get_serial(sd_netlink_message *m) { diff --git a/src/libsystemd/sd-netlink/netlink-message-nfnl.c b/src/libsystemd/sd-netlink/netlink-message-nfnl.c index 72bcdde1bd..321b9b2006 100644 --- a/src/libsystemd/sd-netlink/netlink-message-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-nfnl.c @@ -34,7 +34,7 @@ int sd_nfnl_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int nfproto, assert_return(nfproto_is_valid(nfproto), -EINVAL); assert_return(NFNL_MSG_TYPE(msg_type) == msg_type, -EINVAL); - r = message_new(nfnl, &m, subsys << 8 | msg_type); + r = message_new(nfnl, &m, subsys << 8 | msg_type, NLM_F_REQUEST | NLM_F_ACK); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-message-rtnl.c b/src/libsystemd/sd-netlink/netlink-message-rtnl.c index fdde1fb2c8..b730b63fb0 100644 --- a/src/libsystemd/sd-netlink/netlink-message-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-rtnl.c @@ -244,13 +244,13 @@ int sd_rtnl_message_new_route( IN_SET(family, AF_INET, AF_INET6), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, + ret, + nlmsg_type, + NLM_F_REQUEST|NLM_F_ACK|(nlmsg_type == RTM_NEWROUTE ? NLM_F_CREATE | NLM_F_APPEND : 0)); if (r < 0) return r; - if (nlmsg_type == RTM_NEWROUTE) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND; - rtm = NLMSG_DATA((*ret)->hdr); rtm->rtm_family = family; @@ -281,13 +281,13 @@ int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, } assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, + ret, + nlmsg_type, + NLM_F_REQUEST | NLM_F_ACK | (nlmsg_type == RTM_NEWNEXTHOP ? NLM_F_CREATE | NLM_F_REPLACE : 0)); if (r < 0) return r; - if (nlmsg_type == RTM_NEWNEXTHOP) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - nhm = NLMSG_DATA((*ret)->hdr); nhm->nh_family = family; @@ -311,17 +311,18 @@ int sd_rtnl_message_new_neigh( assert_return(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6, AF_BRIDGE), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); - if (r < 0) - return r; - + uint16_t flags = NLM_F_REQUEST | NLM_F_ACK; if (nlmsg_type == RTM_NEWNEIGH) { if (family == AF_BRIDGE) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND; + flags |= NLM_F_CREATE | NLM_F_APPEND; else - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; + flags |= NLM_F_CREATE | NLM_F_REPLACE; } + r = message_new(rtnl, ret, nlmsg_type, flags); + if (r < 0) + return r; + ndm = NLMSG_DATA((*ret)->hdr); ndm->ndm_family = family; @@ -337,15 +338,16 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret, uint16_ assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + uint16_t flags = NLM_F_REQUEST | NLM_F_ACK; + if (nlmsg_type == RTM_NEWLINK && ifindex == 0) + flags |= NLM_F_CREATE | NLM_F_EXCL; + else if (nlmsg_type == RTM_NEWLINKPROP) + flags |= NLM_F_CREATE | NLM_F_EXCL | NLM_F_APPEND; + + r = message_new(rtnl, ret, nlmsg_type, flags); if (r < 0) return r; - if (nlmsg_type == RTM_NEWLINK && ifindex == 0) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; - else if (nlmsg_type == RTM_NEWLINKPROP) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL | NLM_F_APPEND; - ifi = NLMSG_DATA((*ret)->hdr); ifi->ifi_family = AF_UNSPEC; @@ -371,7 +373,7 @@ int sd_rtnl_message_new_addr( IN_SET(family, AF_INET, AF_INET6), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, ret, nlmsg_type, NLM_F_REQUEST | NLM_F_ACK); if (r < 0) return r; @@ -439,13 +441,13 @@ int sd_rtnl_message_new_addrlabel( assert_return(rtnl_message_type_is_addrlabel(nlmsg_type), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, + ret, + nlmsg_type, + NLM_F_REQUEST | NLM_F_ACK | (nlmsg_type == RTM_NEWADDRLABEL ? NLM_F_CREATE | NLM_F_REPLACE : 0)); if (r < 0) return r; - if (nlmsg_type == RTM_NEWADDRLABEL) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - addrlabel = NLMSG_DATA((*ret)->hdr); addrlabel->ifal_family = family; @@ -466,13 +468,13 @@ int sd_rtnl_message_new_routing_policy_rule( assert_return(rtnl_message_type_is_routing_policy_rule(nlmsg_type), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, + ret, + nlmsg_type, + NLM_F_REQUEST | NLM_F_ACK | (nlmsg_type == RTM_NEWRULE ? NLM_F_CREATE | NLM_F_EXCL : 0)); if (r < 0) return r; - if (nlmsg_type == RTM_NEWRULE) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; - frh = NLMSG_DATA((*ret)->hdr); frh->family = family; @@ -493,13 +495,13 @@ int sd_rtnl_message_new_traffic_control( assert_return(rtnl_message_type_is_traffic_control(nlmsg_type), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, + ret, + nlmsg_type, + NLM_F_REQUEST | NLM_F_ACK | (IN_SET(nlmsg_type, RTM_NEWQDISC, RTM_NEWTCLASS) ? NLM_F_CREATE | NLM_F_REPLACE : 0)); if (r < 0) return r; - if (IN_SET(nlmsg_type, RTM_NEWQDISC, RTM_NEWTCLASS)) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - tcm = NLMSG_DATA((*ret)->hdr); tcm->tcm_ifindex = ifindex; tcm->tcm_handle = handle; @@ -520,13 +522,13 @@ int sd_rtnl_message_new_mdb( assert_return(rtnl_message_type_is_mdb(nlmsg_type), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, + ret, + nlmsg_type, + NLM_F_REQUEST | NLM_F_ACK | (nlmsg_type == RTM_NEWMDB ? NLM_F_CREATE | NLM_F_REPLACE : 0)); if (r < 0) return r; - if (nlmsg_type == RTM_NEWMDB) - (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - bpm = NLMSG_DATA((*ret)->hdr); bpm->family = AF_BRIDGE; bpm->ifindex = ifindex; @@ -545,7 +547,7 @@ int sd_rtnl_message_new_nsid( assert_return(rtnl_message_type_is_nsid(nlmsg_type), -EINVAL); assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nlmsg_type); + r = message_new(rtnl, ret, nlmsg_type, NLM_F_REQUEST | NLM_F_ACK); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index eb88ae5e2b..8052e46768 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -44,6 +44,7 @@ int message_new_empty(sd_netlink *nl, sd_netlink_message **ret) { int message_new_full( sd_netlink *nl, uint16_t nlmsg_type, + uint16_t nlmsg_flags, const NLAPolicySet *policy_set, size_t header_size, sd_netlink_message **ret) { @@ -69,7 +70,7 @@ int message_new_full( if (!m->hdr) return -ENOMEM; - m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + m->hdr->nlmsg_flags = nlmsg_flags; m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = nlmsg_type; @@ -77,7 +78,7 @@ int message_new_full( return 0; } -int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t nlmsg_type) { +int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t nlmsg_type, uint16_t nlmsg_flags) { const NLAPolicySet *policy_set; size_t size; int r; @@ -85,11 +86,11 @@ int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t nlmsg_type) { assert_return(nl, -EINVAL); assert_return(ret, -EINVAL); - r = netlink_get_policy_set_and_header_size(nl, nlmsg_type, &policy_set, &size); + r = netlink_get_policy_set_and_header_size(nl, nlmsg_type, nlmsg_flags, &policy_set, &size); if (r < 0) return r; - return message_new_full(nl, nlmsg_type, policy_set, size, ret); + return message_new_full(nl, nlmsg_type, nlmsg_flags, policy_set, size, ret); } int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret) { @@ -98,7 +99,7 @@ int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_n assert(error <= 0); - r = message_new(nl, ret, NLMSG_ERROR); + r = message_new(nl, ret, NLMSG_ERROR, 0); if (r < 0) return r; @@ -1328,8 +1329,12 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *nl) { assert(m->hdr); - r = netlink_get_policy_set_and_header_size(nl, m->hdr->nlmsg_type, - &m->containers[0].policy_set, &size); + r = netlink_get_policy_set_and_header_size( + nl, + m->hdr->nlmsg_type, + m->hdr->nlmsg_flags, + &m->containers[0].policy_set, + &size); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 1b098cadee..0f00e3f2fc 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -307,7 +307,7 @@ static int parse_message_one(sd_netlink *nl, uint32_t group, const struct nlmsgh goto finalize; /* check that we support this message type */ - r = netlink_get_policy_set_and_header_size(nl, hdr->nlmsg_type, NULL, &size); + r = netlink_get_policy_set_and_header_size(nl, hdr->nlmsg_type, hdr->nlmsg_flags, NULL, &size); if (r == -EOPNOTSUPP) { log_debug("sd-netlink: ignored message with unknown type: %i", hdr->nlmsg_type); goto finalize; diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 21ef80c2ec..8ce3fc0ec9 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -51,6 +51,7 @@ const NLAPolicySetUnion *policy_get_policy_set_union(const NLAPolicy *policy) { int netlink_get_policy_set_and_header_size( sd_netlink *nl, uint16_t type, + uint16_t flags, const NLAPolicySet **ret_policy_set, size_t *ret_header_size) { diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index e034a984e9..4643952729 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -52,6 +52,7 @@ const NLAPolicySetUnion *policy_get_policy_set_union(const NLAPolicy *policy); int netlink_get_policy_set_and_header_size( sd_netlink *nl, uint16_t type, + uint16_t flags, const NLAPolicySet **ret_policy_set, size_t *ret_header_size);