merge: branch 'bg/macsec-bgo762114'

https://bugzilla.gnome.org/show_bug.cgi?id=762114
This commit is contained in:
Beniamino Galvani 2017-01-16 17:50:42 +01:00
commit 1a24f528c8
44 changed files with 3488 additions and 47 deletions

View file

@ -195,6 +195,8 @@ introspection_sources = \
introspection/org.freedesktop.NetworkManager.Device.Infiniband.h \
introspection/org.freedesktop.NetworkManager.Device.IPTunnel.c \
introspection/org.freedesktop.NetworkManager.Device.IPTunnel.h \
introspection/org.freedesktop.NetworkManager.Device.Macsec.c \
introspection/org.freedesktop.NetworkManager.Device.Macsec.h \
introspection/org.freedesktop.NetworkManager.Device.Macvlan.c \
introspection/org.freedesktop.NetworkManager.Device.Macvlan.h \
introspection/org.freedesktop.NetworkManager.Device.Modem.c \
@ -262,6 +264,7 @@ DBUS_INTERFACE_DOCS = \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Vxlan.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Settings.Connection.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Bond.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Macsec.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Macvlan.xml \
docs/api/dbus-org.freedesktop.NetworkManager.PPP.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Vlan.xml \
@ -313,6 +316,7 @@ dbusinterfaces_DATA = \
introspection/org.freedesktop.NetworkManager.Device.Generic.xml \
introspection/org.freedesktop.NetworkManager.Device.Infiniband.xml \
introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml \
introspection/org.freedesktop.NetworkManager.Device.Macsec.xml \
introspection/org.freedesktop.NetworkManager.Device.Macvlan.xml \
introspection/org.freedesktop.NetworkManager.Device.Modem.xml \
introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.xml \
@ -375,6 +379,7 @@ libnm_core_lib_h_pub_real = \
libnm-core/nm-setting-ip-tunnel.h \
libnm-core/nm-setting-ip4-config.h \
libnm-core/nm-setting-ip6-config.h \
libnm-core/nm-setting-macsec.h \
libnm-core/nm-setting-macvlan.h \
libnm-core/nm-setting-olpc-mesh.h \
libnm-core/nm-setting-ppp.h \
@ -437,6 +442,7 @@ libnm_core_lib_c_real = \
libnm-core/nm-setting-ip-tunnel.c \
libnm-core/nm-setting-ip4-config.c \
libnm-core/nm-setting-ip6-config.c \
libnm-core/nm-setting-macsec.c \
libnm-core/nm-setting-macvlan.c \
libnm-core/nm-setting-olpc-mesh.c \
libnm-core/nm-setting-ppp.c \
@ -668,6 +674,7 @@ libnm_lib_h_pub_real = \
libnm/nm-device-generic.h \
libnm/nm-device-infiniband.h \
libnm/nm-device-ip-tunnel.h \
libnm/nm-device-macsec.h \
libnm/nm-device-macvlan.h \
libnm/nm-device-modem.h \
libnm/nm-device-olpc-mesh.h \
@ -717,6 +724,7 @@ libnm_lib_c_real = \
libnm/nm-device-generic.c \
libnm/nm-device-infiniband.c \
libnm/nm-device-ip-tunnel.c \
libnm/nm-device-macsec.c \
libnm/nm-device-macvlan.c \
libnm/nm-device-modem.c \
libnm/nm-device-olpc-mesh.c \
@ -1291,6 +1299,8 @@ src_libNetworkManager_la_SOURCES = \
src/devices/nm-device-infiniband.h \
src/devices/nm-device-ip-tunnel.c \
src/devices/nm-device-ip-tunnel.h \
src/devices/nm-device-macsec.c \
src/devices/nm-device-macsec.h \
src/devices/nm-device-macvlan.c \
src/devices/nm-device-macvlan.h \
src/devices/nm-device-tun.c \

View file

