Blame src/core/devices/nm-device-macsec.c

Packit Service 5ffa24
/* SPDX-License-Identifier: GPL-2.0-or-later */
Packit Service 5ffa24
/*
Packit Service 5ffa24
 * Copyright (C) 2017 Red Hat, Inc.
Packit Service 5ffa24
 */
Packit Service 5ffa24
Packit Service 2bceb2
#include "src/core/nm-default-daemon.h"
Packit Service 5ffa24
Packit Service 5ffa24
#include "nm-device-macsec.h"
Packit Service 5ffa24
Packit Service 5ffa24
#include <linux/if_ether.h>
Packit Service 5ffa24
Packit Service 5ffa24
#include "nm-act-request.h"
Packit Service 5ffa24
#include "nm-device-private.h"
Packit Service dff8e4
#include "libnm-platform/nm-platform.h"
Packit Service 5ffa24
#include "nm-device-factory.h"
Packit Service 5ffa24
#include "nm-manager.h"
Packit Service 5ffa24
#include "nm-setting-macsec.h"
Packit Service dff8e4
#include "libnm-core-intern/nm-core-internal.h"
Packit Service 5ffa24
#include "supplicant/nm-supplicant-manager.h"
Packit Service 5ffa24
#include "supplicant/nm-supplicant-interface.h"
Packit Service 5ffa24
#include "supplicant/nm-supplicant-config.h"
Packit Service 5ffa24
Packit Service 5ffa24
#define _NMLOG_DEVICE_TYPE NMDeviceMacsec
Packit Service 5ffa24
#include "nm-device-logging.h"
Packit Service 5ffa24
Packit Service 5ffa24
/*****************************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
#define SUPPLICANT_LNK_TIMEOUT_SEC 15
Packit Service 5ffa24
Packit Service 5ffa24
/*****************************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceMacsec,
Packit Service 5ffa24
                             PROP_SCI,
Packit Service 5ffa24
                             PROP_CIPHER_SUITE,
Packit Service 5ffa24
                             PROP_ICV_LENGTH,
Packit Service 5ffa24
                             PROP_WINDOW,
Packit Service 5ffa24
                             PROP_ENCODING_SA,
Packit Service 5ffa24
                             PROP_ENCRYPT,
Packit Service 5ffa24
                             PROP_PROTECT,
Packit Service 5ffa24
                             PROP_INCLUDE_SCI,
Packit Service 5ffa24
                             PROP_ES,
Packit Service 5ffa24
                             PROP_SCB,
Packit Service 5ffa24
                             PROP_REPLAY_PROTECT,
Packit Service 5ffa24
                             PROP_VALIDATION, );
Packit Service 5ffa24
Packit Service 5ffa24
typedef struct {
Packit Service 5ffa24
    NMPlatformLnkMacsec props;
Packit Service 5ffa24
    gulong              parent_state_id;
Packit Service 5ffa24
    gulong              parent_mtu_id;
Packit Service 5ffa24
Packit Service 5ffa24
    struct {
Packit Service 5ffa24
        NMSupplicantManager *        mgr;
Packit Service 5ffa24
        NMSupplMgrCreateIfaceHandle *create_handle;
Packit Service 5ffa24
        NMSupplicantInterface *      iface;
Packit Service 5ffa24
Packit Service 5ffa24
        gulong iface_state_id;
Packit Service 5ffa24
Packit Service 5ffa24
        guint con_timeout_id;
Packit Service 5ffa24
        guint lnk_timeout_id;
Packit Service 5ffa24
Packit Service 5ffa24
        bool is_associated : 1;
Packit Service 5ffa24
    } supplicant;
Packit Service 5ffa24
Packit Service 5ffa24
    NMActRequestGetSecretsCallId *macsec_secrets_id;
Packit Service 5ffa24
} NMDeviceMacsecPrivate;
Packit Service 5ffa24
Packit Service 5ffa24
struct _NMDeviceMacsec {
Packit Service 5ffa24
    NMDevice              parent;
Packit Service 5ffa24
    NMDeviceMacsecPrivate _priv;
Packit Service 5ffa24
};
Packit Service 5ffa24
Packit Service 5ffa24
struct _NMDeviceMacsecClass {
Packit Service 5ffa24
    NMDeviceClass parent;
Packit Service 5ffa24
};
Packit Service 5ffa24
Packit Service 5ffa24
G_DEFINE_TYPE(NMDeviceMacsec, nm_device_macsec, NM_TYPE_DEVICE)
Packit Service 5ffa24
Packit Service 5ffa24
#define NM_DEVICE_MACSEC_GET_PRIVATE(self) \
Packit Service 5ffa24
    _NM_GET_PRIVATE(self, NMDeviceMacsec, NM_IS_DEVICE_MACSEC, NMDevice)
Packit Service 5ffa24
Packit Service 5ffa24
/******************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
static void macsec_secrets_cancel(NMDeviceMacsec *self);
Packit Service 5ffa24
Packit Service 5ffa24
/******************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
static NM_UTILS_LOOKUP_STR_DEFINE(validation_mode_to_string,
Packit Service 5ffa24
                                  guint8,
Packit Service 5ffa24
                                  NM_UTILS_LOOKUP_DEFAULT_WARN("<unknown>"),
Packit Service 5ffa24
                                  NM_UTILS_LOOKUP_STR_ITEM(0, "disable"),
Packit Service 5ffa24
                                  NM_UTILS_LOOKUP_STR_ITEM(1, "check"),
Packit Service 5ffa24
                                  NM_UTILS_LOOKUP_STR_ITEM(2, "strict"), );
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
parent_state_changed(NMDevice *          parent,
Packit Service 5ffa24
                     NMDeviceState       new_state,
Packit Service 5ffa24
                     NMDeviceState       old_state,
Packit Service 5ffa24
                     NMDeviceStateReason reason,
Packit Service 5ffa24
                     gpointer            user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *self = NM_DEVICE_MACSEC(user_data);
Packit Service 5ffa24
Packit Service 5ffa24
    /* We'll react to our own carrier state notifications. Ignore the parent's. */
Packit Service 5ffa24
    if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_CARRIER)
Packit Service 5ffa24
        return;
Packit Service 5ffa24
Packit Service 5ffa24
    nm_device_set_unmanaged_by_flags(NM_DEVICE(self),
Packit Service 5ffa24
                                     NM_UNMANAGED_PARENT,
Packit Service 5ffa24
                                     !nm_device_get_managed(parent, FALSE),
Packit Service 5ffa24
                                     reason);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
parent_mtu_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    /* the MTU of a MACsec device is limited by the parent's MTU.
Packit Service 5ffa24
     *
Packit Service 5ffa24
     * When the parent's MTU changes, try to re-set the MTU. */
Packit Service 5ffa24
    nm_device_commit_mtu(user_data);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
parent_changed_notify(NMDevice *device,
Packit Service 5ffa24
                      int       old_ifindex,
Packit Service 5ffa24
                      NMDevice *old_parent,
Packit Service 5ffa24
                      int       new_ifindex,
Packit Service 5ffa24
                      NMDevice *new_parent)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self = NM_DEVICE_MACSEC(device);
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    NM_DEVICE_CLASS(nm_device_macsec_parent_class)
Packit Service 5ffa24
        ->parent_changed_notify(device, old_ifindex, old_parent, new_ifindex, new_parent);
