This mimics the sd-bus api, as we may need it in the future.
_cleanup_rtnl_message_unref_ sd_rtnl_message *ipv4 = NULL, *ipv6 = NULL;
int r;
- r = sd_rtnl_message_new_addr(RTM_NEWADDR, if_loopback, AF_INET, &ipv4);
+ r = sd_rtnl_message_new_addr(rtnl, RTM_NEWADDR, if_loopback, AF_INET, &ipv4);
if (r < 0)
return r;
if (!socket_ipv6_is_supported())
return 0;
- r = sd_rtnl_message_new_addr(RTM_NEWADDR, if_loopback, AF_INET6, &ipv6);
+ r = sd_rtnl_message_new_addr(rtnl, RTM_NEWADDR, if_loopback, AF_INET6, &ipv6);
if (r < 0)
return r;
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
int r;
- r = sd_rtnl_message_new_link(RTM_SETLINK, if_loopback, &req);
+ r = sd_rtnl_message_new_link(rtnl, RTM_SETLINK, if_loopback, &req);
if (r < 0)
return r;
struct sd_rtnl_message {
RefCount n_ref;
+ sd_rtnl *rtnl;
+
struct nlmsghdr *hdr;
size_t container_offsets[RTNL_CONTAINER_DEPTH]; /* offset from hdr to each container's start */
unsigned n_containers; /* number of containers */
bool sealed:1;
};
-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);
int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m);
int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret);
#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);
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;
return 0;
}
-int sd_rtnl_message_new_route(uint16_t nlmsg_type, unsigned char rtm_family,
+int sd_rtnl_message_new_route(sd_rtnl *rtnl, uint16_t nlmsg_type,
+ unsigned char rtm_family,
sd_rtnl_message **ret) {
struct rtmsg *rtm;
int r;
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;
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, uint16_t nlmsg_type, int index,
+ sd_rtnl_message **ret) {
struct ifinfomsg *ifi;
int r;
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;
return 0;
}
-int sd_rtnl_message_new_addr(uint16_t nlmsg_type, int index, unsigned char family,
+int sd_rtnl_message_new_addr(sd_rtnl *rtnl, uint16_t nlmsg_type, int index,
+ unsigned char family,
sd_rtnl_message **ret) {
struct ifaddrmsg *ifa;
int r;
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;
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);
}
if (r < 0)
return r;
- r = message_new(&m, need);
+ r = message_new(nl, &m, need);
if (r < 0)
return r;
assert(ifindex > 0);
assert(name);
- r = sd_rtnl_message_new_link(RTM_SETLINK, ifindex, &message);
+ r = sd_rtnl_message_new_link(rtnl, RTM_SETLINK, ifindex, &message);
if (r < 0)
return r;
if (!alias && !mac && mtu == 0)
return 0;
- r = sd_rtnl_message_new_link(RTM_SETLINK, ifindex, &message);
+ r = sd_rtnl_message_new_link(rtnl, RTM_SETLINK, ifindex, &message);
if (r < 0)
return r;
assert(error <= 0);
- r = message_new(ret, NLMSG_SPACE(sizeof(struct nlmsgerr)));
+ r = message_new(NULL, ret, NLMSG_SPACE(sizeof(struct nlmsgerr)));
if (r < 0)
return r;
void *data;
/* we'd really like to test NEWLINK, but let's not mess with the running kernel */
- assert(sd_rtnl_message_new_link(RTM_GETLINK, ifindex, &message) >= 0);
+ assert(sd_rtnl_message_new_link(rtnl, RTM_GETLINK, ifindex, &message) >= 0);
assert(sd_rtnl_message_append_string(message, IFLA_IFNAME, name) >= 0);
assert(sd_rtnl_message_append_ether_addr(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
assert(sd_rtnl_message_append_u32(message, IFLA_MTU, mtu) >= 0);
void *data;
uint16_t type;
- assert(sd_rtnl_message_new_link(RTM_GETLINK, ifindex, &m) >= 0);
+ assert(sd_rtnl_message_new_link(rtnl, RTM_GETLINK, ifindex, &m) >= 0);
assert(m);
/* u8 test cases */
void *data;
int r;
- r = sd_rtnl_message_new_route(RTM_NEWROUTE, AF_INET, &req);
+ r = sd_rtnl_message_new_route(NULL, RTM_NEWROUTE, AF_INET, &req);
if (r < 0) {
log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
return;
assert(ifname);
assert(sd_rtnl_open(0, &rtnl) >= 0);
- assert(sd_rtnl_message_new_link(RTM_GETLINK, ifindex, &m) >= 0);
+ assert(sd_rtnl_message_new_link(rtnl, RTM_GETLINK, ifindex, &m) >= 0);
assert(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, NULL) >= 0);
assert(sd_rtnl_open(0, &rtnl) >= 0);
- assert(sd_rtnl_message_new_link(RTM_GETLINK, ifindex, &m) >= 0);
+ assert(sd_rtnl_message_new_link(rtnl, RTM_GETLINK, ifindex, &m) >= 0);
assert(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, &serial) >= 0);
assert(sd_rtnl_open(0, &rtnl) >= 0);
- assert(sd_rtnl_message_new_link(RTM_GETLINK, ifindex, &m1) >= 0);
- assert(sd_rtnl_message_new_link(RTM_GETLINK, ifindex, &m2) >= 0);
+ assert(sd_rtnl_message_new_link(rtnl, RTM_GETLINK, ifindex, &m1) >= 0);
+ assert(sd_rtnl_message_new_link(rtnl, RTM_GETLINK, ifindex, &m2) >= 0);
counter ++;
assert(sd_rtnl_call_async(rtnl, m1, &pipe_handler, &counter, 0, NULL) >= 0);
uint16_t type;
void *data;
- assert(sd_rtnl_message_new_link(RTM_NEWLINK, 0, &m) >= 0);
+ assert(sd_rtnl_message_new_link(NULL, RTM_NEWLINK, 0, &m) >= 0);
assert(sd_rtnl_message_open_container(m, IFLA_LINKINFO) >= 0);
assert(sd_rtnl_message_open_container(m, IFLA_LINKINFO) == -ENOTSUP);
test_link_configure(rtnl, if_loopback);
- assert(sd_rtnl_message_new_link(RTM_GETLINK, if_loopback, &m) >= 0);
+ assert(sd_rtnl_message_new_link(rtnl, RTM_GETLINK, if_loopback, &m) >= 0);
assert(m);
assert(sd_rtnl_message_get_type(m, &type) >= 0);
assert(link->manager);
assert(link->manager->rtnl);
- r = sd_rtnl_message_new_addr(RTM_DELADDR, link->ifindex, address->family, &req);
+ r = sd_rtnl_message_new_addr(link->manager->rtnl, RTM_DELADDR,
+ link->ifindex, address->family, &req);
if (r < 0) {
log_error("Could not allocate RTM_DELADDR message: %s",
strerror(-r));
assert(link->manager);
assert(link->manager->rtnl);
- r = sd_rtnl_message_new_addr(RTM_NEWADDR, link->ifindex,
- address->family, &req);
+ r = sd_rtnl_message_new_addr(link->manager->rtnl, RTM_NEWADDR,
+ link->ifindex, address->family, &req);
if (r < 0) {
log_error("Could not allocate RTM_NEWADDR message: %s",
strerror(-r));
log_debug_link(link, "setting MTU: %" PRIu32, mtu);
- r = sd_rtnl_message_new_link(RTM_SETLINK, link->ifindex, &req);
+ r = sd_rtnl_message_new_link(link->manager->rtnl, RTM_SETLINK,
+ link->ifindex, &req);
if (r < 0) {
log_error_link(link, "Could not allocate RTM_SETLINK message");
return r;
log_debug_link(link, "bringing link up");
- r = sd_rtnl_message_new_link(RTM_SETLINK, link->ifindex, &req);
+ r = sd_rtnl_message_new_link(link->manager->rtnl, RTM_SETLINK,
+ link->ifindex, &req);
if (r < 0) {
log_error_link(link, "Could not allocate RTM_SETLINK message");
return r;
log_debug_link(link, "requesting link status");
- r = sd_rtnl_message_new_link(RTM_GETLINK, link->ifindex, &req);
+ r = sd_rtnl_message_new_link(link->manager->rtnl, RTM_GETLINK,
+ link->ifindex, &req);
if (r < 0) {
log_error_link(link, "Could not allocate RTM_GETLINK message");
return r;
assert(netdev);
assert(netdev->state == NETDEV_STATE_READY);
+ assert(netdev->manager);
+ assert(netdev->manager->rtnl);
assert(link);
assert(callback);
- r = sd_rtnl_message_new_link(RTM_SETLINK, link->ifindex, &req);
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, RTM_SETLINK,
+ link->ifindex, &req);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_SETLINK message: %s",
int r;
assert(netdev);
- assert(!(netdev->kind == NETDEV_KIND_VLAN) || (link && callback && netdev->vlanid <= VLANID_MAX));
+ assert(!(netdev->kind == NETDEV_KIND_VLAN) ||
+ (link && callback && netdev->vlanid <= VLANID_MAX));
assert(netdev->name);
assert(netdev->manager);
assert(netdev->manager->rtnl);
- r = sd_rtnl_message_new_link(RTM_NEWLINK, 0, &req);
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, RTM_NEWLINK, 0, &req);
if (r < 0) {
log_error_netdev(netdev,
"Could not allocate RTM_NEWLINK message: %s",
assert(link->ifindex > 0);
assert(route->family == AF_INET || route->family == AF_INET6);
- r = sd_rtnl_message_new_route(RTM_NEWROUTE, route->family, &req);
+ r = sd_rtnl_message_new_route(link->manager->rtnl, RTM_NEWROUTE,
+ route->family, &req);
if (r < 0) {
log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
return r;
return r;
}
- r = sd_rtnl_message_new_link(RTM_NEWLINK, 0, &m);
+ r = sd_rtnl_message_new_link(rtnl, RTM_NEWLINK, 0, &m);
if (r < 0) {
log_error("Failed to allocate netlink message: %s", strerror(-r));
return r;
return r;
}
- r = sd_rtnl_message_new_link(RTM_SETLINK, 0, &m);
+ r = sd_rtnl_message_new_link(rtnl, RTM_SETLINK, 0, &m);
if (r < 0) {
log_error("Failed to allocate netlink message: %s", strerror(-r));
return r;
return -EBUSY;
}
- r = sd_rtnl_message_new_link(RTM_NEWLINK, ifi, &m);
+ r = sd_rtnl_message_new_link(rtnl, RTM_NEWLINK, ifi, &m);
if (r < 0) {
log_error("Failed to allocate netlink message: %s", strerror(-r));
return r;
int sd_rtnl_detach_event(sd_rtnl *nl);
/* messages */
-int sd_rtnl_message_new_link(uint16_t msg_type, int index, sd_rtnl_message **ret);
-int sd_rtnl_message_new_addr(uint16_t msg_type, int index, unsigned char family,
+int sd_rtnl_message_new_link(sd_rtnl *rtnl, uint16_t msg_type, int index,
sd_rtnl_message **ret);
-int sd_rtnl_message_new_route(uint16_t nlmsg_type, unsigned char rtm_family,
- sd_rtnl_message **ret);
+int sd_rtnl_message_new_addr(sd_rtnl *rtnl, uint16_t msg_type, int index,
+ unsigned char family, sd_rtnl_message **ret);
+int sd_rtnl_message_new_route(sd_rtnl *rtnl, uint16_t nlmsg_type,
+ unsigned char rtm_family, sd_rtnl_message **ret);
sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);