summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-03-26 22:31:44 +0100
committerThomas Haller <thaller@redhat.com>2020-08-17 18:10:34 +0200
commitbddbf5a5120b2f5bbaa217ed2ce8945d0bf9f69d (patch)
tree11c6015c69fec90439e54507a37c4749dbce34f2
parent0862893e3860487c6fd2c705ab8fa178c0d5da1c (diff)
parent9c6b7d1e665bf8d71982e4f9c411c4d073b9803f (diff)
downloadNetworkManager-bddbf5a5120b2f5bbaa217ed2ce8945d0bf9f69d.tar.gz
ovs: merge branch 'bg/ovs-interface-mtu-rh1808124'
https://bugzilla.redhat.com/show_bug.cgi?id=1807726 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/433 (cherry picked from commit 2da77547bafedd352d5c40f66ccd365c454c30d4) (cherry picked from commit f0b7cb60dd44060b10c9e2d64aeeba7d2143ca4d) (cherry picked from commit e62afcf0bd9172825294802ef13de8d55714ccc0)
-rw-r--r--src/devices/nm-device.c17
-rw-r--r--src/devices/nm-device.h2
-rw-r--r--src/devices/ovs/nm-device-ovs-interface.c39
-rw-r--r--src/devices/ovs/nm-ovsdb.c89
-rw-r--r--src/devices/ovs/nm-ovsdb.h3
5 files changed, 130 insertions, 20 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index f966ae6f4c..5b7015779c 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -9152,6 +9152,17 @@ _set_mtu (NMDevice *self, guint32 mtu)
}
}
+static gboolean
+set_platform_mtu (NMDevice *self, guint32 mtu)
+{
+ int r;
+
+ r = nm_platform_link_set_mtu (nm_device_get_platform (self),
+ nm_device_get_ip_ifindex (self),
+ mtu);
+ return (r != -NME_PL_CANT_SET_MTU);
+}
+
static void
_commit_mtu (NMDevice *self, const NMIP4Config *config)
{
@@ -9310,10 +9321,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config)
}
if (mtu_desired && mtu_desired != mtu_plat) {
- int r;
-
- r = nm_platform_link_set_mtu (nm_device_get_platform (self), ifindex, mtu_desired);
- if (r == -NME_PL_CANT_SET_MTU) {
+ if (!NM_DEVICE_GET_CLASS (self)->set_platform_mtu (self, mtu_desired)) {
anticipated_failure = TRUE;
success = FALSE;
_LOGW (LOGD_DEVICE, "mtu: failure to set MTU. %s",
@@ -16995,6 +17003,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->parent_changed_notify = parent_changed_notify;
klass->can_reapply_change = can_reapply_change;
klass->reapply_connection = reapply_connection;
+ klass->set_platform_mtu = set_platform_mtu;
obj_properties[PROP_UDI] =
g_param_spec_string (NM_DEVICE_UDI, "", "",
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 0eab3aca19..5a9339d03d 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -462,6 +462,8 @@ typedef struct _NMDeviceClass {
gboolean (* can_update_from_platform_link) (NMDevice *self, const NMPlatformLink *plink);
+ gboolean (* set_platform_mtu) (NMDevice *self, guint32 mtu);
+
/* Controls, whether to call act_stage2_config() callback also for assuming
* a device or for external activations. In this case, act_stage2_config() must
* take care not to touch the device's configuration. */
diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c
index 9c74ffd1c2..f2919b4881 100644
--- a/src/devices/ovs/nm-device-ovs-interface.c
+++ b/src/devices/ovs/nm-device-ovs-interface.c
@@ -134,6 +134,43 @@ _is_internal_interface (NMDevice *device)
return nm_streq (nm_setting_ovs_interface_get_interface_type (s_ovs_iface), "internal");
}
+static void
+set_platform_mtu_cb (GError *error, gpointer user_data)
+{
+ NMDevice *device = user_data;
+ NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device);
+
+ if ( error
+ && !g_error_matches (error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING)) {
+ _LOGW (LOGD_DEVICE, "could not change mtu of '%s': %s",
+ nm_device_get_iface (device), error->message);
+ }
+
+ g_object_unref (device);
+}
+
+static gboolean
+set_platform_mtu (NMDevice *device, guint32 mtu)
+{
+ /*
+ * If the MTU is not set in ovsdb, Open vSwitch will change
+ * the MTU of an internal interface to match the minimum of
+ * the other interfaces in the bridge.
+ */
+ /* FIXME(shutdown): the function should become cancellable so
+ * that it doesn't need to hold a reference to the device, and
+ * it can be stopped during shutdown.
+ */
+ if (_is_internal_interface (device)) {
+ nm_ovsdb_set_interface_mtu (nm_ovsdb_get (),
+ nm_device_get_ip_iface (device),
+ mtu, set_platform_mtu_cb,
+ g_object_ref (device));
+ }
+
+ return NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->set_platform_mtu (device, mtu);
+}
+
static NMActStageReturn
act_stage3_ip_config_start (NMDevice *device,
int addr_family,
@@ -364,4 +401,6 @@ nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass)
device_class->link_changed = link_changed;
device_class->act_stage3_ip_config_start = act_stage3_ip_config_start;
device_class->can_unmanaged_external_down = can_unmanaged_external_down;
+ device_class->set_platform_mtu = set_platform_mtu;
+ device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired;
}
diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c
index c85115201e..753f5f172a 100644
--- a/src/devices/ovs/nm-ovsdb.c
+++ b/src/devices/ovs/nm-ovsdb.c
@@ -118,6 +118,7 @@ typedef enum {
OVSDB_MONITOR,
OVSDB_ADD_INTERFACE,
OVSDB_DEL_INTERFACE,
+ OVSDB_SET_INTERFACE_MTU,
} OvsdbCommand;
typedef struct {
@@ -127,7 +128,10 @@ typedef struct {
OvsdbMethodCallback callback;
gpointer user_data;
union {
- char *ifname;
+ struct {
+ char *ifname;
+ guint32 mtu;
+ };
struct {
NMConnection *bridge;
NMConnection *port;
@@ -169,6 +173,13 @@ _call_trace (const char *comment, OvsdbMethodCall *call, json_t *msg)
msg ? ": " : "",
msg ? str : "");
break;
+ case OVSDB_SET_INTERFACE_MTU:
+ _LOGT ("%s: set-iface-mtu interface=%s%s%s mtu=%u",
+ comment, call->ifname,
+ msg ? ": " : "",
+ msg ? str : "",
+ call->mtu);
+ break;
}
if (msg)
@@ -187,7 +198,7 @@ ovsdb_call_method (NMOvsdb *self, OvsdbCommand command,
const char *ifname,
NMConnection *bridge, NMConnection *port, NMConnection *interface,
NMDevice *bridge_device, NMDevice *interface_device,
- OvsdbMethodCallback callback, gpointer user_data)
+ guint32 mtu, OvsdbMethodCallback callback, gpointer user_data)
{
NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self);
OvsdbMethodCall *call;
@@ -215,6 +226,10 @@ ovsdb_call_method (NMOvsdb *self, OvsdbCommand command,
case OVSDB_DEL_INTERFACE:
call->ifname = g_strdup (ifname);
break;
+ case OVSDB_SET_INTERFACE_MTU:
+ call->ifname = g_strdup (ifname);
+ call->mtu = mtu;
+ break;
}
_call_trace ("enqueue", call, NULL);
@@ -352,11 +367,20 @@ _insert_interface (json_t *params, NMConnection *interface, NMDevice *interface_
gs_free char *cloned_mac = NULL;
gs_free_error GError *error = NULL;
json_t *row;
+ guint32 mtu = 0;
s_ovs_iface = nm_connection_get_setting_ovs_interface (interface);
if (s_ovs_iface)
type = nm_setting_ovs_interface_get_interface_type (s_ovs_iface);
+ if (nm_streq0 (type, "internal")) {
+ NMSettingWired *s_wired;
+
+ s_wired = _nm_connection_get_setting (interface, NM_TYPE_SETTING_WIRED);
+ if (s_wired)
+ mtu = nm_setting_wired_get_mtu (s_wired);
+ }
+
if (!nm_device_hw_addr_get_cloned (interface_device,
interface,
FALSE,
@@ -389,6 +413,9 @@ _insert_interface (json_t *params, NMConnection *interface, NMDevice *interface_
if (cloned_mac)
json_object_set_new (row, "mac", json_string (cloned_mac));
+ if (mtu != 0)
+ json_object_set_new (row, "mtu_request", json_integer (mtu));
+
json_array_append_new (params,
json_pack ("{s:s, s:s, s:o, s:s}",
"op", "insert",
@@ -821,6 +848,22 @@ ovsdb_next_command (NMOvsdb *self)
"id", call->id,
"method", "transact", "params", params);
break;
+ case OVSDB_SET_INTERFACE_MTU:
+ params = json_array ();
+ json_array_append_new (params, json_string ("Open_vSwitch"));
+ json_array_append_new (params, _inc_next_cfg (priv->db_uuid));
+
+ json_array_append_new (params,
+ json_pack ("{s:s, s:s, s:{s: i}, s:[[s, s, s]]}",
+ "op", "update",
+ "table", "Interface",
+ "row", "mtu_request", call->mtu,
+ "where", "name", "==", call->ifname));
+
+ msg = json_pack ("{s:i, s:s, s:o}",
+ "id", call->id,
+ "method", "transact", "params", params);
+ break;
}
g_return_if_fail (msg);
@@ -1462,7 +1505,7 @@ ovsdb_try_connect (NMOvsdb *self)
/* Queue a monitor call before any other command, ensuring that we have an up
* to date view of existing bridged that we need for add and remove ops. */
ovsdb_call_method (self, OVSDB_MONITOR, NULL,
- NULL, NULL, NULL, NULL, NULL, _monitor_bridges_cb, NULL);
+ NULL, NULL, NULL, NULL, NULL, 0, _monitor_bridges_cb, NULL);
}
/*****************************************************************************/
@@ -1500,11 +1543,8 @@ out:
g_slice_free (OvsdbCall, call);
}
-void
-nm_ovsdb_add_interface (NMOvsdb *self,
- NMConnection *bridge, NMConnection *port, NMConnection *interface,
- NMDevice *bridge_device, NMDevice *interface_device,
- NMOvsdbCallback callback, gpointer user_data)
+static OvsdbCall *
+ovsdb_call_new (NMOvsdbCallback callback, gpointer user_data)
{
OvsdbCall *call;
@@ -1512,24 +1552,40 @@ nm_ovsdb_add_interface (NMOvsdb *self,
call->callback = callback;
call->user_data = user_data;
+ return call;
+}
+
+void
+nm_ovsdb_add_interface (NMOvsdb *self,
+ NMConnection *bridge, NMConnection *port, NMConnection *interface,
+ NMDevice *bridge_device, NMDevice *interface_device,
+ NMOvsdbCallback callback, gpointer user_data)
+{
ovsdb_call_method (self, OVSDB_ADD_INTERFACE, NULL,
bridge, port, interface,
bridge_device, interface_device,
- _transact_cb, call);
+ 0,
+ _transact_cb,
+ ovsdb_call_new (callback, user_data));
}
void
nm_ovsdb_del_interface (NMOvsdb *self, const char *ifname,
NMOvsdbCallback callback, gpointer user_data)
{
- OvsdbCall *call;
-
- call = g_slice_new (OvsdbCall);
- call->callback = callback;
- call->user_data = user_data;
-
ovsdb_call_method (self, OVSDB_DEL_INTERFACE, ifname,
- NULL, NULL, NULL, NULL, NULL, _transact_cb, call);
+ NULL, NULL, NULL, NULL, NULL, 0,
+ _transact_cb,
+ ovsdb_call_new (callback, user_data));
+}
+
+void nm_ovsdb_set_interface_mtu (NMOvsdb *self, const char *ifname, guint32 mtu,
+ NMOvsdbCallback callback, gpointer user_data)
+{
+ ovsdb_call_method (self, OVSDB_SET_INTERFACE_MTU, ifname,
+ NULL, NULL, NULL, NULL, NULL, mtu,
+ _transact_cb,
+ ovsdb_call_new (callback, user_data));
}
/*****************************************************************************/
@@ -1550,6 +1606,7 @@ _clear_call (gpointer data)
g_clear_object (&call->interface_device);
break;
case OVSDB_DEL_INTERFACE:
+ case OVSDB_SET_INTERFACE_MTU:
g_clear_pointer (&call->ifname, g_free);
break;
}
diff --git a/src/devices/ovs/nm-ovsdb.h b/src/devices/ovs/nm-ovsdb.h
index e7f9d71984..9552dcca32 100644
--- a/src/devices/ovs/nm-ovsdb.h
+++ b/src/devices/ovs/nm-ovsdb.h
@@ -48,4 +48,7 @@ void nm_ovsdb_add_interface (NMOvsdb *self,
void nm_ovsdb_del_interface (NMOvsdb *self, const char *ifname,
NMOvsdbCallback callback, gpointer user_data);
+void nm_ovsdb_set_interface_mtu (NMOvsdb *self, const char *ifname, guint32 mtu,
+ NMOvsdbCallback callback, gpointer user_data);
+
#endif /* __NETWORKMANAGER_OVSDB_H__ */