platform: bridging and bonding options
This commit is contained in:
@@ -389,6 +389,37 @@ link_get_master (NMPlatform *platform, int slave)
|
||||
return device->master;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
master_set_option (NMPlatform *platform, int master, const char *option, const char *value)
|
||||
{
|
||||
auto_g_free char *path = g_strdup_printf ("master:%d:%s", master, option);
|
||||
|
||||
return sysctl_set (platform, path, value);
|
||||
}
|
||||
|
||||
static char *
|
||||
master_get_option (NMPlatform *platform, int master, const char *option)
|
||||
{
|
||||
auto_g_free char *path = g_strdup_printf ("master:%d:%s", master, option);
|
||||
|
||||
return sysctl_get (platform, path);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
slave_set_option (NMPlatform *platform, int slave, const char *option, const char *value)
|
||||
{
|
||||
auto_g_free char *path = g_strdup_printf ("slave:%d:%s", slave, option);
|
||||
|
||||
return sysctl_set (platform, path, value);
|
||||
}
|
||||
|
||||
static char *
|
||||
slave_get_option (NMPlatform *platform, int slave, const char *option)
|
||||
{
|
||||
auto_g_free char *path = g_strdup_printf ("slave:%d:%s", slave, option);
|
||||
|
||||
return sysctl_get (platform, path);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
@@ -831,6 +862,10 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
|
||||
platform_class->link_enslave = link_enslave;
|
||||
platform_class->link_release = link_release;
|
||||
platform_class->link_get_master = link_get_master;
|
||||
platform_class->master_set_option = master_set_option;
|
||||
platform_class->master_get_option = master_get_option;
|
||||
platform_class->slave_set_option = slave_set_option;
|
||||
platform_class->slave_get_option = slave_get_option;
|
||||
|
||||
platform_class->ip4_address_get_all = ip4_address_get_all;
|
||||
platform_class->ip6_address_get_all = ip6_address_get_all;
|
||||
|
@@ -1072,6 +1072,88 @@ link_get_master (NMPlatform *platform, int slave)
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *
|
||||
link_option_path (int master, const char *category, const char *option)
|
||||
{
|
||||
const char *name = nm_platform_link_get_name (master);
|
||||
|
||||
if (!name || !category || !option)
|
||||
return NULL;
|
||||
|
||||
return g_strdup_printf ("/sys/class/net/%s/%s/%s", name, category, option);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
link_set_option (int master, const char *category, const char *option, const char *value)
|
||||
{
|
||||
auto_g_free char *path = link_option_path (master, category, option);
|
||||
|
||||
return path && nm_platform_sysctl_set (path, value);
|
||||
}
|
||||
|
||||
static char *
|
||||
link_get_option (int master, const char *category, const char *option)
|
||||
{
|
||||
auto_g_free char *path = link_option_path (master, category, option);
|
||||
|
||||
return path ? nm_platform_sysctl_get (path) : NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
master_category (NMPlatform *platform, int master)
|
||||
{
|
||||
switch (link_get_type (platform, master)) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
return "bridge";
|
||||
case NM_LINK_TYPE_BOND:
|
||||
return "bonding";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
slave_category (NMPlatform *platform, int slave)
|
||||
{
|
||||
int master = link_get_master (platform, slave);
|
||||
|
||||
if (master) {
|
||||
platform->error = NM_PLATFORM_ERROR_NOT_SLAVE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (link_get_type (platform, master)) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
return "brport";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
master_set_option (NMPlatform *platform, int master, const char *option, const char *value)
|
||||
{
|
||||
return link_set_option (master, master_category (platform, master), option, value);
|
||||
}
|
||||
|
||||
static char *
|
||||
master_get_option (NMPlatform *platform, int master, const char *option)
|
||||
{
|
||||
return link_get_option (master, master_category (platform, master), option);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
slave_set_option (NMPlatform *platform, int slave, const char *option, const char *value)
|
||||
{
|
||||
return link_set_option (slave, slave_category (platform, slave), option, value);
|
||||
}
|
||||
|
||||
static char *
|
||||
slave_get_option (NMPlatform *platform, int slave, const char *option)
|
||||
{
|
||||
return link_get_option (slave, slave_category (platform, slave), option);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static int
|
||||
@@ -1539,6 +1621,10 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
||||
platform_class->link_enslave = link_enslave;
|
||||
platform_class->link_release = link_release;
|
||||
platform_class->link_get_master = link_get_master;
|
||||
platform_class->master_set_option = master_set_option;
|
||||
platform_class->master_get_option = master_get_option;
|
||||
platform_class->slave_set_option = slave_set_option;
|
||||
platform_class->slave_get_option = slave_get_option;
|
||||
|
||||
platform_class->ip4_address_get_all = ip4_address_get_all;
|
||||
platform_class->ip6_address_get_all = ip6_address_get_all;
|
||||
|
@@ -663,6 +663,56 @@ nm_platform_team_add (const char *name)
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_TEAM);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_master_set_option (int ifindex, const char *option, const char *value)
|
||||
{
|
||||
reset_error ();
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (option, FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
g_return_val_if_fail (klass->master_set_option, FALSE);
|
||||
|
||||
return klass->master_set_option (platform, ifindex, option, value);
|
||||
}
|
||||
|
||||
char *
|
||||
nm_platform_master_get_option (int ifindex, const char *option)
|
||||
{
|
||||
reset_error ();
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (option, FALSE);
|
||||
g_return_val_if_fail (klass->master_set_option, FALSE);
|
||||
|
||||
return klass->master_get_option (platform, ifindex, option);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_slave_set_option (int ifindex, const char *option, const char *value)
|
||||
{
|
||||
reset_error ();
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (option, FALSE);
|
||||
g_return_val_if_fail (value, FALSE);
|
||||
g_return_val_if_fail (klass->slave_set_option, FALSE);
|
||||
|
||||
return klass->slave_set_option (platform, ifindex, option, value);
|
||||
}
|
||||
|
||||
char *
|
||||
nm_platform_slave_get_option (int ifindex, const char *option)
|
||||
{
|
||||
reset_error ();
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (option, FALSE);
|
||||
g_return_val_if_fail (klass->slave_set_option, FALSE);
|
||||
|
||||
return klass->slave_get_option (platform, ifindex, option);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
GArray *
|
||||
|
@@ -149,6 +149,10 @@ typedef struct {
|
||||
gboolean (*link_enslave) (NMPlatform *, int master, int slave);
|
||||
gboolean (*link_release) (NMPlatform *, int master, int slave);
|
||||
gboolean (*link_get_master) (NMPlatform *, int slave);
|
||||
gboolean (*master_set_option) (NMPlatform *, int ifindex, const char *option, const char *value);
|
||||
char * (*master_get_option) (NMPlatform *, int ifindex, const char *option);
|
||||
gboolean (*slave_set_option) (NMPlatform *, int ifindex, const char *option, const char *value);
|
||||
char * (*slave_get_option) (NMPlatform *, int ifindex, const char *option);
|
||||
|
||||
GArray * (*ip4_address_get_all) (NMPlatform *, int ifindex);
|
||||
GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex);
|
||||
@@ -256,6 +260,10 @@ gboolean nm_platform_link_supports_vlans (int ifindex);
|
||||
gboolean nm_platform_link_enslave (int master, int slave);
|
||||
gboolean nm_platform_link_release (int master, int slave);
|
||||
int nm_platform_link_get_master (int slave);
|
||||
gboolean nm_platform_master_set_option (int ifindex, const char *option, const char *value);
|
||||
char *nm_platform_master_get_option (int ifindex, const char *option);
|
||||
gboolean nm_platform_slave_set_option (int ifindex, const char *option, const char *value);
|
||||
char *nm_platform_slave_get_option (int ifindex, const char *option);
|
||||
|
||||
GArray *nm_platform_ip4_address_get_all (int ifindex);
|
||||
GArray *nm_platform_ip6_address_get_all (int ifindex);
|
||||
@@ -282,4 +290,16 @@ gboolean nm_platform_ip4_route_exists (int ifindex,
|
||||
gboolean nm_platform_ip6_route_exists (int ifindex,
|
||||
struct in6_addr network, int plen, struct in6_addr gateway, int metric);
|
||||
|
||||
#define auto_g_free __attribute__((cleanup(put_g_free)))
|
||||
static void __attribute__((unused))
|
||||
put_g_free (void *ptr)
|
||||
{
|
||||
gpointer *object = ptr;
|
||||
|
||||
if (object && *object) {
|
||||
g_free (*object);
|
||||
*object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NM_PLATFORM_H */
|
||||
|
@@ -120,6 +120,7 @@ test_slave (int master, int type, SignalData *link_added, SignalData *master_cha
|
||||
{
|
||||
int ifindex;
|
||||
SignalData *link_changed = add_signal ("link-changed", link_callback);
|
||||
char *value;
|
||||
|
||||
g_assert (virtual_add (type, SLAVE_NAME, link_added, link_changed));
|
||||
ifindex = nm_platform_link_get_ifindex (SLAVE_NAME);
|
||||
@@ -179,6 +180,20 @@ test_slave (int master, int type, SignalData *link_added, SignalData *master_cha
|
||||
accept_signal (link_changed);
|
||||
accept_signal (master_changed);
|
||||
|
||||
/* Set slave option */
|
||||
switch (type) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
g_assert (nm_platform_slave_set_option (ifindex, "priority", "789"));
|
||||
no_error ();
|
||||
value = nm_platform_slave_get_option (ifindex, "priority");
|
||||
no_error ();
|
||||
g_assert (!g_strcmp0 (value, "789"));
|
||||
g_free (value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Release */
|
||||
g_assert (nm_platform_link_release (master, ifindex));
|
||||
g_assert (nm_platform_link_get_master (ifindex) == 0); no_error ();
|
||||
@@ -201,6 +216,7 @@ static void
|
||||
test_virtual (NMLinkType link_type)
|
||||
{
|
||||
int ifindex;
|
||||
char *value;
|
||||
|
||||
SignalData *link_added = add_signal ("link-added", link_callback);
|
||||
SignalData *link_changed = add_signal ("link-changed", link_callback);
|
||||
@@ -228,6 +244,29 @@ test_virtual (NMLinkType link_type)
|
||||
g_assert (nm_platform_link_uses_arp (ifindex));
|
||||
accept_signal (link_changed);
|
||||
|
||||
/* Set master option */
|
||||
switch (link_type) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
g_assert (nm_platform_master_set_option (ifindex, "forward_delay", "789"));
|
||||
no_error ();
|
||||
value = nm_platform_master_get_option (ifindex, "forward_delay");
|
||||
no_error ();
|
||||
g_assert (!g_strcmp0 (value, "789"));
|
||||
g_free (value);
|
||||
break;
|
||||
case NM_LINK_TYPE_BOND:
|
||||
g_assert (nm_platform_master_set_option (ifindex, "mode", "active-backup"));
|
||||
no_error ();
|
||||
value = nm_platform_master_get_option (ifindex, "mode");
|
||||
no_error ();
|
||||
/* When reading back, the output looks slightly different. */
|
||||
g_assert (g_str_has_prefix (value, "active-backup"));
|
||||
g_free (value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enslave and release */
|
||||
switch (link_type) {
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
|
Reference in New Issue
Block a user