Packit Service 5ffa24
Packit Service 5ffa24
    /*  note that @self doesn't have to clear @parent_state_id on dispose,
Packit Service 5ffa24
     *  because NMDevice's dispose() will unset the parent, which in turn calls
Packit Service 5ffa24
     *  parent_changed_notify(). */
Packit Service 5ffa24
    nm_clear_g_signal_handler(old_parent, &priv->parent_state_id);
Packit Service 5ffa24
    nm_clear_g_signal_handler(old_parent, &priv->parent_mtu_id);
Packit Service 5ffa24
Packit Service 5ffa24
    if (new_parent) {
Packit Service 5ffa24
        priv->parent_state_id = g_signal_connect(new_parent,
Packit Service 5ffa24
                                                 NM_DEVICE_STATE_CHANGED,
Packit Service 5ffa24
                                                 G_CALLBACK(parent_state_changed),
Packit Service 5ffa24
                                                 device);
Packit Service 5ffa24
        priv->parent_mtu_id   = g_signal_connect(new_parent,
Packit Service 5ffa24
                                               "notify::" NM_DEVICE_MTU,
Packit Service 5ffa24
                                               G_CALLBACK(parent_mtu_maybe_changed),
Packit Service 5ffa24
                                               device);
Packit Service 5ffa24
Packit Service 5ffa24
        /* Set parent-dependent unmanaged flag */
Packit Service 5ffa24
        nm_device_set_unmanaged_by_flags(device,
Packit Service 5ffa24
                                         NM_UNMANAGED_PARENT,
Packit Service 5ffa24
                                         !nm_device_get_managed(new_parent, FALSE),
Packit Service 5ffa24
                                         NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED);
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    /* Recheck availability now that the parent has changed */
Packit Service 5ffa24
    if (new_ifindex > 0) {
Packit Service 5ffa24
        nm_device_queue_recheck_available(device,
Packit Service 5ffa24
                                          NM_DEVICE_STATE_REASON_PARENT_CHANGED,
Packit Service 5ffa24
                                          NM_DEVICE_STATE_REASON_PARENT_CHANGED);
Packit Service 5ffa24
    }
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
update_properties(NMDevice *device)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *           self;
Packit Service 5ffa24
    NMDeviceMacsecPrivate *    priv;
Packit Service 5ffa24
    const NMPlatformLink *     plink = NULL;
Packit Service 5ffa24
    const NMPlatformLnkMacsec *props = NULL;
Packit Service 5ffa24
    int                        ifindex;
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_if_fail(NM_IS_DEVICE_MACSEC(device));
Packit Service 5ffa24
    self = NM_DEVICE_MACSEC(device);
Packit Service 5ffa24
    priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    ifindex = nm_device_get_ifindex(device);
Packit Service 5ffa24
    g_return_if_fail(ifindex > 0);
Packit Service 5ffa24
    props = nm_platform_link_get_lnk_macsec(nm_device_get_platform(device), ifindex, &plink);
Packit Service 5ffa24
Packit Service 5ffa24
    if (!props) {
Packit Service 5ffa24
        _LOGW(LOGD_PLATFORM, "could not get macsec properties");
Packit Service 5ffa24
        return;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    g_object_freeze_notify((GObject *) device);
Packit Service 5ffa24
Packit Service 5ffa24
    if (priv->props.parent_ifindex != props->parent_ifindex)
Packit Service 5ffa24
        nm_device_parent_set_ifindex(device, props->parent_ifindex);
Packit Service 5ffa24
Packit Service 5ffa24
#define CHECK_PROPERTY_CHANGED(field, prop)      \
Packit Service 5ffa24
    G_STMT_START                                 \
Packit Service 5ffa24
    {                                            \
Packit Service 5ffa24
        if (priv->props.field != props->field) { \
Packit Service 5ffa24
            priv->props.field = props->field;    \
Packit Service 5ffa24
            _notify(self, prop);                 \
Packit Service 5ffa24
        }                                        \
Packit Service 5ffa24
    }                                            \
Packit Service 5ffa24
    G_STMT_END
Packit Service 5ffa24
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(sci, PROP_SCI);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(cipher_suite, PROP_CIPHER_SUITE);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(window, PROP_WINDOW);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(icv_length, PROP_ICV_LENGTH);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(encoding_sa, PROP_ENCODING_SA);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(validation, PROP_VALIDATION);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(encrypt, PROP_ENCRYPT);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(protect, PROP_PROTECT);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(include_sci, PROP_INCLUDE_SCI);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(es, PROP_ES);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(scb, PROP_SCB);
Packit Service 5ffa24
    CHECK_PROPERTY_CHANGED(replay_protect, PROP_REPLAY_PROTECT);
Packit Service 5ffa24
Packit Service 5ffa24
    g_object_thaw_notify((GObject *) device);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static NMSupplicantConfig *
Packit Service 5ffa24
build_supplicant_config(NMDeviceMacsec *self, GError **error)
Packit Service 5ffa24
{
Packit Service 5ffa24
    gs_unref_object NMSupplicantConfig *config = NULL;
Packit Service 5ffa24
    NMSettingMacsec *                   s_macsec;
Packit Service 5ffa24
    NMSetting8021x *                    s_8021x;
Packit Service 5ffa24
    NMConnection *                      connection;
Packit Service 5ffa24
    const char *                        con_uuid;
Packit Service 5ffa24
    guint32                             mtu;
Packit Service 5ffa24
Packit Service 5ffa24
    connection = nm_device_get_applied_connection(NM_DEVICE(self));
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_val_if_fail(connection, NULL);
Packit Service 5ffa24
Packit Service 5ffa24
    con_uuid = nm_connection_get_uuid(connection);
Packit Service 5ffa24
    mtu      = nm_platform_link_get_mtu(nm_device_get_platform(NM_DEVICE(self)),
Packit Service 5ffa24
                                   nm_device_get_ifindex(NM_DEVICE(self)));
Packit Service 5ffa24
Packit Service 5ffa24
    config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE);
Packit Service 5ffa24
Packit Service 5ffa24
    s_macsec = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_MACSEC);
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_val_if_fail(s_macsec, NULL);
Packit Service 5ffa24
Packit Service 5ffa24
    if (!nm_supplicant_config_add_setting_macsec(config, s_macsec, error)) {
Packit Service 5ffa24
        g_prefix_error(error, "macsec-setting: ");
Packit Service 5ffa24
        return NULL;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    if (nm_setting_macsec_get_mode(s_macsec) == NM_SETTING_MACSEC_MODE_EAP) {
Packit Service 5ffa24
        s_8021x = nm_connection_get_setting_802_1x(connection);
Packit Service 5ffa24
        if (!nm_supplicant_config_add_setting_8021x(config, s_8021x, con_uuid, mtu, TRUE, error)) {
Packit Service 5ffa24
            g_prefix_error(error, "802-1x-setting: ");
Packit Service 5ffa24
            return NULL;
Packit Service 5ffa24
        }
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    return g_steal_pointer(&config);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
supplicant_interface_release(NMDeviceMacsec *self)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    nm_clear_pointer(&priv->supplicant.create_handle,
Packit Service 5ffa24
                     nm_supplicant_manager_create_interface_cancel);
Packit Service 5ffa24
Packit Service 5ffa24
    nm_clear_g_source(&priv->supplicant.lnk_timeout_id);
Packit Service 5ffa24
    nm_clear_g_source(&priv->supplicant.con_timeout_id);
Packit Service 5ffa24
    nm_clear_g_signal_handler(priv->supplicant.iface, &priv->supplicant.iface_state_id);
Packit Service 5ffa24
Packit Service 5ffa24
    if (priv->supplicant.iface) {
Packit Service 5ffa24
        nm_supplicant_interface_disconnect(priv->supplicant.iface);
Packit Service 5ffa24
        g_clear_object(&priv->supplicant.iface);
Packit Service 5ffa24
    }
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
macsec_secrets_cb(NMActRequest *                req,
Packit Service 5ffa24
                  NMActRequestGetSecretsCallId *call_id,
Packit Service 5ffa24
                  NMSettingsConnection *        connection,
Packit Service 5ffa24
                  GError *                      error,
Packit Service 5ffa24
                  gpointer                      user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self   = NM_DEVICE_MACSEC(user_data);
Packit Service 5ffa24
    NMDevice *             device = NM_DEVICE(self);
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv;
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_if_fail(NM_IS_DEVICE_MACSEC(self));
Packit Service 5ffa24
    g_return_if_fail(NM_IS_ACT_REQUEST(req));
Packit Service 5ffa24
Packit Service 5ffa24
    priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_if_fail(priv->macsec_secrets_id == call_id);
Packit Service 5ffa24
Packit Service 5ffa24
    priv->macsec_secrets_id = NULL;
Packit Service 5ffa24
Packit Service 5ffa24
    if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
Packit Service 5ffa24
        return;
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_if_fail(req == nm_device_get_act_request(device));
Packit Service 5ffa24
    g_return_if_fail(nm_device_get_state(device) == NM_DEVICE_STATE_NEED_AUTH);
Packit Service 5ffa24
    g_return_if_fail(nm_act_request_get_settings_connection(req) == connection);
Packit Service 5ffa24
Packit Service 5ffa24
    if (error) {
Packit Service 5ffa24
        _LOGW(LOGD_ETHER, "%s", error->message);
Packit Service 5ffa24
        nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
Packit Service 5ffa24
        return;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    nm_device_activate_schedule_stage1_device_prepare(device, FALSE);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
macsec_secrets_cancel(NMDeviceMacsec *self)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    if (priv->macsec_secrets_id)
Packit Service 5ffa24
        nm_act_request_cancel_secrets(NULL, priv->macsec_secrets_id);
Packit Service 5ffa24
    nm_assert(!priv->macsec_secrets_id);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
macsec_secrets_get_secrets(NMDeviceMacsec *             self,
Packit Service 5ffa24
                           const char *                 setting_name,
Packit Service 5ffa24
                           NMSecretAgentGetSecretsFlags flags)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
    NMActRequest *         req;
Packit Service 5ffa24
Packit Service 5ffa24
    macsec_secrets_cancel(self);
Packit Service 5ffa24
Packit Service 5ffa24
    req = nm_device_get_act_request(NM_DEVICE(self));
Packit Service 5ffa24
    g_return_if_fail(NM_IS_ACT_REQUEST(req));
Packit Service 5ffa24
Packit Service 5ffa24
    priv->macsec_secrets_id =
Packit Service 5ffa24
        nm_act_request_get_secrets(req, TRUE, setting_name, flags, NULL, macsec_secrets_cb, self);
Packit Service 5ffa24
    g_return_if_fail(priv->macsec_secrets_id);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static gboolean
Packit Service 5ffa24
supplicant_lnk_timeout_cb(gpointer user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self = NM_DEVICE_MACSEC(user_data);
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
    NMDevice *             dev  = NM_DEVICE(self);
Packit Service 5ffa24
    NMActRequest *         req;
Packit Service 5ffa24
    NMConnection *         applied_connection;
Packit Service 5ffa24
    const char *           setting_name;
Packit Service 5ffa24
Packit Service 5ffa24
    priv->supplicant.lnk_timeout_id = 0;
Packit Service 5ffa24
Packit Service 5ffa24
    req = nm_device_get_act_request(dev);
Packit Service 5ffa24
Packit Service 5ffa24
    if (nm_device_get_state(dev) == NM_DEVICE_STATE_ACTIVATED) {
Packit Service 5ffa24
        nm_device_state_changed(dev,
Packit Service 5ffa24
                                NM_DEVICE_STATE_FAILED,
Packit Service 5ffa24
                                NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT);
Packit Service 5ffa24
        return G_SOURCE_REMOVE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    /* Disconnect event during initial authentication and credentials
Packit Service 5ffa24
     * ARE checked - we are likely to have wrong key.  Ask the user for
Packit Service 5ffa24
     * another one.
Packit Service 5ffa24
     */
Packit Service 5ffa24
    if (nm_device_get_state(dev) != NM_DEVICE_STATE_CONFIG)
Packit Service 5ffa24
        goto time_out;
Packit Service 5ffa24
Packit Service 5ffa24
    nm_active_connection_clear_secrets(NM_ACTIVE_CONNECTION(req));
Packit Service 5ffa24
Packit Service 5ffa24
    applied_connection = nm_act_request_get_applied_connection(req);
Packit Service 5ffa24
    setting_name       = nm_connection_need_secrets(applied_connection, NULL);
Packit Service 5ffa24
    if (!setting_name)
Packit Service 5ffa24
        goto time_out;
Packit Service 5ffa24
Packit Service 5ffa24
    _LOGI(LOGD_DEVICE | LOGD_ETHER,
Packit Service 5ffa24
          "Activation: disconnected during authentication, asking for new key.");
Packit Service 5ffa24
    supplicant_interface_release(self);
Packit Service 5ffa24
Packit Service 5ffa24
    nm_device_state_changed(dev,
Packit Service 5ffa24
                            NM_DEVICE_STATE_NEED_AUTH,
Packit Service 5ffa24
                            NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
Packit Service 5ffa24
    macsec_secrets_get_secrets(self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
Packit Service 5ffa24
Packit Service 5ffa24
    return G_SOURCE_REMOVE;
Packit Service 5ffa24
Packit Service 5ffa24
time_out:
Packit Service 5ffa24
    _LOGW(LOGD_DEVICE | LOGD_ETHER, "link timed out.");
Packit Service 5ffa24
    nm_device_state_changed(dev,
Packit Service 5ffa24
                            NM_DEVICE_STATE_FAILED,
Packit Service 5ffa24
                            NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
Packit Service 5ffa24
Packit Service 5ffa24
    return G_SOURCE_REMOVE;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
supplicant_iface_state_is_completed(NMDeviceMacsec *self, NMSupplicantInterfaceState state)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    if (state == NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) {
Packit Service 5ffa24
        nm_clear_g_source(&priv->supplicant.lnk_timeout_id);
Packit Service 5ffa24
        nm_clear_g_source(&priv->supplicant.con_timeout_id);
Packit Service 5ffa24
Packit Service 5ffa24
        nm_device_bring_up(NM_DEVICE(self), TRUE, NULL);
Packit Service 5ffa24
Packit Service 5ffa24
        /* If this is the initial association during device activation,
Packit Service 5ffa24
         * schedule the next activation stage.
Packit Service 5ffa24
         */
Packit Service 5ffa24
        if (nm_device_get_state(NM_DEVICE(self)) == NM_DEVICE_STATE_CONFIG) {
Packit Service 5ffa24
            _LOGI(LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) successful.");
Packit Service 5ffa24
            nm_device_activate_schedule_stage3_ip_config_start(NM_DEVICE(self));
Packit Service 5ffa24
        }
Packit Service 5ffa24
        return;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    if (!priv->supplicant.lnk_timeout_id && !priv->supplicant.con_timeout_id)
Packit Service 5ffa24
        priv->supplicant.lnk_timeout_id =
Packit Service 5ffa24
            g_timeout_add_seconds(SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
supplicant_iface_assoc_cb(NMSupplicantInterface *iface, GError *error, gpointer user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self;
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv;
Packit Service 5ffa24
Packit Service 5ffa24
    if (nm_utils_error_is_cancelled_or_disposing(error))
Packit Service 5ffa24
        return;
Packit Service 5ffa24
Packit Service 5ffa24
    self = user_data;
Packit Service 5ffa24
    priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    if (error) {
Packit Service 5ffa24
        supplicant_interface_release(self);
Packit Service 5ffa24
        nm_device_queue_state(NM_DEVICE(self),
Packit Service 5ffa24
                              NM_DEVICE_STATE_FAILED,
Packit Service 5ffa24
                              NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
Packit Service 5ffa24
        return;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    nm_assert(!priv->supplicant.lnk_timeout_id);
Packit Service 5ffa24
    nm_assert(!priv->supplicant.is_associated);
Packit Service 5ffa24
Packit Service 5ffa24
    priv->supplicant.is_associated = TRUE;
Packit Service 5ffa24
    supplicant_iface_state_is_completed(self,
Packit Service 5ffa24
                                        nm_supplicant_interface_get_state(priv->supplicant.iface));
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static gboolean
Packit Service 5ffa24
supplicant_iface_start(NMDeviceMacsec *self)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv                = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
    gs_unref_object NMSupplicantConfig *config = NULL;
Packit Service 5ffa24
    gs_free_error GError *error                = NULL;
Packit Service 5ffa24
Packit Service 5ffa24
    config = build_supplicant_config(self, &error);
Packit Service 5ffa24
    if (!config) {
Packit Service 5ffa24
        _LOGE(LOGD_DEVICE, "Activation: couldn't build security configuration: %s", error->message);
Packit Service 5ffa24
        supplicant_interface_release(self);
Packit Service 5ffa24
        nm_device_state_changed(NM_DEVICE(self),
Packit Service 5ffa24
                                NM_DEVICE_STATE_FAILED,
Packit Service 5ffa24
                                NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
Packit Service 5ffa24
        return FALSE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    nm_supplicant_interface_disconnect(priv->supplicant.iface);
Packit Service 5ffa24
    nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self);
Packit Service 5ffa24
    return TRUE;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
supplicant_iface_state_cb(NMSupplicantInterface *iface,
Packit Service 5ffa24
                          int                    new_state_i,
Packit Service 5ffa24
                          int                    old_state_i,
Packit Service 5ffa24
                          int                    disconnect_reason,
Packit Service 5ffa24
                          gpointer               user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *           self      = NM_DEVICE_MACSEC(user_data);
Packit Service 5ffa24
    NMDeviceMacsecPrivate *    priv      = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
    NMSupplicantInterfaceState new_state = new_state_i;
Packit Service 5ffa24
    NMSupplicantInterfaceState old_state = old_state_i;
Packit Service 5ffa24
Packit Service 5ffa24
    _LOGI(LOGD_DEVICE,
Packit Service 5ffa24
          "supplicant interface state: %s -> %s",
Packit Service 5ffa24
          nm_supplicant_interface_state_to_string(old_state),
Packit Service 5ffa24
          nm_supplicant_interface_state_to_string(new_state));
Packit Service 5ffa24
Packit Service 5ffa24
    if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
Packit Service 5ffa24
        supplicant_interface_release(self);
Packit Service 5ffa24
        nm_device_state_changed(NM_DEVICE(self),
Packit Service 5ffa24
                                NM_DEVICE_STATE_FAILED,
Packit Service 5ffa24
                                NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
Packit Service 5ffa24
        return;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    if (old_state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
Packit Service 5ffa24
        if (!supplicant_iface_start(self))
Packit Service 5ffa24
            return;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    if (priv->supplicant.is_associated)
Packit Service 5ffa24
        supplicant_iface_state_is_completed(self, new_state);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static gboolean
Packit Service 5ffa24
handle_auth_or_fail(NMDeviceMacsec *self, NMActRequest *req, gboolean new_secrets)
Packit Service 5ffa24
{
Packit Service 5ffa24
    const char *  setting_name;
Packit Service 5ffa24
    NMConnection *applied_connection;
Packit Service 5ffa24
Packit Service 5ffa24
    if (!nm_device_auth_retries_try_next(NM_DEVICE(self)))
Packit Service 5ffa24
        return FALSE;
Packit Service 5ffa24
Packit Service 5ffa24
    nm_device_state_changed(NM_DEVICE(self),
Packit Service 5ffa24
                            NM_DEVICE_STATE_NEED_AUTH,
Packit Service 5ffa24
                            NM_DEVICE_STATE_REASON_NONE);
Packit Service 5ffa24
Packit Service 5ffa24
    nm_active_connection_clear_secrets(NM_ACTIVE_CONNECTION(req));
Packit Service 5ffa24
Packit Service 5ffa24
    applied_connection = nm_act_request_get_applied_connection(req);
Packit Service 5ffa24
    setting_name       = nm_connection_need_secrets(applied_connection, NULL);
Packit Service 5ffa24
    if (!setting_name) {
Packit Service 5ffa24
        _LOGI(LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets.");
Packit Service 5ffa24
        return FALSE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    macsec_secrets_get_secrets(
Packit Service 5ffa24
        self,
Packit Service 5ffa24
        setting_name,
Packit Service 5ffa24
        NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
Packit Service 5ffa24
            | (new_secrets ? NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW : 0));
Packit Service 5ffa24
    return TRUE;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static gboolean
Packit Service 5ffa24
supplicant_connection_timeout_cb(gpointer user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self   = NM_DEVICE_MACSEC(user_data);
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv   = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
    NMDevice *             device = NM_DEVICE(self);
Packit Service 5ffa24
    NMActRequest *         req;
Packit Service 5ffa24
    NMSettingsConnection * connection;
Packit Service 5ffa24
    guint64                timestamp   = 0;
Packit Service 5ffa24
    gboolean               new_secrets = TRUE;
Packit Service 5ffa24
Packit Service 5ffa24
    priv->supplicant.con_timeout_id = 0;
Packit Service 5ffa24
Packit Service 5ffa24
    /* Authentication failed; either driver problems, the encryption key is
Packit Service 5ffa24
     * wrong, the passwords or certificates were wrong or the Ethernet switch's
Packit Service 5ffa24
     * port is not configured for 802.1x. */
Packit Service 5ffa24
    _LOGW(LOGD_DEVICE, "Activation: (macsec) association took too long.");
Packit Service 5ffa24
Packit Service 5ffa24
    supplicant_interface_release(self);
Packit Service 5ffa24
Packit Service 5ffa24
    req        = nm_device_get_act_request(device);
Packit Service 5ffa24
    connection = nm_act_request_get_settings_connection(req);
Packit Service 5ffa24
    g_return_val_if_fail(connection, G_SOURCE_REMOVE);
Packit Service 5ffa24
Packit Service 5ffa24
    /* Ask for new secrets only if we've never activated this connection
Packit Service 5ffa24
     * before.  If we've connected before, don't bother the user with dialogs,
Packit Service 5ffa24
     * just retry or fail, and if we never connect the user can fix the
Packit Service 5ffa24
     * password somewhere else. */
Packit Service 5ffa24
    if (nm_settings_connection_get_timestamp(connection, &timestamp))
Packit Service 5ffa24
        new_secrets = !timestamp;
Packit Service 5ffa24
Packit Service 5ffa24
    if (!handle_auth_or_fail(self, req, new_secrets)) {
Packit Service 5ffa24
        nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
Packit Service 5ffa24
        return G_SOURCE_REMOVE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    _LOGW(LOGD_DEVICE, "Activation: (macsec) asking for new secrets");
Packit Service 5ffa24
Packit Service 5ffa24
    if (!priv->supplicant.lnk_timeout_id && priv->supplicant.iface) {
Packit Service 5ffa24
        NMSupplicantInterfaceState state;
Packit Service 5ffa24
Packit Service 5ffa24
        state = nm_supplicant_interface_get_state(priv->supplicant.iface);
Packit Service 5ffa24
        if (state != NM_SUPPLICANT_INTERFACE_STATE_COMPLETED
Packit Service 5ffa24
            && nm_supplicant_interface_state_is_operational(state))
Packit Service 5ffa24
            priv->supplicant.lnk_timeout_id =
Packit Service 5ffa24
                g_timeout_add_seconds(SUPPLICANT_LNK_TIMEOUT_SEC, supplicant_lnk_timeout_cb, self);
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    return G_SOURCE_REMOVE;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
supplicant_interface_create_cb(NMSupplicantManager *        supplicant_manager,
Packit Service 5ffa24
                               NMSupplMgrCreateIfaceHandle *handle,
Packit Service 5ffa24
                               NMSupplicantInterface *      iface,
Packit Service 5ffa24
                               GError *                     error,
Packit Service 5ffa24
                               gpointer                     user_data)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self;
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv;
Packit Service 5ffa24
    guint                  timeout;
Packit Service 5ffa24
Packit Service 5ffa24
    if (nm_utils_error_is_cancelled(error))
Packit Service 5ffa24
        return;
Packit Service 5ffa24
Packit Service 5ffa24
    self = user_data;
Packit Service 5ffa24
    priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    nm_assert(priv->supplicant.create_handle == handle);
Packit Service 5ffa24
Packit Service 5ffa24
    priv->supplicant.create_handle = NULL;
Packit Service 5ffa24
Packit Service 5ffa24
    if (error) {
Packit Service 5ffa24
        _LOGE(LOGD_DEVICE, "Couldn't initialize supplicant interface: %s", error->message);
Packit Service 5ffa24
        supplicant_interface_release(self);
Packit Service 5ffa24
        nm_device_state_changed(NM_DEVICE(self),
Packit Service 5ffa24
                                NM_DEVICE_STATE_FAILED,
Packit Service 5ffa24
                                NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
Packit Service 5ffa24
        return;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    priv->supplicant.iface         = g_object_ref(iface);
Packit Service 5ffa24
    priv->supplicant.is_associated = FALSE;
Packit Service 5ffa24
Packit Service 5ffa24
    priv->supplicant.iface_state_id = g_signal_connect(priv->supplicant.iface,
Packit Service 5ffa24
                                                       NM_SUPPLICANT_INTERFACE_STATE,
Packit Service 5ffa24
                                                       G_CALLBACK(supplicant_iface_state_cb),
Packit Service 5ffa24
                                                       self);
Packit Service 5ffa24
Packit Service 5ffa24
    timeout = nm_device_get_supplicant_timeout(NM_DEVICE(self));
Packit Service 5ffa24
    priv->supplicant.con_timeout_id =
Packit Service 5ffa24
        g_timeout_add_seconds(timeout, supplicant_connection_timeout_cb, self);
Packit Service 5ffa24
Packit Service 5ffa24
    if (nm_supplicant_interface_state_is_operational(nm_supplicant_interface_get_state(iface)))
Packit Service 5ffa24
        supplicant_iface_start(self);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static NMActStageReturn
Packit Service 5ffa24
act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self = NM_DEVICE_MACSEC(device);
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
    NMConnection *         connection;
Packit Service 5ffa24
    NMDevice *             parent;
Packit Service 5ffa24
    const char *           setting_name;
Packit Service 5ffa24
    int                    ifindex;
Packit Service 5ffa24
Packit Service 5ffa24
    connection = nm_device_get_applied_connection(NM_DEVICE(self));
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
Packit Service 5ffa24
Packit Service 5ffa24
    if (!priv->supplicant.mgr)
Packit Service 5ffa24
        priv->supplicant.mgr = g_object_ref(nm_supplicant_manager_get());
Packit Service 5ffa24
Packit Service 5ffa24
    /* If we need secrets, get them */
Packit Service 5ffa24
    setting_name = nm_connection_need_secrets(connection, NULL);
Packit Service 5ffa24
    if (setting_name) {
Packit Service 5ffa24
        NMActRequest *req = nm_device_get_act_request(NM_DEVICE(self));
Packit Service 5ffa24
Packit Service 5ffa24
        _LOGI(LOGD_DEVICE,
Packit Service 5ffa24
              "Activation: connection '%s' has security, but secrets are required.",
Packit Service 5ffa24
              nm_connection_get_id(connection));
Packit Service 5ffa24
Packit Service 5ffa24
        if (!handle_auth_or_fail(self, req, FALSE)) {
Packit Service 5ffa24
            NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NO_SECRETS);
Packit Service 5ffa24
            return NM_ACT_STAGE_RETURN_FAILURE;
Packit Service 5ffa24
        }
Packit Service 5ffa24
Packit Service 5ffa24
        return NM_ACT_STAGE_RETURN_POSTPONE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    _LOGI(LOGD_DEVICE | LOGD_ETHER,
Packit Service 5ffa24
          "Activation: connection '%s' requires no security. No secrets needed.",
Packit Service 5ffa24
          nm_connection_get_id(connection));
Packit Service 5ffa24
Packit Service 5ffa24
    supplicant_interface_release(self);
Packit Service 5ffa24
Packit Service 5ffa24
    parent = nm_device_parent_get_device(NM_DEVICE(self));
Packit Service 5ffa24
    g_return_val_if_fail(parent, NM_ACT_STAGE_RETURN_FAILURE);
Packit Service 5ffa24
    ifindex = nm_device_get_ifindex(parent);
Packit Service 5ffa24
    g_return_val_if_fail(ifindex > 0, NM_ACT_STAGE_RETURN_FAILURE);
Packit Service 5ffa24
Packit Service 5ffa24
    priv->supplicant.create_handle =
Packit Service 5ffa24
        nm_supplicant_manager_create_interface(priv->supplicant.mgr,
Packit Service 5ffa24
                                               ifindex,
Packit Service 5ffa24
                                               NM_SUPPLICANT_DRIVER_MACSEC,
Packit Service 5ffa24
                                               supplicant_interface_create_cb,
Packit Service 5ffa24
                                               self);
Packit Service 5ffa24
    return NM_ACT_STAGE_RETURN_POSTPONE;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
deactivate(NMDevice *device)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *self = NM_DEVICE_MACSEC(device);
Packit Service 5ffa24
Packit Service 5ffa24
    supplicant_interface_release(self);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
/******************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
static NMDeviceCapabilities
Packit Service 5ffa24
get_generic_capabilities(NMDevice *dev)
Packit Service 5ffa24
{
Packit Service 5ffa24
    /* We assume MACsec interfaces always support carrier detect */
Packit Service 5ffa24
    return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
/******************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
static gboolean
Packit Service 5ffa24
is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
Packit Service 5ffa24
{
Packit Service 5ffa24
    if (!nm_device_parent_get_device(device))
Packit Service 5ffa24
        return FALSE;
Packit Service 5ffa24
    return NM_DEVICE_CLASS(nm_device_macsec_parent_class)->is_available(device, flags);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static gboolean
Packit Service 5ffa24
create_and_realize(NMDevice *             device,
Packit Service 5ffa24
                   NMConnection *         connection,
Packit Service 5ffa24
                   NMDevice *             parent,
Packit Service 5ffa24
                   const NMPlatformLink **out_plink,
Packit Service 5ffa24
                   GError **              error)
Packit Service 5ffa24
{
Packit Service 5ffa24
    const char *        iface = nm_device_get_iface(device);
Packit Service 5ffa24
    NMSettingMacsec *   s_macsec;
Packit Service 5ffa24
    NMPlatformLnkMacsec lnk = {};
Packit Service 5ffa24
    int                 parent_ifindex;
Packit Service 5ffa24
    const char *        hw_addr;
Packit Service 5ffa24
    union {
Packit Service 5ffa24
        struct {
Packit Service 5ffa24
            guint8  mac[6];
Packit Service 5ffa24
            guint16 port;
Packit Service 5ffa24
        } s;
Packit Service 5ffa24
        guint64 u;
Packit Service 5ffa24
    } sci;
Packit Service 5ffa24
    int r;
Packit Service 5ffa24
Packit Service 5ffa24
    s_macsec = nm_connection_get_setting_macsec(connection);
Packit Service 5ffa24
    g_assert(s_macsec);
Packit Service 5ffa24
Packit Service 5ffa24
    if (!parent) {
Packit Service 5ffa24
        g_set_error(error,
Packit Service 5ffa24
                    NM_DEVICE_ERROR,
Packit Service 5ffa24
                    NM_DEVICE_ERROR_MISSING_DEPENDENCIES,
Packit Service 5ffa24
                    "MACsec devices can not be created without a parent interface");
Packit Service 5ffa24
        return FALSE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    lnk.encrypt = nm_setting_macsec_get_encrypt(s_macsec);
Packit Service 5ffa24
Packit Service 5ffa24
    hw_addr = nm_device_get_hw_address(parent);
Packit Service 5ffa24
    if (!hw_addr) {
Packit Service 5ffa24
        g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "can't read parent MAC");
Packit Service 5ffa24
        return FALSE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    nm_utils_hwaddr_aton(hw_addr, sci.s.mac, ETH_ALEN);
Packit Service 5ffa24
    sci.s.port      = htons(nm_setting_macsec_get_port(s_macsec));
Packit Service 5ffa24
    lnk.sci         = be64toh(sci.u);
Packit Service 5ffa24
    lnk.validation  = nm_setting_macsec_get_validation(s_macsec);
Packit Service 5ffa24
    lnk.include_sci = nm_setting_macsec_get_send_sci(s_macsec);
Packit Service 5ffa24
Packit Service 5ffa24
    parent_ifindex = nm_device_get_ifindex(parent);
Packit Service 5ffa24
    g_warn_if_fail(parent_ifindex > 0);
Packit Service 5ffa24
Packit Service 5ffa24
    r = nm_platform_link_macsec_add(nm_device_get_platform(device),
Packit Service 5ffa24
                                    iface,
Packit Service 5ffa24
                                    parent_ifindex,
Packit Service 5ffa24
                                    &lnk,
Packit Service 5ffa24
                                    out_plink);
Packit Service 5ffa24
    if (r < 0) {
Packit Service 5ffa24
        g_set_error(error,
Packit Service 5ffa24
                    NM_DEVICE_ERROR,
Packit Service 5ffa24
                    NM_DEVICE_ERROR_CREATION_FAILED,
Packit Service 5ffa24
                    "Failed to create macsec interface '%s' for '%s': %s",
Packit Service 5ffa24
                    iface,
Packit Service 5ffa24
                    nm_connection_get_id(connection),
Packit Service 5ffa24
                    nm_strerror(r));
Packit Service 5ffa24
        return FALSE;
Packit Service 5ffa24
    }
Packit Service 5ffa24
Packit Service 5ffa24
    nm_device_parent_set_ifindex(device, parent_ifindex);
Packit Service 5ffa24
Packit Service 5ffa24
    return TRUE;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
link_changed(NMDevice *device, const NMPlatformLink *pllink)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NM_DEVICE_CLASS(nm_device_macsec_parent_class)->link_changed(device, pllink);
Packit Service 5ffa24
    update_properties(device);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
device_state_changed(NMDevice *          device,
Packit Service 5ffa24
                     NMDeviceState       new_state,
Packit Service 5ffa24
                     NMDeviceState       old_state,
Packit Service 5ffa24
                     NMDeviceStateReason reason)
Packit Service 5ffa24
{
Packit Service 5ffa24
    if (new_state > NM_DEVICE_STATE_ACTIVATED)
Packit Service 5ffa24
        macsec_secrets_cancel(NM_DEVICE_MACSEC(device));
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
/******************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *       self = NM_DEVICE_MACSEC(object);
Packit Service 5ffa24
    NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
Packit Service 5ffa24
Packit Service 5ffa24
    switch (prop_id) {
Packit Service 5ffa24
    case PROP_SCI:
Packit Service 5ffa24
        g_value_set_uint64(value, priv->props.sci);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_CIPHER_SUITE:
Packit Service 5ffa24
        g_value_set_uint64(value, priv->props.cipher_suite);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_ICV_LENGTH:
Packit Service 5ffa24
        g_value_set_uchar(value, priv->props.icv_length);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_WINDOW:
Packit Service 5ffa24
        g_value_set_uint(value, priv->props.window);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_ENCODING_SA:
Packit Service 5ffa24
        g_value_set_uchar(value, priv->props.encoding_sa);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_ENCRYPT:
Packit Service 5ffa24
        g_value_set_boolean(value, priv->props.encrypt);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_PROTECT:
Packit Service 5ffa24
        g_value_set_boolean(value, priv->props.protect);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_INCLUDE_SCI:
Packit Service 5ffa24
        g_value_set_boolean(value, priv->props.include_sci);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_ES:
Packit Service 5ffa24
        g_value_set_boolean(value, priv->props.es);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_SCB:
Packit Service 5ffa24
        g_value_set_boolean(value, priv->props.scb);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_REPLAY_PROTECT:
Packit Service 5ffa24
        g_value_set_boolean(value, priv->props.replay_protect);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    case PROP_VALIDATION:
Packit Service 5ffa24
        g_value_set_string(value, validation_mode_to_string(priv->props.validation));
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    default:
Packit Service 5ffa24
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
Packit Service 5ffa24
        break;
Packit Service 5ffa24
    }
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
nm_device_macsec_init(NMDeviceMacsec *self)
Packit Service 5ffa24
{}
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
dispose(GObject *object)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMDeviceMacsec *self = NM_DEVICE_MACSEC(object);
Packit Service 5ffa24
Packit Service 5ffa24
    macsec_secrets_cancel(self);
Packit Service 5ffa24
    supplicant_interface_release(self);
Packit Service 5ffa24
Packit Service 5ffa24
    G_OBJECT_CLASS(nm_device_macsec_parent_class)->dispose(object);
Packit Service 5ffa24
Packit Service 5ffa24
    nm_assert(NM_DEVICE_MACSEC_GET_PRIVATE(self)->parent_state_id == 0);
Packit Service 5ffa24
    nm_assert(NM_DEVICE_MACSEC_GET_PRIVATE(self)->parent_mtu_id == 0);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static const NMDBusInterfaceInfoExtended interface_info_device_macsec = {
Packit Service 5ffa24
    .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
Packit Service 5ffa24
        NM_DBUS_INTERFACE_DEVICE_MACSEC,
Packit Service 5ffa24
        .signals    = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ),
Packit Service 5ffa24
        .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Sci", "t", NM_DEVICE_MACSEC_SCI),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IcvLength",
Packit Service 5ffa24
                                                             "y",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_ICV_LENGTH),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CipherSuite",
Packit Service 5ffa24
                                                             "t",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_CIPHER_SUITE),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Window",
Packit Service 5ffa24
                                                             "u",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_WINDOW),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("EncodingSa",
Packit Service 5ffa24
                                                             "y",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_ENCODING_SA),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Validation",
Packit Service 5ffa24
                                                             "s",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_VALIDATION),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Encrypt",
Packit Service 5ffa24
                                                             "b",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_ENCRYPT),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Protect",
Packit Service 5ffa24
                                                             "b",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_PROTECT),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IncludeSci",
Packit Service 5ffa24
                                                             "b",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_INCLUDE_SCI),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Es", "b", NM_DEVICE_MACSEC_ES),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Scb", "b", NM_DEVICE_MACSEC_SCB),
Packit Service 5ffa24
            NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ReplayProtect",
Packit Service 5ffa24
                                                             "b",
Packit Service 5ffa24
                                                             NM_DEVICE_MACSEC_REPLAY_PROTECT), ), ),
Packit Service 5ffa24
    .legacy_property_changed = TRUE,
Packit Service 5ffa24
};
Packit Service 5ffa24
Packit Service 5ffa24
static void
Packit Service 5ffa24
nm_device_macsec_class_init(NMDeviceMacsecClass *klass)
Packit Service 5ffa24
{
Packit Service 5ffa24
    GObjectClass *     object_class      = G_OBJECT_CLASS(klass);
Packit Service 5ffa24
    NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
Packit Service 5ffa24
    NMDeviceClass *    device_class      = NM_DEVICE_CLASS(klass);
Packit Service 5ffa24
Packit Service 5ffa24
    object_class->get_property = get_property;
Packit Service 5ffa24
    object_class->dispose      = dispose;
Packit Service 5ffa24
Packit Service 5ffa24
    dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_macsec);
Packit Service 5ffa24
Packit Service 5ffa24
    device_class->connection_type_supported        = NM_SETTING_MACSEC_SETTING_NAME;
Packit Service 5ffa24
    device_class->connection_type_check_compatible = NM_SETTING_MACSEC_SETTING_NAME;
Packit Service 5ffa24
    device_class->link_types       = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_MACSEC);
Packit Service 5ffa24
    device_class->mtu_parent_delta = 32;
Packit Service 5ffa24
Packit Service 5ffa24
    device_class->act_stage2_config        = act_stage2_config;
Packit Service 5ffa24
    device_class->create_and_realize       = create_and_realize;
Packit Service 5ffa24
    device_class->deactivate               = deactivate;
Packit Service 5ffa24
    device_class->get_generic_capabilities = get_generic_capabilities;
Packit Service 5ffa24
    device_class->link_changed             = link_changed;
Packit Service 5ffa24
    device_class->is_available             = is_available;
Packit Service 5ffa24
    device_class->parent_changed_notify    = parent_changed_notify;
Packit Service 5ffa24
    device_class->state_changed            = device_state_changed;
Packit Service 5ffa24
    device_class->get_configured_mtu       = nm_device_get_configured_mtu_wired_parent;
Packit Service 5ffa24
Packit Service 5ffa24
    obj_properties[PROP_SCI] = g_param_spec_uint64(NM_DEVICE_MACSEC_SCI,
Packit Service 5ffa24
                                                   "",
Packit Service 5ffa24
                                                   "",
Packit Service 5ffa24
                                                   0,
Packit Service 5ffa24
                                                   G_MAXUINT64,
Packit Service 5ffa24
                                                   0,
Packit Service 5ffa24
                                                   G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_CIPHER_SUITE] =
Packit Service 5ffa24
        g_param_spec_uint64(NM_DEVICE_MACSEC_CIPHER_SUITE,
Packit Service 5ffa24
                            "",
Packit Service 5ffa24
                            "",
Packit Service 5ffa24
                            0,
Packit Service 5ffa24
                            G_MAXUINT64,
Packit Service 5ffa24
                            0,
Packit Service 5ffa24
                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_ICV_LENGTH] = g_param_spec_uchar(NM_DEVICE_MACSEC_ICV_LENGTH,
Packit Service 5ffa24
                                                         "",
Packit Service 5ffa24
                                                         "",
Packit Service 5ffa24
                                                         0,
Packit Service 5ffa24
                                                         G_MAXUINT8,
Packit Service 5ffa24
                                                         0,
Packit Service 5ffa24
                                                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_WINDOW]     = g_param_spec_uint(NM_DEVICE_MACSEC_WINDOW,
Packit Service 5ffa24
                                                    "",
Packit Service 5ffa24
                                                    "",
Packit Service 5ffa24
                                                    0,
Packit Service 5ffa24
                                                    G_MAXUINT32,
Packit Service 5ffa24
                                                    0,
Packit Service 5ffa24
                                                    G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_ENCODING_SA] =
Packit Service 5ffa24
        g_param_spec_uchar(NM_DEVICE_MACSEC_ENCODING_SA,
Packit Service 5ffa24
                           "",
Packit Service 5ffa24
                           "",
Packit Service 5ffa24
                           0,
Packit Service 5ffa24
                           3,
Packit Service 5ffa24
                           0,
Packit Service 5ffa24
                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_VALIDATION] =
Packit Service 5ffa24
        g_param_spec_string(NM_DEVICE_MACSEC_VALIDATION,
Packit Service 5ffa24
                            "",
Packit Service 5ffa24
                            "",
Packit Service 5ffa24
                            NULL,
Packit Service 5ffa24
                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_ENCRYPT] = g_param_spec_boolean(NM_DEVICE_MACSEC_ENCRYPT,
Packit Service 5ffa24
                                                        "",
Packit Service 5ffa24
                                                        "",
Packit Service 5ffa24
                                                        FALSE,
Packit Service 5ffa24
                                                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_PROTECT] = g_param_spec_boolean(NM_DEVICE_MACSEC_PROTECT,
Packit Service 5ffa24
                                                        "",
Packit Service 5ffa24
                                                        "",
Packit Service 5ffa24
                                                        FALSE,
Packit Service 5ffa24
                                                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_INCLUDE_SCI] =
Packit Service 5ffa24
        g_param_spec_boolean(NM_DEVICE_MACSEC_INCLUDE_SCI,
Packit Service 5ffa24
                             "",
Packit Service 5ffa24
                             "",
Packit Service 5ffa24
                             FALSE,
Packit Service 5ffa24
                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_ES]  = g_param_spec_boolean(NM_DEVICE_MACSEC_ES,
Packit Service 5ffa24
                                                   "",
Packit Service 5ffa24
                                                   "",
Packit Service 5ffa24
                                                   FALSE,
Packit Service 5ffa24
                                                   G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_SCB] = g_param_spec_boolean(NM_DEVICE_MACSEC_SCB,
Packit Service 5ffa24
                                                    "",
Packit Service 5ffa24
                                                    "",
Packit Service 5ffa24
                                                    FALSE,
Packit Service 5ffa24
                                                    G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
    obj_properties[PROP_REPLAY_PROTECT] =
Packit Service 5ffa24
        g_param_spec_boolean(NM_DEVICE_MACSEC_REPLAY_PROTECT,
Packit Service 5ffa24
                             "",
Packit Service 5ffa24
                             "",
Packit Service 5ffa24
                             FALSE,
Packit Service 5ffa24
                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
Packit Service 5ffa24
Packit Service 5ffa24
    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
/*************************************************************/
Packit Service 5ffa24
Packit Service 5ffa24
#define NM_TYPE_MACSEC_DEVICE_FACTORY (nm_macsec_device_factory_get_type())
Packit Service 5ffa24
#define NM_MACSEC_DEVICE_FACTORY(obj) \
Packit Service 5ffa24
    (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MACSEC_DEVICE_FACTORY, NMMacsecDeviceFactory))
Packit Service 5ffa24
Packit Service 5ffa24
static NMDevice *
Packit Service 5ffa24
create_device(NMDeviceFactory *     factory,
Packit Service 5ffa24
              const char *          iface,
Packit Service 5ffa24
              const NMPlatformLink *plink,
Packit Service 5ffa24
              NMConnection *        connection,
Packit Service 5ffa24
              gboolean *            out_ignore)
Packit Service 5ffa24
{
Packit Service 5ffa24
    return g_object_new(NM_TYPE_DEVICE_MACSEC,
Packit Service 5ffa24
                        NM_DEVICE_IFACE,
Packit Service 5ffa24
                        iface,
Packit Service 5ffa24
                        NM_DEVICE_TYPE_DESC,
Packit Service 5ffa24
                        "Macsec",
Packit Service 5ffa24
                        NM_DEVICE_DEVICE_TYPE,
Packit Service 5ffa24
                        NM_DEVICE_TYPE_MACSEC,
Packit Service 5ffa24
                        NM_DEVICE_LINK_TYPE,
Packit Service 5ffa24
                        NM_LINK_TYPE_MACSEC,
Packit Service 5ffa24
                        NULL);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static const char *
Packit Service 5ffa24
get_connection_parent(NMDeviceFactory *factory, NMConnection *connection)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMSettingMacsec *s_macsec;
Packit Service 5ffa24
    NMSettingWired * s_wired;
Packit Service 5ffa24
    const char *     parent = NULL;
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACSEC_SETTING_NAME), NULL);
Packit Service 5ffa24
Packit Service 5ffa24
    s_macsec = nm_connection_get_setting_macsec(connection);
Packit Service 5ffa24
    g_assert(s_macsec);
Packit Service 5ffa24
Packit Service 5ffa24
    parent = nm_setting_macsec_get_parent(s_macsec);
Packit Service 5ffa24
    if (parent)
Packit Service 5ffa24
        return parent;
Packit Service 5ffa24
Packit Service 5ffa24
    /* Try the hardware address from the MACsec connection's hardware setting */
Packit Service 5ffa24
    s_wired = nm_connection_get_setting_wired(connection);
Packit Service 5ffa24
    if (s_wired)
Packit Service 5ffa24
        return nm_setting_wired_get_mac_address(s_wired);
Packit Service 5ffa24
Packit Service 5ffa24
    return NULL;
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
static char *
Packit Service 5ffa24
get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface)
Packit Service 5ffa24
{
Packit Service 5ffa24
    NMSettingMacsec *s_macsec;
Packit Service 5ffa24
    const char *     ifname;
Packit Service 5ffa24
Packit Service 5ffa24
    g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACSEC_SETTING_NAME), NULL);
Packit Service 5ffa24
Packit Service 5ffa24
    s_macsec = nm_connection_get_setting_macsec(connection);
Packit Service 5ffa24
    g_assert(s_macsec);
Packit Service 5ffa24
Packit Service 5ffa24
    if (!parent_iface)
Packit Service 5ffa24
        return NULL;
Packit Service 5ffa24
Packit Service 5ffa24
    ifname = nm_connection_get_interface_name(connection);
Packit Service 5ffa24
    return g_strdup(ifname);
Packit Service 5ffa24
}
Packit Service 5ffa24
Packit Service 5ffa24
NM_DEVICE_FACTORY_DEFINE_INTERNAL(
Packit Service 5ffa24
    MACSEC,
Packit Service 5ffa24
    Macsec,
Packit Service 5ffa24
    macsec,
Packit Service 5ffa24
    NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_MACSEC)
Packit Service 5ffa24
        NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_MACSEC_SETTING_NAME),
Packit Service 5ffa24
    factory_class->create_device         = create_device;
Packit Service 5ffa24
    factory_class->get_connection_parent = get_connection_parent;
Packit Service 5ffa24
    factory_class->get_connection_iface  = get_connection_iface;)