Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve address cache info: Fix wrong datatypes and apply various cleanups #752

Merged
merged 11 commits into from Jun 1, 2018
2 changes: 1 addition & 1 deletion autoip4/fsm.c
Expand Up @@ -186,7 +186,7 @@ ni_autoip_fsm_build_lease(ni_autoip_device_t *dev)
ni_route_create(16, &addr, NULL, 0, &lease->routes);

lease->state = NI_ADDRCONF_STATE_GRANTED;
lease->time_acquired = time(NULL);
ni_timer_get_time(&lease->acquired);
lease->uuid = dev->request.uuid;
lease->flags = dev->request.flags;

Expand Down
8 changes: 3 additions & 5 deletions client/compat.c
Expand Up @@ -2114,16 +2114,14 @@ __ni_compat_generate_static_address_list(xml_node_t *afnode, ni_address_t *addr_

/* We are applying static address, but at least valid_lft = infinite,
* preferred_lft = 0 is a valid case to apply deprecated addresses...
* A valid_lft = preferred_lft = 0 means unspecified / omit lifetimes.
*/
if (ap->ipv6_cache_info.valid_lft &&
ap->ipv6_cache_info.preferred_lft != NI_LIFETIME_INFINITE) {
if (ap->cache_info.preferred_lft != NI_LIFETIME_INFINITE) {
xml_node_t *cache_info = xml_node_new("cache-info", anode);
if (cache_info) {
xml_node_new_element_uint("valid-lifetime", cache_info,
ap->ipv6_cache_info.valid_lft);
ap->cache_info.valid_lft);
xml_node_new_element_uint("preferred-lifetime", cache_info,
ap->ipv6_cache_info.preferred_lft);
ap->cache_info.preferred_lft);
}
}
}
Expand Down
47 changes: 11 additions & 36 deletions client/ifstatus.c
Expand Up @@ -442,12 +442,16 @@ ni_ifstatus_show_addrs(ni_netdev_t *dev, ni_bool_t verbose)
if (ni_address_is_linklocal(ap) && !verbose)
continue;

if_printf("", "addr:", "%s %s/%u",
ni_addrfamily_type_to_name(ap->family),
ni_sockaddr_print(&ap->local_addr), ap->prefixlen);
if (verbose) {
ni_address_print(&buf, ap);
} else {
ni_stringbuf_printf(&buf, "%s %s/%u",
ni_addrfamily_type_to_name(ap->family),
ni_sockaddr_print(&ap->local_addr), ap->prefixlen);
}

if ((owner = ni_addrconf_type_to_name(ap->owner)))
printf(" [%s]", owner);
ni_stringbuf_printf(&buf, " [%s]", owner);
else
if (ap->family == AF_INET6 && ni_address_is_temporary(ap)) {
/*
Expand All @@ -458,40 +462,11 @@ ni_ifstatus_show_addrs(ni_netdev_t *dev, ni_bool_t verbose)
*/
if (ni_netdev_get_lease(dev, ap->family, NI_ADDRCONF_AUTOCONF)
&& (owner = ni_addrconf_type_to_name(NI_ADDRCONF_AUTOCONF)))
printf(" [%s]", owner);
}

if (verbose) {
ni_address_format_flags(&buf, ap->family, ap->flags, "|");
if (ap->family == AF_INET) {
if (buf.string) {
printf("\n");
if_printf("", " ", "%s", buf.string);
}
ni_stringbuf_destroy(&buf);
if (!ni_string_empty(ap->label) &&
!ni_string_eq(ap->label, dev->name))
printf(" label %s", ap->label);
} else
if (ap->family == AF_INET6) {
if (buf.string) {
printf("\n");
if_printf("", " ", "%s", buf.string);
}
ni_stringbuf_destroy(&buf);
if (ap->ipv6_cache_info.valid_lft != -1U) {
ni_stringbuf_printf(&buf, "%u",
ap->ipv6_cache_info.valid_lft);
ni_stringbuf_puts(&buf, "/");
ni_stringbuf_printf(&buf, "%u",
ap->ipv6_cache_info.preferred_lft);
printf(" lifetime %s", buf.string);
}
}
ni_stringbuf_destroy(&buf);
ni_stringbuf_printf(&buf, " [%s]", owner);
}

printf("\n");
if_printf("", "addr:", "%s\n", buf.string);
ni_stringbuf_destroy(&buf);
}
}

