diff options
Diffstat (limited to 'src/core/devices/ovs')
| -rw-r--r-- | src/core/devices/ovs/nm-device-ovs-bridge.c | 28 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-device-ovs-interface.c | 58 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-device-ovs-port.c | 28 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-ovs-factory.c | 27 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-ovsdb.c | 80 |
5 files changed, 152 insertions, 69 deletions
diff --git a/src/core/devices/ovs/nm-device-ovs-bridge.c b/src/core/devices/ovs/nm-device-ovs-bridge.c index c9b1f4c6..c9736eeb 100644 --- a/src/core/devices/ovs/nm-device-ovs-bridge.c +++ b/src/core/devices/ovs/nm-device-ovs-bridge.c @@ -162,6 +162,11 @@ can_reapply_change(NMDevice *device, NM_SETTING_OVS_BRIDGE_STP_ENABLE); } + if (NM_IN_STRSET(setting_name, + NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + NM_SETTING_OVS_OTHER_CONFIG_SETTING_NAME)) + return TRUE; + return device_class->can_reapply_change(device, setting_name, s_old, s_new, diffs, error); } @@ -194,16 +199,15 @@ nm_device_ovs_bridge_class_init(NMDeviceOvsBridgeClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_BRIDGE_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(); - device_class->is_controller = TRUE; - device_class->get_type_description = get_type_description; - device_class->create_and_realize = create_and_realize; - device_class->unrealize = unrealize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->act_stage3_ip_config = act_stage3_ip_config; - device_class->ready_for_ip_config = ready_for_ip_config; - device_class->attach_port = attach_port; - device_class->detach_port = detach_port; - device_class->can_reapply_change = can_reapply_change; - device_class->can_reapply_change_ovs_external_ids = TRUE; - device_class->reapply_connection = nm_device_ovs_reapply_connection; + device_class->is_controller = TRUE; + device_class->get_type_description = get_type_description; + device_class->create_and_realize = create_and_realize; + device_class->unrealize = unrealize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->act_stage3_ip_config = act_stage3_ip_config; + device_class->ready_for_ip_config = ready_for_ip_config; + device_class->attach_port = attach_port; + device_class->detach_port = detach_port; + device_class->can_reapply_change = can_reapply_change; + device_class->reapply_connection = nm_device_ovs_reapply_connection; } diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 512aa5c3..922ed345 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -16,6 +16,8 @@ #include "nm-setting-ovs-bridge.h" #include "nm-setting-ovs-interface.h" #include "nm-setting-ovs-port.h" +#include "nm-setting-ovs-external-ids.h" +#include "nm-setting-ovs-other-config.h" #define _NMLOG_DEVICE_TYPE NMDeviceOvsInterface #include "devices/nm-device-logging.h" @@ -631,6 +633,28 @@ can_update_from_platform_link(NMDevice *device, const NMPlatformLink *plink) return !plink || nm_device_get_state(device) != NM_DEVICE_STATE_DEACTIVATING; } +static gboolean +can_reapply_change(NMDevice *device, + const char *setting_name, + NMSetting *s_old, + NMSetting *s_new, + GHashTable *diffs, + GError **error) +{ + NMDeviceClass *device_class = NM_DEVICE_CLASS(nm_device_ovs_interface_parent_class); + + if (NM_IN_STRSET(setting_name, + NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + NM_SETTING_OVS_OTHER_CONFIG_SETTING_NAME)) { + /* TODO: it's currently not possible to reapply those settings on OVS + * system interfaces because they have type != "ovs-interface" (e.g. + * "ethernet") */ + return TRUE; + } + + return device_class->can_reapply_change(device, setting_name, s_old, s_new, diffs, error); +} + /*****************************************************************************/ static void @@ -696,21 +720,21 @@ nm_device_ovs_interface_class_init(NMDeviceOvsInterfaceClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_INTERFACE_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_OPENVSWITCH); - device_class->can_auto_connect = can_auto_connect; - device_class->can_update_from_platform_link = can_update_from_platform_link; - device_class->deactivate = deactivate; - device_class->deactivate_async = deactivate_async; - device_class->get_type_description = get_type_description; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->is_available = is_available; - device_class->check_connection_compatible = check_connection_compatible; - device_class->link_changed = link_changed; - device_class->act_stage3_ip_config = act_stage3_ip_config; - device_class->ready_for_ip_config = ready_for_ip_config; - 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; - device_class->can_reapply_change_ovs_external_ids = TRUE; - device_class->reapply_connection = nm_device_ovs_reapply_connection; + device_class->can_auto_connect = can_auto_connect; + device_class->can_update_from_platform_link = can_update_from_platform_link; + device_class->deactivate = deactivate; + device_class->deactivate_async = deactivate_async; + device_class->get_type_description = get_type_description; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->is_available = is_available; + device_class->check_connection_compatible = check_connection_compatible; + device_class->link_changed = link_changed; + device_class->act_stage3_ip_config = act_stage3_ip_config; + device_class->ready_for_ip_config = ready_for_ip_config; + 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; + device_class->can_reapply_change = can_reapply_change; + device_class->reapply_connection = nm_device_ovs_reapply_connection; } diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c index e9928548..0e3ef92c 100644 --- a/src/core/devices/ovs/nm-device-ovs-port.c +++ b/src/core/devices/ovs/nm-device-ovs-port.c @@ -16,6 +16,8 @@ #include "nm-setting-connection.h" #include "nm-setting-ovs-port.h" #include "nm-setting-ovs-interface.h" +#include "nm-setting-ovs-external-ids.h" +#include "nm-setting-ovs-other-config.h" #include "nm-setting-wired.h" #define _NMLOG_DEVICE_TYPE NMDeviceOvsPort @@ -279,6 +281,11 @@ can_reapply_change(NMDevice *device, NM_SETTING_OVS_PORT_TRUNKS); } + if (NM_IN_STRSET(setting_name, + NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME, + NM_SETTING_OVS_OTHER_CONFIG_SETTING_NAME)) + return TRUE; + return device_class->can_reapply_change(device, setting_name, s_old, s_new, diffs, error); } @@ -311,15 +318,14 @@ nm_device_ovs_port_class_init(NMDeviceOvsPortClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_PORT_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(); - device_class->is_controller = TRUE; - device_class->get_type_description = get_type_description; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->act_stage3_ip_config = act_stage3_ip_config; - device_class->ready_for_ip_config = ready_for_ip_config; - device_class->attach_port = attach_port; - device_class->detach_port = detach_port; - device_class->can_reapply_change = can_reapply_change; - device_class->can_reapply_change_ovs_external_ids = TRUE; - device_class->reapply_connection = nm_device_ovs_reapply_connection; + device_class->is_controller = TRUE; + device_class->get_type_description = get_type_description; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->act_stage3_ip_config = act_stage3_ip_config; + device_class->ready_for_ip_config = ready_for_ip_config; + device_class->attach_port = attach_port; + device_class->detach_port = detach_port; + device_class->can_reapply_change = can_reapply_change; + device_class->reapply_connection = nm_device_ovs_reapply_connection; } diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c index 2ca1a0b5..4084356f 100644 --- a/src/core/devices/ovs/nm-ovs-factory.c +++ b/src/core/devices/ovs/nm-ovs-factory.c @@ -75,9 +75,6 @@ new_device_from_type(const char *name, NMDeviceType device_type) const char *type_desc; NMLinkType link_type = NM_LINK_TYPE_NONE; - if (nm_manager_get_device(NM_MANAGER_GET, name, device_type)) - return NULL; - if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE) { type = NM_TYPE_DEVICE_OVS_INTERFACE; type_desc = "Open vSwitch Interface"; @@ -89,6 +86,7 @@ new_device_from_type(const char *name, NMDeviceType device_type) type = NM_TYPE_DEVICE_OVS_BRIDGE; type_desc = "Open vSwitch Bridge"; } else { + _LOGT(name, NULL, "Unrecognized link type: %d", device_type); return NULL; } @@ -125,6 +123,11 @@ ovsdb_device_added(NMOvsdb *ovsdb, return; } + if (nm_manager_get_device(NM_MANAGER_GET, name, device_type)) { + _LOGT(name, NULL, "Device already registered with manager, skipping."); + return; + } + device = new_device_from_type(name, device_type); if (!device) return; @@ -288,23 +291,31 @@ create_device(NMDeviceFactory *self, { NMDeviceType device_type = NM_DEVICE_TYPE_UNKNOWN; const char *connection_type = NULL; + const char *connection_uuid = NULL; if (g_strcmp0(iface, "ovs-system") == 0) { *out_ignore = TRUE; return NULL; } - if (connection) + if (connection) { connection_type = nm_connection_get_connection_type(connection); + connection_uuid = nm_connection_get_uuid(connection); + } - if (plink) + if (plink) { + _LOGD(iface, connection_uuid, "creating OVS interface (from a platform link)"); device_type = NM_DEVICE_TYPE_OVS_INTERFACE; - else if (g_strcmp0(connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0) + } else if (nm_streq0(connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) { + _LOGD(iface, connection_uuid, "creating OVS interface (from setting)"); device_type = NM_DEVICE_TYPE_OVS_INTERFACE; - else if (g_strcmp0(connection_type, NM_SETTING_OVS_PORT_SETTING_NAME) == 0) + } else if (nm_streq0(connection_type, NM_SETTING_OVS_PORT_SETTING_NAME)) { + _LOGD(iface, connection_uuid, "creating OVS port (from setting)"); device_type = NM_DEVICE_TYPE_OVS_PORT; - else if (g_strcmp0(connection_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME) == 0) + } else if (nm_streq0(connection_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) { + _LOGD(iface, connection_uuid, "creating OVS bridge (from setting)"); device_type = NM_DEVICE_TYPE_OVS_BRIDGE; + } return new_device_from_type(iface, device_type); } diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index 2dbc842a..164bfd35 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -900,15 +900,17 @@ _insert_interface(json_t *params, s_ovs_patch = nm_connection_get_setting_ovs_patch(interface); if (s_ovs_dpdk) { - const char *devargs; - guint32 n_rxq; - guint32 n_rxq_desc; - guint32 n_txq_desc; + const char *devargs; + guint32 n_rxq; + guint32 n_rxq_desc; + guint32 n_txq_desc; + NMSettingOvsDpdkLscInterrupt lsc_int; devargs = nm_setting_ovs_dpdk_get_devargs(s_ovs_dpdk); n_rxq = nm_setting_ovs_dpdk_get_n_rxq(s_ovs_dpdk); n_rxq_desc = nm_setting_ovs_dpdk_get_n_rxq_desc(s_ovs_dpdk); n_txq_desc = nm_setting_ovs_dpdk_get_n_txq_desc(s_ovs_dpdk); + lsc_int = nm_setting_ovs_dpdk_get_lsc_interrupt(s_ovs_dpdk); dpdk_array = json_array(); @@ -930,6 +932,17 @@ _insert_interface(json_t *params, json_pack("[s,s]", "n_txq_desc", nm_sprintf_buf(sbuf, "%u", n_txq_desc))); } + switch (lsc_int) { + case NM_SETTING_OVS_DPDK_LSC_INTERRUPT_IGNORE: + break; + case NM_SETTING_OVS_DPDK_LSC_INTERRUPT_ENABLED: + json_array_append_new(dpdk_array, json_pack("[s,s]", "dpdk-lsc-interrupt", "true")); + break; + case NM_SETTING_OVS_DPDK_LSC_INTERRUPT_DISABLED: + json_array_append_new(dpdk_array, json_pack("[s,s]", "dpdk-lsc-interrupt", "false")); + break; + } + json_array_append_new(options, dpdk_array); } else if (s_ovs_patch) { @@ -1374,88 +1387,113 @@ _delete_interface(NMOvsdb *self, json_t *params, const char *ifname) nm_auto_decref_json json_t *bridges = NULL; nm_auto_decref_json json_t *new_bridges = NULL; gboolean bridges_changed; - gboolean ports_changed; - gboolean interfaces_changed; - int pi; - int ii; bridges = json_array(); new_bridges = json_array(); bridges_changed = FALSE; + /* Loop over all bridges */ g_hash_table_iter_init(&iter, priv->bridges); while (g_hash_table_iter_next(&iter, (gpointer) &ovs_bridge, NULL)) { - nm_auto_decref_json json_t *ports = NULL; - nm_auto_decref_json json_t *new_ports = NULL; + nm_auto_decref_json json_t *ports = NULL; + nm_auto_decref_json json_t *new_ports = NULL; + guint num_nm_ports = 0; + gboolean ports_changed = FALSE; + int pi; - ports = json_array(); - new_ports = json_array(); - ports_changed = FALSE; + ports = json_array(); + new_ports = json_array(); + /* Add the bridge UUID to the list of known bridges for the "expect" condition */ json_array_append_new(bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid)); + if (!ovs_bridge->connection_uuid) { + /* Externally created, don't touch it */ + json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid)); + continue; + } + + /* Loop over all bridge's ports */ for (pi = 0; pi < ovs_bridge->ports->len; pi++) { - nm_auto_decref_json json_t *interfaces = NULL; - nm_auto_decref_json json_t *new_interfaces = NULL; + nm_auto_decref_json json_t *interfaces = NULL; + nm_auto_decref_json json_t *new_interfaces = NULL; + guint num_nm_interfaces = 0; + gboolean interfaces_changed = FALSE; + int ii; interfaces = json_array(); new_interfaces = json_array(); port_uuid = g_ptr_array_index(ovs_bridge->ports, pi); ovs_port = g_hash_table_lookup(priv->ports, &port_uuid); + /* Add the port UUID to the list of known bridge port for the "expect" condition */ json_array_append_new(ports, json_pack("[s,s]", "uuid", port_uuid)); - interfaces_changed = FALSE; - if (!ovs_port) { /* This would be a violation of ovsdb's reference integrity (a bug). */ _LOGW("Unknown port '%s' in bridge '%s'", port_uuid, ovs_bridge->bridge_uuid); continue; } + /* Loop over all port's interfaces */ for (ii = 0; ii < ovs_port->interfaces->len; ii++) { interface_uuid = g_ptr_array_index(ovs_port->interfaces, ii); ovs_interface = g_hash_table_lookup(priv->interfaces, &interface_uuid); + /* Add the interface UUID to the list of known port interfaces for the "expect" condition */ json_array_append_new(interfaces, json_pack("[s,s]", "uuid", interface_uuid)); if (ovs_interface) { if (nm_streq(ovs_interface->name, ifname)) { - /* skip the interface */ + /* We are deleting this interface, don't count it */ interfaces_changed = TRUE; continue; } + if (ovs_interface->connection_uuid) + num_nm_interfaces++; } else { /* This would be a violation of ovsdb's reference integrity (a bug). */ _LOGW("Unknown interface '%s' in port '%s'", interface_uuid, port_uuid); } + /* Add the interface to the list of new interfaces to set on the port */ json_array_append_new(new_interfaces, json_pack("[s,s]", "uuid", interface_uuid)); } - if (json_array_size(new_interfaces) == 0) { + if (num_nm_interfaces == 0) { + /* The port no longer has any NM interface. Don't add it to "new_ports" and set + * ports_changed=TRUE, so that it will be deleted. */ ports_changed = TRUE; } else { if (interfaces_changed) { + /* An interface needs to be deleted from this port */ _expect_port_interfaces(params, ovs_port->name, interfaces); _set_port_interfaces(params, ovs_port->name, new_interfaces); } + /* The port is still alive */ json_array_append_new(new_ports, json_pack("[s,s]", "uuid", port_uuid)); + if (ovs_port->connection_uuid) + num_nm_ports++; } } - if (json_array_size(new_ports) == 0) { + if (num_nm_ports == 0) { + /* The bridge no longer has any NM port. Don't add it to "new_bridges" and set + * bridges_changed=TRUE, so that it will be deleted. */ bridges_changed = TRUE; } else { if (ports_changed) { + /* A port needs to be deleted from this bridge */ _expect_bridge_ports(params, ovs_bridge->name, ports); _set_bridge_ports(params, ovs_bridge->name, new_ports); } + /* The bridge is still alive */ json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid)); } } if (bridges_changed) { + /* A port needs to be deleted from this bridge */ _expect_ovs_bridges(params, priv->db_uuid, bridges); _set_ovs_bridges(params, priv->db_uuid, new_bridges); } @@ -2211,7 +2249,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) ovs_bridge->connection_uuid, ""), (strtmp1 = _strdict_to_string(ovs_bridge->external_ids)), - (strtmp2 = _strdict_to_string(ovs_bridge->external_ids))); + (strtmp2 = _strdict_to_string(ovs_bridge->other_config))); } } else { gs_free char *strtmp1 = NULL; |