@ -169,9 +169,10 @@ NmcOutputField nmc_fields_settings_names[] = {
SETTING_FIELD (NM_SETTING_DCB_SETTING_NAME, nmc_fields_setting_dcb + 1), /* 24 */
SETTING_FIELD (NM_SETTING_TUN_SETTING_NAME, nmc_fields_setting_tun + 1), /* 25 */
SETTING_FIELD (NM_SETTING_IP_TUNNEL_SETTING_NAME, nmc_fields_setting_ip_tunnel + 1), /* 26 */
SETTING_FIELD (NM_SETTING_MACVLAN_SETTING_NAME, nmc_fields_setting_macvlan + 1), /* 27 */
SETTING_FIELD (NM_SETTING_VXLAN_SETTING_NAME, nmc_fields_setting_vxlan + 1), /* 28 */
SETTING_FIELD (NM_SETTING_PROXY_SETTING_NAME, nmc_fields_setting_proxy + 1), /* 29 */
SETTING_FIELD (NM_SETTING_MACSEC_SETTING_NAME, nmc_fields_setting_macsec + 1), /* 27 */
SETTING_FIELD (NM_SETTING_MACVLAN_SETTING_NAME, nmc_fields_setting_macvlan + 1), /* 28 */
SETTING_FIELD (NM_SETTING_VXLAN_SETTING_NAME, nmc_fields_setting_vxlan + 1), /* 29 */
SETTING_FIELD (NM_SETTING_PROXY_SETTING_NAME, nmc_fields_setting_proxy + 1), /* 30 */
{NULL, NULL, 0, NULL, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTINGS_NAMES_ALL_X NM_SETTING_CONNECTION_SETTING_NAME","\
@ -200,6 +201,7 @@ NmcOutputField nmc_fields_settings_names[] = {
NM_SETTING_DCB_SETTING_NAME"," \
NM_SETTING_TUN_SETTING_NAME"," \
NM_SETTING_IP_TUNNEL_SETTING_NAME"," \
NM_SETTING_MACSEC_SETTING_NAME"," \
NM_SETTING_MACVLAN_SETTING_NAME"," \
NM_SETTING_VXLAN_SETTING_NAME"," \
NM_SETTING_PROXY_SETTING_NAME
@ -450,6 +452,11 @@ usage_connection_add (void)
" remote <remote endpoint IP>\n"
" [local <local endpoint IP>]\n"
" [dev <parent device (ifname or connection UUID)>]\n\n"
" macsec: dev <parent device (connection UUID, ifname, or MAC)>\n"
" mode <psk|eap>\n"
" [cak <key> ckn <key>]\n"
" [encrypt yes|no]\n"
" [port 1-65534]\n\n\n"
" macvlan: dev <parent device (connection UUID, ifname, or MAC)>\n"
" mode vepa|bridge|private|passthru|source\n"
" [tap yes|no]\n\n"
@ -3028,6 +3035,14 @@ static const NameItem nmc_ip_tunnel_settings [] = {
{ NULL, NULL, NULL, FALSE }
};
static const NameItem nmc_macsec_settings [] = {
{ NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE },
{ NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE },
{ NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE },
{ NM_SETTING_MACSEC_SETTING_NAME, NULL, NULL, TRUE },
{ NULL, NULL, NULL, FALSE }
};
static const NameItem nmc_macvlan_settings [] = {
{ NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE },
{ NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE },
@ -3066,6 +3081,7 @@ static const NameItem nmc_valid_connection_types[] = {
{ "no-slave", NULL, nmc_no_slave_settings },
{ NM_SETTING_TUN_SETTING_NAME, NULL, nmc_tun_settings },
{ NM_SETTING_IP_TUNNEL_SETTING_NAME, NULL, nmc_ip_tunnel_settings },
{ NM_SETTING_MACSEC_SETTING_NAME, NULL, nmc_macsec_settings },
{ NM_SETTING_MACVLAN_SETTING_NAME, NULL, nmc_macvlan_settings },
{ NM_SETTING_VXLAN_SETTING_NAME, NULL, nmc_vxlan_settings },
{ NULL, NULL, NULL }
@ -3877,6 +3893,17 @@ gen_func_ip_tunnel_mode (const char *text, int state)
return nmc_rl_gen_func_basic (text, state, words);
}
static char *
gen_func_macsec_mode (const char *text, int state)
{
gs_free const char **words = NULL;
words = nm_utils_enum_get_values (nm_setting_macsec_mode_get_type (),
G_MININT,
G_MAXINT);
return nmc_rl_gen_func_basic (text, state, words);
}
static char *
gen_func_macvlan_mode (const char *text, int state)
{
@ -4292,6 +4319,13 @@ static OptionInfo option_info[] = {
{ NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PASSWORD, "password", OPTION_NONE, N_("Password [none]"), NULL, NULL, NULL },
{ NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_ENCAPSULATION, "encapsulation", OPTION_NONE, PROMPT_ADSL_ENCAP, PROMPT_ADSL_ENCAP_CHOICES,
NULL, gen_func_adsl_encap },
{ NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PARENT, "dev", OPTION_REQD, N_("MACsec parent device or connection UUID"), NULL, NULL, NULL },
{ NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MODE, "mode", OPTION_REQD, N_("Mode"), NULL, NULL, gen_func_macsec_mode },
{ NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_ENCRYPT, "encrypt", OPTION_NONE, N_("Enable encryption [yes]"), NULL, set_yes_no, gen_func_bool_values_l10n },
{ NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CAK, "cak", OPTION_NONE, N_("MKA CAK"), NULL, NULL, NULL },
{ NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CKN, "ckn", OPTION_NONE, N_("MKA_CKN"), NULL, NULL, NULL },
{ NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PORT, "port", OPTION_NONE, N_("SCI port [1]"), NULL, NULL, NULL },
{ NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT, "dev", OPTION_REQD, N_("MACVLAN parent device or connection UUID"), NULL,
NULL, nmc_rl_gen_func_ifnames },
{ NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_MODE, "mode", OPTION_REQD, PROMPT_MACVLAN_MODE, NULL,
@ -4823,6 +4857,8 @@ setting_name_to_name (const char *name)
return _("OLPC Mesh connection");
if (strcmp (name, NM_SETTING_ADSL_SETTING_NAME) == 0)
return _("ADSL connection");
if (strcmp (name, NM_SETTING_MACSEC_SETTING_NAME) == 0)
return _("MACsec connection");
if (strcmp (name, NM_SETTING_MACVLAN_SETTING_NAME) == 0)
return _("macvlan connection");
if (strcmp (name, NM_SETTING_VXLAN_SETTING_NAME) == 0)

View file

@ -743,6 +743,29 @@ NmcOutputField nmc_fields_setting_ip_tunnel[] = {
NM_SETTING_IP_TUNNEL_FLOW_LABEL","\
NM_SETTING_IP_TUNNEL_MTU
/* Available fields for NM_SETTING_MACSEC_SETTING_NAME */
NmcOutputField nmc_fields_setting_macsec[] = {
SETTING_FIELD ("name"), /* 0 */
SETTING_FIELD (NM_SETTING_MACSEC_PARENT), /* 1 */
SETTING_FIELD (NM_SETTING_MACSEC_MODE), /* 2 */
SETTING_FIELD (NM_SETTING_MACSEC_ENCRYPT), /* 3 */
SETTING_FIELD (NM_SETTING_MACSEC_MKA_CAK), /* 4 */
SETTING_FIELD (NM_SETTING_MACSEC_MKA_CAK_FLAGS), /* 5 */
SETTING_FIELD (NM_SETTING_MACSEC_MKA_CKN), /* 6 */
SETTING_FIELD (NM_SETTING_MACSEC_PORT), /* 7 */
SETTING_FIELD (NM_SETTING_MACSEC_VALIDATION), /* 8 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_MACSEC_ALL "name"","\
NM_SETTING_MACSEC_PARENT","\
NM_SETTING_MACSEC_MODE","\
NM_SETTING_MACSEC_ENCRYPT","\
NM_SETTING_MACSEC_MKA_CAK","\
NM_SETTING_MACSEC_MKA_CAK_FLAGS","\
NM_SETTING_MACSEC_MKA_CKN","\
NM_SETTING_MACSEC_PORT","\
NM_SETTING_MACSEC_VALIDATION
/* Available fields for NM_SETTING_MACVLAN_SETTING_NAME */
NmcOutputField nmc_fields_setting_macvlan[] = {
SETTING_FIELD ("name"), /* 0 */
@ -2115,6 +2138,94 @@ nmc_property_wifi_sec_get_wep_key_type (NMSetting *setting, NmcPropertyGetType g
return wep_key_type_to_string (nm_setting_wireless_security_get_wep_key_type (s_wireless_sec));
}
/* --- NM_SETTING_MACSEC_SETTING_NAME property get functions --- */
DEFINE_GETTER (nmc_property_macsec_get_parent, NM_SETTING_MACSEC_PARENT)
DEFINE_GETTER (nmc_property_macsec_get_encrypt, NM_SETTING_MACSEC_ENCRYPT)
DEFINE_GETTER (nmc_property_macsec_get_mka_cak, NM_SETTING_MACSEC_MKA_CAK)
DEFINE_SECRET_FLAGS_GETTER (nmc_property_macsec_get_mka_cak_flags, NM_SETTING_MACSEC_MKA_CAK_FLAGS)
DEFINE_GETTER (nmc_property_macsec_get_mka_ckn, NM_SETTING_MACSEC_MKA_CKN)
DEFINE_GETTER (nmc_property_macsec_get_port, NM_SETTING_MACSEC_PORT)
/* 'mode' */
static char *
nmc_property_macsec_get_mode (NMSetting *setting, NmcPropertyGetType get_type)
{
NMSettingMacsec *s_macsec = NM_SETTING_MACSEC (setting);
NMSettingMacsecMode mode;
mode = nm_setting_macsec_get_mode (s_macsec);
return nm_utils_enum_to_str (nm_setting_macsec_mode_get_type (), mode);
}
static gboolean
nmc_property_macsec_set_mode (NMSetting *setting, const char *prop,
const char *val, GError **error)
{
NMSettingMacsecMode mode;
gs_free char *options = NULL;
if (!nm_utils_enum_from_str (nm_setting_macsec_mode_get_type (), val,
(int *) &mode, NULL)) {
options = g_strjoinv (",",
(char **) nm_utils_enum_get_values (nm_setting_macsec_mode_get_type (),
G_MININT,
G_MAXINT));
g_set_error (error, 1, 0, _("invalid option '%s', use one of [%s]"),
val, options);
return FALSE;
}
g_object_set (setting, prop, mode, NULL);
return TRUE;
}
/* 'mode' */
static char *
nmc_property_macsec_get_validation (NMSetting *setting, NmcPropertyGetType get_type)
{
NMSettingMacsec *s_macsec = NM_SETTING_MACSEC (setting);
NMSettingMacsecValidation validation;
validation = nm_setting_macsec_get_validation (s_macsec);
return nm_utils_enum_to_str (nm_setting_macsec_validation_get_type (), validation);
}
static gboolean
nmc_property_macsec_set_validation (NMSetting *setting, const char *prop,
const char *val, GError **error)
{
NMSettingMacsecMode validation;
gs_free char *options = NULL;
if (!nm_utils_enum_from_str (nm_setting_macsec_validation_get_type (), val,
(int *) &validation, NULL)) {
options = g_strjoinv (",",
(char **) nm_utils_enum_get_values (nm_setting_macsec_validation_get_type (),
G_MININT,
G_MAXINT));
g_set_error (error, 1, 0, _("invalid option '%s', use one of [%s]"),
val, options);
return FALSE;
}
g_object_set (setting, prop, validation, NULL);
return TRUE;
}
static const char **
nmc_property_macsec_allowed_validation (NMSetting *setting, const char *prop)
{
static const char **words = NULL;
if (!words)
words = nm_utils_enum_get_values (nm_setting_macsec_validation_get_type(),
G_MININT,
G_MAXINT);
return words;
}
/* --- NM_SETTING_MACVLAN_SETTING_NAME property get functions --- */
DEFINE_GETTER (nmc_property_macvlan_get_parent, NM_SETTING_MACVLAN_PARENT)
DEFINE_GETTER (nmc_property_macvlan_get_promiscuous, NM_SETTING_MACVLAN_PROMISCUOUS)
@ -7836,6 +7947,64 @@ nmc_properties_init (void)
NULL,
NULL);
/* Add editable properties for NM_SETTING_MACSEC_SETTING_NAME */
nmc_add_prop_funcs (GLUE (MACSEC, PARENT),
nmc_property_macsec_get_parent,
nmc_property_set_string,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (MACSEC, MODE),
nmc_property_macsec_get_mode,
nmc_property_macsec_set_mode,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (MACSEC, ENCRYPT),
nmc_property_macsec_get_encrypt,
nmc_property_set_bool,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (MACSEC, MKA_CAK),
nmc_property_macsec_get_mka_cak,
nmc_property_set_string,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (MACSEC, MKA_CAK_FLAGS),
nmc_property_macsec_get_mka_cak_flags,
nmc_property_set_secret_flags,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (MACSEC, MKA_CKN),
nmc_property_macsec_get_mka_ckn,
nmc_property_set_string,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (MACSEC, PORT),
nmc_property_macsec_get_port,
nmc_property_set_int,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE (MACSEC, VALIDATION),
nmc_property_macsec_get_validation,
nmc_property_macsec_set_validation,
NULL,
NULL,
nmc_property_macsec_allowed_validation,
NULL);
/* Add editable properties for NM_SETTING_MACVLAN_SETTING_NAME */
nmc_add_prop_funcs (GLUE (MACVLAN, PARENT),
nmc_property_macvlan_get_parent,
@ -9232,6 +9401,39 @@ setting_ip_tunnel_details (NMSetting *setting, NmCli *nmc, const char *one_prop
return TRUE;
}
static gboolean
setting_macsec_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gboolean secrets)
{
NMSettingMacsec *s_macsec = NM_SETTING_MACSEC (setting);
NmcOutputField *tmpl, *arr;
size_t tmpl_len;
g_return_val_if_fail (NM_IS_SETTING_MACSEC (s_macsec), FALSE);
tmpl = nmc_fields_setting_macsec;
tmpl_len = sizeof (nmc_fields_setting_macsec);
nmc->print_fields.indices = parse_output_fields (one_prop ? one_prop : NMC_FIELDS_SETTING_MACSEC_ALL,
tmpl, FALSE, NULL, NULL);
arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES);
g_ptr_array_add (nmc->output_data, arr);
arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX);
set_val_str (arr, 0, g_strdup (nm_setting_get_name (setting)));
set_val_str (arr, 1, nmc_property_macsec_get_parent (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 2, nmc_property_macsec_get_mode (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 3, nmc_property_macsec_get_encrypt (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 4, GET_SECRET (secrets, setting, nmc_property_macsec_get_mka_cak));
set_val_str (arr, 5, nmc_property_macsec_get_mka_cak_flags (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 6, nmc_property_macsec_get_mka_ckn (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 7, nmc_property_macsec_get_port (setting, NMC_PROPERTY_GET_PRETTY));
set_val_str (arr, 8, nmc_property_macsec_get_validation (setting, NMC_PROPERTY_GET_PRETTY));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
return TRUE;
}
static gboolean
setting_macvlan_details (NMSetting *setting, NmCli *nmc, const char *one_prop, gboolean secrets)
{
@ -9364,6 +9566,7 @@ static const SettingDetails detail_printers[] = {
{ NM_SETTING_DCB_SETTING_NAME, setting_dcb_details },
{ NM_SETTING_TUN_SETTING_NAME, setting_tun_details },
{ NM_SETTING_IP_TUNNEL_SETTING_NAME, setting_ip_tunnel_details },
{ NM_SETTING_MACSEC_SETTING_NAME, setting_macsec_details },
{ NM_SETTING_MACVLAN_SETTING_NAME, setting_macvlan_details },
{ NM_SETTING_VXLAN_SETTING_NAME, setting_vxlan_details },
{ NM_SETTING_PROXY_SETTING_NAME, setting_proxy_details },

View file

@ -92,6 +92,7 @@ extern NmcOutputField nmc_fields_setting_dcb[];
extern NmcOutputField nmc_fields_setting_tun[];
extern NmcOutputField nmc_fields_setting_ip_tunnel[];
extern NmcOutputField nmc_fields_setting_macvlan[];
extern NmcOutputField nmc_fields_setting_macsec[];
extern NmcOutputField nmc_fields_setting_vxlan[];
extern NmcOutputField nmc_fields_setting_proxy[];

View file

@ -492,7 +492,7 @@ request_secrets_from_ui (NMSecretAgentSimpleRequest *request)
secret = nm_secret_agent_simple_secret_new (_("PIN"),
NM_SETTING (s_gsm),
NM_SETTING_GSM_PIN,
NULL,
NULL,
NULL,
FALSE);
g_ptr_array_add (secrets, secret);
@ -509,6 +509,25 @@ request_secrets_from_ui (NMSecretAgentSimpleRequest *request)
TRUE);
g_ptr_array_add (secrets, secret);
}
} else if (nm_connection_is_type (request->connection, NM_SETTING_MACSEC_SETTING_NAME)) {
NMSettingMacsec *s_macsec = nm_connection_get_setting_macsec (request->connection);
msg = g_strdup_printf (_("Secrets are required to access the MACsec network '%s'"),
nm_connection_get_id (request->connection));
if (nm_setting_macsec_get_mode (s_macsec) == NM_SETTING_MACSEC_MODE_PSK) {
title = _("MACsec PSK authentication");
secret = nm_secret_agent_simple_secret_new (_("MKA CAK"),
NM_SETTING (s_macsec),
NM_SETTING_MACSEC_MKA_CAK,
NULL,
NULL,
TRUE);
g_ptr_array_add (secrets, secret);
} else {
title = _("MACsec EAP authentication");
ok = add_8021x_secrets (request, secrets);
}
} else if (nm_connection_is_type (request->connection, NM_SETTING_CDMA_SETTING_NAME)) {
NMSettingCdma *s_cdma = nm_connection_get_setting_cdma (request->connection);

102
contrib/scripts/test-macsec Executable file
View file

@ -0,0 +1,102 @@
#!/bin/sh
# Test for MACsec in PSK mode
if [ "$#" = 2 ]; then
# DHCP helper
dev=$1
addr=$2
net=${addr%.*}
while [ ! -d "/sys/class/net/$dev" ]; do
sleep 1
done
ip a add $addr/24 dev "$dev"
dnsmasq --conf-file --no-hosts --keep-in-foreground --listen-address=$addr \
--dhcp-range=$net.250,$net.255,60m -i "$dev" \
--bind-interface --except-interface=lo
exit 0
fi
TMPDIR=$(mktemp -d /tmp/macsec-XXXXXX)
ADDR=172.16.10.1
MKA_CAK=00112233445566778899001122334455
MKA_CKN=5544332211009988776655443322110055443322110099887766554433221100
trap 'rm -rf "$TMPDIR"; kill $(jobs -p)' EXIT
echo "* Setup..."
# Clean up
ip netns del macsec-ns 2> /dev/null
ip link del macsec-veth 2> /dev/null
# Create namespace
ip netns add macsec-ns
# Create interfaces
ip link add macsec-veth type veth peer name macsec-vethp
# Move interfaces into namespace
ip link set macsec-vethp netns macsec-ns
# Bring up interfaces
ip link set macsec-veth up
ip -n macsec-ns link set macsec-vethp up
echo "* Start wpa_supplicant..."
cat <<EOF > $TMPDIR/wpa_supplicant.conf
ctrl_interface=/var/run/hostapd1
eapol_version=3
ap_scan=0
fast_reauth=1
network={
key_mgmt=NONE
eapol_flags=0
macsec_policy=1
mka_cak=$MKA_CAK
mka_ckn=$MKA_CKN
}
EOF
ip netns exec macsec-ns wpa_supplicant \
-c "$TMPDIR/wpa_supplicant.conf" -i macsec-vethp -Dmacsec_linux -dd > /dev/null 2>&1 &
ip netns exec macsec-ns $0 macsec0 $ADDR > /dev/null 2>&1 &
echo "* Create connections..."
nmcli connection delete test-macsec+ test-veth+ > /dev/null 2>&1
nmcli connection add type ethernet ifname macsec-veth con-name test-veth+ \
ipv4.method disabled ipv6.method ignore
nmcli connection add type macsec con-name test-macsec+ ifname macsec0 \
connection.autoconnect no \
macsec.parent macsec-veth macsec.mode psk \
macsec.mka-cak $MKA_CAK \
macsec.mka-cak-flags 0 \
macsec.mka-ckn $MKA_CKN
echo "* Bring up connections..."
nmcli connection up test-veth+
nmcli connection up test-macsec+
echo "* Test connectivity..."
ping $ADDR -c2 -q > /dev/null
res=$?
echo "* Clean up..."
nmcli connection delete test-macsec+ test-veth+ > /dev/null 2>&1
ip link del macsec-veth 2> /dev/null
ip netns del macsec-ns 2> /dev/null
echo
if [ "$res" = 0 ]; then
echo "Success"
else
echo "Failure"
fi
exit $res

View file

@ -55,6 +55,7 @@ content_files = \
dbus-org.freedesktop.NetworkManager.Settings.Connection.xml \
dbus-org.freedesktop.NetworkManager.Device.Bond.xml \
dbus-org.freedesktop.NetworkManager.Device.Macvlan.xml \
dbus-org.freedesktop.NetworkManager.Device.Macsec.xml \
dbus-org.freedesktop.NetworkManager.PPP.xml \
dbus-org.freedesktop.NetworkManager.Device.Vlan.xml \
dbus-org.freedesktop.NetworkManager.Device.Adsl.xml \

View file

@ -82,6 +82,7 @@
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Generic.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Infiniband.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.IPTunnel.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Macsec.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Macvlan.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Modem.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.OlpcMesh.xml"/>

View file

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<interface name="org.freedesktop.NetworkManager.Device.Macsec">
<!--
Parent:
The object path of the parent device.
-->
<property name="Parent" type="o" access="read"/>
<!--
Sci:
The Secure Channel Identifier in use.
-->
<property name="Sci" type="t" access="read"/>
<!--
IcvLength:
The length of ICV (Integrity Check Value).
-->
<property name="IcvLength" type="y" access="read"/>
<!--
CipherSuite:
The set of cryptographic algorithms in use
(e.g. 0x0080020001000001 for GCM-AES-128).
-->
<property name="CipherSuite" type="t" access="read"/>
<!--
Window:
The size of the replay window.
-->
<property name="Window" type="u" access="read"/>
<!--
EncodingSa:
The value of the Association Number (0..3) for the Security
Association in use.
-->
<property name="EncodingSa" type="y" access="read"/>
<!--
Validation:
The validation mode for incoming packets (strict, check,
disabled).
-->
<property name="Validation" type="s" access="read"/>
<!--
Encrypt:
Whether encryption of transmitted frames is enabled.
-->
<property name="Encrypt" type="b" access="read"/>
<!--
Protect:
Whether protection of transmitted frames is enabled.
-->
<property name="Protect" type="b" access="read"/>
<!--
IncludeSci:
Whether the SCI is always included in SecTAG for transmitted
frames.
-->
<property name="IncludeSci" type="b" access="read"/>
<!--
Es:
Whether the ES (End station) bit is enabled in SecTAG for
transmitted frames.
-->
<property name="Es" type="b" access="read"/>
<!--
Scb:
Whether the SCB (Single Copy Broadcast) bit is enabled in
SecTAG for transmitted frames.
-->
<property name="Scb" type="b" access="read"/>
<!--
ReplayProtect:
Whether replay protection is enabled.
-->
<property name="ReplayProtect" type="b" access="read"/>
<!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
DEPRECATED. Use the standard "PropertiesChanged" signal from "org.freedesktop.DBus.Properties" instead which exists since version NetworkManager 1.2.0.
-->
<signal name="PropertiesChanged">
<arg name="properties" type="a{sv}"/>
</signal>
</interface>
</node>

View file

@ -1850,6 +1850,7 @@ nm_connection_is_virtual (NMConnection *connection)
|| !strcmp (type, NM_SETTING_VLAN_SETTING_NAME)
|| !strcmp (type, NM_SETTING_TUN_SETTING_NAME)
|| !strcmp (type, NM_SETTING_IP_TUNNEL_SETTING_NAME)
|| !strcmp (type, NM_SETTING_MACSEC_SETTING_NAME)
|| !strcmp (type, NM_SETTING_MACVLAN_SETTING_NAME)
|| !strcmp (type, NM_SETTING_VXLAN_SETTING_NAME))
return TRUE;
@ -2161,6 +2162,24 @@ nm_connection_get_setting_ip6_config (NMConnection *connection)
return (NMSettingIPConfig *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
}
/**
* nm_connection_get_setting_macsec:
* @connection: the #NMConnection
*
* A shortcut to return any #NMSettingMacsec the connection might contain.
*
* Returns: (transfer none): an #NMSettingMacsec if the connection contains one, otherwise %NULL
*
* Since: 1.6
**/
NMSettingMacsec *
nm_connection_get_setting_macsec (NMConnection *connection)
{
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
return (NMSettingMacsec *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MACSEC);
}
/**
* nm_connection_get_setting_macvlan:
* @connection: the #NMConnection

View file

@ -206,6 +206,8 @@ NM_AVAILABLE_IN_1_2
NMSettingIPTunnel * nm_connection_get_setting_ip_tunnel (NMConnection *connection);
NMSettingIPConfig * nm_connection_get_setting_ip4_config (NMConnection *connection);
NMSettingIPConfig * nm_connection_get_setting_ip6_config (NMConnection *connection);
NM_AVAILABLE_IN_1_6
NMSettingMacsec * nm_connection_get_setting_macsec (NMConnection *connection);
NM_AVAILABLE_IN_1_2
NMSettingMacvlan * nm_connection_get_setting_macvlan (NMConnection *connection);
NMSettingOlpcMesh * nm_connection_get_setting_olpc_mesh (NMConnection *connection);

View file

@ -52,6 +52,7 @@
#include "nm-setting-proxy.h"
#include "nm-setting-ip4-config.h"
#include "nm-setting-ip6-config.h"
#include "nm-setting-macsec.h"
#include "nm-setting-macvlan.h"
#include "nm-setting-olpc-mesh.h"
#include "nm-setting-ppp.h"

View file

@ -46,6 +46,7 @@ typedef struct _NMSettingIPTunnel NMSettingIPTunnel;
typedef struct _NMSettingProxy NMSettingProxy;
typedef struct _NMSettingIP4Config NMSettingIP4Config;
typedef struct _NMSettingIP6Config NMSettingIP6Config;
typedef struct _NMSettingMacsec NMSettingMacsec;
typedef struct _NMSettingMacvlan NMSettingMacvlan;
typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh;
typedef struct _NMSettingPpp NMSettingPpp;

View file

@ -64,6 +64,7 @@
#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic"
#define NM_DBUS_INTERFACE_DEVICE_VETH NM_DBUS_INTERFACE_DEVICE ".Veth"
#define NM_DBUS_INTERFACE_DEVICE_TUN NM_DBUS_INTERFACE_DEVICE ".Tun"
#define NM_DBUS_INTERFACE_DEVICE_MACSEC NM_DBUS_INTERFACE_DEVICE ".Macsec"
#define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan"
#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan"
#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre"
@ -169,6 +170,7 @@ typedef enum {
* @NM_DEVICE_TYPE_MACVLAN: a MACVLAN interface
* @NM_DEVICE_TYPE_VXLAN: a VXLAN interface
* @NM_DEVICE_TYPE_VETH: a VETH interface
* @NM_DEVICE_TYPE_MACSEC: a MACsec interface
*
* #NMDeviceType values indicate the type of hardware represented by a
* device object.
@ -195,6 +197,7 @@ typedef enum {
NM_DEVICE_TYPE_MACVLAN = 18,
NM_DEVICE_TYPE_VXLAN = 19,
NM_DEVICE_TYPE_VETH = 20,
NM_DEVICE_TYPE_MACSEC = 21,
} NMDeviceType;
/**

View file

@ -0,0 +1,592 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-setting-macsec.h"
#include <stdlib.h>
#include <string.h>
#include "nm-utils.h"
#include "nm-core-types-internal.h"
#include "nm-setting-connection.h"
#include "nm-setting-private.h"
#include "nm-setting-wired.h"
#include "nm-connection-private.h"
/**
* SECTION:nm-setting-macsec
* @short_description: Describes connection properties for MACSEC interfaces
*
* The #NMSettingMacsec object is a #NMSetting subclass that describes properties
* necessary for connection to MACsec (IEEE 802.1AE) interfaces.
**/
G_DEFINE_TYPE_WITH_CODE (NMSettingMacsec, nm_setting_macsec, NM_TYPE_SETTING,
_nm_register_setting (MACSEC, 1))
NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_MACSEC)
#define NM_SETTING_MACSEC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_MACSEC, NMSettingMacsecPrivate))
typedef struct {
char *parent;
NMSettingMacsecMode mode;
gboolean encrypt;
char *mka_cak;
NMSettingSecretFlags mka_cak_flags;
char *mka_ckn;
int port;
NMSettingMacsecValidation validation;
} NMSettingMacsecPrivate;
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_PARENT,
PROP_MODE,
PROP_ENCRYPT,
PROP_MKA_CAK,
PROP_MKA_CAK_FLAGS,
PROP_MKA_CKN,
PROP_PORT,
PROP_VALIDATION,
);
/**
* nm_setting_macsec_new:
*
* Creates a new #NMSettingMacsec object with default values.
*
* Returns: (transfer full): the new empty #NMSettingMacsec object
*
* Since: 1.6
**/
NMSetting *
nm_setting_macsec_new (void)
{
return (NMSetting *) g_object_new (NM_TYPE_SETTING_MACSEC, NULL);
}
/**
* nm_setting_macsec_get_parent:
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingMacsec:parent property of the setting
*
* Since: 1.6
**/
const char *
nm_setting_macsec_get_parent (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), NULL);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->parent;
}
/**
* nm_setting_macsec_get_mode:
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingMacsec:mode property of the setting
*
* Since: 1.6
**/
NMSettingMacsecMode
nm_setting_macsec_get_mode (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), NM_SETTING_MACSEC_MODE_PSK);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->mode;
}
/**
* nm_setting_macsec_get_encrypt:
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingMacsec:encrypt property of the setting
*
* Since: 1.6
**/
gboolean
nm_setting_macsec_get_encrypt (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), TRUE);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->encrypt;
}
/**
* nm_setting_macsec_get_mka_cak
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingMacsec:mka-cak property of the setting
*
* Since: 1.6
**/
const char *
nm_setting_macsec_get_mka_cak (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), NULL);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->mka_cak;
}
/**
* nm_setting_macsec_get_mka_cak_flags:
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingSecretFlags pertaining to the #NMSettingMacsec:mka-cak
*
* Since: 1.6
**/
NMSettingSecretFlags
nm_setting_macsec_get_mka_cak_flags (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), NM_SETTING_SECRET_FLAG_NONE);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->mka_cak_flags;
}
/**
* nm_setting_macsec_get_mka_ckn:
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingMacsec:mka-ckn property of the setting
*
* Since: 1.6
**/
const char *
nm_setting_macsec_get_mka_ckn (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), NULL);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->mka_ckn;
}
/**
* nm_setting_macsec_get_port:
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingMacsec:port property of the setting
*
* Since: 1.6
**/
int
nm_setting_macsec_get_port (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), 1);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->port;
}
/**
* nm_setting_macsec_get_validation:
* @setting: the #NMSettingMacsec
*
* Returns: the #NMSettingMacsec:validation property of the setting
*
* Since: 1.6
**/
NMSettingMacsecValidation
nm_setting_macsec_get_validation (NMSettingMacsec *setting)
{
g_return_val_if_fail (NM_IS_SETTING_MACSEC (setting), NM_SETTING_MACSEC_VALIDATION_DISABLE);
return NM_SETTING_MACSEC_GET_PRIVATE (setting)->validation;
}
static GPtrArray *
need_secrets (NMSetting *setting)
{
NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE (setting);
GPtrArray *secrets = NULL;
if (priv->mode == NM_SETTING_MACSEC_MODE_PSK) {
if ( !priv->mka_cak
&& !NM_FLAGS_HAS (priv->mka_cak_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {
secrets = g_ptr_array_sized_new (1);
g_ptr_array_add (secrets, NM_SETTING_MACSEC_MKA_CAK);
}
}
return secrets;
}
/*********************************************************************/
static gboolean
verify_macsec_key (const char *key, gboolean cak, GError **error)
{
int req_len;
if (!key || !key[0]) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("the key is empty"));
return FALSE;
}
req_len = cak ?
NM_SETTING_MACSEC_MKA_CAK_LENGTH :
NM_SETTING_MACSEC_MKA_CKN_LENGTH;
if (strlen (key) != req_len) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("the key must be %d characters"), req_len);
return FALSE;
}
if (!NM_STRCHAR_ALL (key, ch, g_ascii_isxdigit (ch))) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("the key contais non-hexadecimal characters"));
return FALSE;
}
return TRUE;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE (setting);
NMSettingConnection *s_con = NULL;
NMSettingWired *s_wired = NULL;
NMSetting8021x *s_8021x = NULL;
if (connection) {
s_con = nm_connection_get_setting_connection (connection);
s_wired = nm_connection_get_setting_wired (connection);
s_8021x = nm_connection_get_setting_802_1x (connection);
}
if (priv->parent) {
if (nm_utils_is_uuid (priv->parent)) {
/* If we have an NMSettingConnection:master with slave-type="macsec",
* then it must be the same UUID.
*/
if (s_con) {
const char *master = NULL, *slave_type = NULL;
slave_type = nm_setting_connection_get_slave_type (s_con);
if (!g_strcmp0 (slave_type, NM_SETTING_MACSEC_SETTING_NAME))
master = nm_setting_connection_get_master (s_con);
if (master && g_strcmp0 (priv->parent, master) != 0) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' value doesn't match '%s=%s'"),
priv->parent, NM_SETTING_CONNECTION_MASTER, master);
g_prefix_error (error, "%s.%s: ", NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PARENT);
return FALSE;
}
}
} else if (!nm_utils_iface_valid_name (priv->parent)) {
/* parent must be either a UUID or an interface name */
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is neither an UUID nor an interface name"),
priv->parent);
g_prefix_error (error, "%s.%s: ", NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PARENT);
return FALSE;
}
} else {
/* If parent is NULL, the parent must be specified via
* NMSettingWired:mac-address.
*/
if ( connection
&& (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is not specified and neither is '%s:%s'"),
NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
g_prefix_error (error, "%s.%s: ", NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PARENT);
return FALSE;
}
}
if (priv->mode == NM_SETTING_MACSEC_MODE_PSK) {
if (!verify_macsec_key (priv->mka_ckn, FALSE, error)) {
g_prefix_error (error, "%s.%s: ", NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_MKA_CKN);
return FALSE;
}
} else if (priv->mode == NM_SETTING_MACSEC_MODE_EAP) {
if (!s_8021x) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("EAP key management requires '%s' setting presence"),
NM_SETTING_802_1X_SETTING_NAME);
g_prefix_error (error, "%s: ", NM_SETTING_MACSEC_SETTING_NAME);
return FALSE;
}
}
if (priv->port <= 0 || priv->port > 65534) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("invalid port %d"),
priv->port);
g_prefix_error (error, "%s.%s: ", NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACSEC_PORT);
return FALSE;
}
return TRUE;
}
static void
nm_setting_macsec_init (NMSettingMacsec *setting)
{
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingMacsec *setting = NM_SETTING_MACSEC (object);
NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE (setting);
switch (prop_id) {
case PROP_PARENT:
g_free (priv->parent);
priv->parent = g_value_dup_string (value);
break;
case PROP_MODE:
priv->mode = g_value_get_int (value);
break;
case PROP_ENCRYPT:
priv->encrypt = g_value_get_boolean (value);
break;
case PROP_MKA_CAK:
g_free (priv->mka_cak);
priv->mka_cak = g_value_dup_string (value);
break;
case PROP_MKA_CAK_FLAGS:
priv->mka_cak_flags = g_value_get_flags (value);
break;
case PROP_MKA_CKN:
g_free (priv->mka_ckn);
priv->mka_ckn = g_value_dup_string (value);
break;
case PROP_PORT:
priv->port = g_value_get_int (value);
break;
case PROP_VALIDATION:
priv->validation = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingMacsec *setting = NM_SETTING_MACSEC (object);
NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE (setting);
switch (prop_id) {
case PROP_PARENT:
g_value_set_string (value, priv->parent);
break;
case PROP_MODE:
g_value_set_int (value, priv->mode);
break;
case PROP_ENCRYPT:
g_value_set_boolean (value, priv->encrypt);
break;
case PROP_MKA_CAK:
g_value_set_string (value, priv->mka_cak);
break;
case PROP_MKA_CAK_FLAGS:
g_value_set_flags (value, priv->mka_cak_flags);
break;
case PROP_MKA_CKN:
g_value_set_string (value, priv->mka_ckn);
break;
case PROP_PORT:
g_value_set_int (value, priv->port);
break;
case PROP_VALIDATION:
g_value_set_int (value, priv->validation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
finalize (GObject *object)
{
NMSettingMacsec *setting = NM_SETTING_MACSEC (object);
NMSettingMacsecPrivate *priv = NM_SETTING_MACSEC_GET_PRIVATE (setting);
g_free (priv->parent);
if (priv->mka_cak) {
memset (priv->mka_cak, 0, strlen (priv->mka_cak));
g_free (priv->mka_cak);
}
g_free (priv->mka_ckn);
G_OBJECT_CLASS (nm_setting_macsec_parent_class)->finalize (object);
}
static void
nm_setting_macsec_class_init (NMSettingMacsecClass *setting_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
g_type_class_add_private (setting_class, sizeof (NMSettingMacsecPrivate));
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
parent_class->need_secrets = need_secrets;
/**
* NMSettingMacsec:parent:
*
* If given, specifies the parent interface name or parent connection UUID
* from which this MACSEC interface should be created. If this property is
* not specified, the connection must contain an #NMSettingWired setting
* with a #NMSettingWired:mac-address property.
*
* Since: 1.6
**/
obj_properties[PROP_PARENT] =
g_param_spec_string (NM_SETTING_MACSEC_PARENT, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingMacsec:mode:
*
* Specifies how the CAK (Connectivity Association Key) for MKA (MACsec Key
* Agreement) is obtained.
*
* Since: 1.6
**/
obj_properties[PROP_MODE] =
g_param_spec_int (NM_SETTING_MACSEC_MODE, "", "",
G_MININT, G_MAXINT, NM_SETTING_MACSEC_MODE_PSK,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingMacsec:encrypt:
*
* Whether the transmitted traffic must be encrypted.
*
* Since: 1.6
**/
obj_properties[PROP_ENCRYPT] =
g_param_spec_boolean (NM_SETTING_MACSEC_ENCRYPT, "", "",
TRUE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingMacsec:mka-cak:
*
* The pre-shared CAK (Connectivity Association Key) for MACsec
* Key Agreement.
*
* Since: 1.6
**/
obj_properties[PROP_MKA_CAK] =
g_param_spec_string (NM_SETTING_MACSEC_MKA_CAK, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_SECRET |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingMacsec:mka-cak-flags:
*
* Flags indicating how to handle the #NMSettingMacsec:mka-cak
* property.
*
* Since: 1.6
**/
obj_properties[PROP_MKA_CAK_FLAGS] =
g_param_spec_flags (NM_SETTING_MACSEC_MKA_CAK_FLAGS, "", "",
NM_TYPE_SETTING_SECRET_FLAGS,
NM_SETTING_SECRET_FLAG_NONE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingMacsec:mka-ckn:
*
* The pre-shared CKN (Connectivity-association Key Name) for
* MACsec Key Agreement.
*
* Since: 1.6
**/
obj_properties[PROP_MKA_CKN] =
g_param_spec_string (NM_SETTING_MACSEC_MKA_CKN, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingMacsec:port:
*
* The port component of the SCI (Secure Channel Identifier), between 1 and 65534.
*
* Since: 1.6
**/
obj_properties[PROP_PORT] =
g_param_spec_int (NM_SETTING_MACSEC_PORT, "", "",
1, 65534, 1,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingMacsec:validation:
*
* Specifies the validation mode for incoming frames.
*
* Since: 1.6
**/
obj_properties[PROP_VALIDATION] =
g_param_spec_int (NM_SETTING_MACSEC_VALIDATION, "", "",
G_MININT, G_MAXINT, NM_SETTING_MACSEC_VALIDATION_STRICT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
}

View file

@ -0,0 +1,126 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_SETTING_MACSEC_H__
#define __NM_SETTING_MACSEC_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-setting.h"
G_BEGIN_DECLS
#define NM_TYPE_SETTING_MACSEC (nm_setting_macsec_get_type ())
#define NM_SETTING_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_MACSEC, NMSettingMacsec))
#define NM_SETTING_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_MACSECCONFIG, NMSettingMacsecClass))
#define NM_IS_SETTING_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_MACSEC))
#define NM_IS_SETTING_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_MACSEC))
#define NM_SETTING_MACSEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_MACSEC, NMSettingMacsecClass))
#define NM_SETTING_MACSEC_SETTING_NAME "macsec"
#define NM_SETTING_MACSEC_PARENT "parent"
#define NM_SETTING_MACSEC_MODE "mode"
#define NM_SETTING_MACSEC_ENCRYPT "encrypt"
#define NM_SETTING_MACSEC_MKA_CAK "mka-cak"
#define NM_SETTING_MACSEC_MKA_CAK_FLAGS "mka-cak-flags"
#define NM_SETTING_MACSEC_MKA_CKN "mka-ckn"
#define NM_SETTING_MACSEC_PORT "port"
#define NM_SETTING_MACSEC_VALIDATION "validation"
/**
* NMSettingMacsec:
*/
struct _NMSettingMacsec {
NMSetting parent;
};
typedef struct {
NMSettingClass parent;
/*< private >*/
gpointer padding[4];
} NMSettingMacsecClass;
/**
* NMSettingMacsecMode:
* @NM_SETTING_MACSEC_MODE_PSK: The CAK is pre-shared
* @NM_SETTING_MACSEC_MODE_EAP: The CAK is the result of participation in EAP
*
* #NMSettingMacsecMode controls how the CAK (Connectivity Association Key) used
* in MKA (MACsec Key Agreement) is obtained.
*
* Since: 1.6
*/
typedef enum {
NM_SETTING_MACSEC_MODE_PSK = 0,
NM_SETTING_MACSEC_MODE_EAP = 1,
} NMSettingMacsecMode;
/**
* NMSettingMacsecValidation:
* @NM_SETTING_MACSEC_VALIDATION_DISABLE: All incoming frames are accepted if
* possible
* @NM_SETTING_MACSEC_VALIDATION_CHECK: Non protected, invalid, or impossible to
* verify frames are accepted and counted as "invalid"
* @NM_SETTING_MACSEC_VALIDATION_STRICT: Non protected, invalid, or impossible to
* verify frames are dropped
*
* #NMSettingMacsecValidation specifies a validation mode for incoming frames.
*
* Since: 1.6
*/
typedef enum {
NM_SETTING_MACSEC_VALIDATION_DISABLE = 0,
NM_SETTING_MACSEC_VALIDATION_CHECK = 1,
NM_SETTING_MACSEC_VALIDATION_STRICT = 2,
} NMSettingMacsecValidation;
#define NM_SETTING_MACSEC_MKA_CAK_LENGTH 32
#define NM_SETTING_MACSEC_MKA_CKN_LENGTH 64
NM_AVAILABLE_IN_1_6
GType nm_setting_macsec_get_type (void);
NM_AVAILABLE_IN_1_6
NMSetting *nm_setting_macsec_new (void);
NM_AVAILABLE_IN_1_6
const char *nm_setting_macsec_get_parent (NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_6
NMSettingMacsecMode nm_setting_macsec_get_mode (NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_6
gboolean nm_setting_macsec_get_encrypt (NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_6
const char *nm_setting_macsec_get_mka_cak (NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_6
NMSettingSecretFlags nm_setting_macsec_get_mka_cak_flags (NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_6
const char *nm_setting_macsec_get_mka_ckn (NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_6
int nm_setting_macsec_get_port (NMSettingMacsec *setting);
NM_AVAILABLE_IN_1_6
NMSettingMacsecValidation nm_setting_macsec_get_validation (NMSettingMacsec *setting);
G_END_DECLS
#endif /* __NM_SETTING_MACSEC_H__ */

View file

@ -68,6 +68,7 @@
#include <nm-setting-ip6-config.h>
#include <nm-setting-ip-config.h>
#include <nm-setting-ip-tunnel.h>
#include <nm-setting-macsec.h>
#include <nm-setting-macvlan.h>
#include <nm-setting-olpc-mesh.h>
#include <nm-setting-ppp.h>

View file

@ -1090,7 +1090,22 @@ global:
nm_client_get_dns_configuration;
nm_client_get_dns_mode;
nm_client_get_dns_rc_manager;
nm_connection_get_setting_macsec;
nm_connection_get_setting_proxy;
nm_device_macsec_get_cipher_suite;
nm_device_macsec_get_encoding_sa;
nm_device_macsec_get_encrypt;
nm_device_macsec_get_es;
nm_device_macsec_get_hw_address;
nm_device_macsec_get_icv_length;
nm_device_macsec_get_include_sci;
nm_device_macsec_get_protect;
nm_device_macsec_get_replay_protect;
nm_device_macsec_get_scb;
nm_device_macsec_get_sci;
nm_device_macsec_get_type;
nm_device_macsec_get_validation;
nm_device_macsec_get_window;
nm_dns_entry_get_domains;
nm_dns_entry_get_interface;
nm_dns_entry_get_nameservers;
@ -1099,6 +1114,18 @@ global:
nm_dns_entry_get_vpn;
nm_dns_entry_unref;
nm_setting_connection_get_autoconnect_retries;
nm_setting_macsec_get_encrypt;
nm_setting_macsec_get_mka_cak;
nm_setting_macsec_get_mka_cak_flags;
nm_setting_macsec_get_mka_ckn;
nm_setting_macsec_get_mode;
nm_setting_macsec_get_parent;
nm_setting_macsec_get_port;
nm_setting_macsec_get_type;
nm_setting_macsec_get_validation;
nm_setting_macsec_mode_get_type;
nm_setting_macsec_new;
nm_setting_macsec_validation_get_type;
nm_setting_proxy_get_type;
nm_setting_proxy_new;
nm_setting_proxy_get_method;

View file

@ -56,6 +56,7 @@
#include "nm-device-generic.h"
#include "nm-device-infiniband.h"
#include "nm-device-ip-tunnel.h"
#include "nm-device-macsec.h"
#include "nm-device-macvlan.h"
#include "nm-device-modem.h"
#include "nm-device-olpc-mesh.h"
@ -2061,6 +2062,8 @@ obj_nm_for_gdbus_object (GDBusObject *object, GDBusObjectManager *object_manager
type = NM_TYPE_DEVICE_INFINIBAND;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL) == 0)
type = NM_TYPE_DEVICE_IP_TUNNEL;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MACSEC) == 0)
type = NM_TYPE_DEVICE_MACSEC;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MACVLAN) == 0)
type = NM_TYPE_DEVICE_MACVLAN;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MODEM) == 0)

639
libnm/nm-device-macsec.c Normal file
View file

@ -0,0 +1,639 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include <string.h>
#include "nm-device-macsec.h"
#include "nm-device-private.h"
#include "nm-object-private.h"
#include "nm-utils.h"
G_DEFINE_TYPE (NMDeviceMacsec, nm_device_macsec, NM_TYPE_DEVICE)
#define NM_DEVICE_MACSEC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecPrivate))
typedef struct {
NMDevice *parent;
char *hw_address;
guint64 sci;
guint64 cipher_suite;
guint8 icv_length;
guint32 window;
guint8 encoding_sa;
gboolean encrypt;
gboolean protect;
gboolean include_sci;
gboolean es;
gboolean scb;
gboolean replay_protect;
char *validation;
} NMDeviceMacsecPrivate;
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_PARENT,
PROP_HW_ADDRESS,
PROP_SCI,
PROP_CIPHER_SUITE,
PROP_ICV_LENGTH,
PROP_WINDOW,
PROP_ENCODING_SA,
PROP_ENCRYPT,
PROP_PROTECT,
PROP_INCLUDE_SCI,
PROP_ES,
PROP_SCB,
PROP_REPLAY_PROTECT,
PROP_VALIDATION,
);
/**
* nm_device_macsec_get_parent:
* @device: a #NMDeviceMacsec
*
* Returns: (transfer none): the device's parent device
*
* Since: 1.6
**/
NMDevice *
nm_device_macsec_get_parent (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), NULL);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->parent;
}
/**
* nm_device_macsec_get_hw_address:
* @device: a #NMDeviceMacsec
*
* Gets the hardware (MAC) address of the #NMDeviceMacsec
*
* Returns: the hardware address. This is the internal string used by the
* device, and must not be modified.
*
* Since: 1.6
**/
const char *
nm_device_macsec_get_hw_address (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), NULL);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->hw_address;
}
/**
* nm_device_macsec_get_sci:
* @device: a #NMDeviceMacsec
*
* Gets the Secure Channel Identifier in use
*
* Returns: the SCI
*
* Since: 1.6
**/
guint64
nm_device_macsec_get_sci (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), 0);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->sci;
}
/**
* nm_device_macsec_get_icv_length:
* @device: a #NMDeviceMacsec
*
* Gets the length of ICV (Integrity Check Value)
*
* Returns: the length of ICV
*
* Since: 1.6
**/
guint8
nm_device_macsec_get_icv_length (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), 0);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->icv_length;
}
/**
* nm_device_macsec_get_cipher_suite:
* @device: a #NMDeviceMacsec
*
* Gets the set of cryptographic algorithms in use
*
* Returns:
*
* Since: 1.6
**/
guint64
nm_device_macsec_get_cipher_suite (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), 0);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->cipher_suite;
}
/**
* nm_device_macsec_get_window:
* @device: a #NMDeviceMacsec
*
* Gets the size of the replay window
*
* Returns: size of the replay window
*
* Since: 1.6
**/
guint
nm_device_macsec_get_window (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), 0);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->window;
}
/**
* nm_device_macsec_get_encoding_sa:
* @device: a #NMDeviceMacsec
*
* Gets the value of the Association Number (0..3) for the Security
* Association in use.
*
* Returns: the current Security Association
*
* Since: 1.6
**/
guint8
nm_device_macsec_get_encoding_sa (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), 0);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->encoding_sa;
}
/**
* nm_device_macsec_get_validation:
* @device: a #NMDeviceMacsec
*
* Gets the validation mode for incoming packets (strict, check,
* disabled)
*
* Returns: the validation mode
*
* Since: 1.6
**/
const char *
nm_device_macsec_get_validation (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), NULL);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->validation;
}
/**
* nm_device_macsec_get_encrypt:
* @device: a #NMDeviceMacsec
*
* Gets whether encryption of transmitted frames is enabled
*
* Returns: whether encryption is enabled
*
* Since: 1.6
**/
gboolean
nm_device_macsec_get_encrypt (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), FALSE);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->encrypt;
}
/**
* nm_device_macsec_get_protect:
* @device: a #NMDeviceMacsec
*
* Gets whether protection of transmitted frames is enabled
*
* Returns: whether protection is enabled
*
* Since: 1.6
**/
gboolean
nm_device_macsec_get_protect (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), FALSE);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->protect;
}
/**
* nm_device_macsec_get_include_sci:
* @device: a #NMDeviceMacsec
*
* Gets whether the SCI is always included in SecTAG for transmitted
* frames
*
* Returns: whether the SCI is always included
*
* Since: 1.6
**/
gboolean
nm_device_macsec_get_include_sci (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), FALSE);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->include_sci;
}
/**
* nm_device_macsec_get_es:
* @device: a #NMDeviceMacsec
*
* Gets whether the ES (End station) bit is enabled in SecTAG for
* transmitted frames
*
* Returns: whether the ES (End station) bit is enabled
*
* Since: 1.6
**/
gboolean
nm_device_macsec_get_es (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), FALSE);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->es;
}
/**
* nm_device_macsec_get_scb:
* @device: a #NMDeviceMacsec
*
* Gets whether the SCB (Single Copy Broadcast) bit is enabled in
* SecTAG for transmitted frames
*
* Returns: whether the SCB (Single Copy Broadcast) bit is enabled
*
* Since: 1.6
**/
gboolean
nm_device_macsec_get_scb (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), FALSE);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->scb;
}
/**
* nm_device_macsec_get_replay_protect:
* @device: a #NMDeviceMacsec
*
* Gets whether replay protection is enabled
*
* Returns: whether replay protection is enabled
*
* Since: 1.6
**/
gboolean
nm_device_macsec_get_replay_protect (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), FALSE);
return NM_DEVICE_MACSEC_GET_PRIVATE (device)->replay_protect;
}
static const char *
get_hw_address (NMDevice *device)
{
return nm_device_macsec_get_hw_address (NM_DEVICE_MACSEC (device));
}
/***********************************************************/
static void
nm_device_macsec_init (NMDeviceMacsec *device)
{
}
static void
init_dbus (NMObject *object)
{
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (object);
const NMPropertiesInfo property_info[] = {
{ NM_DEVICE_MACSEC_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
{ NM_DEVICE_MACSEC_HW_ADDRESS, &priv->hw_address },
{ NM_DEVICE_MACSEC_SCI, &priv->sci },
{ NM_DEVICE_MACSEC_CIPHER_SUITE, &priv->cipher_suite },
{ NM_DEVICE_MACSEC_ICV_LENGTH, &priv->icv_length },
{ NM_DEVICE_MACSEC_WINDOW, &priv->window },
{ NM_DEVICE_MACSEC_ENCODING_SA, &priv->encoding_sa },
{ NM_DEVICE_MACSEC_ENCRYPT, &priv->encrypt },
{ NM_DEVICE_MACSEC_PROTECT, &priv->protect },
{ NM_DEVICE_MACSEC_INCLUDE_SCI, &priv->include_sci },
{ NM_DEVICE_MACSEC_ES, &priv->es },
{ NM_DEVICE_MACSEC_SCB, &priv->scb },
{ NM_DEVICE_MACSEC_REPLAY_PROTECT, &priv->replay_protect },
{ NM_DEVICE_MACSEC_VALIDATION, &priv->validation },
{ NULL },
};
NM_OBJECT_CLASS (nm_device_macsec_parent_class)->init_dbus (object);
_nm_object_register_properties (object,
NM_DBUS_INTERFACE_DEVICE_MACSEC,
property_info);
}
static void
finalize (GObject *object)
{
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (object);
g_free (priv->validation);
g_free (priv->hw_address);
g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_macsec_parent_class)->finalize (object);
}
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NMDeviceMacsec *device = NM_DEVICE_MACSEC (object);
switch (prop_id) {
case PROP_PARENT:
g_value_set_object (value, nm_device_macsec_get_parent (device));
break;
case PROP_HW_ADDRESS:
g_value_set_string (value, nm_device_macsec_get_hw_address (device));
break;
case PROP_SCI:
g_value_set_uint64 (value, nm_device_macsec_get_sci (device));
break;
case PROP_ICV_LENGTH:
g_value_set_uchar (value, nm_device_macsec_get_icv_length (device));
break;
case PROP_CIPHER_SUITE:
g_value_set_uint64 (value, nm_device_macsec_get_cipher_suite (device));
break;
case PROP_WINDOW:
g_value_set_uint (value, nm_device_macsec_get_window (device));
break;
case PROP_ENCODING_SA:
g_value_set_uchar (value, nm_device_macsec_get_encoding_sa (device));
break;
case PROP_VALIDATION:
g_value_set_string (value, nm_device_macsec_get_validation (device));
break;
case PROP_ENCRYPT:
g_value_set_boolean (value, nm_device_macsec_get_encrypt (device));
break;
case PROP_PROTECT:
g_value_set_boolean (value, nm_device_macsec_get_protect (device));
break;
case PROP_INCLUDE_SCI:
g_value_set_boolean (value, nm_device_macsec_get_include_sci (device));
break;
case PROP_ES:
g_value_set_boolean (value, nm_device_macsec_get_es (device));
break;
case PROP_SCB:
g_value_set_boolean (value, nm_device_macsec_get_scb (device));
break;
case PROP_REPLAY_PROTECT:
g_value_set_boolean (value, nm_device_macsec_get_replay_protect (device));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_device_macsec_class_init (NMDeviceMacsecClass *macsec_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (macsec_class);
NMObjectClass *nm_object_class = NM_OBJECT_CLASS (macsec_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (macsec_class);
g_type_class_add_private (macsec_class, sizeof (NMDeviceMacsecPrivate));
object_class->finalize = finalize;
object_class->get_property = get_property;
nm_object_class->init_dbus = init_dbus;
device_class->get_hw_address = get_hw_address;
/**
* NMDeviceMacsec:parent:
*
* The devices's parent device.
*
* Since: 1.6
**/
obj_properties[PROP_PARENT] =
g_param_spec_object (NM_DEVICE_MACSEC_PARENT, "", "",
NM_TYPE_DEVICE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:hw-address:
*
* The hardware (MAC) address of the device.
*
* Since: 1.6
**/
obj_properties[PROP_HW_ADDRESS] =
g_param_spec_string (NM_DEVICE_MACSEC_HW_ADDRESS, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:sci:
*
* The Secure Channel Identifier in use.
*
* Since: 1.6
**/
obj_properties[PROP_SCI] =
g_param_spec_uint64 (NM_DEVICE_MACSEC_SCI, "", "",
0, G_MAXUINT64, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:icv-length:
*
* The length of ICV (Integrity Check Value).
*
* Since: 1.6
**/
obj_properties[PROP_ICV_LENGTH] =
g_param_spec_uchar (NM_DEVICE_MACSEC_ICV_LENGTH, "", "",
0, G_MAXUINT8, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:cipher-suite:
*
* The set of cryptographic algorithms in use.
*
* Since: 1.6
**/
obj_properties[PROP_CIPHER_SUITE] =
g_param_spec_uint64 (NM_DEVICE_MACSEC_CIPHER_SUITE, "", "",
0, G_MAXUINT64, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:window:
*
* The size of the replay window.
*
* Since: 1.6
**/
obj_properties[PROP_WINDOW] =
g_param_spec_uint (NM_DEVICE_MACSEC_WINDOW, "", "",
0, G_MAXUINT32, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:encoding-sa:
*
* The value of the Association Number (0..3) for the Security
* Association in use.
*
* Since: 1.6
**/
obj_properties[PROP_ENCODING_SA] =
g_param_spec_uchar (NM_DEVICE_MACSEC_ENCODING_SA, "", "",
0, G_MAXUINT8, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:validation:
*
* The validation mode for incoming packets (strict, check,
* disabled).
*
* Since: 1.6
**/
obj_properties[PROP_VALIDATION] =
g_param_spec_string (NM_DEVICE_MACSEC_VALIDATION, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:encrypt:
*
* Whether encryption of transmitted frames is enabled.
*
* Since: 1.6
**/
obj_properties[PROP_ENCRYPT] =
g_param_spec_boolean (NM_DEVICE_MACSEC_ENCRYPT, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:protect:
*
* Whether protection of transmitted frames is enabled.
*
* Since: 1.6
**/
obj_properties[PROP_PROTECT] =
g_param_spec_boolean (NM_DEVICE_MACSEC_PROTECT, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:include-sci:
*
* Whether the SCI is always included in SecTAG for transmitted
* frames.
*
* Since: 1.6
**/
obj_properties[PROP_INCLUDE_SCI] =
g_param_spec_boolean (NM_DEVICE_MACSEC_INCLUDE_SCI, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:es:
*
* Whether the ES (End station) bit is enabled in SecTAG for
* transmitted frames.
*
* Since: 1.6
**/
obj_properties[PROP_ES] =
g_param_spec_boolean (NM_DEVICE_MACSEC_ES, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:scb:
*
* Whether the SCB (Single Copy Broadcast) bit is enabled in
* SecTAG for transmitted frames.
*
* Since: 1.6
**/
obj_properties[PROP_SCB] =
g_param_spec_boolean (NM_DEVICE_MACSEC_SCB, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMDeviceMacsec:replay-protect:
*
* Whether replay protection is enabled.
*
* Since: 1.6
**/
obj_properties[PROP_REPLAY_PROTECT] =
g_param_spec_boolean (NM_DEVICE_MACSEC_REPLAY_PROTECT, "", "",
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
}

101
libnm/nm-device-macsec.h Normal file
View file

@ -0,0 +1,101 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_MACSEC_H__
#define __NM_DEVICE_MACSEC_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include <nm-device.h>
G_BEGIN_DECLS
#define NM_TYPE_DEVICE_MACSEC (nm_device_macsec_get_type ())
#define NM_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsec))
#define NM_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass))
#define NM_IS_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MACSEC))
#define NM_IS_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MACSEC))
#define NM_DEVICE_MACSEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass))
#define NM_DEVICE_MACSEC_PARENT "parent"
#define NM_DEVICE_MACSEC_HW_ADDRESS "hw-address"
#define NM_DEVICE_MACSEC_SCI "sci"
#define NM_DEVICE_MACSEC_ICV_LENGTH "icv-length"
#define NM_DEVICE_MACSEC_CIPHER_SUITE "cipher-suite"
#define NM_DEVICE_MACSEC_WINDOW "window"
#define NM_DEVICE_MACSEC_ENCODING_SA "encoding-sa"
#define NM_DEVICE_MACSEC_VALIDATION "validation"
#define NM_DEVICE_MACSEC_ENCRYPT "encrypt"
#define NM_DEVICE_MACSEC_PROTECT "protect"
#define NM_DEVICE_MACSEC_INCLUDE_SCI "include-sci"
#define NM_DEVICE_MACSEC_ES "es"
#define NM_DEVICE_MACSEC_SCB "scb"
#define NM_DEVICE_MACSEC_REPLAY_PROTECT "replay-protect"
/**
* NMDeviceMacsec:
*/
struct _NMDeviceMacsec {
NMDevice parent;
};
typedef struct {
NMDeviceClass parent;
/*< private >*/
gpointer padding[4];
} NMDeviceMacsecClass;
NM_AVAILABLE_IN_1_6
GType nm_device_macsec_get_type (void);
NM_AVAILABLE_IN_1_6
NMDevice * nm_device_macsec_get_parent (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
const char * nm_device_macsec_get_hw_address (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
guint64 nm_device_macsec_get_sci (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
guint8 nm_device_macsec_get_icv_length (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
guint64 nm_device_macsec_get_cipher_suite (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
guint nm_device_macsec_get_window (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
guint8 nm_device_macsec_get_encoding_sa (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
const char * nm_device_macsec_get_validation (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
gboolean nm_device_macsec_get_encrypt (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
gboolean nm_device_macsec_get_protect (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
gboolean nm_device_macsec_get_include_sci (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
gboolean nm_device_macsec_get_es (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
gboolean nm_device_macsec_get_scb (NMDeviceMacsec *device);
NM_AVAILABLE_IN_1_6
gboolean nm_device_macsec_get_replay_protect (NMDeviceMacsec *device);
G_END_DECLS
#endif /* __NM_DEVICE_MACSEC_H__ */

View file

@ -267,6 +267,7 @@ coerce_type (NMDeviceType type)
case NM_DEVICE_TYPE_BRIDGE:
case NM_DEVICE_TYPE_VLAN:
case NM_DEVICE_TYPE_ADSL:
case NM_DEVICE_TYPE_MACSEC:
case NM_DEVICE_TYPE_MACVLAN:
case NM_DEVICE_TYPE_VXLAN:
case NM_DEVICE_TYPE_IP_TUNNEL:
@ -1691,6 +1692,8 @@ get_type_name (NMDevice *device)
return _("Tun");
case NM_DEVICE_TYPE_VETH:
return _("Veth");
case NM_DEVICE_TYPE_MACSEC:
return _("MACsec");
case NM_DEVICE_TYPE_GENERIC:
case NM_DEVICE_TYPE_UNUSED1:
case NM_DEVICE_TYPE_UNUSED2:

View file

@ -38,6 +38,7 @@ typedef struct _NMDeviceEthernet NMDeviceEthernet;
typedef struct _NMDeviceGeneric NMDeviceGeneric;
typedef struct _NMDeviceInfiniband NMDeviceInfiniband;
typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel;
typedef struct _NMDeviceMacsec NMDeviceMacsec;
typedef struct _NMDeviceMacvlan NMDeviceMacvlan;
typedef struct _NMDeviceModem NMDeviceModem;
typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh;

View file

@ -68,6 +68,7 @@ libnm-core/nm-setting-ip-config.c
libnm-core/nm-setting-ip4-config.c
libnm-core/nm-setting-ip6-config.c
libnm-core/nm-setting-ip-tunnel.c
libnm-core/nm-setting-macsec.c
libnm-core/nm-setting-macvlan.c
libnm-core/nm-setting-olpc-mesh.c
libnm-core/nm-setting-ppp.c

View file

@ -75,7 +75,6 @@ typedef struct Supplicant {
gulong iface_state_id;
/* Timeouts and idles */
guint iface_con_error_cb_id;
guint con_timeout_id;
} Supplicant;
@ -430,7 +429,6 @@ supplicant_interface_clear_handlers (NMDeviceEthernet *self)
nm_clear_g_source (&priv->supplicant_timeout_id);
nm_clear_g_source (&priv->supplicant.con_timeout_id);
nm_clear_g_source (&priv->supplicant.iface_con_error_cb_id);
nm_clear_g_signal_handler (priv->supplicant.iface, &priv->supplicant.iface_error_id);
}
@ -679,19 +677,6 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
}
}
static gboolean
supplicant_iface_connection_error_cb_handler (gpointer user_data)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
supplicant_interface_release (self);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
priv->supplicant.iface_con_error_cb_id = 0;
return FALSE;
}
static void
supplicant_iface_connection_error_cb (NMSupplicantInterface *iface,
const char *name,
@ -699,18 +684,15 @@ supplicant_iface_connection_error_cb (NMSupplicantInterface *iface,
gpointer user_data)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
guint id;
_LOGW (LOGD_DEVICE | LOGD_ETHER,
"Activation: (ethernet) association request to the supplicant failed: %s - %s",
name, message);
if (priv->supplicant.iface_con_error_cb_id)
g_source_remove (priv->supplicant.iface_con_error_cb_id);
id = g_idle_add (supplicant_iface_connection_error_cb_handler, self);
priv->supplicant.iface_con_error_cb_id = id;
supplicant_interface_release (self);
nm_device_queue_state (NM_DEVICE (self),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
}
static NMActStageReturn
@ -794,7 +776,7 @@ supplicant_interface_init (NMDeviceEthernet *self)
priv->supplicant.iface = nm_supplicant_manager_create_interface (priv->supplicant.mgr,
nm_device_get_iface (NM_DEVICE (self)),
FALSE);
NM_SUPPLICANT_DRIVER_WIRED);
if (!priv->supplicant.iface) {
_LOGE (LOGD_DEVICE | LOGD_ETHER,
@ -810,7 +792,7 @@ supplicant_interface_init (NMDeviceEthernet *self)
/* Hook up error signal handler to capture association errors */
priv->supplicant.iface_error_id = g_signal_connect (priv->supplicant.iface,
"connection-error",
NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR,
G_CALLBACK (supplicant_iface_connection_error_cb),
self);

View file

@ -405,6 +405,7 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call
_ADD_INTERNAL (nm_ethernet_device_factory_get_type);
_ADD_INTERNAL (nm_infiniband_device_factory_get_type);
_ADD_INTERNAL (nm_ip_tunnel_device_factory_get_type);
_ADD_INTERNAL (nm_macsec_device_factory_get_type);
_ADD_INTERNAL (nm_macvlan_device_factory_get_type);
_ADD_INTERNAL (nm_tun_device_factory_get_type);
_ADD_INTERNAL (nm_veth_device_factory_get_type);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,54 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_MACSEC_H__
#define __NM_DEVICE_MACSEC_H__
#include "nm-device.h"
#define NM_TYPE_DEVICE_MACSEC (nm_device_macsec_get_type ())
#define NM_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsec))
#define NM_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass))
#define NM_IS_DEVICE_MACSEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MACSEC))
#define NM_IS_DEVICE_MACSEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MACSEC))
#define NM_DEVICE_MACSEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MACSEC, NMDeviceMacsecClass))
#define NM_DEVICE_MACSEC_SCI "sci"
#define NM_DEVICE_MACSEC_CIPHER_SUITE "cipher-suite"
#define NM_DEVICE_MACSEC_ICV_LENGTH "icv-length"
#define NM_DEVICE_MACSEC_WINDOW "window"
#define NM_DEVICE_MACSEC_ENCODING_SA "encoding-sa"
#define NM_DEVICE_MACSEC_VALIDATION "validation"
#define NM_DEVICE_MACSEC_ENCRYPT "encrypt"
#define NM_DEVICE_MACSEC_PROTECT "protect"
#define NM_DEVICE_MACSEC_INCLUDE_SCI "include-sci"
#define NM_DEVICE_MACSEC_ES "es"
#define NM_DEVICE_MACSEC_SCB "scb"
#define NM_DEVICE_MACSEC_REPLAY_PROTECT "replay-protect"
/* defined in the parent class, but exposed on D-Bus by the subclass. */
#define NM_DEVICE_MACSEC_PARENT NM_DEVICE_PARENT
typedef struct _NMDeviceMacsec NMDeviceMacsec;
typedef struct _NMDeviceMacsecClass NMDeviceMacsecClass;
GType nm_device_macsec_get_type (void);
#endif /* __NM_DEVICE_MACSEC_H__ */

View file

@ -1330,6 +1330,8 @@ nm_device_get_priority (NMDevice *self)
case NM_DEVICE_TYPE_ETHERNET:
case NM_DEVICE_TYPE_VETH:
return 100;
case NM_DEVICE_TYPE_MACSEC:
return 125;
case NM_DEVICE_TYPE_INFINIBAND:
return 150;
case NM_DEVICE_TYPE_ADSL:

View file

@ -232,7 +232,7 @@ supplicant_interface_acquire (NMDeviceWifi *self)
priv->sup_iface = nm_supplicant_manager_create_interface (priv->sup_mgr,
nm_device_get_iface (NM_DEVICE (self)),
TRUE);
NM_SUPPLICANT_DRIVER_WIRELESS);
if (!priv->sup_iface) {
_LOGE (LOGD_WIFI, "Couldn't initialize supplicant interface");
return FALSE;

View file

@ -129,6 +129,7 @@ typedef enum {
NM_LINK_TYPE_IP6TNL,
NM_LINK_TYPE_IPIP,
NM_LINK_TYPE_LOOPBACK,
NM_LINK_TYPE_MACSEC,
NM_LINK_TYPE_MACVLAN,
NM_LINK_TYPE_MACVTAP,
NM_LINK_TYPE_OPENVSWITCH,
@ -160,6 +161,7 @@ typedef enum {
NMP_OBJECT_TYPE_LNK_INFINIBAND,
NMP_OBJECT_TYPE_LNK_IP6TNL,
NMP_OBJECT_TYPE_LNK_IPIP,
NMP_OBJECT_TYPE_LNK_MACSEC,
NMP_OBJECT_TYPE_LNK_MACVLAN,
NMP_OBJECT_TYPE_LNK_MACVTAP,
NMP_OBJECT_TYPE_LNK_SIT,

View file

@ -21,6 +21,7 @@
#include "nm-linux-platform.h"
#include <endian.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
@ -111,6 +112,25 @@
/*****************************************************************************/
#define IFLA_MACSEC_UNSPEC 0
#define IFLA_MACSEC_SCI 1
#define IFLA_MACSEC_PORT 2
#define IFLA_MACSEC_ICV_LEN 3
#define IFLA_MACSEC_CIPHER_SUITE 4
#define IFLA_MACSEC_WINDOW 5
#define IFLA_MACSEC_ENCODING_SA 6
#define IFLA_MACSEC_ENCRYPT 7
#define IFLA_MACSEC_PROTECT 8
#define IFLA_MACSEC_INC_SCI 9
#define IFLA_MACSEC_ES 10
#define IFLA_MACSEC_SCB 11
#define IFLA_MACSEC_REPLAY_PROTECT 12
#define IFLA_MACSEC_VALIDATION 13
#define IFLA_MACSEC_PAD 14
#define __IFLA_MACSEC_MAX 15
/*****************************************************************************/
#define _NMLOG_PREFIX_NAME "platform-linux"
#define _NMLOG_DOMAIN LOGD_PLATFORM
#define _NMLOG2_DOMAIN LOGD_PLATFORM
@ -365,6 +385,7 @@ static const LinkDesc linktypes[] = {
{ NM_LINK_TYPE_IP6TNL, "ip6tnl", "ip6tnl", NULL },
{ NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL },
{ NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL },
{ NM_LINK_TYPE_MACSEC, "macsec", "macsec", NULL },
{ NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL },
{ NM_LINK_TYPE_MACVTAP, "macvtap", "macvtap", NULL },
{ NM_LINK_TYPE_OPENVSWITCH, "openvswitch", "openvswitch", NULL },
@ -1109,6 +1130,56 @@ _parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
/*****************************************************************************/
static NMPObject *
_parse_lnk_macsec (const char *kind, struct nlattr *info_data)
{
static struct nla_policy policy[__IFLA_MACSEC_MAX] = {
[IFLA_MACSEC_SCI] = { .type = NLA_U64 },
[IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 },
[IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 },
[IFLA_MACSEC_WINDOW] = { .type = NLA_U32 },
[IFLA_MACSEC_ENCODING_SA] = { .type = NLA_U8 },
[IFLA_MACSEC_ENCRYPT] = { .type = NLA_U8 },
[IFLA_MACSEC_PROTECT] = { .type = NLA_U8 },
[IFLA_MACSEC_INC_SCI] = { .type = NLA_U8 },
[IFLA_MACSEC_ES] = { .type = NLA_U8 },
[IFLA_MACSEC_SCB] = { .type = NLA_U8 },
[IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 },
[IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 },
};
struct nlattr *tb[__IFLA_MACSEC_MAX];
int err;
NMPObject *obj;
NMPlatformLnkMacsec *props;
if (!info_data || !nm_streq0 (kind, "macsec"))
return NULL;
err = nla_parse_nested (tb, __IFLA_MACSEC_MAX - 1, info_data, policy);
if (err < 0)
return NULL;
obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_MACSEC, NULL);
props = &obj->lnk_macsec;
props->sci = tb[IFLA_MACSEC_SCI] ? be64toh (nla_get_u64 (tb[IFLA_MACSEC_SCI])) : 0;
props->icv_length = tb[IFLA_MACSEC_ICV_LEN] ? nla_get_u8 (tb[IFLA_MACSEC_ICV_LEN]) : 0;
props->cipher_suite = tb [IFLA_MACSEC_CIPHER_SUITE] ? nla_get_u64 (tb[IFLA_MACSEC_CIPHER_SUITE]) : 0;
props->window = tb [IFLA_MACSEC_WINDOW] ? nla_get_u32 (tb[IFLA_MACSEC_WINDOW]) : 0;
props->encoding_sa = tb[IFLA_MACSEC_ENCODING_SA] ? !!nla_get_u8 (tb[IFLA_MACSEC_ENCODING_SA]) : 0;
props->encrypt = tb[IFLA_MACSEC_ENCRYPT] ? !!nla_get_u8 (tb[IFLA_MACSEC_ENCRYPT]) : 0;
props->protect = tb[IFLA_MACSEC_PROTECT] ? !!nla_get_u8 (tb[IFLA_MACSEC_PROTECT]) : 0;
props->include_sci = tb[IFLA_MACSEC_INC_SCI] ? !!nla_get_u8 (tb[IFLA_MACSEC_INC_SCI]) : 0;
props->es = tb[IFLA_MACSEC_ES] ? !!nla_get_u8 (tb[IFLA_MACSEC_ES]) : 0;
props->scb = tb[IFLA_MACSEC_SCB] ? !!nla_get_u8 (tb[IFLA_MACSEC_SCB]) : 0;
props->replay_protect = tb[IFLA_MACSEC_REPLAY_PROTECT] ? !!nla_get_u8 (tb[IFLA_MACSEC_REPLAY_PROTECT]) : 0;
props->validation = tb[IFLA_MACSEC_VALIDATION] ? nla_get_u8 (tb[IFLA_MACSEC_VALIDATION]) : 0;
return obj;
}
/*****************************************************************************/
static NMPObject *
_parse_lnk_sit (const char *kind, struct nlattr *info_data)
{
@ -1555,6 +1626,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
case NM_LINK_TYPE_IPIP:
lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data);
break;
case NM_LINK_TYPE_MACSEC:
lnk_data = _parse_lnk_macsec (nl_info_kind, nl_info_data);
break;
case NM_LINK_TYPE_MACVLAN:
case NM_LINK_TYPE_MACVTAP:
lnk_data = _parse_lnk_macvlan (nl_info_kind, nl_info_data);
@ -4812,6 +4886,68 @@ nla_put_failure:
g_return_val_if_reached (FALSE);
}
static int
link_macsec_add (NMPlatform *platform,
const char *name,
int parent,
const NMPlatformLnkMacsec *props,
const NMPlatformLink **out_link)
{
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
struct nlattr *info;
struct nlattr *data;
_LOGD ("adding macsec '%s' parent %u sci %llx",
name,
parent,
(unsigned long long) props->sci);
nlmsg = _nl_msg_new_link (RTM_NEWLINK,
NLM_F_CREATE | NLM_F_EXCL,
0,
name,
0,
0);
if (!nlmsg)
return FALSE;
NLA_PUT_U32 (nlmsg, IFLA_LINK, parent);
if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO)))
goto nla_put_failure;
NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "macsec");
if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA)))
goto nla_put_failure;
if (props->icv_length)
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_ICV_LEN, 16);
if (props->cipher_suite)
NLA_PUT_U64 (nlmsg, IFLA_MACSEC_CIPHER_SUITE, props->cipher_suite);
if (props->replay_protect)
NLA_PUT_U32 (nlmsg, IFLA_MACSEC_WINDOW, props->window);
NLA_PUT_U64 (nlmsg, IFLA_MACSEC_SCI, htobe64 (props->sci));
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_ENCODING_SA, props->encoding_sa);
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_ENCRYPT, props->encrypt);
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_PROTECT, props->protect);
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_INC_SCI, props->include_sci);
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_ES, props->es);
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_SCB, props->scb);
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_REPLAY_PROTECT, props->replay_protect);
NLA_PUT_U8 (nlmsg, IFLA_MACSEC_VALIDATION, props->validation);
nla_nest_end (nlmsg, data);
nla_nest_end (nlmsg, info);
return do_add_link_with_lookup (platform,
NM_LINK_TYPE_MACSEC,
name, nlmsg, out_link);
nla_put_failure:
g_return_val_if_reached (FALSE);
}
static int
link_macvlan_add (NMPlatform *platform,
const char *name,
@ -6654,6 +6790,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->link_gre_add = link_gre_add;
platform_class->link_ip6tnl_add = link_ip6tnl_add;
platform_class->link_macsec_add = link_macsec_add;
platform_class->link_macvlan_add = link_macvlan_add;
platform_class->link_ipip_add = link_ipip_add;
platform_class->link_sit_add = link_sit_add;

View file

@ -1527,6 +1527,12 @@ nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLi
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IPIP, out_link);
}
const NMPlatformLnkMacsec *
nm_platform_link_get_lnk_macsec (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_MACSEC, out_link);
}
const NMPlatformLnkMacvlan *
nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
@ -2170,6 +2176,43 @@ nm_platform_link_ipip_add (NMPlatform *self,
return NM_PLATFORM_ERROR_SUCCESS;
}
/**
* nm_platform_macsec_add:
* @self: platform instance
* @name: name of the new interface
* @props: interface properties
* @out_link: on success, the link object
*
* Create a MACsec interface.
*/
NMPlatformError
nm_platform_link_macsec_add (NMPlatform *self,
const char *name,
int parent,
const NMPlatformLnkMacsec *props,
const NMPlatformLink **out_link)
{
NMPlatformError plerr;
_CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_MACSEC, out_link);
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
return plerr;
_LOGD ("adding macsec '%s' parent %u sci %llx",
name,
parent,
(unsigned long long) props->sci);
if (!klass->link_macsec_add (self, name, parent, props, out_link))
return NM_PLATFORM_ERROR_UNSPECIFIED;
return NM_PLATFORM_ERROR_SUCCESS;
}
/**
* nm_platform_macvlan_add:
* @self: platform instance
@ -3483,6 +3526,39 @@ nm_platform_lnk_ipip_to_string (const NMPlatformLnkIpIp *lnk, char *buf, gsize l
return buf;
}
const char *
nm_platform_lnk_macsec_to_string (const NMPlatformLnkMacsec *lnk, char *buf, gsize len)
{
if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
return buf;
g_snprintf (buf, len,
"macsec "
"sci %016llx "
"protect %s "
"cipher %016llx "
"icvlen %u "
"encodingsa %u "
"validate %u "
"encrypt %s "
"send_sci %s "
"end_station %s "
"scb %s "
"replay %s",
(unsigned long long) lnk->sci,
lnk->protect ? "on" : "off",
(unsigned long long) lnk->cipher_suite,
lnk->icv_length,
lnk->encoding_sa,
lnk->validation,
lnk->encrypt ? "on" : "off",
lnk->include_sci ? "on" : "off",
lnk->es ? "on" : "off",
lnk->scb ? "on" : "off",
lnk->replay_protect ? "on" : "off");
return buf;
}
const char *
nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, gsize len)
{
@ -4064,6 +4140,25 @@ nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b
return 0;
}
int
nm_platform_lnk_macsec_cmp (const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b)
{
_CMP_SELF (a, b);
_CMP_FIELD (a, b, sci);
_CMP_FIELD (a, b, icv_length);
_CMP_FIELD (a, b, cipher_suite);
_CMP_FIELD (a, b, window);
_CMP_FIELD (a, b, encoding_sa);
_CMP_FIELD (a, b, validation);
_CMP_FIELD (a, b, encrypt);
_CMP_FIELD (a, b, protect);
_CMP_FIELD (a, b, include_sci);
_CMP_FIELD (a, b, es);
_CMP_FIELD (a, b, scb);
_CMP_FIELD (a, b, replay_protect);
return 0;
}
int
nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b)
{

View file

@ -426,6 +426,22 @@ typedef struct {
bool path_mtu_discovery:1;
} NMPlatformLnkIpIp;
typedef struct {
int parent_ifindex;
guint64 sci; /* host byte order */
guint64 cipher_suite;
guint32 window;
guint8 icv_length;
guint8 encoding_sa;
guint8 validation;
bool encrypt:1;
bool protect:1;
bool include_sci:1;
bool es:1;
bool scb:1;
bool replay_protect:1;
} NMPlatformLnkMacsec;
typedef struct {
guint mode;
bool no_promisc:1;
@ -588,6 +604,11 @@ typedef struct {
const char *name,
const NMPlatformLnkIpIp *props,
const NMPlatformLink **out_link);
gboolean (*link_macsec_add) (NMPlatform *,
const char *name,
int parent,
const NMPlatformLnkMacsec *props,
const NMPlatformLink **out_link);
gboolean (*link_macvlan_add) (NMPlatform *,
const char *name,
int parent,
@ -818,6 +839,7 @@ const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6tnl (NMPlatform *self, in
const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkMacsec *nm_platform_link_get_lnk_macsec (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkMacvlan *nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkMacvtap *nm_platform_link_get_lnk_macvtap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
@ -902,6 +924,11 @@ NMPlatformError nm_platform_link_ipip_add (NMPlatform *self,
const char *name,
const NMPlatformLnkIpIp *props,
const NMPlatformLink **out_link);
NMPlatformError nm_platform_link_macsec_add (NMPlatform *self,
const char *name,
int parent,
const NMPlatformLnkMacsec *props,
const NMPlatformLink **out_link);
NMPlatformError nm_platform_link_macvlan_add (NMPlatform *self,
const char *name,
int parent,
@ -956,6 +983,7 @@ const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *bu
const char *nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len);
const char *nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len);
const char *nm_platform_lnk_ipip_to_string (const NMPlatformLnkIpIp *lnk, char *buf, gsize len);
const char *nm_platform_lnk_macsec_to_string (const NMPlatformLnkMacsec *lnk, char *buf, gsize len);
const char *nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, gsize len);
const char *nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len);
const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len);
@ -976,6 +1004,7 @@ int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *
int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b);
int nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b);
int nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b);
int nm_platform_lnk_macsec_cmp (const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b);
int nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b);
int nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b);
int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b);

View file

@ -2230,6 +2230,15 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ipip_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ipip_cmp,
},
[NMP_OBJECT_TYPE_LNK_MACSEC - 1] = {
.obj_type = NMP_OBJECT_TYPE_LNK_MACSEC,
.sizeof_data = sizeof (NMPObjectLnkMacsec),
.sizeof_public = sizeof (NMPlatformLnkMacsec),
.obj_type_name = "macsec",
.lnk_link_type = NM_LINK_TYPE_MACSEC,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macsec_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macsec_cmp,
},
[NMP_OBJECT_TYPE_LNK_MACVLAN - 1] = {
.obj_type = NMP_OBJECT_TYPE_LNK_MACVLAN,
.sizeof_data = sizeof (NMPObjectLnkMacvlan),

View file

@ -206,6 +206,10 @@ typedef struct {
NMPlatformLnkIpIp _public;
} NMPObjectLnkIpIp;
typedef struct {
NMPlatformLnkMacsec _public;
} NMPObjectLnkMacsec;
typedef struct {
NMPlatformLnkMacvlan _public;
} NMPObjectLnkMacvlan;
@ -267,6 +271,9 @@ struct _NMPObject {
NMPlatformLnkIp6Tnl lnk_ip6tnl;
NMPObjectLnkIp6Tnl _lnk_ip6tnl;
NMPlatformLnkMacsec lnk_macsec;
NMPObjectLnkMacsec _lnk_macsec;
NMPlatformLnkMacvlan lnk_macvlan;
NMPObjectLnkMacvlan _lnk_macvlan;

View file

@ -362,6 +362,83 @@ wifi_freqs_to_string (gboolean bg_band)
return str;
}
gboolean
nm_supplicant_config_add_setting_macsec (NMSupplicantConfig * self,
NMSettingMacsec * setting,
GError **error)
{
NMSupplicantConfigPrivate *priv;
gs_unref_bytes GBytes *bytes = NULL;
const char *value;
char buf[32];
int port;
g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
g_return_val_if_fail (setting != NULL, FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
if (!nm_supplicant_config_add_option (self, "macsec_policy", "1", -1, NULL, error))
return FALSE;
value = nm_setting_macsec_get_encrypt (setting) ? "0" : "1";
if (!nm_supplicant_config_add_option (self, "macsec_integ_only", value, -1, NULL, error))
return FALSE;
port = nm_setting_macsec_get_port (setting);
if (port > 0 && port < 65534) {
snprintf (buf, sizeof (buf), "%d", port);
if (!nm_supplicant_config_add_option (self, "macsec_port", buf, -1, NULL, error))
return FALSE;
}
if (nm_setting_macsec_get_mode (setting) == NM_SETTING_MACSEC_MODE_PSK) {
if (!nm_supplicant_config_add_option (self, "key_mgmt", "NONE", -1, NULL, error))
return FALSE;
/* CAK */
value = nm_setting_macsec_get_mka_cak (setting);
if (!value) {
g_set_error_literal (error,
NM_SUPPLICANT_ERROR,
NM_SUPPLICANT_ERROR_CONFIG,
"missing MKA CAK");
return FALSE;
}
bytes = nm_utils_hexstr2bin (value);
if (!nm_supplicant_config_add_option (self,
"mka_cak",
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes),
"<hidden>",
error))
return FALSE;
/* CKN */
value = nm_setting_macsec_get_mka_ckn (setting);
if (!value) {
g_set_error_literal (error,
NM_SUPPLICANT_ERROR,
NM_SUPPLICANT_ERROR_CONFIG,
"missing MKA CKN");
return FALSE;
}
bytes = nm_utils_hexstr2bin (value);
if (!nm_supplicant_config_add_option (self,
"mka_ckn",
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes),
NULL,
error))
return FALSE;
}
return TRUE;
}
gboolean
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
NMSettingWireless * setting,

View file

@ -22,6 +22,7 @@
#ifndef __NETWORKMANAGER_SUPPLICANT_CONFIG_H__
#define __NETWORKMANAGER_SUPPLICANT_CONFIG_H__
#include <nm-setting-macsec.h>
#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-8021x.h>
@ -71,4 +72,8 @@ gboolean nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
gboolean wired,
GError **error);
gboolean nm_supplicant_config_add_setting_macsec (NMSupplicantConfig *self,
NMSettingMacsec *setting,
GError **error);
#endif /* __NETWORKMANAGER_SUPPLICANT_CONFIG_H__ */

