platform: support address labels for IPv4 addresses
This commit is contained in:
@@ -738,7 +738,8 @@ ip6_address_get_all (NMPlatform *platform, int ifindex)
|
||||
static gboolean
|
||||
ip4_address_add (NMPlatform *platform, int ifindex,
|
||||
in_addr_t addr, in_addr_t peer_addr,
|
||||
int plen, guint32 lifetime, guint32 preferred)
|
||||
int plen, guint32 lifetime, guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
|
||||
NMPlatformIP4Address address;
|
||||
@@ -752,6 +753,8 @@ ip4_address_add (NMPlatform *platform, int ifindex,
|
||||
address.timestamp = nm_utils_get_monotonic_timestamp_s ();
|
||||
address.lifetime = lifetime;
|
||||
address.preferred = preferred;
|
||||
if (label)
|
||||
g_strlcpy (address.label, label, sizeof (address.label));
|
||||
|
||||
for (i = 0; i < priv->ip4_addresses->len; i++) {
|
||||
NMPlatformIP4Address *item = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
|
||||
|
@@ -868,6 +868,7 @@ init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr)
|
||||
{
|
||||
struct nl_addr *nladdr = rtnl_addr_get_local (rtnladdr);
|
||||
struct nl_addr *nlpeer = rtnl_addr_get_peer (rtnladdr);
|
||||
const char *label;
|
||||
|
||||
g_return_val_if_fail (nladdr, FALSE);
|
||||
|
||||
@@ -890,6 +891,9 @@ init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr)
|
||||
}
|
||||
memcpy (&address->peer_address, nl_addr_get_binary_addr (nlpeer), sizeof (address->peer_address));
|
||||
}
|
||||
label = rtnl_addr_get_label (rtnladdr);
|
||||
if (label && *label)
|
||||
g_strlcpy (address->label, label, sizeof (address->label));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2783,7 +2787,8 @@ build_rtnl_addr (int family,
|
||||
int plen,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
guint flags)
|
||||
guint flags,
|
||||
const char *label)
|
||||
{
|
||||
struct rtnl_addr *rtnladdr = rtnl_addr_alloc ();
|
||||
int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr);
|
||||
@@ -2824,6 +2829,8 @@ build_rtnl_addr (int family,
|
||||
}
|
||||
if (flags)
|
||||
rtnl_addr_set_flags (rtnladdr, flags);
|
||||
if (label && *label)
|
||||
rtnl_addr_set_label (rtnladdr, label);
|
||||
|
||||
return (struct nl_object *) rtnladdr;
|
||||
}
|
||||
@@ -2835,11 +2842,13 @@ ip4_address_add (NMPlatform *platform,
|
||||
in_addr_t peer_addr,
|
||||
int plen,
|
||||
guint32 lifetime,
|
||||
guint32 preferred)
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr,
|
||||
peer_addr ? &peer_addr : NULL,
|
||||
plen, lifetime, preferred, 0));
|
||||
plen, lifetime, preferred, 0,
|
||||
label));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2854,25 +2863,26 @@ ip6_address_add (NMPlatform *platform,
|
||||
{
|
||||
return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr,
|
||||
IN6_IS_ADDR_UNSPECIFIED (&peer_addr) ? NULL : &peer_addr,
|
||||
plen, lifetime, preferred, flags));
|
||||
plen, lifetime, preferred, flags,
|
||||
NULL));
|
||||
}
|
||||
|
||||
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, NULL, plen, 0, 0, 0));
|
||||
return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, NULL, plen, 0, 0, 0, NULL));
|
||||
}
|
||||
|
||||
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, NULL, plen, 0, 0, 0));
|
||||
return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, NULL, plen, 0, 0, 0, NULL));
|
||||
}
|
||||
|
||||
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, NULL, plen, 0, 0, 0);
|
||||
auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, NULL, plen, 0, 0, 0, NULL);
|
||||
auto_nl_object struct nl_object *cached_object = nl_cache_search (choose_cache (platform, object), object);
|
||||
|
||||
return !!cached_object;
|
||||
|
@@ -1230,7 +1230,8 @@ nm_platform_ip4_address_add (int ifindex,
|
||||
in_addr_t peer_address,
|
||||
int plen,
|
||||
guint32 lifetime,
|
||||
guint32 preferred)
|
||||
guint32 preferred,
|
||||
const char *label)
|
||||
{
|
||||
reset_error ();
|
||||
|
||||
@@ -1238,6 +1239,7 @@ nm_platform_ip4_address_add (int ifindex,
|
||||
g_return_val_if_fail (plen > 0, FALSE);
|
||||
g_return_val_if_fail (lifetime > 0, FALSE);
|
||||
g_return_val_if_fail (klass->ip4_address_add, FALSE);
|
||||
g_return_val_if_fail (!label || strlen (label) < sizeof (((NMPlatformIP4Address *) NULL)->label), FALSE);
|
||||
|
||||
if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) {
|
||||
NMPlatformIP4Address addr = { 0 };
|
||||
@@ -1248,10 +1250,12 @@ nm_platform_ip4_address_add (int ifindex,
|
||||
addr.plen = plen;
|
||||
addr.lifetime = lifetime;
|
||||
addr.preferred = preferred;
|
||||
if (label)
|
||||
g_strlcpy (addr.label, label, sizeof (addr.label));
|
||||
|
||||
debug ("address: adding or updating IPv4 address: %s", nm_platform_ip4_address_to_string (&addr));
|
||||
}
|
||||
return klass->ip4_address_add (platform, ifindex, address, peer_address, plen, lifetime, preferred);
|
||||
return klass->ip4_address_add (platform, ifindex, address, peer_address, plen, lifetime, preferred, label);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1422,7 +1426,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses)
|
||||
} else
|
||||
lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||
|
||||
if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred))
|
||||
if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred, known_address->label))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1914,6 +1918,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address)
|
||||
char s_address[INET_ADDRSTRLEN];
|
||||
char s_peer[INET_ADDRSTRLEN];
|
||||
char str_dev[TO_STRING_DEV_BUF_SIZE];
|
||||
char str_label[32];
|
||||
char *str_peer = NULL;
|
||||
|
||||
g_return_val_if_fail (address, "(unknown)");
|
||||
@@ -1927,11 +1932,17 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address)
|
||||
|
||||
_to_string_dev (address->ifindex, str_dev, sizeof (str_dev));
|
||||
|
||||
g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d lft %u pref %u time %u%s%s src %s",
|
||||
if (*address->label)
|
||||
g_snprintf (str_label, sizeof (str_label), " label %s", address->label);
|
||||
else
|
||||
str_label[0] = 0;
|
||||
|
||||
g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d lft %u pref %u time %u%s%s%s src %s",
|
||||
s_address, address->plen, (guint)address->lifetime, (guint)address->preferred,
|
||||
(guint)address->timestamp,
|
||||
str_peer ? str_peer : "",
|
||||
str_dev,
|
||||
str_label,
|
||||
source_to_string (address->source));
|
||||
g_free (str_peer);
|
||||
return to_string_buffer;
|
||||
@@ -2092,6 +2103,13 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route)
|
||||
return (((a)->field) < ((b)->field)) ? -1 : 1; \
|
||||
} G_STMT_END
|
||||
|
||||
#define _CMP_FIELD_STR(a, b, field) \
|
||||
G_STMT_START { \
|
||||
int c = strcmp ((a)->field, (b)->field); \
|
||||
if (c != 0) \
|
||||
return c < 0 ? -1 : 1; \
|
||||
} G_STMT_END
|
||||
|
||||
#define _CMP_FIELD_MEMCMP(a, b, field) \
|
||||
G_STMT_START { \
|
||||
int c = memcmp (&((a)->field), &((b)->field), \
|
||||
@@ -2112,6 +2130,7 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A
|
||||
_CMP_FIELD (a, b, timestamp);
|
||||
_CMP_FIELD (a, b, lifetime);
|
||||
_CMP_FIELD (a, b, preferred);
|
||||
_CMP_FIELD_STR (a, b, label);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -156,6 +156,7 @@ typedef struct {
|
||||
guint32 timestamp;
|
||||
guint32 lifetime; /* seconds */
|
||||
guint32 preferred; /* seconds */
|
||||
char label[IFNAMSIZ];
|
||||
} NMPlatformIP4Address;
|
||||
|
||||
/**
|
||||
@@ -346,7 +347,8 @@ typedef struct {
|
||||
GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex);
|
||||
gboolean (*ip4_address_add) (NMPlatform *, int ifindex,
|
||||
in_addr_t address, in_addr_t peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft);
|
||||
guint32 lifetime, guint32 preferred_lft,
|
||||
const char *label);
|
||||
gboolean (*ip6_address_add) (NMPlatform *, int ifindex,
|
||||
struct in6_addr address, struct in6_addr peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft, guint flags);
|
||||
@@ -475,7 +477,8 @@ 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, in_addr_t peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft);
|
||||
guint32 lifetime, guint32 preferred_lft,
|
||||
const char *label);
|
||||
gboolean nm_platform_ip6_address_add (int ifindex,
|
||||
struct in6_addr address, struct in6_addr peer_address, int plen,
|
||||
guint32 lifetime, guint32 preferred_lft, guint flags);
|
||||
|
@@ -570,7 +570,7 @@ do_ip4_address_add (char **argv)
|
||||
guint32 lifetime = strtol (*argv++, NULL, 10);
|
||||
guint32 preferred = strtol (*argv++, NULL, 10);
|
||||
|
||||
gboolean value = nm_platform_ip4_address_add (ifindex, address, 0, plen, lifetime, preferred);
|
||||
gboolean value = nm_platform_ip4_address_add (ifindex, address, 0, plen, lifetime, preferred, NULL);
|
||||
return value;
|
||||
} else
|
||||
return FALSE;
|
||||
|
@@ -60,14 +60,14 @@ test_ip4_address (void)
|
||||
/* Add address */
|
||||
g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN));
|
||||
no_error ();
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
no_error ();
|
||||
g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN));
|
||||
no_error ();
|
||||
accept_signal (address_added);
|
||||
|
||||
/* Add address again (aka update) */
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
no_error ();
|
||||
accept_signal (address_changed);
|
||||
|
||||
@@ -183,7 +183,7 @@ test_ip4_address_external (void)
|
||||
/* Add/delete conflict */
|
||||
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, 0, IP4_PLEN, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
|
||||
no_error ();
|
||||
g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN));
|
||||
accept_signal (address_added);
|
||||
|
@@ -41,7 +41,7 @@ test_cleanup_internal ()
|
||||
g_assert (ifindex > 0);
|
||||
|
||||
/* Add routes and addresses */
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr4, 0, plen4, lifetime, preferred));
|
||||
g_assert (nm_platform_ip4_address_add (ifindex, addr4, 0, plen4, lifetime, preferred, NULL));
|
||||
g_assert (nm_platform_ip6_address_add (ifindex, addr6, in6addr_any, plen6, lifetime, preferred, flags));
|
||||
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));
|
||||
|
Reference in New Issue
Block a user