Commit f5507633 authored by Pavel Šimerda's avatar Pavel Šimerda
Browse files

platform: bridging and bonding options

parent 359dc35a
......@@ -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:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment