From 5a72317435a39f23520b42731e53bd13d20f489e Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Tue, 21 Jan 2014 15:55:57 +0100 Subject: [PATCH] sd-rtnl: simplify sd_rtnl_message_addr_new() Split out into sd_rtnl_message_addr_set_{prefixlen,flags,scope}(). --- src/core/loopback-setup.c | 30 +++++++++-- src/libsystemd/sd-rtnl/rtnl-message.c | 75 +++++++++++++++++++++++++-- src/network/networkd-address.c | 30 +++++++++-- src/systemd/sd-rtnl.h | 7 ++- 4 files changed, 127 insertions(+), 15 deletions(-) diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c index 7eb28fc03..9058b6f1c 100644 --- a/src/core/loopback-setup.c +++ b/src/core/loopback-setup.c @@ -51,8 +51,19 @@ static int add_addresses(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_ad _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *ipv4 = NULL, *ipv6 = NULL; int r; - r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET, 8, - IFA_F_PERMANENT, RT_SCOPE_HOST, &ipv4); + r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET, &ipv4); + if (r < 0) + return r; + + r = sd_rtnl_message_addr_set_prefixlen(ipv4, 8); + if (r < 0) + return r; + + r = sd_rtnl_message_addr_set_flags(ipv4, IFA_F_PERMANENT); + if (r < 0) + return r; + + r = sd_rtnl_message_addr_set_scope(ipv4, RT_SCOPE_HOST); if (r < 0) return r; @@ -69,8 +80,19 @@ static int add_addresses(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_ad if (!socket_ipv6_is_supported()) return 0; - r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET6, 128, - IFA_F_PERMANENT, RT_SCOPE_HOST, &ipv6); + r = sd_rtnl_message_addr_new(RTM_NEWADDR, if_loopback, AF_INET6, &ipv6); + if (r < 0) + return r; + + r = sd_rtnl_message_addr_set_prefixlen(ipv6, 128); + if (r < 0) + return r; + + r = sd_rtnl_message_addr_set_flags(ipv6, IFA_F_PERMANENT); + if (r < 0) + return r; + + r = sd_rtnl_message_addr_set_scope(ipv6, RT_SCOPE_HOST); if (r < 0) return r; diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c index d55c3673a..d158ff793 100644 --- a/src/libsystemd/sd-rtnl/rtnl-message.c +++ b/src/libsystemd/sd-rtnl/rtnl-message.c @@ -129,8 +129,16 @@ bool message_type_is_addr(uint16_t type) { int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) { struct rtmsg *rtm; + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(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_dst_len = prefixlen; return 0; @@ -170,6 +178,10 @@ int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family, int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) { struct ifinfomsg *ifi; + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(message_type_is_link(m->hdr->nlmsg_type), -EINVAL); + ifi = NLMSG_DATA(m->hdr); ifi->ifi_flags = flags; @@ -184,6 +196,10 @@ int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type) { struct ifinfomsg *ifi; + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(message_type_is_link(m->hdr->nlmsg_type), -EINVAL); + ifi = NLMSG_DATA(m->hdr); ifi->ifi_type = type; @@ -218,12 +234,60 @@ int sd_rtnl_message_link_new(uint16_t nlmsg_type, int index, sd_rtnl_message **r return 0; } -int sd_rtnl_message_addr_new(uint16_t nlmsg_type, int index, unsigned char family, unsigned char prefixlen, unsigned char flags, unsigned char scope, sd_rtnl_message **ret) { +int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen) { + struct ifaddrmsg *ifa; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); + + ifa = NLMSG_DATA(m->hdr); + + if ((ifa->ifa_family == AF_INET && prefixlen > 32) || + (ifa->ifa_family == AF_INET6 && prefixlen > 128)) + return -ERANGE; + + ifa->ifa_prefixlen = prefixlen; + + return 0; +} + +int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags) { + struct ifaddrmsg *ifa; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); + + ifa = NLMSG_DATA(m->hdr); + + ifa->ifa_flags = flags; + + return 0; +} + +int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) { + struct ifaddrmsg *ifa; + + assert_return(m, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(message_type_is_addr(m->hdr->nlmsg_type), -EINVAL); + + ifa = NLMSG_DATA(m->hdr); + + ifa->ifa_scope = scope; + + return 0; +} + +int sd_rtnl_message_addr_new(uint16_t nlmsg_type, int index, unsigned char family, + sd_rtnl_message **ret) { struct ifaddrmsg *ifa; int r; assert_return(message_type_is_addr(nlmsg_type), -EINVAL); assert_return(index > 0, -EINVAL); + assert_return(family == AF_INET || family == AF_INET6, -EINVAL); assert_return(ret, -EINVAL); r = message_new(ret, NLMSG_SPACE(sizeof(struct ifaddrmsg))); @@ -235,11 +299,12 @@ int sd_rtnl_message_addr_new(uint16_t nlmsg_type, int index, unsigned char famil ifa = NLMSG_DATA((*ret)->hdr); - ifa->ifa_family = family; - ifa->ifa_prefixlen = prefixlen; - ifa->ifa_flags = flags; - ifa->ifa_scope = scope; ifa->ifa_index = index; + ifa->ifa_family = family; + if (family == AF_INET) + ifa->ifa_prefixlen = 32; + else if (family == AF_INET6) + ifa->ifa_prefixlen = 128; UPDATE_RTA(*ret, IFA_RTA(ifa)); diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 7d06cf887..3f787948f 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -101,14 +101,19 @@ int address_drop(Address *address, Link *link, assert(link->manager); assert(link->manager->rtnl); - r = sd_rtnl_message_addr_new(RTM_DELADDR, link->ifindex, - address->family, address->prefixlen, 0, 0, &req); + r = sd_rtnl_message_addr_new(RTM_DELADDR, link->ifindex, address->family, &req); if (r < 0) { log_error("Could not allocate RTM_DELADDR message: %s", strerror(-r)); return r; } + r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen); + if (r < 0) { + log_error("Could not set prefixlen: %s", strerror(-r)); + return r; + } + if (address->family == AF_INET) r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in); else if (address->family == AF_INET6) @@ -141,14 +146,31 @@ int address_configure(Address *address, Link *link, assert(link->manager->rtnl); r = sd_rtnl_message_addr_new(RTM_NEWADDR, link->ifindex, - address->family, address->prefixlen, - IFA_F_PERMANENT, RT_SCOPE_UNIVERSE, &req); + address->family, &req); if (r < 0) { log_error("Could not allocate RTM_NEWADDR message: %s", strerror(-r)); return r; } + r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen); + if (r < 0) { + log_error("Could not set prefixlen: %s", strerror(-r)); + return r; + } + + r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT); + if (r < 0) { + log_error("Could not set flags: %s", strerror(-r)); + return r; + } + + r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_UNIVERSE); + if (r < 0) { + log_error("Could not set scope: %s", strerror(-r)); + return r; + } + if (address->family == AF_INET) r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in); else if (address->family == AF_INET6) diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h index 87a58a98e..5539e2315 100644 --- a/src/systemd/sd-rtnl.h +++ b/src/systemd/sd-rtnl.h @@ -68,8 +68,7 @@ int sd_rtnl_detach_event(sd_rtnl *nl); /* messages */ int sd_rtnl_message_link_new(uint16_t msg_type, int index, sd_rtnl_message **ret); int sd_rtnl_message_addr_new(uint16_t msg_type, int index, unsigned char family, - unsigned char prefixlen, unsigned char flags, - unsigned char scope, sd_rtnl_message **ret); + sd_rtnl_message **ret); int sd_rtnl_message_route_new(uint16_t nlmsg_type, unsigned char rtm_family, sd_rtnl_message **ret); /* @@ -84,6 +83,10 @@ sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m); int sd_rtnl_message_get_errno(sd_rtnl_message *m); int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type); +int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen); +int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope); +int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags); + int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change); int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type); int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex); -- 2.30.2