[systemd-devel] [PATCH] networkd: smooth transition from ipv4ll to dhcp address
Tom Gundersen
teg at jklm.no
Thu Apr 3 07:01:32 PDT 2014
Applied. Thanks!
Cheers,
Tom
On Wed, Apr 2, 2014 at 9:31 PM, Umut Tezduyar Lindskog
<umut.tezduyar at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
More information about the systemd-devel
mailing list