platform: link address setting
This commit is contained in:
@@ -40,6 +40,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
NMPlatformLink link;
|
NMPlatformLink link;
|
||||||
|
|
||||||
|
GBytes *address;
|
||||||
int vlan_parent;
|
int vlan_parent;
|
||||||
int vlan_id;
|
int vlan_id;
|
||||||
} NMFakePlatformLink;
|
} NMFakePlatformLink;
|
||||||
@@ -123,6 +124,7 @@ link_init (NMFakePlatformLink *device, int ifindex, int type, const char *name)
|
|||||||
default:
|
default:
|
||||||
device->link.arp = TRUE;
|
device->link.arp = TRUE;
|
||||||
}
|
}
|
||||||
|
device->address = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NMFakePlatformLink *
|
static NMFakePlatformLink *
|
||||||
@@ -354,6 +356,35 @@ link_uses_arp (NMPlatform *platform, int ifindex)
|
|||||||
return device ? device->link.arp : FALSE;
|
return device ? device->link.arp : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t len)
|
||||||
|
{
|
||||||
|
NMFakePlatformLink *device = link_get (platform, ifindex);
|
||||||
|
|
||||||
|
if (device->address)
|
||||||
|
g_bytes_unref (device->address);
|
||||||
|
|
||||||
|
device->address = g_bytes_new (addr, len);
|
||||||
|
|
||||||
|
link_changed (platform, link_get (platform, ifindex));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gconstpointer
|
||||||
|
link_get_address (NMPlatform *platform, int ifindex, size_t *length)
|
||||||
|
{
|
||||||
|
NMFakePlatformLink *device = link_get (platform, ifindex);
|
||||||
|
|
||||||
|
if (!device || !device->address) {
|
||||||
|
if (length)
|
||||||
|
*length = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_bytes_get_data (device->address, length);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
link_supports_carrier_detect (NMPlatform *platform, int ifindex)
|
link_supports_carrier_detect (NMPlatform *platform, int ifindex)
|
||||||
{
|
{
|
||||||
@@ -896,8 +927,14 @@ static void
|
|||||||
nm_fake_platform_finalize (GObject *object)
|
nm_fake_platform_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (object);
|
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (object);
|
||||||
|
int i;
|
||||||
|
|
||||||
g_hash_table_unref (priv->options);
|
g_hash_table_unref (priv->options);
|
||||||
|
for (i = 0; i < priv->links->len; i++) {
|
||||||
|
NMFakePlatformLink *device = &g_array_index (priv->links, NMFakePlatformLink, i);
|
||||||
|
|
||||||
|
g_bytes_unref (device->address);
|
||||||
|
}
|
||||||
g_array_unref (priv->links);
|
g_array_unref (priv->links);
|
||||||
g_array_unref (priv->ip4_addresses);
|
g_array_unref (priv->ip4_addresses);
|
||||||
g_array_unref (priv->ip6_addresses);
|
g_array_unref (priv->ip6_addresses);
|
||||||
@@ -939,6 +976,9 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
|
|||||||
platform_class->link_is_connected = link_is_connected;
|
platform_class->link_is_connected = link_is_connected;
|
||||||
platform_class->link_uses_arp = link_uses_arp;
|
platform_class->link_uses_arp = link_uses_arp;
|
||||||
|
|
||||||
|
platform_class->link_set_address = link_set_address;
|
||||||
|
platform_class->link_get_address = link_get_address;
|
||||||
|
|
||||||
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
||||||
platform_class->link_supports_vlans = link_supports_vlans;
|
platform_class->link_supports_vlans = link_supports_vlans;
|
||||||
|
|
||||||
|
@@ -1108,6 +1108,37 @@ link_supports_vlans (NMPlatform *platform, int ifindex)
|
|||||||
return !(features->features[block].active & (1 << bit));
|
return !(features->features[block].active & (1 << bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size_t length)
|
||||||
|
{
|
||||||
|
auto_nl_object struct rtnl_link *change = NULL;
|
||||||
|
auto_nl_addr struct nl_addr *nladdr = NULL;
|
||||||
|
|
||||||
|
change = rtnl_link_alloc ();
|
||||||
|
g_return_val_if_fail (change, FALSE);
|
||||||
|
|
||||||
|
nladdr = nl_addr_build (AF_LLC, address, length);
|
||||||
|
g_return_val_if_fail (nladdr, FALSE);
|
||||||
|
|
||||||
|
rtnl_link_set_addr (change, nladdr);
|
||||||
|
|
||||||
|
return link_change (platform, ifindex, change);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gconstpointer
|
||||||
|
link_get_address (NMPlatform *platform, int ifindex, size_t *length)
|
||||||
|
{
|
||||||
|
auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex);
|
||||||
|
struct nl_addr *nladdr;
|
||||||
|
|
||||||
|
nladdr = rtnllink ? rtnl_link_get_addr (rtnllink) : NULL;
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
*length = nladdr ? nl_addr_get_len (nladdr) : 0;
|
||||||
|
|
||||||
|
return nladdr ? nl_addr_get_binary_addr (nladdr) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint32 vlan_flags)
|
vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint32 vlan_flags)
|
||||||
{
|
{
|
||||||
@@ -1740,6 +1771,9 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
|||||||
platform_class->link_is_connected = link_is_connected;
|
platform_class->link_is_connected = link_is_connected;
|
||||||
platform_class->link_uses_arp = link_uses_arp;
|
platform_class->link_uses_arp = link_uses_arp;
|
||||||
|
|
||||||
|
platform_class->link_get_address = link_get_address;
|
||||||
|
platform_class->link_set_address = link_set_address;
|
||||||
|
|
||||||
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
||||||
platform_class->link_supports_vlans = link_supports_vlans;
|
platform_class->link_supports_vlans = link_supports_vlans;
|
||||||
|
|
||||||
|
@@ -493,6 +493,48 @@ nm_platform_link_uses_arp (int ifindex)
|
|||||||
return klass->link_uses_arp (platform, ifindex);
|
return klass->link_uses_arp (platform, ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_platform_link_set_address:
|
||||||
|
* @ifindex: Interface index
|
||||||
|
* @address: The new MAC address
|
||||||
|
*
|
||||||
|
* Set interface MAC address.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
nm_platform_link_set_address (int ifindex, gconstpointer address, size_t length)
|
||||||
|
{
|
||||||
|
reset_error ();
|
||||||
|
|
||||||
|
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||||
|
g_return_val_if_fail (address, FALSE);
|
||||||
|
g_return_val_if_fail (length > 0, FALSE);
|
||||||
|
g_return_val_if_fail (klass->link_set_address, FALSE);
|
||||||
|
|
||||||
|
debug ("link: setting '%s' (%d) hardware address", nm_platform_link_get_name (ifindex), ifindex);
|
||||||
|
return klass->link_set_address (platform, ifindex, address, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_platform_link_get_address:
|
||||||
|
* @ifindex: Interface index
|
||||||
|
* @length: Pointer to a variable to store address length
|
||||||
|
*
|
||||||
|
* Saves interface hardware address to @address.
|
||||||
|
*/
|
||||||
|
gconstpointer
|
||||||
|
nm_platform_link_get_address (int ifindex, size_t *length)
|
||||||
|
{
|
||||||
|
reset_error ();
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
*length = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (ifindex > 0, NULL);
|
||||||
|
g_return_val_if_fail (klass->link_get_address, NULL);
|
||||||
|
|
||||||
|
return klass->link_get_address (platform, ifindex, length);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_platform_link_supports_carrier_detect (int ifindex)
|
nm_platform_link_supports_carrier_detect (int ifindex)
|
||||||
{
|
{
|
||||||
|
@@ -159,6 +159,9 @@ typedef struct {
|
|||||||
gboolean (*link_is_connected) (NMPlatform *, int ifindex);
|
gboolean (*link_is_connected) (NMPlatform *, int ifindex);
|
||||||
gboolean (*link_uses_arp) (NMPlatform *, int ifindex);
|
gboolean (*link_uses_arp) (NMPlatform *, int ifindex);
|
||||||
|
|
||||||
|
gconstpointer (*link_get_address) (NMPlatform *, int ifindex, size_t *length);
|
||||||
|
gboolean (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
|
||||||
|
|
||||||
gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex);
|
gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex);
|
||||||
gboolean (*link_supports_vlans) (NMPlatform *, int ifindex);
|
gboolean (*link_supports_vlans) (NMPlatform *, int ifindex);
|
||||||
|
|
||||||
@@ -261,6 +264,9 @@ gboolean nm_platform_link_is_up (int ifindex);
|
|||||||
gboolean nm_platform_link_is_connected (int ifindex);
|
gboolean nm_platform_link_is_connected (int ifindex);
|
||||||
gboolean nm_platform_link_uses_arp (int ifindex);
|
gboolean nm_platform_link_uses_arp (int ifindex);
|
||||||
|
|
||||||
|
gconstpointer nm_platform_link_get_address (int ifindex, size_t *length);
|
||||||
|
gboolean nm_platform_link_set_address (int ifindex, const void *address, size_t length);
|
||||||
|
|
||||||
gboolean nm_platform_link_supports_carrier_detect (int ifindex);
|
gboolean nm_platform_link_supports_carrier_detect (int ifindex);
|
||||||
gboolean nm_platform_link_supports_vlans (int ifindex);
|
gboolean nm_platform_link_supports_vlans (int ifindex);
|
||||||
|
|
||||||
|
@@ -21,6 +21,8 @@ dump_interface (NMPlatformLink *link)
|
|||||||
char networkstr[INET6_ADDRSTRLEN];
|
char networkstr[INET6_ADDRSTRLEN];
|
||||||
char gatewaystr[INET6_ADDRSTRLEN];
|
char gatewaystr[INET6_ADDRSTRLEN];
|
||||||
int vlan_id, vlan_parent;
|
int vlan_id, vlan_parent;
|
||||||
|
const char *address;
|
||||||
|
size_t addrlen;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_assert (link->up || !link->connected);
|
g_assert (link->up || !link->connected);
|
||||||
@@ -44,6 +46,14 @@ dump_interface (NMPlatformLink *link)
|
|||||||
if (nm_platform_link_supports_vlans (link->ifindex))
|
if (nm_platform_link_supports_vlans (link->ifindex))
|
||||||
printf (" feature vlans\n");
|
printf (" feature vlans\n");
|
||||||
|
|
||||||
|
address = nm_platform_link_get_address (link->ifindex, &addrlen);
|
||||||
|
if (address) {
|
||||||
|
printf (" link-address ");
|
||||||
|
for (i = 0; i < addrlen; i++)
|
||||||
|
printf ("%s%02hhx", i ? ":" : "", address[i]);
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
ip4_addresses = nm_platform_ip4_address_get_all (link->ifindex);
|
ip4_addresses = nm_platform_ip4_address_get_all (link->ifindex);
|
||||||
ip6_addresses = nm_platform_ip6_address_get_all (link->ifindex);
|
ip6_addresses = nm_platform_ip6_address_get_all (link->ifindex);
|
||||||
|
|
||||||
|
@@ -184,6 +184,52 @@ LINK_CMD_GET (is_up, boolean)
|
|||||||
LINK_CMD_GET (is_connected, boolean)
|
LINK_CMD_GET (is_connected, boolean)
|
||||||
LINK_CMD_GET (uses_arp, boolean)
|
LINK_CMD_GET (uses_arp, boolean)
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_link_set_address (char **argv)
|
||||||
|
{
|
||||||
|
int ifindex = parse_ifindex (*argv++);
|
||||||
|
char *hex = *argv++;
|
||||||
|
int hexlen = strlen (hex);
|
||||||
|
char address[hexlen/2];
|
||||||
|
char *endptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_assert (!(hexlen % 2));
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof (address); i++) {
|
||||||
|
char digit[3];
|
||||||
|
|
||||||
|
digit[0] = hex[2*i];
|
||||||
|
digit[1] = hex[2*i+1];
|
||||||
|
digit[2] = '\0';
|
||||||
|
|
||||||
|
address[i] = strtoul (digit, &endptr, 16);
|
||||||
|
g_assert (!*endptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nm_platform_link_set_address (ifindex, address, sizeof (address));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_link_get_address (char **argv)
|
||||||
|
{
|
||||||
|
int ifindex = parse_ifindex (*argv++);
|
||||||
|
const char *address;
|
||||||
|
size_t length;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
address = nm_platform_link_get_address (ifindex, &length);
|
||||||
|
|
||||||
|
if (!address || length <= 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
printf ("%02x", address[i]);
|
||||||
|
printf ("\n");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
LINK_CMD_GET (supports_carrier_detect, boolean)
|
LINK_CMD_GET (supports_carrier_detect, boolean)
|
||||||
LINK_CMD_GET (supports_vlans, boolean)
|
LINK_CMD_GET (supports_vlans, boolean)
|
||||||
|
|
||||||
@@ -546,6 +592,8 @@ static const command_t commands[] = {
|
|||||||
{ "link-is-up", "check if interface is up", do_link_is_up, 1, "<ifname/ifindex>" },
|
{ "link-is-up", "check if interface is up", do_link_is_up, 1, "<ifname/ifindex>" },
|
||||||
{ "link-is-connected", "check interface carrier", do_link_is_connected, 1, "<ifname/ifindex>" },
|
{ "link-is-connected", "check interface carrier", do_link_is_connected, 1, "<ifname/ifindex>" },
|
||||||
{ "link-uses-arp", "check whether interface uses arp", do_link_uses_arp, 1, "<ifname/ifindex>" },
|
{ "link-uses-arp", "check whether interface uses arp", do_link_uses_arp, 1, "<ifname/ifindex>" },
|
||||||
|
{ "link-get-address", "print link address", do_link_get_address, 1, "<ifname/ifindex>" },
|
||||||
|
{ "link-set-address", "set link address", do_link_set_address, 2, "<ifname/ifindex> <hex>" },
|
||||||
{ "link-supports-carrier-detect", "check whether interface supports carrier detect",
|
{ "link-supports-carrier-detect", "check whether interface supports carrier detect",
|
||||||
do_link_supports_carrier_detect, 1, "<ifname/ifindex>" },
|
do_link_supports_carrier_detect, 1, "<ifname/ifindex>" },
|
||||||
{ "link-supports-vlans", "check whether interface supports VLANs",
|
{ "link-supports-vlans", "check whether interface supports VLANs",
|
||||||
|
@@ -58,6 +58,8 @@ link_callback (NMPlatform *platform, int ifindex, NMPlatformLink *received, Sign
|
|||||||
static void
|
static void
|
||||||
test_bogus(void)
|
test_bogus(void)
|
||||||
{
|
{
|
||||||
|
size_t addrlen;
|
||||||
|
|
||||||
g_assert (!nm_platform_link_exists (BOGUS_NAME));
|
g_assert (!nm_platform_link_exists (BOGUS_NAME));
|
||||||
no_error ();
|
no_error ();
|
||||||
g_assert (!nm_platform_link_delete (BOGUS_IFINDEX));
|
g_assert (!nm_platform_link_delete (BOGUS_IFINDEX));
|
||||||
@@ -88,6 +90,12 @@ test_bogus(void)
|
|||||||
g_assert (!nm_platform_link_uses_arp (BOGUS_IFINDEX));
|
g_assert (!nm_platform_link_uses_arp (BOGUS_IFINDEX));
|
||||||
error (NM_PLATFORM_ERROR_NOT_FOUND);
|
error (NM_PLATFORM_ERROR_NOT_FOUND);
|
||||||
|
|
||||||
|
g_assert (!nm_platform_link_get_address (BOGUS_IFINDEX, &addrlen));
|
||||||
|
g_assert (!addrlen);
|
||||||
|
error (NM_PLATFORM_ERROR_NOT_FOUND);
|
||||||
|
g_assert (!nm_platform_link_get_address (BOGUS_IFINDEX, NULL));
|
||||||
|
error (NM_PLATFORM_ERROR_NOT_FOUND);
|
||||||
|
|
||||||
g_assert (!nm_platform_link_supports_carrier_detect (BOGUS_IFINDEX));
|
g_assert (!nm_platform_link_supports_carrier_detect (BOGUS_IFINDEX));
|
||||||
error (NM_PLATFORM_ERROR_NOT_FOUND);
|
error (NM_PLATFORM_ERROR_NOT_FOUND);
|
||||||
g_assert (!nm_platform_link_supports_vlans (BOGUS_IFINDEX));
|
g_assert (!nm_platform_link_supports_vlans (BOGUS_IFINDEX));
|
||||||
@@ -382,6 +390,9 @@ test_internal (void)
|
|||||||
SignalData *link_added = add_signal (NM_PLATFORM_LINK_ADDED, link_callback);
|
SignalData *link_added = add_signal (NM_PLATFORM_LINK_ADDED, link_callback);
|
||||||
SignalData *link_changed = add_signal (NM_PLATFORM_LINK_CHANGED, link_callback);
|
SignalData *link_changed = add_signal (NM_PLATFORM_LINK_CHANGED, link_callback);
|
||||||
SignalData *link_removed = add_signal (NM_PLATFORM_LINK_REMOVED, link_callback);
|
SignalData *link_removed = add_signal (NM_PLATFORM_LINK_REMOVED, link_callback);
|
||||||
|
const char mac[6] = { 0x00, 0xff, 0x11, 0xee, 0x22, 0xdd };
|
||||||
|
const char *address;
|
||||||
|
size_t addrlen;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
||||||
/* Check the functions for non-existent devices */
|
/* Check the functions for non-existent devices */
|
||||||
@@ -430,6 +441,15 @@ test_internal (void)
|
|||||||
g_assert (!nm_platform_link_supports_carrier_detect (ifindex));
|
g_assert (!nm_platform_link_supports_carrier_detect (ifindex));
|
||||||
g_assert (nm_platform_link_supports_vlans (ifindex));
|
g_assert (nm_platform_link_supports_vlans (ifindex));
|
||||||
|
|
||||||
|
/* Set MAC address */
|
||||||
|
g_assert (nm_platform_link_set_address (ifindex, mac, sizeof (mac)));
|
||||||
|
address = nm_platform_link_get_address (ifindex, &addrlen);
|
||||||
|
g_assert (addrlen == sizeof(mac));
|
||||||
|
g_assert (!memcmp (address, mac, addrlen));
|
||||||
|
address = nm_platform_link_get_address (ifindex, NULL);
|
||||||
|
g_assert (!memcmp (address, mac, addrlen));
|
||||||
|
accept_signal (link_changed);
|
||||||
|
|
||||||
/* Delete device */
|
/* Delete device */
|
||||||
g_assert (nm_platform_link_delete (ifindex));
|
g_assert (nm_platform_link_delete (ifindex));
|
||||||
no_error ();
|
no_error ();
|
||||||
|
Reference in New Issue
Block a user