Applied. Thanks! Cheers,
Tom On Wed, Apr 2, 2014 at 9:31 PM, Umut Tezduyar Lindskog <umut.tezdu...@axis.com> wrote: > Currently when both ipv4ll and dhcp are enabled, ipv4ll > address (if one has been claimed) is removed when dhcp > address is aquired. This is not the best thing to do > since there might be clients unaware of the removal > trying to communicate. > > This patch provides a smooth transition between ipv4ll > and dhcp. If ipv4ll address was claimed [1] before dhcp, > address is marked as deprecated. Deprecated address is still > a valid address and packets can be received on it but address > cannot be selected as a source address. If dhcp lease cannot > be extended, then ipv4ll address is marked as valid again. > > [1] If there is no collision, claiming IPv4LL takes between 4 to > 7 seconds. > --- > TODO | 1 - > man/systemd.network.xml | 5 +- > src/libsystemd-network/sd-ipv4ll.c | 6 +++ > src/libsystemd/sd-rtnl/rtnl-message.c | 50 +++++++++++++++++ > src/libsystemd/sd-rtnl/rtnl-types.c | 2 +- > src/libsystemd/sd-rtnl/rtnl-types.h | 1 + > src/libsystemd/sd-rtnl/test-rtnl.c | 2 + > src/network/networkd-address.c | 96 > +++++++++++++++++++++++++++++++-- > src/network/networkd-link.c | 94 ++++++++++++++++++++++++++++---- > src/network/networkd.h | 4 ++ > src/systemd/sd-ipv4ll.h | 12 +++-- > src/systemd/sd-rtnl.h | 3 ++ > 12 files changed, 253 insertions(+), 23 deletions(-) > > diff --git a/TODO b/TODO > index 2d56e81..4ff69ff 100644 > --- a/TODO > +++ b/TODO > @@ -665,7 +665,6 @@ Features: > - add reduced [Link] support to .network files > - add IPv4LL tests (inspire by DHCP) > - add Scope= parsing option for [Network] > - - have smooth transition from LL to routable address, without > disconnecting clients. > > * sd-network: > - make sure ipv4ll and dhcp clients can handle changing mac addresses > while running > diff --git a/man/systemd.network.xml b/man/systemd.network.xml > index f3b3b31..f49de17 100644 > --- a/man/systemd.network.xml > +++ b/man/systemd.network.xml > @@ -192,8 +192,9 @@ > > <term><varname>IPv4LL=</varname></term> > <listitem> > <para>A boolean. When true, > enables IPv4 link-local support. > - If <literal>DHCP=</literal> > is also true, IPv4 link-local > - address will be removed upon > acquiring a DHCP lease. > + If <literal>DHCP=</literal> > is also true, acquiring DHCP address > + will deprecate previously > acquired IPv4 link-local address or > + stop acquiring process if > there hasn't been one acquired before. > </para> > </listitem> > </varlistentry> > diff --git a/src/libsystemd-network/sd-ipv4ll.c > b/src/libsystemd-network/sd-ipv4ll.c > index a201139..81fe85b 100644 > --- a/src/libsystemd-network/sd-ipv4ll.c > +++ b/src/libsystemd-network/sd-ipv4ll.c > @@ -481,6 +481,12 @@ error: > return r; > } > > +bool sd_ipv4ll_is_running(sd_ipv4ll *ll) { > + assert_return(ll, -EINVAL); > + > + return ll->state != IPV4LL_STATE_INIT; > +} > + > #define HASH_KEY > SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2) > > int sd_ipv4ll_start (sd_ipv4ll *ll) { > diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c > b/src/libsystemd/sd-rtnl/rtnl-message.c > index 4ace94c..e5854de 100644 > --- a/src/libsystemd/sd-rtnl/rtnl-message.c > +++ b/src/libsystemd/sd-rtnl/rtnl-message.c > @@ -286,6 +286,19 @@ int sd_rtnl_message_new_addr(sd_rtnl *rtnl, > sd_rtnl_message **ret, > return 0; > } > > +int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret, > + int index, unsigned char family) { > + int r; > + > + r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family); > + if (r < 0) > + return r; > + > + (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE; > + > + return 0; > +} > + > sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) { > if (m) > assert_se(REFCNT_INC(m->n_ref) >= 2); > @@ -559,6 +572,24 @@ int sd_rtnl_message_append_ether_addr(sd_rtnl_message > *m, unsigned short type, c > return 0; > } > > +int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short > type, const struct ifa_cacheinfo *info) { > + int r; > + > + assert_return(m, -EINVAL); > + assert_return(!m->sealed, -EPERM); > + assert_return(info, -EINVAL); > + > + r = message_attribute_has_type(m, type, NLA_CACHE_INFO); > + if (r < 0) > + return r; > + > + r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo)); > + if (r < 0) > + return r; > + > + return 0; > +} > + > int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) { > size_t size; > int r; > @@ -741,6 +772,25 @@ int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, > unsigned short type, str > return 0; > } > > +int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, > struct ifa_cacheinfo *info) { > + int r; > + void *attr_data; > + > + r = message_attribute_has_type(m, type, NLA_CACHE_INFO); > + if (r < 0) > + return r; > + > + r = rtnl_message_read_internal(m, type, &attr_data); > + if (r < 0) > + return r; > + else if ((size_t)r < sizeof(struct ifa_cacheinfo)) > + return -EIO; > + > + memcpy(info, attr_data, sizeof(struct ifa_cacheinfo)); > + > + return 0; > +} > + > int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, > struct in_addr *data) { > int r; > void *attr_data; > diff --git a/src/libsystemd/sd-rtnl/rtnl-types.c > b/src/libsystemd/sd-rtnl/rtnl-types.c > index 29ee5bc..4e70c95 100644 > --- a/src/libsystemd/sd-rtnl/rtnl-types.c > +++ b/src/libsystemd/sd-rtnl/rtnl-types.c > @@ -216,9 +216,9 @@ static const NLType rtnl_address_types[IFA_MAX + 1] = { > [IFA_LOCAL] = { .type = NLA_IN_ADDR }, > [IFA_LABEL] = { .type = NLA_STRING, .size = IFNAMSIZ - 1 > }, > [IFA_BROADCAST] = { .type = NLA_IN_ADDR }, /* 6? */ > + [IFA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = > sizeof(struct ifa_cacheinfo) }, > /* > [IFA_ANYCAST], > - [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, > [IFA_MULTICAST], > */ > #ifdef IFA_FLAGS > diff --git a/src/libsystemd/sd-rtnl/rtnl-types.h > b/src/libsystemd/sd-rtnl/rtnl-types.h > index 2425dc9..7ce9597 100644 > --- a/src/libsystemd/sd-rtnl/rtnl-types.h > +++ b/src/libsystemd/sd-rtnl/rtnl-types.h > @@ -31,6 +31,7 @@ enum { > NLA_STRING, > NLA_IN_ADDR, > NLA_ETHER_ADDR, > + NLA_CACHE_INFO, > NLA_NESTED, > NLA_UNION, > }; > diff --git a/src/libsystemd/sd-rtnl/test-rtnl.c > b/src/libsystemd/sd-rtnl/test-rtnl.c > index 4436962..529231a 100644 > --- a/src/libsystemd/sd-rtnl/test-rtnl.c > +++ b/src/libsystemd/sd-rtnl/test-rtnl.c > @@ -106,6 +106,7 @@ static void test_address_get(sd_rtnl *rtnl, int ifindex) { > sd_rtnl_message *m; > sd_rtnl_message *r; > struct in_addr in_data; > + struct ifa_cacheinfo cache; > char *label; > > assert_se(sd_rtnl_message_new_addr(rtnl, &m, RTM_GETADDR, ifindex, > AF_INET) >= 0); > @@ -116,6 +117,7 @@ static void test_address_get(sd_rtnl *rtnl, int ifindex) { > assert_se(sd_rtnl_message_read_in_addr(r, IFA_LOCAL, &in_data) == 0); > assert_se(sd_rtnl_message_read_in_addr(r, IFA_ADDRESS, &in_data) == > 0); > assert_se(sd_rtnl_message_read_string(r, IFA_LABEL, &label) == 0); > + assert_se(sd_rtnl_message_read_cache_info(r, IFA_CACHEINFO, &cache) > == 0); > > assert_se(sd_rtnl_flush(rtnl) >= 0); > assert_se((m = sd_rtnl_message_unref(m)) == NULL); > diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c > index dd4c822..87688a5 100644 > --- a/src/network/networkd-address.c > +++ b/src/network/networkd-address.c > @@ -28,6 +28,15 @@ > #include "conf-parser.h" > #include "network-internal.h" > > +static void address_init(Address *address) { > + assert(address); > + > + address->family = AF_UNSPEC; > + address->scope = RT_SCOPE_UNIVERSE; > + address->cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME; > + address->cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME; > +} > + > int address_new_static(Network *network, unsigned section, Address **ret) { > _cleanup_address_free_ Address *address = NULL; > > @@ -46,8 +55,7 @@ int address_new_static(Network *network, unsigned section, > Address **ret) { > if (!address) > return -ENOMEM; > > - address->family = AF_UNSPEC; > - address->scope = RT_SCOPE_UNIVERSE; > + address_init(address); > > address->network = network; > > @@ -71,8 +79,7 @@ int address_new_dynamic(Address **ret) { > if (!address) > return -ENOMEM; > > - address->family = AF_UNSPEC; > - address->scope = RT_SCOPE_UNIVERSE; > + address_init(address); > > *ret = address; > address = NULL; > @@ -140,6 +147,87 @@ int address_drop(Address *address, Link *link, > return 0; > } > > +int address_update(Address *address, Link *link, > + sd_rtnl_message_handler_t callback) { > + _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; > + int r; > + > + assert(address); > + assert(address->family == AF_INET || address->family == AF_INET6); > + assert(link->ifindex > 0); > + assert(link->manager); > + assert(link->manager->rtnl); > + > + r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req, > + link->ifindex, address->family); > + 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, address->scope); > + 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) > + r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, > &address->in_addr.in6); > + if (r < 0) { > + log_error("Could not append IFA_LOCAL attribute: %s", > + strerror(-r)); > + return r; > + } > + > + if (address->family == AF_INET) { > + r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, > &address->broadcast); > + if (r < 0) { > + log_error("Could not append IFA_BROADCAST attribute: > %s", > + strerror(-r)); > + return r; > + } > + } > + > + if (address->label) { > + r = sd_rtnl_message_append_string(req, IFA_LABEL, > address->label); > + if (r < 0) { > + log_error("Could not append IFA_LABEL attribute: %s", > + strerror(-r)); > + return r; > + } > + } > + > + r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO, > &address->cinfo); > + if (r < 0) { > + log_error("Could not append IFA_CACHEINFO attribute: %s", > + strerror(-r)); > + return r; > + } > + > + r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, > NULL); > + if (r < 0) { > + log_error("Could not send rtnetlink message: %s", > strerror(-r)); > + return r; > + } > + > + return 0; > +} > + > int address_configure(Address *address, Link *link, > sd_rtnl_message_handler_t callback) { > _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; > diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c > index 973755a..8ea8f10 100644 > --- a/src/network/networkd-link.c > +++ b/src/network/networkd-link.c > @@ -30,6 +30,9 @@ > > #include "dhcp-lease-internal.h" > > +static int ipv4ll_address_update(Link *link, bool deprecate); > +static bool ipv4ll_is_bound(sd_ipv4ll *ll); > + > int link_new(Manager *manager, struct udev_device *device, Link **ret) { > _cleanup_link_free_ Link *link = NULL; > const char *ifname; > @@ -168,7 +171,6 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message > *m, void *userdata) { > > static int link_enter_set_routes(Link *link) { > Route *rt; > - struct in_addr a; > int r; > > assert(link); > @@ -178,7 +180,7 @@ static int link_enter_set_routes(Link *link) { > link->state = LINK_STATE_SETTING_ROUTES; > > if (!link->network->static_routes && !link->dhcp_lease && > - (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < > 0)) > + (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false)) > return link_enter_configured(link); > > log_debug_link(link, "setting routes"); > @@ -345,7 +347,6 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message > *m, void *userdata) { > > static int link_enter_set_addresses(Link *link) { > Address *ad; > - struct in_addr a; > int r; > > assert(link); > @@ -355,7 +356,7 @@ static int link_enter_set_addresses(Link *link) { > link->state = LINK_STATE_SETTING_ADDRESSES; > > if (!link->network->static_addresses && !link->dhcp_lease && > - (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < > 0)) > + (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false)) > return link_enter_set_routes(link); > > log_debug_link(link, "setting addresses"); > @@ -456,6 +457,28 @@ static int link_enter_set_addresses(Link *link) { > return 0; > } > > +static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void > *userdata) { > + Link *link = userdata; > + int r; > + > + assert(m); > + assert(link); > + assert(link->ifname); > + > + if (link->state == LINK_STATE_FAILED) > + return 1; > + > + r = sd_rtnl_message_get_errno(m); > + if (r < 0 && r != -ENOENT) > + log_struct_link(LOG_WARNING, link, > + "MESSAGE=%s: could not update address: %s", > + link->ifname, strerror(-r), > + "ERRNO=%d", -r, > + NULL); > + > + return 0; > +} > + > static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void > *userdata) { > Link *link = userdata; > int r; > @@ -731,7 +754,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, > Link *link) { > > static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) { > Link *link = userdata; > - int r; > + int r = 0; > > assert(link); > assert(link->network); > @@ -770,7 +793,10 @@ static void dhcp_handler(sd_dhcp_client *client, int > event, void *userdata) { > } > > if (event == DHCP_EVENT_EXPIRED && > link->network->ipv4ll) { > - r = sd_ipv4ll_start (link->ipv4ll); > + if (!sd_ipv4ll_is_running(link->ipv4ll)) > + r = sd_ipv4ll_start(link->ipv4ll); > + else if (ipv4ll_is_bound(link->ipv4ll)) > + r = ipv4ll_address_update(link, > false); > if (r < 0) { > link_enter_failed(link); > return; > @@ -785,7 +811,10 @@ static void dhcp_handler(sd_dhcp_client *client, int > event, void *userdata) { > return; > } > if (link->ipv4ll) { > - r = sd_ipv4ll_stop(link->ipv4ll); > + if (ipv4ll_is_bound(link->ipv4ll)) > + r = ipv4ll_address_update(link, > true); > + else > + r = sd_ipv4ll_stop(link->ipv4ll); > if (r < 0) { > link_enter_failed(link); > return; > @@ -803,11 +832,44 @@ static void dhcp_handler(sd_dhcp_client *client, int > event, void *userdata) { > return; > } > > -static int ipv4ll_address_lost(sd_ipv4ll *ll, Link *link) { > +static int ipv4ll_address_update(Link *link, bool deprecate) { > + int r; > + struct in_addr addr; > + > + assert(link); > + > + r = sd_ipv4ll_get_address(link->ipv4ll, &addr); > + if (r >= 0) { > + _cleanup_address_free_ Address *address = NULL; > + > + log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u", > + deprecate ? "deprecate" : "approve", > + ADDRESS_FMT_VAL(addr)); > + > + r = address_new_dynamic(&address); > + if (r < 0) { > + log_error_link(link, "Could not allocate address: > %s", strerror(-r)); > + return r; > + } > + > + address->family = AF_INET; > + address->in_addr.in = addr; > + address->prefixlen = 16; > + address->scope = RT_SCOPE_LINK; > + address->cinfo.ifa_prefered = deprecate ? 0 : > CACHE_INFO_INFINITY_LIFE_TIME; > + address->broadcast.s_addr = address->in_addr.in.s_addr | > htonl(0xfffffffflu >> address->prefixlen); > + > + address_update(address, link, &address_update_handler); > + } > + > + return 0; > + > +} > + > +static int ipv4ll_address_lost(Link *link) { > int r; > struct in_addr addr; > > - assert(ll); > assert(link); > > r = sd_ipv4ll_get_address(link->ipv4ll, &addr); > @@ -848,6 +910,18 @@ static int ipv4ll_address_lost(sd_ipv4ll *ll, Link > *link) { > return 0; > } > > +static bool ipv4ll_is_bound(sd_ipv4ll *ll) { > + int r; > + struct in_addr addr; > + > + assert(ll); > + > + r = sd_ipv4ll_get_address(ll, &addr); > + if (r < 0) > + return false; > + return true; > +} > + > static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) { > struct in_addr address; > int r; > @@ -881,7 +955,7 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void > *userdata){ > switch(event) { > case IPV4LL_EVENT_STOP: > case IPV4LL_EVENT_CONFLICT: > - r = ipv4ll_address_lost(ll, link); > + r = ipv4ll_address_lost(link); > if (r < 0) { > link_enter_failed(link); > return; > diff --git a/src/network/networkd.h b/src/network/networkd.h > index 8144031..36902e3 100644 > --- a/src/network/networkd.h > +++ b/src/network/networkd.h > @@ -36,6 +36,8 @@ > #include "set.h" > #include "condition-util.h" > > +#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU > + > typedef struct NetDev NetDev; > typedef struct Network Network; > typedef struct Link Link; > @@ -150,6 +152,7 @@ struct Address { > char *label; > > struct in_addr broadcast; > + struct ifa_cacheinfo cinfo; > > union { > struct in_addr in; > @@ -335,6 +338,7 @@ int address_new_static(Network *network, unsigned > section, Address **ret); > int address_new_dynamic(Address **ret); > void address_free(Address *address); > int address_configure(Address *address, Link *link, > sd_rtnl_message_handler_t callback); > +int address_update(Address *address, Link *link, sd_rtnl_message_handler_t > callback); > int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t > callback); > > DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free); > diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h > index 6273c89..28405a1 100644 > --- a/src/systemd/sd-ipv4ll.h > +++ b/src/systemd/sd-ipv4ll.h > @@ -22,6 +22,7 @@ > along with systemd; If not, see <http://www.gnu.org/licenses/>. > ***/ > > +#include <stdbool.h> > #include <netinet/in.h> > #include <net/ethernet.h> > > @@ -42,10 +43,11 @@ int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr > *address); > int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata); > int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr); > int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index); > -int sd_ipv4ll_set_address_seed (sd_ipv4ll *ll, uint8_t seed[8]); > -int sd_ipv4ll_start (sd_ipv4ll *ll); > -int sd_ipv4ll_stop (sd_ipv4ll *ll); > -void sd_ipv4ll_free (sd_ipv4ll *ll); > -int sd_ipv4ll_new (sd_ipv4ll **ret); > +int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint8_t seed[8]); > +bool sd_ipv4ll_is_running(sd_ipv4ll *ll); > +int sd_ipv4ll_start(sd_ipv4ll *ll); > +int sd_ipv4ll_stop(sd_ipv4ll *ll); > +void sd_ipv4ll_free(sd_ipv4ll *ll); > +int sd_ipv4ll_new(sd_ipv4ll **ret); > > #endif > diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h > index 80e88e3..f7f7074 100644 > --- a/src/systemd/sd-rtnl.h > +++ b/src/systemd/sd-rtnl.h > @@ -68,6 +68,7 @@ int sd_rtnl_detach_event(sd_rtnl *nl); > > /* messages */ > int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t > msg_type, int index); > +int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret, > int index, unsigned char family); > int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t > msg_type, int index, > unsigned char family); > int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t > nlmsg_type, > @@ -99,6 +100,7 @@ int sd_rtnl_message_append_u32(sd_rtnl_message *m, > unsigned short type, uint32_t > int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, > const struct in_addr *data); > int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, > const struct in6_addr *data); > int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short > type, const struct ether_addr *data); > +int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short > type, const struct ifa_cacheinfo *info); > > int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type); > int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short > type, const char *key); > @@ -109,6 +111,7 @@ int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned > short type, uint8_t *da > int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, > uint16_t *data); > int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, > uint32_t *data); > int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, > struct ether_addr *data); > +int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, > struct ifa_cacheinfo *info); > int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, > struct in_addr *data); > int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, > struct in6_addr *data); > int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type); > -- > 1.7.10.4 > > _______________________________________________ > systemd-devel mailing list > systemd-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel