From aba496a58acf9d9c61314de71353550e579f85ee Mon Sep 17 00:00:00 2001 From: Umut Tezduyar Lindskog Date: Wed, 2 Apr 2014 21:31:12 +0200 Subject: networkd: smooth transition from ipv4ll to dhcp address 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. --- src/libsystemd/sd-rtnl/rtnl-message.c | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/libsystemd/sd-rtnl/rtnl-message.c') diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c index 4ace94ce18..e5854de4c6 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; -- cgit v1.2.3-54-g00ecf