View file

@ -56,14 +56,14 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSupplicantInterface,
PROP_IFACE,
PROP_SCANNING,
PROP_CURRENT_BSS,
PROP_IS_WIRELESS,
PROP_DRIVER,
PROP_FAST_SUPPORTED,
PROP_AP_SUPPORT,
);
typedef struct {
char * dev;
bool is_wireless;
NMSupplicantDriver driver;
bool fast_supported;
gboolean has_credreq; /* Whether querying 802.1x credentials is supported */
NMSupplicantFeature ap_support; /* Lightweight AP mode support */
@ -918,6 +918,7 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
gs_free_error GError *error = NULL;
GDBusProxy *wpas_proxy;
GVariantBuilder props;
const char *driver_name = NULL;
wpas_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
if (!wpas_proxy) {
@ -939,10 +940,24 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
* when the supplicant has started.
*/
switch (priv->driver) {
case NM_SUPPLICANT_DRIVER_WIRELESS:
driver_name = DEFAULT_WIFI_DRIVER;
break;
case NM_SUPPLICANT_DRIVER_WIRED:
driver_name = "wired";
break;
case NM_SUPPLICANT_DRIVER_MACSEC:
driver_name = "macsec_linux";
break;
}
g_return_if_fail (driver_name);
g_variant_builder_init (&props, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&props, "{sv}",
"Driver",
g_variant_new_string (priv->is_wireless ? DEFAULT_WIFI_DRIVER : "wired"));
g_variant_new_string (driver_name));
g_variant_builder_add (&props, "{sv}",
"Ifname",
g_variant_new_string (priv->dev));
@ -1448,7 +1463,7 @@ nm_supplicant_interface_get_max_scan_ssids (NMSupplicantInterface *self)
NMSupplicantInterface *
nm_supplicant_interface_new (const char *ifname,
gboolean is_wireless,
NMSupplicantDriver driver,
gboolean fast_supported,
NMSupplicantFeature ap_support)
{
@ -1456,7 +1471,7 @@ nm_supplicant_interface_new (const char *ifname,
return g_object_new (NM_TYPE_SUPPLICANT_INTERFACE,
NM_SUPPLICANT_INTERFACE_IFACE, ifname,
NM_SUPPLICANT_INTERFACE_IS_WIRELESS, is_wireless,
NM_SUPPLICANT_INTERFACE_DRIVER, (guint) driver,
NM_SUPPLICANT_INTERFACE_FAST_SUPPORTED, fast_supported,
NM_SUPPLICANT_INTERFACE_AP_SUPPORT, (int) ap_support,
NULL);
@ -1485,9 +1500,9 @@ set_property (GObject *object,
priv->dev = g_value_dup_string (value);
g_return_if_fail (priv->dev);
break;
case PROP_IS_WIRELESS:
case PROP_DRIVER:
/* construct-only */
priv->is_wireless = g_value_get_boolean (value);
priv->driver = g_value_get_uint (value);
break;
case PROP_FAST_SUPPORTED:
/* construct-only */
@ -1576,12 +1591,12 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_IS_WIRELESS] =
g_param_spec_boolean (NM_SUPPLICANT_INTERFACE_IS_WIRELESS, "", "",
TRUE,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_DRIVER] =
g_param_spec_uint (NM_SUPPLICANT_INTERFACE_DRIVER, "", "",
0, G_MAXUINT, NM_SUPPLICANT_DRIVER_WIRELESS,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_FAST_SUPPORTED] =
g_param_spec_boolean (NM_SUPPLICANT_INTERFACE_FAST_SUPPORTED, "", "",
TRUE,

View file

@ -57,7 +57,7 @@ enum {
#define NM_SUPPLICANT_INTERFACE_IFACE "iface"
#define NM_SUPPLICANT_INTERFACE_SCANNING "scanning"
#define NM_SUPPLICANT_INTERFACE_CURRENT_BSS "current-bss"
#define NM_SUPPLICANT_INTERFACE_IS_WIRELESS "is-wireless"
#define NM_SUPPLICANT_INTERFACE_DRIVER "driver"
#define NM_SUPPLICANT_INTERFACE_FAST_SUPPORTED "fast-supported"
#define NM_SUPPLICANT_INTERFACE_AP_SUPPORT "ap-support"
@ -76,7 +76,7 @@ typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass;
GType nm_supplicant_interface_get_type (void);
NMSupplicantInterface * nm_supplicant_interface_new (const char *ifname,
gboolean is_wireless,
NMSupplicantDriver driver,
gboolean fast_supported,
NMSupplicantFeature ap_support);

View file

@ -137,7 +137,7 @@ _sup_iface_last_ref (gpointer data,
NMSupplicantInterface *
nm_supplicant_manager_create_interface (NMSupplicantManager *self,
const char *ifname,
gboolean is_wireless)
NMSupplicantDriver driver)
{
NMSupplicantManagerPrivate *priv;
NMSupplicantInterface *iface;
@ -157,7 +157,7 @@ nm_supplicant_manager_create_interface (NMSupplicantManager *self,
}
iface = nm_supplicant_interface_new (ifname,
is_wireless,
driver,
priv->fast_supported,
priv->ap_support);

View file

@ -40,6 +40,6 @@ NMSupplicantManager *nm_supplicant_manager_get (void);
NMSupplicantInterface *nm_supplicant_manager_create_interface (NMSupplicantManager *mgr,
const char *ifname,
gboolean is_wireless);
NMSupplicantDriver driver);
#endif /* __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ */

View file

@ -141,6 +141,11 @@ static const struct Opt opt_table[] = {
{ "bgscan", TYPE_BYTES, 0, 0, FALSE, NULL },
{ "pac_file", TYPE_BYTES, 0, 1024, FALSE, NULL },
{ "freq_list", TYPE_KEYWORD, 0, 0, FALSE, NULL },
{ "macsec_policy", TYPE_INT, 0, 1, FALSE, NULL },
{ "macsec_integ_only", TYPE_INT, 0, 1, FALSE, NULL },
{ "mka_cak", TYPE_BYTES, 0, 65536, FALSE, NULL },
{ "mka_ckn", TYPE_BYTES, 0, 65536, FALSE, NULL },
{ "macsec_port", TYPE_INT, 1, 65534, FALSE, NULL },
};

View file

@ -46,6 +46,12 @@ typedef enum {
NM_SUPPLICANT_ERROR_CONFIG = 1, /*< nick=Config >*/
} NMSupplicantError;
typedef enum {
NM_SUPPLICANT_DRIVER_WIRELESS,
NM_SUPPLICANT_DRIVER_WIRED,
NM_SUPPLICANT_DRIVER_MACSEC,
} NMSupplicantDriver;
#define NM_SUPPLICANT_ERROR (nm_supplicant_error_quark ())
GQuark nm_supplicant_error_quark (void);