Expand Down
4 changes: 2 additions & 2 deletions client/suse/compat-suse.c
Expand Up @@ -4670,8 +4670,8 @@ __get_ipaddr_opts(const char *value, ni_address_t *ap)
preferred_lft = valid_lft;

if (preferred_lft != NI_LIFETIME_INFINITE) {
ap->ipv6_cache_info.valid_lft = valid_lft;
ap->ipv6_cache_info.preferred_lft = preferred_lft;
ap->cache_info.valid_lft = valid_lft;
ap->cache_info.preferred_lft = preferred_lft;
}

return ret;
Expand Down
3 changes: 1 addition & 2 deletions include/wicked/addrconf.h
Expand Up @@ -136,8 +136,7 @@ struct ni_addrconf_lease {

ni_uuid_t uuid;
int state;

unsigned int time_acquired;
struct timeval acquired;

unsigned int update;

Expand Down
13 changes: 11 additions & 2 deletions include/wicked/address.h
Expand Up @@ -30,6 +30,12 @@ typedef struct ni_sockaddr_array {
ni_sockaddr_t * data;
} ni_sockaddr_array_t;

typedef struct ni_address_cache_info {
struct timeval acquired;
unsigned int valid_lft;
unsigned int preferred_lft;
} ni_address_cache_info_t;

typedef struct ni_address {
unsigned int refcount;
struct ni_address * next;
Expand All @@ -47,7 +53,7 @@ typedef struct ni_address {
ni_sockaddr_t bcast_addr;
char * label;

ni_ipv6_cache_info_t ipv6_cache_info;
ni_address_cache_info_t cache_info;
} ni_address_t;

typedef struct ni_address_array {
Expand Down Expand Up @@ -113,6 +119,7 @@ extern void ni_address_free(ni_address_t *);
extern ni_bool_t ni_address_equal_ref(const ni_address_t *, const ni_address_t *);
extern ni_bool_t ni_address_equal_local_addr(const ni_address_t *, const ni_address_t *);
extern const char * ni_address_format_flags(ni_stringbuf_t *, unsigned int, unsigned int, const char *);
extern const char * ni_address_print(ni_stringbuf_t *, const ni_address_t *);
extern ni_bool_t ni_address_can_reach(const ni_address_t *laddr, const ni_sockaddr_t *gw);
extern ni_bool_t ni_address_is_loopback(const ni_address_t *laddr);
extern ni_bool_t ni_address_is_linklocal(const ni_address_t *laddr);
Expand Down Expand Up @@ -147,8 +154,10 @@ extern unsigned int ni_address_array_index(const ni_address_array_t *, const ni_
extern ni_address_t * ni_address_array_find_match(ni_address_array_t *, const ni_address_t *, unsigned int *,
ni_bool_t (*match)(const ni_address_t *, const ni_address_t *));

extern const char * ni_lifetime_print_valid(ni_stringbuf_t *, unsigned int);
extern const char * ni_lifetime_print_preferred(ni_stringbuf_t *, unsigned int);
extern unsigned int ni_lifetime_left(unsigned int, const struct timeval *, const struct timeval *);
extern void ni_ipv6_cache_info_rebase(ni_ipv6_cache_info_t *, const ni_ipv6_cache_info_t *,
extern void ni_address_cache_info_rebase(ni_address_cache_info_t *, const ni_address_cache_info_t *,
const struct timeval *);

#endif /* __WICKED_ADDRESS_H__ */
6 changes: 5 additions & 1 deletion include/wicked/ipv6.h
Expand Up @@ -58,13 +58,16 @@ struct ni_ipv6_ra_pinfo {
ni_bool_t on_link;
ni_bool_t autoconf;

ni_ipv6_cache_info_t lifetime;
struct timeval acquired;
unsigned int valid_lft;
unsigned int preferred_lft;
};

struct ni_ipv6_ra_rdnss {
ni_ipv6_ra_rdnss_t * next;

ni_sockaddr_t server;

struct timeval acquired;
unsigned int lifetime;
};
Expand All @@ -73,6 +76,7 @@ struct ni_ipv6_ra_dnssl {
ni_ipv6_ra_dnssl_t * next;

char * domain;

struct timeval acquired;
unsigned int lifetime;
};
Expand Down
2 changes: 0 additions & 2 deletions include/wicked/route.h
Expand Up @@ -84,8 +84,6 @@ struct ni_route {
unsigned int hoplimit;
unsigned int features;
unsigned int reordering;

ni_ipv6_cache_info_t ipv6_cache_info;
};

typedef struct ni_route_array ni_route_array_t;
Expand Down
6 changes: 0 additions & 6 deletions include/wicked/types.h
Expand Up @@ -150,12 +150,6 @@ typedef struct ni_int_range {
int min, max;
} ni_int_range_t;

typedef struct ni_ipv6_cache_info {
struct timeval acquired;
unsigned int valid_lft;
unsigned int preferred_lft;
} ni_ipv6_cache_info_t;

/*
* Prototypes for ipv6 devinfo RA details
*/
Expand Down
2 changes: 1 addition & 1 deletion schema/addrconf.xml
Expand Up @@ -22,7 +22,7 @@
<state type="builtin-addrconf-state"
description="State of the lease - usually GRANTED or RELEASED"/>

<acquired type="uint32"
<acquired type="int64"
description="Timestamp when the lease was acquired"/>
<update type="builtin-addrconf-update-mask"
description="This is a bitmap describing which system services should be configured through this lease" />
Expand Down
116 changes: 110 additions & 6 deletions src/address.c
Expand Up @@ -25,6 +25,7 @@
#include <wicked/logging.h>
#include <wicked/netinfo.h>
#include <wicked/socket.h>
#include <wicked/route.h>
#include "util_priv.h"

#define NI_ADDRESS_ARRAY_CHUNK 16
Expand All @@ -47,6 +48,8 @@ do_address_new(void)
ap = xcalloc(1, sizeof(*ap));
if (ap) {
ap->refcount = 1;
ap->cache_info.valid_lft = NI_LIFETIME_INFINITE;
ap->cache_info.preferred_lft = NI_LIFETIME_INFINITE;
}
return ap;
}
Expand Down Expand Up @@ -100,7 +103,7 @@ ni_address_copy(ni_address_t *dst, const ni_address_t *src)
dst->peer_addr = src->peer_addr;
dst->bcast_addr = src->bcast_addr;
dst->anycast_addr = src->anycast_addr;
dst->ipv6_cache_info = src->ipv6_cache_info;
dst->cache_info = src->cache_info;
ni_string_dup(&dst->label, src->label);
}
return FALSE;
Expand Down Expand Up @@ -206,6 +209,62 @@ ni_address_format_flags(ni_stringbuf_t *buf, unsigned int family,
return buf->string;
}

const char *
ni_address_print(ni_stringbuf_t *out, const ni_address_t *ap)
{
ni_stringbuf_t flags = NI_STRINGBUF_INIT_DYNAMIC;
ni_address_cache_info_t lft;
const char *beg, *ptr;

if (!out || !ap || ap->family == AF_UNSPEC)
return NULL;

beg = out->string;
if ((ptr = ni_addrfamily_type_to_name(ap->family)))
ni_stringbuf_printf(out, "%s", ptr);

if (ni_sockaddr_is_specified(&ap->local_addr)) {
ni_stringbuf_printf(out, " %s", ni_sockaddr_print(&ap->local_addr));
if (ap->prefixlen)
ni_stringbuf_printf(out, "/%u", ap->prefixlen);
} else
if (ni_sockaddr_is_specified(&ap->anycast_addr)) {
ni_stringbuf_printf(out, " anycast %s", ni_sockaddr_print(&ap->anycast_addr));
if (ap->prefixlen)
ni_stringbuf_printf(out, "/%u", ap->prefixlen);
}
if (ni_sockaddr_is_specified(&ap->peer_addr))
ni_stringbuf_printf(out, " peer %s", ni_sockaddr_print(&ap->peer_addr));
else
if (ni_sockaddr_is_specified(&ap->bcast_addr))
ni_stringbuf_printf(out, " brd %s", ni_sockaddr_print(&ap->local_addr));

if (ni_route_is_valid_scope(ap->scope) &&
(ptr = ni_route_scope_type_to_name(ap->scope)))
ni_stringbuf_printf(out, " scope %s", ptr);

if (ap->cache_info.preferred_lft == NI_LIFETIME_INFINITE)
ni_address_format_flags(&flags, ap->family, ap->flags | IFA_F_PERMANENT, NULL);
else
ni_address_format_flags(&flags, ap->family, ap->flags & ~IFA_F_PERMANENT, NULL);
if (flags.string)
ni_stringbuf_printf(out, " flags %s", flags.string);
ni_stringbuf_destroy(&flags);

if (ap->family == AF_INET && ap->label)
ni_stringbuf_printf(out, " label %s", ap->label);

ni_address_cache_info_rebase(&lft, &ap->cache_info, NULL);
if (lft.preferred_lft != NI_LIFETIME_INFINITE) {
ni_stringbuf_printf(out, " valid-lft ");
ni_lifetime_print_valid(out, lft.valid_lft);
ni_stringbuf_printf(out, " pref-lft ");
ni_lifetime_print_preferred(out, lft.preferred_lft);
}

return beg ? beg : out->string;
}

ni_bool_t
ni_address_is_loopback(const ni_address_t *laddr)
{
Expand Down Expand Up @@ -1491,8 +1550,51 @@ ni_link_address_is_invalid(const ni_hwaddr_t *hwa)
}

/*
* Adjust IPv6 lifetimes in address cache info
* Address, ... cache-info lifetime utils.
*/
static const ni_intmap_t ni_lifetime_valid_names_map[] = {
{ "infinite", NI_LIFETIME_INFINITE },
{ "expired", NI_LIFETIME_EXPIRED },

{ NULL, 0 }
};

static const ni_intmap_t ni_lifetime_preferred_names_map[] = {
{ "infinite", NI_LIFETIME_INFINITE },
{ "deprecated", NI_LIFETIME_EXPIRED },

{ NULL, 0 }
};

static const char *
ni_lifetime_print(ni_stringbuf_t *out, unsigned int lft, const ni_intmap_t *map)
{
const char *str;

if (out) {
str = map ? ni_format_uint_mapped(lft, map) : NULL;
if (str)
ni_stringbuf_puts(out, str);
else
ni_stringbuf_printf(out, "%u", lft);

return out->string;
}
return NULL;
}

const char *
ni_lifetime_print_valid(ni_stringbuf_t *out, unsigned int lft)
{
return ni_lifetime_print(out, lft, ni_lifetime_valid_names_map);
}

const char *
ni_lifetime_print_preferred(ni_stringbuf_t *out, unsigned int lft)
{
return ni_lifetime_print(out, lft, ni_lifetime_preferred_names_map);
}

unsigned int
ni_lifetime_left(unsigned int lifetime, const struct timeval *acquired, const struct timeval *current)
{
Expand Down Expand Up @@ -1525,7 +1627,7 @@ ni_lifetime_left(unsigned int lifetime, const struct timeval *acquired, const st
}

void
ni_ipv6_cache_info_rebase(ni_ipv6_cache_info_t *res, const ni_ipv6_cache_info_t *lft, const struct timeval *base)
ni_address_cache_info_rebase(ni_address_cache_info_t *res, const ni_address_cache_info_t *lft, const struct timeval *base)
{
#define rebase_lft(lft, dif) (lft -= lft > dif ? dif : lft)
struct timeval now, dif;
Expand All @@ -1535,7 +1637,9 @@ ni_ipv6_cache_info_rebase(ni_ipv6_cache_info_t *res, const ni_ipv6_cache_info_t
if (!timerisset(&lft->acquired))
return;

if (lft->valid_lft == -1U && lft->preferred_lft == -1U)
if (lft->valid_lft == NI_LIFETIME_INFINITE &&
(lft->preferred_lft == NI_LIFETIME_INFINITE ||
lft->preferred_lft == NI_LIFETIME_EXPIRED))
return;

if (!base || !timerisset(base))
Expand All @@ -1548,13 +1652,13 @@ ni_ipv6_cache_info_rebase(ni_ipv6_cache_info_t *res, const ni_ipv6_cache_info_t
timersub(&now, &lft->acquired, &dif);

res->acquired = now;
if (res->valid_lft == -1U)
if (res->valid_lft == NI_LIFETIME_INFINITE)
rebase_lft(res->preferred_lft, (unsigned long)dif.tv_sec);
else
if (rebase_lft(res->valid_lft, (unsigned long)dif.tv_sec))
rebase_lft(res->preferred_lft, (unsigned long)dif.tv_sec);
else
res->preferred_lft = 0;
res->preferred_lft = NI_LIFETIME_EXPIRED;
#undef rebase_lft
}