mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-21 10:14:41 +00:00
ovs, dpdk: fix creating ovs-interface when the ovs-bridge is netdev
When the ovs-bridge datapath is netdev, OpenvSwitch will not create a ovs-interface but a tun interface. The ovs-interface device must check all the link-change signals and check if the link type is tun and the interface name is the same than the device name. If so, the ovs-interface device will get the ifindex of the tun device. This allow NetworkManager to manage the interface properly, modifying MTU, configuring IPv4/IPv6 and others. Example: ``` 55: ovsbridge-port0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 9000 qdisc fq_codel state UNKNOWN group default qlen 1000 link/ether fa:fb:07:98:e0:c6 brd ff:ff:ff:ff:ff:ff inet 192.168.123.100/24 brd 192.168.123.255 scope global noprefixroute ovsbridge-port0 valid_lft forever preferred_lft forever inet6 fe80::9805:55c4:4c5f:da1c/64 scope link noprefixroute valid_lft forever preferred_lft forever ``` https://bugzilla.redhat.com/show_bug.cgi?id=2001792 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1179
This commit is contained in:
parent
f3be419719
commit
99a6c6eda6
|
@ -13,6 +13,7 @@
|
|||
#include "devices/nm-device-private.h"
|
||||
#include "nm-active-connection.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-ovs-bridge.h"
|
||||
#include "nm-setting-ovs-interface.h"
|
||||
#include "nm-setting-ovs-port.h"
|
||||
|
||||
|
@ -23,7 +24,10 @@
|
|||
|
||||
typedef struct {
|
||||
NMOvsdb *ovsdb;
|
||||
bool waiting_for_interface : 1;
|
||||
GSource *wait_link_idle_source;
|
||||
gulong wait_link_signal_id;
|
||||
int wait_link_ifindex;
|
||||
bool wait_link_is_waiting : 1;
|
||||
} NMDeviceOvsInterfacePrivate;
|
||||
|
||||
struct _NMDeviceOvsInterface {
|
||||
|
@ -115,10 +119,10 @@ link_changed(NMDevice *device, const NMPlatformLink *pllink)
|
|||
{
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(device);
|
||||
|
||||
if (!pllink || !priv->waiting_for_interface)
|
||||
if (!pllink || !priv->wait_link_is_waiting)
|
||||
return;
|
||||
|
||||
priv->waiting_for_interface = FALSE;
|
||||
priv->wait_link_is_waiting = FALSE;
|
||||
|
||||
if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG) {
|
||||
if (!nm_device_hw_addr_set_cloned(device,
|
||||
|
@ -199,17 +203,83 @@ ready_for_ip_config(NMDevice *device)
|
|||
return nm_device_get_ip_ifindex(device) > 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_ip_ifindex_tun(gpointer user_data)
|
||||
{
|
||||
NMDevice *device = user_data;
|
||||
NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE(device);
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
|
||||
|
||||
nm_clear_g_source_inst(&priv->wait_link_idle_source);
|
||||
|
||||
priv->wait_link_is_waiting = FALSE;
|
||||
nm_device_set_ip_ifindex(device, priv->wait_link_ifindex);
|
||||
|
||||
nm_device_devip_set_state(device, AF_INET, NM_DEVICE_IP_STATE_PENDING, NULL);
|
||||
nm_device_devip_set_state(device, AF_INET6, NM_DEVICE_IP_STATE_PENDING, NULL);
|
||||
nm_device_activate_schedule_stage3_ip_config(device, FALSE);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_netdev_tun_link_cb(NMPlatform *platform,
|
||||
int obj_type_i,
|
||||
int ifindex,
|
||||
NMPlatformLink *pllink,
|
||||
int change_type_i,
|
||||
NMDevice *device)
|
||||
{
|
||||
const NMPlatformSignalChangeType change_type = change_type_i;
|
||||
NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE(device);
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
|
||||
|
||||
if (change_type == NM_PLATFORM_SIGNAL_ADDED) {
|
||||
if (pllink->type == NM_LINK_TYPE_TUN
|
||||
&& nm_streq0(pllink->name, nm_device_get_iface(device))) {
|
||||
nm_clear_g_signal_handler(platform, &priv->wait_link_signal_id);
|
||||
|
||||
priv->wait_link_ifindex = ifindex;
|
||||
|
||||
priv->wait_link_idle_source = nm_g_idle_add_source(_set_ip_ifindex_tun, device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
act_stage3_ip_config(NMDevice *device, int addr_family)
|
||||
{
|
||||
NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE(device);
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
|
||||
NMActiveConnection *controller_act = NULL;
|
||||
NMSettingOvsBridge *s_ovs_bridge = NULL;
|
||||
NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE(device);
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
|
||||
|
||||
if (!_is_internal_interface(device)) {
|
||||
nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_READY, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* When the ovs-bridge controller is using netdev datapath, the interface
|
||||
* link created is a tun device instead of a ovs-interface. NetworkManager must
|
||||
* detect the creation of the tun link and attach the ifindex to the
|
||||
* ovs-interface device. */
|
||||
controller_act = NM_ACTIVE_CONNECTION(nm_device_get_act_request(device));
|
||||
if (controller_act && nm_device_get_ip_ifindex(device) <= 0 && priv->wait_link_signal_id == 0) {
|
||||
controller_act = nm_active_connection_get_master(controller_act);
|
||||
if (controller_act) {
|
||||
controller_act = nm_active_connection_get_master(controller_act);
|
||||
if (controller_act)
|
||||
s_ovs_bridge = nm_connection_get_setting_ovs_bridge(
|
||||
nm_active_connection_get_applied_connection(controller_act));
|
||||
if (s_ovs_bridge
|
||||
&& nm_streq0(nm_setting_ovs_bridge_get_datapath_type(s_ovs_bridge), "netdev"))
|
||||
priv->wait_link_signal_id = g_signal_connect(nm_device_get_platform(device),
|
||||
NM_PLATFORM_SIGNAL_LINK_CHANGED,
|
||||
G_CALLBACK(_netdev_tun_link_cb),
|
||||
self);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME(l3cfg): we should create the IP ifindex before stage3 start.
|
||||
*
|
||||
* For now it's here because when the ovs-interface enters stage3, then it's added to the
|
||||
|
@ -219,11 +289,15 @@ act_stage3_ip_config(NMDevice *device, int addr_family)
|
|||
* This should change. */
|
||||
if (nm_device_get_ip_ifindex(device) <= 0) {
|
||||
_LOGT(LOGD_DEVICE, "waiting for link to appear");
|
||||
priv->waiting_for_interface = TRUE;
|
||||
priv->wait_link_is_waiting = TRUE;
|
||||
nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_PENDING, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->wait_link_is_waiting = FALSE;
|
||||
nm_clear_g_source_inst(&priv->wait_link_idle_source);
|
||||
nm_clear_g_signal_handler(nm_device_get_platform(device), &priv->wait_link_signal_id);
|
||||
|
||||
if (!nm_device_hw_addr_set_cloned(device, nm_device_get_applied_connection(device), FALSE)) {
|
||||
nm_device_devip_set_failed(device, addr_family, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||
return;
|
||||
|
@ -244,7 +318,8 @@ deactivate(NMDevice *device)
|
|||
NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE(device);
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
|
||||
|
||||
priv->waiting_for_interface = FALSE;
|
||||
priv->wait_link_is_waiting = FALSE;
|
||||
nm_clear_g_source_inst(&priv->wait_link_idle_source);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -351,7 +426,7 @@ deactivate_async(NMDevice *device,
|
|||
.callback_user_data = callback_user_data,
|
||||
};
|
||||
|
||||
if (!priv->waiting_for_interface
|
||||
if (!priv->wait_link_is_waiting
|
||||
&& !nm_platform_link_get_by_ifname(nm_device_get_platform(device),
|
||||
nm_device_get_iface(device))) {
|
||||
_LOGT(LOGD_CORE, "deactivate: link not present, proceeding");
|
||||
|
@ -360,7 +435,9 @@ deactivate_async(NMDevice *device,
|
|||
return;
|
||||
}
|
||||
|
||||
if (priv->waiting_for_interface) {
|
||||
nm_clear_g_source_inst(&priv->wait_link_idle_source);
|
||||
|
||||
if (priv->wait_link_is_waiting) {
|
||||
/* At this point we have issued an INSERT and a DELETE
|
||||
* command for the interface to ovsdb. We don't know if
|
||||
* vswitchd will see the two updates or only one. We
|
||||
|
|
Loading…
Reference in a new issue