diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 816af0c17a..0b10a27df9 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -719,8 +719,18 @@ ip6_address_get_all (NMPlatform *platform, int ifindex) return addresses; } +static guint32 +get_time (void) +{ + struct timespec tp; + + clock_gettime (CLOCK_MONOTONIC, &tp); + + return tp.tv_sec; +} + static gboolean -ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) +ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, guint32 lifetime, guint32 preferred) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP4Address address; @@ -729,6 +739,9 @@ ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) address.ifindex = ifindex; address.address = addr; address.plen = plen; + address.timestamp = get_time (); + address.lifetime = lifetime; + address.preferred = preferred; g_array_append_val (priv->ip4_addresses, address); @@ -738,7 +751,7 @@ ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) } static gboolean -ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) +ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP6Address address; @@ -747,6 +760,9 @@ ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int pl address.ifindex = ifindex; address.address = addr; address.plen = plen; + address.timestamp = get_time (); + address.lifetime = lifetime; + address.preferred = preferred; g_array_append_val (priv->ip6_addresses, address); diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 3a005871ed..cfd237933a 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -614,6 +614,9 @@ init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr) address->ifindex = rtnl_addr_get_ifindex (rtnladdr); address->plen = rtnl_addr_get_prefixlen (rtnladdr); + address->timestamp = rtnl_addr_get_create_time (rtnladdr); + address->lifetime = rtnl_addr_get_valid_lifetime (rtnladdr); + address->preferred = rtnl_addr_get_preferred_lifetime (rtnladdr); g_assert (nl_addr_get_len (nladdr) == sizeof (address->address)); memcpy (&address->address, nl_addr_get_binary_addr (nladdr), sizeof (address->address)); } @@ -627,6 +630,9 @@ init_ip6_address (NMPlatformIP6Address *address, struct rtnl_addr *rtnladdr) address->ifindex = rtnl_addr_get_ifindex (rtnladdr); address->plen = rtnl_addr_get_prefixlen (rtnladdr); + address->timestamp = rtnl_addr_get_create_time (rtnladdr); + address->lifetime = rtnl_addr_get_valid_lifetime (rtnladdr); + address->preferred = rtnl_addr_get_preferred_lifetime (rtnladdr); g_assert (nl_addr_get_len (nladdr) == sizeof (address->address)); memcpy (&address->address, nl_addr_get_binary_addr (nladdr), sizeof (address->address)); } @@ -1985,7 +1991,7 @@ ip6_address_get_all (NMPlatform *platform, int ifindex) } static struct nl_object * -build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen) +build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 lifetime, guint32 preferred) { struct rtnl_addr *rtnladdr = rtnl_addr_alloc (); int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); @@ -1998,38 +2004,42 @@ build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen) nle = rtnl_addr_set_local (rtnladdr, nladdr); g_assert (!nle); rtnl_addr_set_prefixlen (rtnladdr, plen); + if (lifetime) { + rtnl_addr_set_valid_lifetime (rtnladdr, lifetime); + rtnl_addr_set_preferred_lifetime (rtnladdr, preferred); + } return (struct nl_object *) rtnladdr; } static gboolean -ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) +ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, guint32 lifetime, guint32 preferred) { - return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen)); + return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, lifetime, preferred)); } static gboolean -ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) +ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred) { - return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen)); + return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, lifetime, preferred)); } static gboolean ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) { - return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen)); + return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, 0, 0)); } static gboolean ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) { - return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen)); + return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, 0, 0)); } static gboolean ip_address_exists (NMPlatform *platform, int family, int ifindex, gconstpointer addr, int plen) { - auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, plen); + auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, plen, 0, 0); auto_nl_object struct nl_object *cached_object = nl_cache_search (choose_cache (platform, object), object); return !!cached_object; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 3a4a66539e..699d4d9aeb 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1064,12 +1064,14 @@ nm_platform_ip6_address_get_all (int ifindex) } gboolean -nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen) +nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, guint32 lifetime, guint32 preferred) { reset_error (); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen > 0, FALSE); + g_return_val_if_fail (lifetime > 0, FALSE); + g_return_val_if_fail (preferred >= 0, FALSE); g_return_val_if_fail (klass->ip4_address_add, FALSE); if (nm_platform_ip4_address_exists (ifindex, address, plen)) { @@ -1079,16 +1081,18 @@ nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen) } debug ("address: adding IPv4 address"); - return klass->ip4_address_add (platform, ifindex, address, plen); + return klass->ip4_address_add (platform, ifindex, address, plen, lifetime, preferred); } gboolean -nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen) +nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, guint32 lifetime, guint32 preferred) { reset_error (); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen > 0, FALSE); + g_return_val_if_fail (lifetime > 0, FALSE); + g_return_val_if_fail (preferred >= 0, FALSE); g_return_val_if_fail (klass->ip6_address_add, FALSE); if (nm_platform_ip6_address_exists (ifindex, address, plen)) { @@ -1098,7 +1102,7 @@ nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen) } debug ("address: adding IPv6 address"); - return klass->ip6_address_add (platform, ifindex, address, plen); + return klass->ip6_address_add (platform, ifindex, address, plen, lifetime, preferred); } gboolean @@ -1187,6 +1191,26 @@ array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address return FALSE; } +static guint32 +get_time (void) +{ + struct timespec tp; + + clock_gettime (CLOCK_MONOTONIC, &tp); + + return tp.tv_sec; +} + +/* Compute (a + b - c) in an overflow-safe manner. */ +static guint32 +addsubstract_guint32 (guint32 a, guint32 b, guint32 c) +{ + a = a > c ? a - c : 0; + a = a < G_MAXUINT32 - b ? a + b : G_MAXUINT32; + + return a; +} + /** * nm_platform_ip4_address_sync: * @ifindex: Interface index @@ -1204,6 +1228,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) GArray *addresses; NMPlatformIP4Address *address; const NMPlatformIP4Address *known_address; + guint32 now = get_time (); int i; /* Delete unknown addresses */ @@ -1224,9 +1249,21 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) for (i = 0; i < known_addresses->len; i++) { known_address = &g_array_index (known_addresses, NMPlatformIP4Address, i); - if (!nm_platform_ip4_address_exists (ifindex, known_address->address, known_address->plen)) - if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->plen)) + if (!nm_platform_ip4_address_exists (ifindex, known_address->address, known_address->plen)) { + guint32 lifetime, preferred; + + if (known_address->lifetime) { + guint32 shift = addsubstract_guint32 (now, 0, known_address->timestamp); + + /* Pad the lifetime by 5 seconds to avoid potential races. */ + lifetime = addsubstract_guint32 (known_address->lifetime, 5, shift); + preferred = addsubstract_guint32 (known_address->lifetime, 5, shift); + } else + lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; + + if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) return FALSE; + } } return TRUE; @@ -1249,6 +1286,7 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) GArray *addresses; NMPlatformIP6Address *address; const NMPlatformIP6Address *known_address; + guint32 now = get_time (); int i; /* Delete unknown addresses */ @@ -1273,9 +1311,21 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) for (i = 0; i < known_addresses->len; i++) { known_address = &g_array_index (known_addresses, NMPlatformIP6Address, i); - if (!nm_platform_ip6_address_exists (ifindex, known_address->address, known_address->plen)) - if (!nm_platform_ip6_address_add (ifindex, known_address->address, known_address->plen)) + if (!nm_platform_ip6_address_exists (ifindex, known_address->address, known_address->plen)) { + guint32 lifetime, preferred; + + if (known_address->lifetime) { + guint32 shift = addsubstract_guint32 (now, 0, known_address->timestamp); + + /* Pad the lifetime by 5 seconds to avoid potential races. */ + lifetime = addsubstract_guint32 (known_address->lifetime, 5, shift); + preferred = addsubstract_guint32 (known_address->lifetime, 5, shift); + } else + lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; + + if (!nm_platform_ip6_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) return FALSE; + } } return TRUE; diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index b29b564f78..dde754f904 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -103,16 +103,24 @@ typedef struct { guint mtu; } NMPlatformLink; +#define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32 + typedef struct { int ifindex; in_addr_t address; int plen; + guint32 timestamp; + guint32 lifetime; + guint32 preferred; } NMPlatformIP4Address; typedef struct { int ifindex; struct in6_addr address; int plen; + guint32 timestamp; + guint32 lifetime; + guint32 preferred; } NMPlatformIP6Address; typedef struct { @@ -255,8 +263,10 @@ typedef struct { GArray * (*ip4_address_get_all) (NMPlatform *, int ifindex); GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex); - gboolean (*ip4_address_add) (NMPlatform *, int ifindex, in_addr_t address, int plen); - gboolean (*ip6_address_add) (NMPlatform *, int ifindex, struct in6_addr address, int plen); + gboolean (*ip4_address_add) (NMPlatform *, int ifindex, in_addr_t address, int plen, + guint32 lifetime, guint32 preferred_lft); + gboolean (*ip6_address_add) (NMPlatform *, int ifindex, struct in6_addr address, int plen, + guint32 lifetime, guint32 preferred_lft); gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen); gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, int plen); gboolean (*ip4_address_exists) (NMPlatform *, int ifindex, in_addr_t address, int plen); @@ -372,8 +382,10 @@ gboolean nm_platform_gre_get_properties (int ifindex, NMPlatformGreProperties *p GArray *nm_platform_ip4_address_get_all (int ifindex); GArray *nm_platform_ip6_address_get_all (int ifindex); -gboolean nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen); -gboolean nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen); +gboolean nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, + guint32 lifetime, guint32 preferred_lft); +gboolean nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, + guint32 lifetime, guint32 preferred_lft); gboolean nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen); gboolean nm_platform_ip6_address_delete (int ifindex, struct in6_addr address, int plen); gboolean nm_platform_ip4_address_exists (int ifindex, in_addr_t address, int plen); diff --git a/src/platform/tests/dump.c b/src/platform/tests/dump.c index 9ffbba237c..5a7f6ee8fb 100644 --- a/src/platform/tests/dump.c +++ b/src/platform/tests/dump.c @@ -73,13 +73,13 @@ dump_interface (NMPlatformLink *link) for (i = 0; i < ip4_addresses->len; i++) { ip4_address = &g_array_index (ip4_addresses, NMPlatformIP4Address, i); inet_ntop (AF_INET, &ip4_address->address, addrstr, sizeof (addrstr)); - printf (" ip4-address %s/%d\n", addrstr, ip4_address->plen); + printf (" ip4-address %s/%d lifetime %u preferred %u\n", addrstr, ip4_address->plen, ip4_address->lifetime, ip4_address->preferred); } for (i = 0; i < ip6_addresses->len; i++) { ip6_address = &g_array_index (ip6_addresses, NMPlatformIP6Address, i); inet_ntop (AF_INET6, &ip6_address->address, addrstr, sizeof (addrstr)); - printf (" ip6-address %s/%d\n", addrstr, ip6_address->plen); + printf (" ip6-address %s/%d lifetime %u preferred %u\n", addrstr, ip6_address->plen, ip6_address->lifetime, ip6_address->preferred); } g_array_unref (ip4_addresses); diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c index a059966f84..8bb8ce35a5 100644 --- a/src/platform/tests/platform.c +++ b/src/platform/tests/platform.c @@ -511,14 +511,48 @@ typedef struct in6_addr ip6_t; #define parse_ip4_address(s, a, p) parse_ip_address (AF_INET, s, a, p) #define parse_ip6_address(s, a, p) parse_ip_address (AF_INET6, s, a, p) +static gboolean +do_ip4_address_add (char **argv) +{ + int ifindex = parse_ifindex (*argv++); + ip4_t address; + int plen; + + if (ifindex && parse_ip4_address (*argv++, &address, &plen)) { + guint32 lifetime = strtol (*argv++, NULL, 10); + guint32 preferred = strtol (*argv++, NULL, 10); + + gboolean value = nm_platform_ip4_address_add (ifindex, address, plen, lifetime, preferred); + return value; + } else + return FALSE; +} + +static gboolean +do_ip6_address_add (char **argv) +{ + int ifindex = parse_ifindex (*argv++); + ip6_t address; + int plen; + + if (ifindex && parse_ip6_address (*argv++, &address, &plen)) { + guint32 lifetime = strtol (*argv++, NULL, 10); + guint32 preferred = strtol (*argv++, NULL, 10); + + gboolean value = nm_platform_ip6_address_add (ifindex, address, plen, lifetime, preferred); + return value; + } else + return FALSE; +} + #define ADDR_CMD_FULL(v, cmdname, print) \ static gboolean \ do_##v##_address_##cmdname (char **argv) \ { \ - int ifindex = parse_ifindex (argv[0]); \ + int ifindex = parse_ifindex (*argv++); \ v##_t address; \ int plen; \ - if (ifindex && parse_##v##_address (argv[1], &address, &plen)) { \ + if (ifindex && parse_##v##_address (*argv++, &address, &plen)) { \ gboolean value = nm_platform_##v##_address_##cmdname (ifindex, address, plen); \ if (print) { \ print_boolean (value); \ @@ -531,7 +565,6 @@ typedef struct in6_addr ip6_t; #define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE) ADDR_CMD_FULL (ip6, cmdname, FALSE) #define ADDR_CMD_PRINT(cmdname) ADDR_CMD_FULL (ip4, cmdname, TRUE) ADDR_CMD_FULL (ip6, cmdname, TRUE) -ADDR_CMD (add) ADDR_CMD (delete) ADDR_CMD_PRINT (exists) @@ -590,7 +623,7 @@ do_ip4_route_add (char **argv) in_addr_t network, gateway; int plen, metric, mss; - parse_ip4_address (*argv++, &network, &plen); + parse_ip4_address (*argv++, &network, &plen); parse_ip4_address (*argv++, &gateway, NULL); metric = strtol (*argv++, NULL, 10); mss = strtol (*argv++, NULL, 10); @@ -605,7 +638,7 @@ do_ip6_route_add (char **argv) struct in6_addr network, gateway; int plen, metric, mss; - parse_ip6_address (*argv++, &network, &plen); + parse_ip6_address (*argv++, &network, &plen); parse_ip6_address (*argv++, &gateway, NULL); metric = strtol (*argv++, NULL, 10); mss = strtol (*argv++, NULL, 10); @@ -619,7 +652,7 @@ do_ip4_route_delete (char **argv) in_addr_t network; int plen, metric; - parse_ip4_address (*argv++, &network, &plen); + parse_ip4_address (*argv++, &network, &plen); metric = strtol (*argv++, NULL, 10); return nm_platform_ip4_route_delete (ifindex, network, plen, metric); @@ -632,7 +665,7 @@ do_ip6_route_delete (char **argv) struct in6_addr network; int plen, metric; - parse_ip6_address (*argv++, &network, &plen); + parse_ip6_address (*argv++, &network, &plen); metric = strtol (*argv++, NULL, 10); return nm_platform_ip6_route_delete (ifindex, network, plen, metric); @@ -645,7 +678,7 @@ do_ip4_route_exists (char **argv) in_addr_t network; int plen, metric; - parse_ip4_address (*argv++, &network, &plen); + parse_ip4_address (*argv++, &network, &plen); metric = strtol (*argv++, NULL, 10); print_boolean (nm_platform_ip4_route_exists (ifindex, network, plen, metric)); @@ -659,7 +692,7 @@ do_ip6_route_exists (char **argv) struct in6_addr network; int plen, metric; - parse_ip6_address (*argv++, &network, &plen); + parse_ip6_address (*argv++, &network, &plen); metric = strtol (*argv++, NULL, 10); print_boolean (nm_platform_ip6_route_exists (ifindex, network, plen, metric)); @@ -731,8 +764,8 @@ static const command_t commands[] = { "" }, { "ip4-address-get-all", "print all IPv4 addresses", do_ip4_address_get_all, 1, "" }, { "ip6-address-get-all", "print all IPv6 addresses", do_ip6_address_get_all, 1, "" }, - { "ip4-address-add", "add IPv4 address", do_ip4_address_add, 2, "
/" }, - { "ip6-address-add", "add IPv6 address", do_ip6_address_add, 2, "
/" }, + { "ip4-address-add", "add IPv4 address", do_ip4_address_add, 4, "
/ <>" }, + { "ip6-address-add", "add IPv6 address", do_ip6_address_add, 4, "
/ <>" }, { "ip4-address-delete", "delete IPv4 address", do_ip4_address_delete, 2, "
/" }, { "ip6-address-delete", "delete IPv6 address", do_ip6_address_delete, 2, diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index e896c077ca..99be977bd5 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -49,34 +49,35 @@ test_ip4_address (void) SignalData *address_removed = add_signal (NM_PLATFORM_IP4_ADDRESS_REMOVED, ip4_address_callback); int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); GArray *addresses; - NMPlatformIP4Address addrs[2]; + NMPlatformIP4Address *address; in_addr_t addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; inet_pton (AF_INET, IP4_ADDRESS, &addr); /* Add address */ g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); no_error (); - g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN)); + g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); no_error (); g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); no_error (); accept_signal (address_added); /* Add address again */ - g_assert (!nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN)); + g_assert (!nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); error (NM_PLATFORM_ERROR_EXISTS); /* Test address listing */ addresses = nm_platform_ip4_address_get_all (ifindex); g_assert (addresses); no_error (); - memset (addrs, 0, sizeof (addrs)); - addrs[0].ifindex = ifindex; - addrs[0].address = addr; - addrs[0].plen = IP4_PLEN; g_assert_cmpint (addresses->len, ==, 1); - g_assert (!memcmp (addresses->data, addrs, sizeof (addrs))); + address = &g_array_index (addresses, NMPlatformIP4Address, 0); + g_assert_cmpint (address->ifindex, ==, ifindex); + g_assert_cmphex (address->address, ==, addr); + g_assert_cmpint (address->plen, ==, IP4_PLEN); g_array_unref (addresses); /* Remove address */ @@ -100,34 +101,35 @@ test_ip6_address (void) SignalData *address_removed = add_signal (NM_PLATFORM_IP6_ADDRESS_REMOVED, ip6_address_callback); int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); GArray *addresses; - NMPlatformIP6Address addrs[2]; + NMPlatformIP6Address *address; struct in6_addr addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; inet_pton (AF_INET6, IP6_ADDRESS, &addr); /* Add address */ g_assert (!nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); no_error (); - g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN)); + g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); no_error (); g_assert (nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); no_error (); accept_signal (address_added); /* Add address again */ - g_assert (!nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN)); + g_assert (!nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); error (NM_PLATFORM_ERROR_EXISTS); /* Test address listing */ addresses = nm_platform_ip6_address_get_all (ifindex); g_assert (addresses); no_error (); - memset (addrs, 0, sizeof (addrs)); - addrs[0].ifindex = ifindex; - addrs[0].address = addr; - addrs[0].plen = IP6_PLEN; g_assert_cmpint (addresses->len, ==, 1); - g_assert (!memcmp (addresses->data, addrs, sizeof (addrs))); + address = &g_array_index (addresses, NMPlatformIP6Address, 0); + g_assert_cmpint (address->ifindex, ==, ifindex); + g_assert (!memcmp (&address->address, &addr, sizeof (addr))); + g_assert_cmpint (address->plen, ==, IP6_PLEN); g_array_unref (addresses); /* Remove address */ @@ -151,6 +153,8 @@ test_ip4_address_external (void) SignalData *address_removed = add_signal (NM_PLATFORM_IP4_ADDRESS_REMOVED, ip4_address_callback); int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); in_addr_t addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; inet_pton (AF_INET, IP4_ADDRESS, &addr); g_assert (ifindex > 0); @@ -161,7 +165,8 @@ test_ip4_address_external (void) g_assert (nm_platform_link_set_up (nm_platform_link_get_ifindex (DEVICE_NAME))); /* Add/delete notification */ - run_command ("ip address add %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME); + run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", + IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred); wait_signal (address_added); g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME); @@ -169,8 +174,9 @@ test_ip4_address_external (void) g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); /* Add/delete conflict */ - run_command ("ip address add %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME); - g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN)); + run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", + IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred); + g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); no_error (); g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); accept_signal (address_added); @@ -191,11 +197,14 @@ test_ip6_address_external (void) SignalData *address_removed = add_signal (NM_PLATFORM_IP6_ADDRESS_REMOVED, ip6_address_callback); int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); struct in6_addr addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; inet_pton (AF_INET6, IP6_ADDRESS, &addr); /* Add/delete notification */ - run_command ("ip address add %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME); + run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", + IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred); wait_signal (address_added); g_assert (nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); run_command ("ip address delete %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME); @@ -203,8 +212,9 @@ test_ip6_address_external (void) g_assert (!nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); /* Add/delete conflict */ - run_command ("ip address add %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME); - g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN)); + run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", + IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred); + g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); no_error (); g_assert (nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); accept_signal (address_added); diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 34f214eb45..095cef253b 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -19,6 +19,8 @@ test_cleanup_internal () struct in6_addr network6; int plen6 = 64; struct in6_addr gateway6; + int lifetime = NM_PLATFORM_LIFETIME_PERMANENT; + int preferred = NM_PLATFORM_LIFETIME_PERMANENT; int metric = 20; int mss = 1000; @@ -38,8 +40,8 @@ test_cleanup_internal () g_assert (ifindex > 0); /* Add routes and addresses */ - g_assert (nm_platform_ip4_address_add (ifindex, addr4, plen4)); - g_assert (nm_platform_ip6_address_add (ifindex, addr6, plen6)); + g_assert (nm_platform_ip4_address_add (ifindex, addr4, plen4, lifetime, preferred)); + g_assert (nm_platform_ip6_address_add (ifindex, addr6, plen6, lifetime, preferred)); g_assert (nm_platform_ip4_route_add (ifindex, gateway4, 32, INADDR_ANY, metric, mss)); g_assert (nm_platform_ip4_route_add (ifindex, network4, plen4, gateway4, metric, mss)); g_assert (nm_platform_ip4_route_add (ifindex, 0, 0, gateway4, metric, mss));